From 92b950333c6c7002bdbf1b60af44a249dc0cef9c Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sun, 19 Dec 2021 12:21:44 +0100 Subject: First commit for Version 3 of STC. Main changes are consistent rename of '_del' to '_drop' and '_compare' to '_cmp'. Also i_key_ref (earlier i_key_sptr) and i_val_ref replaced by more general i_key_bind/i_val_bind. --- README.md | 67 +++-- benchmarks/picobench/picobench_cmap.cpp | 12 +- benchmarks/picobench/picobench_csmap.cpp | 14 +- benchmarks/plotbench/cdeq_benchmark.cpp | 4 +- benchmarks/plotbench/clist_benchmark.cpp | 4 +- benchmarks/plotbench/cmap_benchmark.cpp | 4 +- benchmarks/plotbench/cpque_benchmark.cpp | 9 +- benchmarks/plotbench/csmap_benchmark.cpp | 4 +- benchmarks/plotbench/cvec_benchmark.cpp | 4 +- benchmarks/shootout_hashmaps.cpp | 2 +- docs/carray_api.md | 12 +- docs/cbits_api.md | 4 +- docs/cbox_api.md | 66 ++--- docs/ccommon_api.md | 22 +- docs/cdeq_api.md | 6 +- docs/clist_api.md | 10 +- docs/cmap_api.md | 161 ++++++------ docs/cpque_api.md | 8 +- docs/cqueue_api.md | 6 +- docs/crandom_api.md | 4 +- docs/cset_api.md | 8 +- docs/csmap_api.md | 16 +- docs/csptr_api.md | 94 +++---- docs/csset_api.md | 12 +- docs/cstack_api.md | 6 +- docs/cstr_api.md | 13 +- docs/csview_api.md | 6 +- docs/cvec_api.md | 26 +- examples/advanced.c | 68 ------ examples/astar.c | 18 +- examples/bits.c | 6 +- examples/box.c | 39 ++- examples/box2.c | 7 +- examples/complex.c | 61 +++-- examples/cpque.c | 6 +- examples/csmap_find.c | 2 +- examples/csmap_insert.c | 2 +- examples/cstr_match.c | 2 +- examples/demos.c | 12 +- examples/ex_gauss1.c | 2 +- examples/inits.c | 10 +- examples/mapmap.c | 78 +++--- examples/mmap.c | 24 +- examples/multimap.c | 12 +- examples/new_arr.c | 6 +- examples/new_deq.c | 8 +- examples/new_list.c | 8 +- examples/new_map.c | 8 +- examples/new_pque.c | 4 +- examples/new_queue.c | 8 +- examples/new_smap.c | 8 +- examples/new_sptr.c | 20 +- examples/new_vec.c | 16 +- examples/prime.c | 2 +- examples/priority.c | 2 +- examples/queue.c | 2 +- examples/rawptr_elements.c | 4 +- examples/read.c | 8 +- examples/replace.c | 2 +- examples/splitstr.c | 2 +- examples/sptr_demo.c | 16 +- examples/sptr_erase.c | 41 ++-- examples/sptr_music.c | 23 +- examples/sptr_pthread.c | 7 +- examples/sptr_to_maps.c | 11 +- examples/vikings.c | 69 ++++++ include/stc/alt/clist.h | 18 +- include/stc/alt/csmap.h | 30 +-- include/stc/alt/cstr.h | 27 +- include/stc/alt/sstr.h | 406 ------------------------------- include/stc/carr2.h | 13 +- include/stc/carr3.h | 13 +- include/stc/cbits.h | 6 +- include/stc/cbox.h | 63 ++--- include/stc/ccommon.h | 34 +-- include/stc/cdeq.h | 33 +-- include/stc/clist.h | 34 +-- include/stc/cmap.h | 37 +-- include/stc/cpque.h | 10 +- include/stc/cset.h | 2 +- include/stc/csmap.h | 45 ++-- include/stc/csptr.h | 60 ++--- include/stc/csset.h | 2 +- include/stc/cstack.h | 8 +- include/stc/cstr.h | 7 +- include/stc/csview.h | 8 +- include/stc/cvec.h | 41 ++-- include/stc/template.h | 162 ++++++------ 88 files changed, 982 insertions(+), 1305 deletions(-) delete mode 100644 examples/advanced.c create mode 100644 examples/vikings.c delete mode 100644 include/stc/alt/sstr.h diff --git a/README.md b/README.md index 452cc245..9d1587a8 100644 --- a/README.md +++ b/README.md @@ -5,23 +5,36 @@ STC - Smart Template Containers for C News ---- +### Version 3.0 released. Migration guide for breaking changes from version 2.X: +There are new general `i_key_bind` / `i_val_bind` template parameters which auto-binds a set of functions to the type specified, and can be used in place of `i_key` / `i_val`. Use the `_bind` variant for elements of Type which have following functions defined: *Type_cmp*, *Type_clone*, *Type_drop*, *Type_equalto*, and *Type_hash*. Only the functions required by the particular container needs to be defined, e.g. only **cmap** and **cset** require *Type_equalto* and *Type_hash* to be defined. +You may still define template parameters with `i_val` / `i_key` as before, which is easier for simple element types. + +Regex replace in VS Code: +- `_del\b` → `_drop` +- `_compare\b` → `_cmp` + +Whole word + Match case: +- `i_keydel` → `i_keydrop` +- `i_valdel` → `i_valdrop` +- `i_cnt` → `i_type` +- `i_key_csptr` → `i_key_bind` +- `i_val_csptr` → `i_val_bind` +- `cstr_lit` → `cstr_new` +- `csptr_X_make` → `csptr_X_new` + +### Final version 2.1 - Strings: Renamed constructor *cstr_lit()* to `cstr_new(lit)`. Renamed *cstr_assign_fmt()* to `cstr_printf()`. - Added [**cbox**](docs/cbox_api.md) type: container of one element, similar to [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr) - Added [example for **csptr**](examples/sptr_to_maps.c). - Added [**c_forpair**](docs/ccommon_api.md) macro: for-loop with "structured binding". - Deprecated *csptr_X_make()*. Renamed to *csptr_X_new()*. Corresponding **cbox** method is *cbox_X_new()*. - Deprecated *c_default_fromraw(raw)*. Renamed to *c_default_clone(raw)*. -- Deprecated `i_key_csptr` / `i_val_csptr`. Use `i_key_ref` / `i_val_ref` when specifying containers with **csptr** or **cbox** elements. -- Deprecated `i_cnt`. Use `i_type` instead to define the full container type name. +- Deprecated `i_key_csptr` / `i_val_csptr`. Use `i_key_bind` / `i_val_bind` +- Deprecated `i_cnt`. Use `i_type` instead to define the complete container type name. +- Added `i_opt` template parameter: compile-time options: `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_fwd`; may be combined with `|` -Previous: -- Added `i_opt` template parameter: compile-time options: `c_no_compare`, `c_no_clone`, `c_no_atomic`, `c_is_fwd`; may be combined with `|` -- Removed: i_cmp_none and i_fwd: replaced by `c_no_compare` and `c_is_fwd` args to `i_opt`. - -VERSION 2.0 released. Two main breaking changes from V1.X. +### Version 2.0. Two main breaking changes from V1.X. - Uses a different way to instantiate templated containers, which is incompatible with v1.X. -- New **c_auto**, **c_autovar**, and **c_autoscope** macros. These are for automatic scope resource management, aka RAII. -- The new template instantiation style has multiple advantages, e.g. implementation does not contain long macro definitions for code generation. Also, specifying template arguments is more user friendly and flexible. Introduction ------------ @@ -101,24 +114,24 @@ int main(void) { c_foreach (i, cvec_float, vec) printf(" %g", *i.ref); - cvec_float_del(&vec); + cvec_float_drop(&vec); } ``` In order to include two **cvec**s with different element types, include cvec.h twice. For struct, a `i_cmp` compare function is required to enable sorting and searching (`<` and `==` operators is default and works -for integral types only). Alternatively, `#define i_opt c_no_compare` to disable methods using comparison. +for integral types only). Alternatively, `#define i_opt c_no_cmp` to disable methods using comparison. -Similarly, if a destructor `i_del` is defined, either define a `i_valfrom` construct/clone function +Similarly, if a destructor `i_drop` is defined, either define a `i_valfrom` construct/clone function or `#define i_opt c_no_clone` to disable cloning and emplace methods. Unless these requirements are met, compile errors are generated. ```c #define i_val struct One -#define i_opt c_no_compare +#define i_opt c_no_cmp #define i_tag one #include #define i_val struct Two -#define i_opt c_no_compare +#define i_opt c_no_cmp #define i_tag two #include ... @@ -133,16 +146,16 @@ With six different containers: struct Point { float x, y; }; -int Point_compare(const struct Point* a, const struct Point* b) { - int cmp = c_default_compare(&a->x, &b->x); - return cmp ? cmp : c_default_compare(&a->y, &b->y); +int Point_cmp(const struct Point* a, const struct Point* b) { + int cmp = c_default_cmp(&a->x, &b->x); + return cmp ? cmp : c_default_cmp(&a->y, &b->y); } #define i_key int #include // cset_int: unordered set #define i_val struct Point -#define i_cmp Point_compare +#define i_cmp Point_cmp #define i_tag pnt #include // cvec_pnt: vector of struct Point @@ -160,7 +173,7 @@ int Point_compare(const struct Point* a, const struct Point* b) { #include // csmap_int: sorted map int => int int main(void) { - // define six containers with automatic call of init and del (destruction after scope exit) + // define six containers with automatic call of init and drop (destruction after scope exit) c_auto (cset_int, set) c_auto (cvec_pnt, vec) c_auto (cdeq_int, deq) @@ -267,28 +280,28 @@ The list of template parameters: - `i_tag` - Container type tag. Defaults to same as `i_key` - `i_type` - Full container type name (optional, alternative to `i_tag`). -- `i_opt` - Boolean properties: may combine `c_no_compare`, `c_no_clone`, `c_no_atomic`, `c_is_fwd` with `|` separator. +- `i_opt` - Boolean properties: may combine `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_fwd` with `|` separator. - `i_key` - Maps key type. **[required]** for cmap/csmap. - `i_val` - The container **[required]** element type. For cmap/csmap, it is the mapped value. - `i_cmp` - Three-way comparison of two `i_keyraw`, **[required]** for non-integral `i_keyraw`. - `i_equ` - Equality comparison of two `i_keyraw`- defaults to `!i_cmp`. -- `i_keydel` - Destroy map key func - defaults to empty destructor. +- `i_keydrop` - Destroy map key func - defaults to empty destructor. - `i_keyraw` - Convertion "raw" type - defaults to `i_key` type. -- `i_keyfrom` - Convertion func `i_keyraw` => `i_key` - defaults to simple copy. **[required]** if `i_keydel` is defined. +- `i_keyfrom` - Convertion func `i_keyraw` => `i_key` - defaults to simple copy. **[required]** if `i_keydrop` is defined. - `i_keyto` - Convertion func `i_key` => `i_keyraw` - defaults to simple copy. -- `i_valdel` - Destroy mapped or value func - defaults to empty destruct. +- `i_valdrop` - Destroy mapped or value func - defaults to empty destruct. - `i_valraw` - Convertion "raw" type - defaults to `i_val` type. - `i_valfrom` - Convertion func `i_valraw` => `i_val` - defaults to simple copy. - `i_valto` - Convertion func `i_val` => `i_valraw` - defaults to simple copy. -Instead of defining `i_cmp`, you may define `i_opt c_no_compare` to disable methods using comparison. +Instead of defining `i_cmp`, you may define `i_opt c_no_cmp` to disable methods using comparison. Instead of defining `i_valfrom`, you may define `i_opt c_no_clone` to disable methods using deep copy. -If a destructor `i_del` is defined, then define either `i_valfrom` or `i_opt c_no_clone`, otherwise +If a destructor `i_drop` is defined, then define either `i_valfrom` or `i_opt c_no_clone`, otherwise compile errors are generated. The *emplace* versus non-emplace container methods @@ -318,8 +331,8 @@ and non-emplace methods: #define i_val_str // special macro to enable container of cstr #include // vector of string (cstr) ... -c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_del(&vec) -c_autovar (cstr s = cstr_new("a string literal"), cstr_del(&s)) // c_autovar is a more general c_auto. +c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_drop(&vec) +c_autovar (cstr s = cstr_new("a string literal"), cstr_drop(&s)) // c_autovar is a more general c_auto. { const char* hello = "Hello"; cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* diff --git a/benchmarks/picobench/picobench_cmap.cpp b/benchmarks/picobench/picobench_cmap.cpp index 330c5e51..a045cb7c 100644 --- a/benchmarks/picobench/picobench_cmap.cpp +++ b/benchmarks/picobench/picobench_cmap.cpp @@ -91,7 +91,7 @@ static void ins_and_erase_cmap_i(picobench::state& s) c_forrange (s.iterations()) cmap_i_erase(&map, stc64_random()); s.set_result(cmap_i_size(map)); - cmap_i_del(&map); + cmap_i_drop(&map); } static void ins_and_erase_cmap_x(picobench::state& s) @@ -111,7 +111,7 @@ static void ins_and_erase_cmap_x(picobench::state& s) c_forrange (s.iterations()) cmap_x_erase(&map, stc64_random()); s.set_result(cmap_x_size(map)); - cmap_x_del(&map); + cmap_x_drop(&map); } #define P samples(S1).iterations({N1/4}) @@ -153,7 +153,7 @@ static void ins_and_access_cmap_i(picobench::state& s) c_forrange (N1) result += ++cmap_i_emplace(&map, stc64_random() & mask, 0).ref->second; s.set_result(result); - cmap_i_del(&map); + cmap_i_drop(&map); } #define P samples(S1).iterations({N1, N1, N1, N1}).args({18, 23, 25, 31}) @@ -212,8 +212,8 @@ static void ins_and_access_cmap_s(picobench::state& s) result += cmap_str_erase(&map, str.str); } s.set_result(result + cmap_str_size(map)); - cstr_del(&str); - cmap_str_del(&map); + cstr_drop(&str); + cmap_str_drop(&map); } #define P samples(S1).iterations({N1/5, N1/5, N1/5, N1/10, N1/40}).args({13, 7, 8, 100, 1000}) @@ -285,7 +285,7 @@ static void iterate_cmap_x(picobench::state& s) result += i.ref->second; } s.set_result(result); - cmap_x_del(&map); + cmap_x_drop(&map); } diff --git a/benchmarks/picobench/picobench_csmap.cpp b/benchmarks/picobench/picobench_csmap.cpp index 7a0addad..90681cd5 100644 --- a/benchmarks/picobench/picobench_csmap.cpp +++ b/benchmarks/picobench/picobench_csmap.cpp @@ -52,7 +52,7 @@ static void ctor_and_ins_one_csmap_i(picobench::state& s) csmap_i map = csmap_i_init(); csmap_i_emplace(&map, n, 0); result += csmap_i_size(map); - csmap_i_del(&map); + csmap_i_drop(&map); } s.set_result(result); } @@ -86,7 +86,7 @@ static void insert_csmap_i(picobench::state& s) c_forrange (n, s.iterations()) csmap_i_emplace(&map, stc64_random() & 0xfffffff, n); s.set_result(csmap_i_size(map)); - csmap_i_del(&map); + csmap_i_drop(&map); } #define P samples(S1).iterations({N1}) @@ -142,7 +142,7 @@ static void ins_and_erase_csmap_i(picobench::state& s) c_forrange (s.iterations()) csmap_i_erase(&map, stc64_random() & mask); s.set_result(result); - csmap_i_del(&map); + csmap_i_drop(&map); } #define P samples(S1).iterations({N1/2, N1/2, N1/2, N1/2}).args({18, 23, 25, 31}) @@ -183,7 +183,7 @@ static void ins_and_access_csmap_i(picobench::state& s) if (val) csmap_i_erase(&map, val->first); } s.set_result(result + csmap_i_size(map)); - csmap_i_del(&map); + csmap_i_drop(&map); } #define P samples(S1).iterations({N1, N1, N1, N1}).args({18, 23, 25, 31}) @@ -243,8 +243,8 @@ static void ins_and_access_csmap_s(picobench::state& s) }*/ } s.set_result(result + csmap_str_size(map)); - cstr_del(&str); - csmap_str_del(&map); + cstr_drop(&str); + csmap_str_drop(&map); } #define P samples(S1).iterations({N1/5, N1/5, N1/5, N1/10, N1/40}).args({13, 7, 8, 100, 1000}) @@ -309,7 +309,7 @@ static void iterate_csmap_x(picobench::state& s) result += i.ref->second; } s.set_result(result); - csmap_x_del(&map); + csmap_x_drop(&map); } diff --git a/benchmarks/plotbench/cdeq_benchmark.cpp b/benchmarks/plotbench/cdeq_benchmark.cpp index 6db167b0..f57da6b2 100644 --- a/benchmarks/plotbench/cdeq_benchmark.cpp +++ b/benchmarks/plotbench/cdeq_benchmark.cpp @@ -81,7 +81,7 @@ Sample test_stc_deque() { c_forrange (cdeq_x_size(con)/2) { cdeq_x_pop_front(&con); cdeq_x_pop_back(&con); } s.test[ERASE].t2 = clock(); s.test[ERASE].sum = cdeq_x_size(con); - cdeq_x_del(&con); + cdeq_x_drop(&con); }{ stc64_srandom(seed); container con = cdeq_x_init(); @@ -98,7 +98,7 @@ Sample test_stc_deque() { s.test[ITER].t2 = clock(); s.test[ITER].sum = sum; s.test[DESTRUCT].t1 = clock(); - cdeq_x_del(&con); + cdeq_x_drop(&con); } s.test[DESTRUCT].t2 = clock(); s.test[DESTRUCT].sum = 0; diff --git a/benchmarks/plotbench/clist_benchmark.cpp b/benchmarks/plotbench/clist_benchmark.cpp index 676d31e7..eaa18201 100644 --- a/benchmarks/plotbench/clist_benchmark.cpp +++ b/benchmarks/plotbench/clist_benchmark.cpp @@ -78,7 +78,7 @@ Sample test_stc_forward_list() { c_forrange (N) clist_x_pop_front(&con); s.test[ERASE].t2 = clock(); s.test[ERASE].sum = 0; - clist_x_del(&con); + clist_x_drop(&con); }{ stc64_srandom(seed); container con = clist_x_init(); @@ -95,7 +95,7 @@ Sample test_stc_forward_list() { s.test[ITER].t2 = clock(); s.test[ITER].sum = sum; s.test[DESTRUCT].t1 = clock(); - clist_x_del(&con); + clist_x_drop(&con); } s.test[DESTRUCT].t2 = clock(); s.test[DESTRUCT].sum = 0; diff --git a/benchmarks/plotbench/cmap_benchmark.cpp b/benchmarks/plotbench/cmap_benchmark.cpp index 4c9c6c16..16aec8c0 100644 --- a/benchmarks/plotbench/cmap_benchmark.cpp +++ b/benchmarks/plotbench/cmap_benchmark.cpp @@ -82,7 +82,7 @@ Sample test_stc_unordered_map() { c_forrange (N) cmap_x_erase(&con, stc64_random() & mask1); s.test[ERASE].t2 = clock(); s.test[ERASE].sum = cmap_x_size(con); - cmap_x_del(&con); + cmap_x_drop(&con); }{ container con = cmap_x_init(); stc64_srandom(seed); @@ -103,7 +103,7 @@ Sample test_stc_unordered_map() { s.test[ITER].t2 = clock(); s.test[ITER].sum = sum; s.test[DESTRUCT].t1 = clock(); - cmap_x_del(&con); + cmap_x_drop(&con); } s.test[DESTRUCT].t2 = clock(); s.test[DESTRUCT].sum = 0; diff --git a/benchmarks/plotbench/cpque_benchmark.cpp b/benchmarks/plotbench/cpque_benchmark.cpp index 19a9c701..33e55719 100644 --- a/benchmarks/plotbench/cpque_benchmark.cpp +++ b/benchmarks/plotbench/cpque_benchmark.cpp @@ -3,7 +3,7 @@ #include #define i_val float -#define i_cmp -c_default_compare +#define i_cmp -c_default_cmp #define i_tag f #include @@ -14,11 +14,12 @@ int main() int N = 10000000, M = 10; cpque_f pq = cpque_f_init(); + cpque_f_resize(&pq, N, 0.0f); rng = stc64_init(seed); clock_t start = clock(); - c_forrange (i, int, N) - cpque_f_push_back(&pq, (float) stc64_randf(&rng)*100000); + c_forrange (i, N) + pq.data[i] = (float) stc64_randf(&rng)*100000; cpque_f_make_heap(&pq); printf("Built priority queue: %f secs\n", (clock() - start) / (float) CLOCKS_PER_SEC); @@ -44,5 +45,5 @@ int main() } puts(""); - cpque_f_del(&pq); + cpque_f_drop(&pq); } diff --git a/benchmarks/plotbench/csmap_benchmark.cpp b/benchmarks/plotbench/csmap_benchmark.cpp index 47762791..4d1621e3 100644 --- a/benchmarks/plotbench/csmap_benchmark.cpp +++ b/benchmarks/plotbench/csmap_benchmark.cpp @@ -82,7 +82,7 @@ Sample test_stc_map() { c_forrange (N) csmap_x_erase(&con, stc64_random() & mask1); s.test[ERASE].t2 = clock(); s.test[ERASE].sum = csmap_x_size(con); - csmap_x_del(&con); + csmap_x_drop(&con); }{ container con = csmap_x_init(); stc64_srandom(seed); @@ -103,7 +103,7 @@ Sample test_stc_map() { s.test[ITER].t2 = clock(); s.test[ITER].sum = sum; s.test[DESTRUCT].t1 = clock(); - csmap_x_del(&con); + csmap_x_drop(&con); } s.test[DESTRUCT].t2 = clock(); s.test[DESTRUCT].sum = 0; diff --git a/benchmarks/plotbench/cvec_benchmark.cpp b/benchmarks/plotbench/cvec_benchmark.cpp index c4648e34..21e7a229 100644 --- a/benchmarks/plotbench/cvec_benchmark.cpp +++ b/benchmarks/plotbench/cvec_benchmark.cpp @@ -77,7 +77,7 @@ Sample test_stc_vector() { c_forrange (N) { cvec_x_pop_back(&con); } s.test[ERASE].t2 = clock(); s.test[ERASE].sum = cvec_x_size(con); - cvec_x_del(&con); + cvec_x_drop(&con); }{ stc64_srandom(seed); container con = cvec_x_init(); @@ -94,7 +94,7 @@ Sample test_stc_vector() { s.test[ITER].t2 = clock(); s.test[ITER].sum = sum; s.test[DESTRUCT].t1 = clock(); - cvec_x_del(&con); + cvec_x_drop(&con); } s.test[DESTRUCT].t2 = clock(); s.test[DESTRUCT].sum = 0; diff --git a/benchmarks/shootout_hashmaps.cpp b/benchmarks/shootout_hashmaps.cpp index 40e0e579..6439c548 100644 --- a/benchmarks/shootout_hashmaps.cpp +++ b/benchmarks/shootout_hashmaps.cpp @@ -47,7 +47,7 @@ size_t seed; #define CMAP_SIZE(X) cmap_##X##_size(map) #define CMAP_BUCKETS(X) cmap_##X##_bucket_count(map) #define CMAP_CLEAR(X) cmap_##X##_clear(&map) -#define CMAP_DTOR(X) cmap_##X##_del(&map) +#define CMAP_DTOR(X) cmap_##X##_drop(&map) #define KMAP_SETUP(X, Key, Value) khash_t(X)* map = kh_init(X); khiter_t ki; int ret #define KMAP_PUT(X, key, val) (*(ki = kh_put(X, map, key, &ret), map->vals[ki] = val, map->vals+ki)) diff --git a/docs/carray_api.md b/docs/carray_api.md index 5e26f658..3ac6d650 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -10,8 +10,8 @@ See the c++ class [boost::multi_array](https://www.boost.org/doc/libs/release/li ```c #define i_val // value: REQUIRED -#define i_del // destroy value func - defaults to empty destruct -#define i_valfrom // func Raw => i_val - defaults to plain copy +#define i_drop // destroy value func - defaults to empty destruct +#define i_from // func Raw => i_val - defaults to plain copy #define i_valto // func i_val => Raw - defaults to plain copy #define i_tag // defaults to i_val @@ -29,7 +29,7 @@ carr2_X carr2_X_with_storage(size_t xdim, size_t ydim, i_val* array) carr2_X carr2_X_clone(carr2_X arr); void carr2_X_copy(carr2_X* self, carr2_X other); i_val* carr2_X_release(carr2_X* self); // release storage (not freed) -void carr2_X_del(carr2_X* self); +void carr2_X_drop(carr2_X* self); size_t carr2_X_size(carr2_X arr); i_val* carr2_X_data(carr2_X* self); // access storage data @@ -48,7 +48,7 @@ carr3_X carr3_X_with_storage(size_t xdim, size_t ydim, size_t zdim, carr3_X carr3_X_clone(carr3_X arr); void carr3_X_copy(carr3_X* self, carr3_X other); i_val* carr3_X_release(carr3_X* self); // release storage (not freed) -void carr3_X_del(carr3_X* self); +void carr3_X_drop(carr3_X* self); size_t carr3_X_size(carr3_X arr); i_val* carr3_X_data(carr3_X* self); // storage data @@ -91,7 +91,7 @@ int main() int xd = 30, yd = 20, zd = 10; // define arr3[30][20][10], initialized with zeros. c_autovar (carr3_f arr3 = carr3_f_with_values(xd, yd, zd, 0.0f), - carr3_f_del(&arr3)) { + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 3.14f; float *arr1 = arr3.data[5][4]; @@ -104,7 +104,7 @@ int main() // Ex2 int w = 256, h = 128; - c_autovar (carr2_i image = carr2_i_init(w, h), carr2_i_del(&image)) { + c_autovar (carr2_i image = carr2_i_init(w, h), carr2_i_drop(&image)) { int n = 0; c_foreach (i, carr2_i, image) { uint32_t t = n++ % 256; diff --git a/docs/cbits_api.md b/docs/cbits_api.md index b369b5d1..f6077d20 100644 --- a/docs/cbits_api.md +++ b/docs/cbits_api.md @@ -27,7 +27,7 @@ cbits cbits_clone(cbits other); void cbits_clear(cbits* self); cbits* cbits_copy(cbits* self, cbits other); void cbits_resize(cbits* self, size_t size, bool value); -void cbits_del(cbits* self); +void cbits_drop(cbits* self); cbits* cbits_take(cbits* self, cbits other); // give other to self cbits cbits_move(cbits* self); // transfer self to caller @@ -103,7 +103,7 @@ int main(void) if (cbits_test(primes, i>>1)) printf(" %zu", i); puts(""); - cbits_del(&primes); + cbits_drop(&primes); } ``` Output: diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 83cec830..8580e7d7 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -1,12 +1,12 @@ # STC [cbox](../include/stc/cbox.h): (Boxed) Heap Allocated Objects **cbox** is a A box is a smart pointer to a heap allocated value of type X. A **cbox** can -be empty. The *cbox_X_compare()*, *cbox_X_del()* methods are defined based on the `i_cmp` -and `i_valdel` macros specified. Use *cbox_X_clone(p)* to make a deep copy, which uses the +be empty. The *cbox_X_cmp()*, *cbox_X_drop()* methods are defined based on the `i_cmp` +and `i_valdrop` macros specified. Use *cbox_X_clone(p)* to make a deep copy, which uses the `i_valfrom` macro if defined. -When declaring a container of **cbox** values, it is recommended to define `i_val_ref` to the -cbox type instead of defining `i_val`. This will auto-set `i_del`, `i_from`, and `i_cmp` using +When declaring a container of **cbox** values, it is recommended to define `i_val_bind` to the +cbox type instead of defining `i_val`. This will auto-set `i_drop`, `i_from`, and `i_cmp` using functions defined by the specified **cbox**. For containers, make sure to pass the result of create functions like *cbox_X_new()* **only** to @@ -20,21 +20,21 @@ See similar c++ class [std::unique_ptr](https://en.cppreference.com/w/cpp/memory ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_val* : REQUIRED IF i_val is a non-integral type -#define i_del // destroy value func - defaults to empty destruct -#define i_from // create from raw/clone func - REQUIRED if i_del is defined, +#define i_drop // destroy value func - defaults to empty destruct +#define i_from // create from raw/clone func - REQUIRED if i_drop is defined, // unless 'i_opt c_no_clone' is defined. #define i_tag // type name tag, defaults to i_val #include ``` `X` should be replaced by the value of `i_tag` in all of the following documentation. -Define `i_opt` with `c_no_compare` if comparison between i_val's is not needed/available. Will then +Define `i_opt` with `c_no_cmp` if comparison between i_val's is not needed/available. Will then compare the pointer addresses when used. Additionally, `c_no_clone` or `i_is_fwd` may be defined. ## Methods ```c cbox_X cbox_X_init(); // return an empty cbox cbox_X cbox_X_new(i_val val); // allocate new heap object with val. Take ownership of val. -cbox_X cbox_X_from(i_rawval raw); // like cbox_X_new(), but create owned value from raw. +cbox_X cbox_X_from(i_valraw raw); // like cbox_X_new(), but create owned value from raw. cbox_X cbox_X_with(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 @@ -42,14 +42,14 @@ cbox_X cbox_X_move(cbox_X* self); // transfer owners void cbox_X_take(cbox_X* self, cbox_X other); // take ownership of other. void cbox_X_copy(cbox_X* self, cbox_X other); // deep copy to self -void cbox_X_del(cbox_X* self); // destruct the contained object and free's it. +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_new(cbox_X* self, i_val val); // assign new cbox with value. Takes ownership of val. -void cbox_X_reset_from(cbox_X* self, i_rawval raw); // make and assign new cbox from raw value. +void cbox_X_reset_from(cbox_X* self, i_valraw raw); // make and assign new cbox from raw value. void cbox_X_reset_with(cbox_X* self, i_val* p); // create cbox with pointer p. Takes ownership of p. -int cbox_X_compare(const cbox_X* x, const cbox_X* y); // compares pointer addresses if 'i_opt c_no_compare' +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 compare. ``` ## Types and constants @@ -66,14 +66,14 @@ int cbox_X_compare(const cbox_X* x, const cbox_X* y); // compares pointe #include #include -void int_del(int* x) { - printf("del: %d\n", *x); +void int_drop(int* x) { + printf("drop: %d\n", *x); } -// When 'i_del' is defined, you are also forced to define a clone function with -// 'i_valfrom', as it is normally required when i_del destroys resources. +// When 'i_drop' is defined, you are also forced to define a clone function with +// 'i_from', as it is normally required when i_drop destroys resources. // -// If cloning is not needed, define 'i_opt c_no_clone' instead of 'i_valfrom' +// If cloning is not needed, define 'i_opt c_no_clone' instead of 'i_from' // both for the cbox type and the container of cbox elements. It will also // disable emplace container functions. // @@ -81,22 +81,22 @@ void int_del(int* x) { // define cloning internally. #define i_val int -#define i_del int_del // optional func, just to display elements destroyed -#define i_valfrom c_default_clone -#include // cbox_int +#define i_drop int_drop // optional func, just to display elements destroyed +#define i_from c_default_clone +#include // cbox_int -#define i_key_ref cbox_int // note: use i_key_ref instead of i_key -#define i_tag int // tag otherwise defaults to 'ref' -#include // csset_int (like: std::set>) +#define i_key_bind cbox_int // note: use i_key_bind instead of i_key +#define i_tag int // tag otherwise defaults to 'ref' +#include // csset_int (like: std::set>) -#define i_val_ref cbox_int // note: use i_val_ref instead of i_val -#define i_tag int // tag otherwise defaults to 'ref' -#include // cvec_int (like: std::vector>) +#define i_val_bind cbox_int // note: use i_val_bind instead of i_val +#define i_tag int // tag otherwise defaults to 'ref' +#include // cvec_int (like: std::vector>) int main() { - c_auto (cvec_int, vec) // declare and init vec, call del at scope exit - c_auto (csset_int, set) // declare and init set, call del at scope exit + c_auto (cvec_int, vec) // declare and init vec, call drop at scope exit + c_auto (csset_int, set) // declare and init set, call drop at scope exit { c_apply(cvec_int, push_back, &vec, { cbox_int_new(2021), @@ -130,13 +130,13 @@ int main() Output: ``` vec: 2021 2012 2022 2015 -del: 2015 -del: 2022 +drop: 2015 +drop: 2022 vec: 2021 2012 set: 2015 2021 Done -del: 2021 -del: 2015 -del: 2021 -del: 2012 +drop: 2021 +drop: 2015 +drop: 2021 +drop: 2012 ``` diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 740df9a4..cc021001 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -13,7 +13,7 @@ macros, as one must always make sure to unwind temporary allocated resources bef | Usage | Description | |:---------------------------------------|:---------------------------------------------------| -| `c_auto (Type, var...)` | `c_autovar (Type var=Type_init(), Type_del(&var))` | +| `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 | @@ -22,7 +22,7 @@ macros, as one must always make sure to unwind temporary allocated resources bef 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 3 variables. ```c -c_autovar (cstr s = cstr_new("Hello"), cstr_del(&s)) +c_autovar (cstr s = cstr_new("Hello"), cstr_drop(&s)) { cstr_append(&s, " world"); printf("%s\n", s.str); @@ -46,7 +46,7 @@ c_autoscope (mydata_init(&data), mydata_destroy(&data)) } cstr s1 = cstr_new("Hello"), s2 = cstr_new("world"); -c_autodefer (cstr_del(&s1), cstr_del(&s2)) +c_autodefer (cstr_drop(&s1), cstr_drop(&s2)) { printf("%s %s\n", s1.str, s2.str); } @@ -65,7 +65,7 @@ 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_del(&line)) + c_autovar (cstr line = cstr_null, cstr_drop(&line)) while (cstr_getline(&line, fp)) cvec_str_emplace_back(&vec, line.str); return vec; @@ -73,7 +73,7 @@ cvec_str readFile(const char* name) int main() { - c_autovar (cvec_str x = readFile(__FILE__), cvec_str_del(&x)) + c_autovar (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) c_foreach (i, cvec_str, x) printf("%s\n", i.ref->str); } @@ -140,14 +140,14 @@ int arr[] = {1, 2, 3}; c_apply_n(cvec_i, push_back, &vec, arr, c_arraylen(arr)); ``` -### c_new, c_alloc, c_alloc_n, c_del, c_make +### c_new, c_alloc, c_alloc_n, c_drop, c_make | 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_del (ctype, &c1, ..., &cN)` | `ctype_del(&c1); ... ctype_del(&cN)` | +| `c_drop (ctype, &c1, ..., &cN)` | `ctype_drop(&c1); ... ctype_drop(&cN)` | | `c_make(type){value...}` | `(type){value...}` // c++ compatability | ```c @@ -159,17 +159,17 @@ int* array = c_alloc_n (int, 100); c_free(array); cstr a = cstr_new("Hello"), b = cstr_new("World"); -c_del(cstr, &a, &b); +c_drop(cstr, &a, &b); ``` ### General predefined template parameter functions ``` -int c_default_compare(const Type*, const Type*); +int c_default_cmp(const Type*, const Type*); Type c_default_clone(Type val); // simple copy Type c_default_toraw(const Type* val); // dereference val -void c_default_del(Type* val); // does nothing +void c_default_drop(Type* val); // does nothing -int c_rawstr_compare(const char* const* a, const char* const* b); +int c_rawstr_cmp(const char* const* a, const char* const* b); bool c_rawstr_equalto(const char* const* a, const char* const* b); ``` diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 554b4c7b..1985c2ab 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -10,7 +10,7 @@ See the c++ class [std::deque](https://en.cppreference.com/w/cpp/container/deque ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -31,7 +31,7 @@ void cdeq_X_copy(cdeq_X* self, cdeq_X other); 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); -void cdeq_X_del(cdeq_X* self); // destructor +void cdeq_X_drop(cdeq_X* self); // destructor bool cdeq_X_empty(cdeq_X deq); size_t cdeq_X_size(cdeq_X deq); @@ -119,7 +119,7 @@ int main() { c_foreach (i, cdeq_i, q) printf(" %d", *i.ref); puts(""); - cdeq_i_del(&q); + cdeq_i_drop(&q); } ``` Output: diff --git a/docs/clist_api.md b/docs/clist_api.md index b45108a7..0817737b 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -24,10 +24,10 @@ See the c++ class [std::list](https://en.cppreference.com/w/cpp/container/list) ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val -#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_from // convertion func i_valraw => i_val - defaults to plain copy #define i_tag // defaults to i_val #include ``` @@ -42,7 +42,7 @@ clist_X clist_X_clone(clist_X list); void clist_X_clear(clist_X* self); void clist_X_copy(clist_X* self, clist_X other); -void clist_X_del(clist_X* self); // destructor +void clist_X_drop(clist_X* self); // destructor bool clist_X_empty(clist_X list); size_t clist_X_count(clist_X list); // size() in O(n) time @@ -125,7 +125,7 @@ int main() { c_foreach (i, clist_d, list) printf(" %g", *i.ref); - clist_d_del(&list); + clist_d_drop(&list); } ``` Output: @@ -161,7 +161,7 @@ int main () c_foreach (x, clist_i, L) printf(" %d", *x.ref); puts(""); - clist_i_del(&L); + clist_i_drop(&L); } ``` Output: diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 0fec365c..e2cb668f 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -21,13 +21,13 @@ See the c++ class [std::unordered_map](https://en.cppreference.com/w/cpp/contain #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_keyraw*: REQUIRED IF i_keyraw is non-integral type #define i_equ // equality comparison two i_keyraw*: ALTERNATIVE to i_cmp -#define i_keydel // destroy key func - defaults to empty destruct +#define i_keydrop // destroy key func - defaults to empty destruct #define i_keyraw // convertion "raw" type - defaults to i_key -#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy +#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy #define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy -#define i_valdel // destroy value func - defaults to empty destruct +#define i_valdrop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val -#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy #define i_tag // defaults to i_key #include @@ -47,7 +47,7 @@ void cmap_X_max_load_factor(cmap_X* self, float max_load); bool cmap_X_reserve(cmap_X* self, size_t size); void cmap_X_shrink_to_fit(cmap_X* self); void cmap_X_swap(cmap_X* a, cmap_X* b); -void cmap_X_del(cmap_X* self); // destructor +void cmap_X_drop(cmap_X* self); // destructor size_t cmap_X_size(cmap_X map); size_t cmap_X_capacity(cmap_X map); // buckets * max_load_factor @@ -207,15 +207,15 @@ typedef struct { int x, y, z; } Vec3i; int main() { // Define map with defered destruct - c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_del(&vecs)) + c_autovar (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); cmap_vi_insert(&vecs, (Vec3i){ 0, 0, 100}, 3); cmap_vi_insert(&vecs, (Vec3i){100, 100, 100}, 4); - c_foreach (i, cmap_vi, vecs) - printf("{ %3d, %3d, %3d }: %d\n", i.ref->first.x, i.ref->first.y, i.ref->first.z, i.ref->second); + c_forpair (vec, num, cmap_vi, vecs) + printf("{ %3d, %3d, %3d }: %d\n", _.vec.x, _.vec.y, _.vec.z, _.num); } } ``` @@ -240,15 +240,15 @@ typedef struct { int x, y, z; } Vec3i; int main() { - c_autovar (cmap_iv vecs = cmap_iv_init(), cmap_iv_del(&vecs)) + c_auto (cmap_iv, vecs) // shorthand for c_autovar with _init(), _drop(). { cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0}); cmap_iv_insert(&vecs, 3, (Vec3i){ 0, 0, 100}); cmap_iv_insert(&vecs, 4, (Vec3i){100, 100, 100}); - c_foreach (i, cmap_iv, vecs) - printf("%d: { %3d, %3d, %3d }\n", i.ref->first, i.ref->second.x, i.ref->second.y, i.ref->second.z); + c_forpair (num, vec, cmap_iv, vecs) + printf("%d: { %3d, %3d, %3d }\n", _.num_, _.vec.x, _.vec.y, _.vec.z); } } ``` @@ -270,45 +270,56 @@ typedef struct { cstr country; } Viking; -static bool Viking_equalto(const Viking* a, const Viking* b) { +#define Viking_init() ((Viking){cstr_null, cstr_null}) + +static inline bool RViking_equalto(const Viking* a, const Viking* b) { return cstr_equals_s(a->name, b->name) && cstr_equals_s(a->country, b->country); } -static uint32_t Viking_hash(const Viking* a, int ignored) { +static inline uint32_t RViking_hash(const Viking* a, int ignored) { return c_strhash(a->name.str) ^ (c_strhash(a->country.str) >> 15); } -static void Viking_del(Viking* v) { - c_del(cstr, &v->name, &v->country); +static inline Viking Viking_clone(Viking v) { + v.name = cstr_clone(v.name); + v.country = cstr_clone(v.country); +} + +void inline Viking_drop(Viking* vk) { + cstr_drop(&vk->name); + cstr_drop(&vk->country); } -#define i_key Viking +#define i_type Vikings +#define i_key_bind Viking #define i_val int -#define i_equ Viking_equalto -#define i_hash Viking_hash -#define i_del Viking_del -#define i_tag vk +// i_key_bind auto-binds: +// #define i_equ RViking_equalto +// #define i_hash RViking_hash +// #define i_keyfrom Viking_clone +// #define i_drop Viking_drop #include int main() { // Use a HashMap to store the vikings' health points. - cmap_vk vikings = cmap_vk_init(); - - cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25); - cmap_vk_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24); - cmap_vk_insert(&vikings, (Viking){cstr_new("Harald"), cstr_new("Iceland")}, 12); - cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Denmark")}, 21); - - Viking lookup = (Viking){cstr_new("Einar"), cstr_new("Norway")}; - printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, lookup)); - Viking_del(&lookup); - - // Print the status of the vikings. - c_foreach (i, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", i.ref->first.name.str, i.ref->first.country.str, i.ref->second); + c_auto (Vikings, vikings) // uses Vikings_init(), Vikings_drop() + { + Vikings_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25); + Vikings_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24); + Vikings_insert(&vikings, (Viking){cstr_new("Harald"), cstr_new("Iceland")}, 12); + Vikings_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Denmark")}, 21); + + c_auto (Viking, lookup) { + lookup = (Viking){cstr_new("Einar"), cstr_new("Norway")}; + printf("Lookup: Einar of Norway has %d hp\n\n", *Vikings_at(&vikings, lookup)); + } + + // Print the status of the vikings. + c_forpair (viking, hp, Vikings, vikings) { + printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.hp); + } } - cmap_vk_del(&vikings); } ``` Output: @@ -326,65 +337,65 @@ to add "raw" type entries (otherwise compile error): ```c #include -typedef struct { +typedef struct Viking { cstr name; cstr country; } Viking; -static void Viking_del(Viking* v) { - c_del(cstr, &v->name, &v->country); +static inline void Viking_drop(Viking* v) { + c_drop(cstr, &v->name, &v->country); } -// Define a "raw" type that does not need allocations. -// Define equals, hash, fromraw, toraw functions: +// Define Viking raw struct with hash, equalto, and convertion functions between Viking and RViking structs: -typedef struct { +typedef struct RViking { const char* name; const char* country; } RViking; -static bool RViking_equalto(const RViking* r1, const RViking* r2) - { return !strcmp(r1->name, r2->name) && !strcmp(r1->country, r2->country); } - -static uint32_t RViking_hash(const RViking* r, int ignored) - { return c_strhash(r->name) ^ (c_strhash(r->country) >> 15); } - -static Viking Viking_fromR(RViking r) - { return (Viking){cstr_from(r.name), cstr_from(r.country)}; } +static inline uint64_t RViking_hash(const RViking* raw, size_t ignore) { + uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15); + return hash; +} +static inline bool RViking_equalto(const RViking* rx, const RViking* ry) { + return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; +} -static RViking Viking_toR(const Viking* v) - { return (RViking){v->name.str, v->country.str}; } +static inline Viking Viking_from(RViking raw) { + return (Viking){cstr_from(raw.name), cstr_from(raw.country)}; +} +static inline RViking Viking_toraw(const Viking* vk) { + return (RViking){vk->name.str, vk->country.str}; +} -#define i_key Viking -#define i_val int -#define i_keydel Viking_del -#define i_keyraw RViking -#define i_equ RViking_equalto -#define i_hash RViking_hash -#define i_keyfrom Viking_fromR -#define i_keyto Viking_toR -#define i_tag vk +// With this in place, we define the Viking => int hash map type: +#define i_type Vikings +#define i_key_bind Viking +#define i_val int +#define i_keyraw RViking +// i_key_bind macro will make these functions auto-bind: +// #define i_hash RViking_hash +// #define i_equ RViking_equalto +// #define i_keyfrom Viking_from // uses _from because i_keyraw is defined +// #define i_keyto Viking_toraw +// #define i_keydrop Viking_drop #include int main() { - c_auto (cmap_vk, vikings) // RAII - { - // Insert works as before, takes a constructed Viking object - cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25); - cmap_vk_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24); - - // Emplace is simpler to use now - takes rawkey argument - cmap_vk_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); - cmap_vk_emplace(&vikings, (RViking){"Einar", "Denmark"}, 21); + c_auto (Vikings, vikings) { + c_apply_pair(Vikings, emplace, &vikings, { + {{"Einar", "Norway"}, 20}, + {{"Olaf", "Denmark"}, 24}, + {{"Harald", "Iceland"}, 12}, + }); + Vikings_emplace_or_assign(&vikings, (RViking){"Bjorn", "Sweden"}, 10); - // Lookup also uses rawkey args, no need construct/destruct key: - printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, (RViking){"Einar", "Norway"})); + Vikings_value *einar = Vikings_find(&vikings, (RViking){"Einar", "Norway"}).ref; + if (einar) einar->second += 3; // add 3 hp points to Einar - // Print the status of the vikings. - c_foreach (i, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", i.ref->first.name.str, - i.ref->first.country.str, i.ref->second); + c_forpair (viking, health, Vikings, vikings) { + printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.health); } } } diff --git a/docs/cpque_api.md b/docs/cpque_api.md index 5c0c9ec4..e891b7d2 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -12,7 +12,7 @@ See the c++ class [std::priority_queue](https://en.cppreference.com/w/cpp/contai ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_val* : REQUIRED IF i_val is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valfrom // convertion func i_val => i_val - defaults to plain copy #define i_tag // defaults to i_val #include @@ -29,7 +29,7 @@ void cpque_X_clear(cpque_X* self); bool cpque_X_reserve(cpque_X* self, size_t n); void cpque_X_shrink_to_fit(cpque_X* self); void cpque_X_copy(cpque_X* self, cpque_X other); -void cpque_X_del(cpque_X* self); // destructor +void cpque_X_drop(cpque_X* self); // destructor size_t cpque_X_size(cpque_X pq); bool cpque_X_empty(cpque_X pq); @@ -59,7 +59,7 @@ cpque_X_value cpque_X_value_clone(cpque_X_value val); #include #define i_val int64_t -#define i_cmp -c_default_compare // min-heap +#define i_cmp -c_default_cmp // min-heap #define i_tag i #include @@ -69,7 +69,7 @@ int main() stc64_t rng = stc64_init(1234); stc64_uniform_t dist = stc64_uniform_init(0, N * 10); - // Declare heap, with defered del() + // Declare heap, with defered drop() c_auto (cpque_i, heap) { // Push ten million random numbers to priority queue, plus some negative ones. diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md index 469b7c99..9fd2c4e0 100644 --- a/docs/cqueue_api.md +++ b/docs/cqueue_api.md @@ -9,7 +9,7 @@ See the c++ class [std::queue](https://en.cppreference.com/w/cpp/container/queue ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -27,7 +27,7 @@ cqueue_X cqueue_X_clone(cqueue_X q); void cqueue_X_clear(cqueue_X* self); void cqueue_X_copy(cqueue_X* self, cqueue_X other); -void cqueue_X_del(cqueue_X* self); // destructor +void cqueue_X_drop(cqueue_X* self); // destructor size_t cqueue_X_size(cqueue_X q); bool cqueue_X_empty(cqueue_X q); @@ -76,7 +76,7 @@ int main() { c_foreach (i, cqueue_i, Q) printf(" %d", *i.ref); - cqueue_i_del(&Q); + cqueue_i_drop(&Q); } ``` Output: diff --git a/docs/crandom_api.md b/docs/crandom_api.md index 3dd829aa..b099eeaf 100644 --- a/docs/crandom_api.md +++ b/docs/crandom_api.md @@ -108,8 +108,8 @@ int main() } } // Cleanup - cstr_del(&bar); - csmap_i_del(&mhist); + cstr_drop(&bar); + csmap_i_drop(&mhist); } ``` Output: diff --git a/docs/cset_api.md b/docs/cset_api.md index 4883664d..b70f5fb9 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -11,10 +11,10 @@ A **cset** is an associative container that contains a set of unique objects of #define i_hash // hash func: REQUIRED IF i_keyraw is a non-pod type #define i_cmp // three-way compare two i_keyraw*: REQUIRED IF i_keyraw is a non-integral type #define i_equ // equality comparison two i_keyraw*: ALTERNATIVE to i_cmp -#define i_del // destroy key func - defaults to empty destruct +#define i_drop // destroy key func - defaults to empty destruct #define i_keyraw // convertion "raw" type - defaults to i_key -#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy -#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy +#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy +#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy #define i_tag // defaults to i_key #include ``` @@ -33,7 +33,7 @@ void cset_X_max_load_factor(cset_X* self, float max_load); bool cset_X_reserve(cset_X* self, size_t size); void cset_X_shrink_to_fit(cset_X* self); void cset_X_swap(cset_X* a, cset_X* b); -void cset_X_del(cset_X* self); // destructor +void cset_X_drop(cset_X* self); // destructor size_t cset_X_size(cset_X set); // num. of allocated buckets size_t cset_X_capacity(cset_X set); // buckets * max_load_factor diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 646f8c99..88d58cd4 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -18,11 +18,11 @@ See the c++ class [std::map](https://en.cppreference.com/w/cpp/container/map) fo #define i_key // key: REQUIRED #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_keyraw* : REQUIRED IF i_keyraw is a non-integral type -#define i_keydel // destroy key func - defaults to empty destruct +#define i_keydrop // destroy key func - defaults to empty destruct #define i_keyraw // convertion "raw" type - defaults to i_key #define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy #define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy -#define i_valdel // destroy value func - defaults to empty destruct +#define i_valdrop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -40,12 +40,12 @@ csmap_X csmap_X_clone(csmap_x map); void csmap_X_clear(csmap_X* self); void csmap_X_copy(csmap_X* self, csmap_X other); void csmap_X_swap(csmap_X* a, csmap_X* b); -void csmap_X_del(csmap_X* self); // destructor +void csmap_X_drop(csmap_X* self); // destructor size_t csmap_X_size(csmap_X map); bool csmap_X_empty(csmap_X map); -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(const csmap_X* self, i_keyraw rkey); // rkey must be in map. const csmap_X_value* csmap_X_get(const csmap_X* self, i_keyraw rkey); // return NULL if not found csmap_X_value* csmap_X_get_mut(csmap_X* self, i_keyraw rkey); // mutable get bool csmap_X_contains(const csmap_X* self, i_keyraw rkey); @@ -144,7 +144,7 @@ int main() { uint32_t col = 0xcc7744ff; csmap_id idnames = csmap_id_init(); - c_autodefer (csmap_id_del(&idnames)) + c_autodefer (csmap_id_drop(&idnames)) { c_apply_pair(csmap_id, emplace, &idnames, { {100, "Red"}, @@ -174,7 +174,7 @@ Demonstrate csmap with plain-old-data key type Vec3i and int as mapped type: csm ```c typedef struct { int x, y, z; } Vec3i; -static int Vec3i_compare(const Vec3i* a, const Vec3i* b) { +static int Vec3i_cmp(const Vec3i* a, const Vec3i* b) { int c; if ((c = a->x - b->x) != 0) return c; if ((c = a->y - b->y) != 0) return c; @@ -183,7 +183,7 @@ static int Vec3i_compare(const Vec3i* a, const Vec3i* b) { #define i_key Vec3i #define i_val int -#define i_cmp Vec3i_compare // uses c_default_hash +#define i_cmp Vec3i_cmp // uses c_default_hash #define i_tag vi #include #include @@ -224,7 +224,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_del(&vecs)) + c_autovar (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/csptr_api.md b/docs/csptr_api.md index 640f5cf1..5cbe746f 100644 --- a/docs/csptr_api.md +++ b/docs/csptr_api.md @@ -1,19 +1,19 @@ -# STC [csptr](../include/stc/csptr.h): Shared Pointers +# STC [csptr](../include/stc/csptr.h): Atomic Reference Counted **csptr** is a smart pointer that retains shared ownership of an object through a pointer. Several **csptr** objects may own the same object. The object is destroyed and its memory -deallocated when the last remaining **csptr** owning the object is destroyed with *csptr_X_del()*; +deallocated when the last remaining **csptr** owning the object is destroyed with *csptr_X_drop()*; -The object is destroyed using *csptr_X_del()*. A **csptr** may also own no objects, in which -case it is called empty. The *csptr_X_compare()*, *csptr_X_del()* methods are defined based on -the `i_cmp` and `i_valdel` macros specified. Use *csptr_X_clone(p)* when sharing ownership of +The object is destroyed using *csptr_X_drop()*. A **csptr** may also own no objects, in which +case it is called empty. The *csptr_X_cmp()*, *csptr_X_drop()* methods are defined based on +the `i_cmp` and `i_valdrop` macros specified. Use *csptr_X_clone(p)* when sharing ownership of the pointed-to object. All **csptr** functions can be called by multiple threads on different instances of **csptr** without additional synchronization even if these instances are copies and share ownership of the same object. -**csptr** uses thread-safe atomic reference counting, through the *csptr_X_clone()* and *csptr_X_del()* methods. +**csptr** uses thread-safe atomic reference counting, through the *csptr_X_clone()* and *csptr_X_drop()* methods. -When declaring a container with shared pointers, define `i_val_ref` as the csptr type, see example. +When declaring a container with shared pointers, define `i_val_bind` as the csptr type, see example. For containers, make sure to pass the result of create functions *csptr_X_new()* **only** to *insert()*, *push_back()*, and *push()* functions. Use *emplace()* method for sharing existing **csptr**s between @@ -26,7 +26,7 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_val* : REQUIRED IF i_val is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_tag // defaults to i_val #define i_opt c_no_atomic // Non-atomic reference counting, like Rust Rc. #include @@ -35,34 +35,34 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory ## Methods ```c -csptr_X csptr_X_init(); // empty shared pointer -csptr_X csptr_X_new(i_val val); // create new heap allocated object. Take ownership of val. -csptr_X csptr_X_from(i_rawval raw); // like csptr_X_new(), but construct owned value from raw. -csptr_X csptr_X_with(i_val* p); // create a csptr from raw pointer. Takes ownership of p. +csptr_X csptr_X_init(); // empty shared pointer +csptr_X csptr_X_new(i_val val); // create new heap allocated object. Take ownership of val. +csptr_X csptr_X_from(i_valraw raw); // like csptr_X_new(), but construct owned value from raw. +csptr_X csptr_X_with(i_val* p); // create a csptr from raw pointer. Takes ownership of p. -csptr_X csptr_X_clone(csptr_X other); // return other with increased use count -csptr_X csptr_X_move(csptr_X* self); // transfer ownership to another csptr. -void csptr_X_take(csptr_X* self, csptr_X other); // take ownership of other. -void csptr_X_copy(csptr_X* self, csptr_X other); // copy shared (increase use count) +csptr_X csptr_X_clone(csptr_X other); // return other with increased use count +csptr_X csptr_X_move(csptr_X* self); // transfer ownership to another csptr. +void csptr_X_take(csptr_X* self, csptr_X other); // take ownership of other. +void csptr_X_copy(csptr_X* self, csptr_X other); // copy shared (increase use count) -void csptr_X_del(csptr_X* self); // destruct (decrease use count, free at 0) +void csptr_X_drop(csptr_X* self); // destruct (decrease use count, free at 0) long csptr_X_use_count(csptr_X ptr); void csptr_X_reset(csptr_X* self); void csptr_X_reset_new(csptr_X* self, i_val val); // assign new csptr with value. Takes ownership of val. -void csptr_X_reset_from(csptr_X* self, i_rawval raw); // make and assign new csptr from raw value. +void csptr_X_reset_from(csptr_X* self, i_valraw raw); // make and assign new csptr from raw value. void csptr_X_reset_with(csptr_X* self, i_val* p); // create csptr with pointer p. Takes ownership of p. -int csptr_X_compare(const csptr_X* x, const csptr_X* y); // compares pointer addresses if 'i_opt c_no_compare' - // is defined. Otherwise uses 'i_cmp' or default compare. +int csptr_X_cmp(const csptr_X* x, const csptr_X* y); // compares pointer addresses if 'i_opt c_no_cmp' + // is defined. Otherwise uses 'i_cmp' or default compare. ``` ## Types and constants -| Type name | Type definition | Used to represent... | -|:--------------------|:--------------------------------------------------|:-------------------------| -| `csptr_null` | `{NULL, NULL}` | Init nullptr const | -| `csptr_X` | `struct { csptr_X_value* get; long* use_count; }` | The csptr type | +| Type name | Type definition | Used to represent... | +|:-------------------|:--------------------------------------------------|:------------------------| +| `csptr_null` | `{NULL, NULL}` | Init nullptr const | +| `csptr_X` | `struct { csptr_X_value* get; long* use_count; }` | The csptr type | | `csptr_X_value` | `i_val` | The csptr element type | ## Example @@ -73,24 +73,24 @@ int csptr_X_compare(const csptr_X* x, const csptr_X* y); // compares poi #define i_type Map #define i_key_str // strings #define i_val int -#define i_keydel(p) (printf("del name: %s\n", (p)->str), cstr_del(p)) +#define i_keydrop(p) (printf("drop name: %s\n", (p)->str), cstr_drop(p)) #include #define i_type Arc // (atomic) ref. counted type #define i_val Map #define i_from Map_clone -#define i_del(p) (printf("del Arc:\n"), Map_del(p)) +#define i_drop(p) (printf("drop Arc:\n"), Map_drop(p)) // no comparison of Maps needed (or available), and // no need for atomic ref. count in single thread: -#define i_opt c_no_compare|c_no_atomic +#define i_opt c_no_cmp|c_no_atomic #include #define i_type Stack -#define i_val_ref Arc // define i_val_ref for csptr / cbox value, not i_val +#define i_val_bind Arc // define i_val_bind for csptr / cbox value, not i_val #include #define i_type List -#define i_val_ref Arc // as above +#define i_val_bind Arc // as above #include int main() @@ -155,22 +155,22 @@ LIST Joanna:1992 Joey:1990 Mary:1995 Brad:1999 Jack:1980 Rosanna:2001 SHARED:2021 Brad:1999 CLONED:2021 Jack:1980 Rosanna:2001 -del Arc: -del name: Rick -del name: Tracy -del name: Steve -del Arc: -del name: CLONED -del name: Brad -del name: Rosanna -del name: Jack -del Arc: -del name: Brad -del name: SHARED -del name: Rosanna -del name: Jack -del Arc: -del name: Joanna -del name: Mary -del name: Joey +drop Arc: +drop name: Rick +drop name: Tracy +drop name: Steve +drop Arc: +drop name: CLONED +drop name: Brad +drop name: Rosanna +drop name: Jack +drop Arc: +drop name: Brad +drop name: SHARED +drop name: Rosanna +drop name: Jack +drop Arc: +drop name: Joanna +drop name: Mary +drop name: Joey ``` diff --git a/docs/csset_api.md b/docs/csset_api.md index 501473a6..c5cd0f88 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -10,10 +10,10 @@ See the c++ class [std::set](https://en.cppreference.com/w/cpp/container/set) fo ```c #define i_key // key: REQUIRED #define i_cmp // three-way compare two i_keyraw* : REQUIRED IF i_keyraw is a non-integral type -#define i_del // destroy key func - defaults to empty destruct +#define i_drop // destroy key func - defaults to empty destruct #define i_keyraw // convertion "raw" type - defaults to i_key -#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy -#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy +#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy +#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy #define i_tag // defaults to i_key #include ``` @@ -28,7 +28,7 @@ csset_X csset_X_clone(csset_x set); void csset_X_clear(csset_X* self); void csset_X_copy(csset_X* self, csset_X other); void csset_X_swap(csset_X* a, csset_X* b); -void csset_X_del(csset_X* self); // destructor +void csset_X_drop(csset_X* self); // destructor size_t csset_X_size(csset_X set); bool csset_X_empty(csset_X set); @@ -59,8 +59,8 @@ csset_X_value csset_X_value_clone(csset_X_value val); | Type name | Type definition | Used to represent... | |:-------------------|:--------------------------------------------------|:----------------------------| | `csset_X` | `struct { ... }` | The csset type | -| `csset_X_rawkey` | `i_rawkey` | The raw key type | -| `csset_X_rawvalue` | `i_rawkey` | The raw key type | +| `csset_X_rawkey` | `i_keyraw` | The raw key type | +| `csset_X_rawvalue` | `i_keyraw` | The raw key type | | `csset_X_key` | `i_key` | The key type | | `csset_X_value` | `i_key ` | The value: key is immutable | | `csset_X_result` | `struct { csset_X_value* ref; bool inserted; }` | Result of insert/emplace | diff --git a/docs/cstack_api.md b/docs/cstack_api.md index e71b213f..b6992dc0 100644 --- a/docs/cstack_api.md +++ b/docs/cstack_api.md @@ -10,7 +10,7 @@ See the c++ class [std::stack](https://en.cppreference.com/w/cpp/container/stack ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -31,7 +31,7 @@ void cstack_X_clear(cstack_X* self); bool cstack_X_reserve(cstack_X* self, size_t n); void cstack_X_shrink_to_fit(cstack_X* self); void cstack_X_copy(cstack_X* self, cstack_X other); -void cstack_X_del(cstack_X* self); // destructor +void cstack_X_drop(cstack_X* self); // destructor size_t cstack_X_size(cstack_X st); size_t cstack_X_capacity(cstack_X st); @@ -81,7 +81,7 @@ int main() { printf("top: %d\n", *cstack_i_top(&S)); - cstack_i_del(&S); + cstack_i_drop(&S); } ``` Output: diff --git a/docs/cstr_api.md b/docs/cstr_api.md index e54b3a4c..463a723c 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -26,7 +26,7 @@ cstr cstr_clone(cstr s); cstr* cstr_take(cstr* self, cstr s); // take the constructed or moved string cstr cstr_move(cstr* self); // move string to caller, leave empty string -void cstr_del(cstr *self); // destructor +void cstr_drop(cstr *self); // destructor const char* cstr_str(const cstr* self); // self->str char* cstr_data(cstr* self); // self->str @@ -85,13 +85,14 @@ Note that all methods with arguments `(..., const char* str, size_t n)`, `n` mus #### Helper methods: ```c -int cstr_compare(const cstr *s1, const cstr *s2); +int cstr_cmp(const cstr *s1, const cstr *s2); bool cstr_equalto(const cstr *s1, const cstr *s2); bool cstr_hash(const cstr *s, ...); -int c_rawstr_compare(const char** x, const char** y); -bool c_rawstr_equalto(const char** x, const char** y); -uint64_t c_rawstr_hash(const char* const* x, ...); +typedef const char* c_rawstr; +int c_rawstr_cmp(const c_rawstr* x, const c_rawstr* y); +bool c_rawstr_equalto(const c_rawstr* x, const c_rawstr* y); +uint64_t c_rawstr_hash(const c_rawstr* x, size_t dummy); uint64_t c_strhash(const char* str); char* c_strnstrn(const char* str, const char* needle, size_t slen, size_t nlen); @@ -141,7 +142,7 @@ int main() { cstr full_path = cstr_from_fmt("%s/%s.%s", "directory", "filename", "ext"); printf("%s\n", full_path.str); - c_del(cstr, &s0, &s1, &full_path); + c_drop(cstr, &s0, &s1, &full_path); } ``` Output: diff --git a/docs/csview_api.md b/docs/csview_api.md index 7daa67ee..609c5d10 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -77,7 +77,7 @@ bool cstr_ends_with_v(cstr s, csview sub); ``` #### Helper methods ```c -int csview_compare(const csview* x, const csview* y); +int csview_cmp(const csview* x, const csview* y); bool csview_equalto(const csview* x, const csview* y); uint64_t csview_hash(const csview* x, size_t dummy); ``` @@ -118,7 +118,7 @@ int main () cstr s3 = cstr_from_v(cstr_substr(s1, 0, 6)); // "Apples" printf("%s %s\n", s2, s3.str); - c_del(cstr, &str1, &s1, &s2, &s3); + c_drop(cstr, &str1, &s1, &s2, &s3); } ``` Output: @@ -166,7 +166,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_del(&v)) + c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_drop(&v)) c_foreach (i, cvec_str, v) printf("\"%s\"\n", i.ref->str); } diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 00c0498c..b9d4d2d5 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -14,7 +14,7 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -23,7 +23,7 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect ``` `X` should be replaced by the value of `i_tag` in all of the following documentation. -`i_del` may be defined instead of `i_valdel` (or `i_keydel`) for all non-map containers. +`i_drop` may be defined instead of `i_valdrop` (or `i_keydrop`) for all non-map containers. ## Methods @@ -39,7 +39,7 @@ bool cvec_X_reserve(cvec_X* self, size_t cap); bool cvec_X_resize(cvec_X* self, size_t size, i_val null); void cvec_X_shrink_to_fit(cvec_X* self); void cvec_X_swap(cvec_X* a, cvec_X* b); -void cvec_X_del(cvec_X* self); // destructor +void cvec_X_drop(cvec_X* self); // destructor bool cvec_X_empty(cvec_X vec); size_t cvec_X_size(cvec_X vec); @@ -47,7 +47,7 @@ size_t cvec_X_capacity(cvec_X vec); 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_get_mut(cvec_X* self, i_valraw raw); // get mutable value +cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // get mutable value 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_bsearch(const cvec_X* self, i_valraw raw); @@ -152,13 +152,13 @@ int main() { cstr tmp = cstr_from_fmt("%d elements so far", cvec_str_size(names)); // emplace_back() will not compile if adding a new cstr type. Use push_back(): - cvec_str_push_back(&names, tmp); // tmp is moved to names, do not del() it. + cvec_str_push_back(&names, tmp); // tmp is moved to names, do not drop() it. printf("%s\n", names.data[1].str); // Access the second element c_foreach (i, cvec_str, names) printf("item: %s\n", i.ref->str); - cvec_str_del(&names); + cvec_str_drop(&names); } ``` Output: @@ -179,12 +179,12 @@ typedef struct { int id; } User; -int User_compare(const User* a, const User* b) { +int User_cmp(const User* a, const User* b) { int c = strcmp(a->name.str, b->name.str); return c != 0 ? c : a->id - b->id; } -void User_del(User* self) { - cstr_del(&self->name); +void User_drop(User* self) { + cstr_drop(&self->name); } User User_clone(User user) { user.name = cstr_clone(user.name); @@ -194,9 +194,9 @@ User User_clone(User user) { // Declare a memory managed, clonable vector of users. // Note that cvec_u_emplace_back() will clone input: #define i_val User -#define i_cmp User_compare -#define i_del User_del -#define i_valfrom User_clone +#define i_cmp User_cmp +#define i_drop User_drop +#define i_from User_clone #define i_tag u #include @@ -209,6 +209,6 @@ int main(void) { c_foreach (i, cvec_u, vec2) printf("%s: %d\n", i.ref->name.str, i.ref->id); - c_del(cvec_u, &vec, &vec2); // cleanup + c_drop(cvec_u, &vec, &vec2); // cleanup } ``` diff --git a/examples/advanced.c b/examples/advanced.c deleted file mode 100644 index 60276b09..00000000 --- a/examples/advanced.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -typedef struct Viking { - cstr name; - cstr country; -} Viking; - -void viking_del(Viking* vk) { - cstr_del(&vk->name); - cstr_del(&vk->country); -} - -// Define Viking raw struct with hash, equals, and convertion functions between Viking and VikingRaw structs: - -typedef struct VikingRaw { - const char* name; - const char* country; -} VikingRaw; - -uint64_t vikingraw_hash(const VikingRaw* raw, size_t ignore) { - uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15); - return hash; -} -static inline bool vikingraw_equalto(const VikingRaw* rx, const VikingRaw* ry) { - return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; -} - -static inline Viking viking_fromRaw(VikingRaw raw) { // note: parameter is by value - return c_make(Viking){cstr_from(raw.name), cstr_from(raw.country)}; -} -static inline VikingRaw viking_toRaw(const Viking* vk) { - return c_make(VikingRaw){vk->name.str, vk->country.str}; -} - -// With this in place, we define the Viking => int hash map type: -#define i_tag vk -#define i_key Viking -#define i_val int -#define i_equ vikingraw_equalto -#define i_hash vikingraw_hash -#define i_keyraw VikingRaw -#define i_keyfrom viking_fromRaw -#define i_keyto viking_toRaw -#define i_keydel viking_del -#include - -int main() -{ - c_auto (cmap_vk, vikings) { - c_apply_pair(cmap_vk, emplace, &vikings, { - {{"Einar", "Norway"}, 20}, - {{"Olaf", "Denmark"}, 24}, - {{"Harald", "Iceland"}, 12}, - }); - VikingRaw bjorn = {"Bjorn", "Sweden"}; - cmap_vk_emplace_or_assign(&vikings, bjorn, 10); - - VikingRaw einar = {"Einar", "Norway"}; - cmap_vk_value *e = cmap_vk_find(&vikings, einar).ref; - e->second += 3; // add 3 hp points to Einar - cmap_vk_emplace(&vikings, einar, 0).ref->second += 5; // add 5 more to Einar - - c_foreach (k, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", k.ref->first.name.str, k.ref->first.country.str, k.ref->second); - } - } -} \ No newline at end of file diff --git a/examples/astar.c b/examples/astar.c index 88c602ef..ee002b79 100644 --- a/examples/astar.c +++ b/examples/astar.c @@ -24,9 +24,9 @@ point_init(int x, int y, int width) } int -point_compare_priority(const point* a, const point* b) +point_cmp_priority(const point* a, const point* b) { - return c_default_compare(&a->priorty, &b->priorty); + return c_default_cmp(&a->priorty, &b->priorty); } int @@ -49,7 +49,7 @@ point_index(const point* p) } int -point_key_compare(const point* a, const point* b) +point_key_cmp(const point* a, const point* b) { int i = point_index(a); int j = point_index(b); @@ -57,22 +57,22 @@ point_key_compare(const point* a, const point* b) } #define i_val point -#define i_cmp point_compare_priority +#define i_cmp point_cmp_priority #include #define i_val point -#define i_opt c_no_compare +#define i_opt c_no_cmp #include #define i_key point #define i_val int -#define i_cmp point_key_compare +#define i_cmp point_key_cmp #define i_tag pcost #include #define i_key point #define i_val point -#define i_cmp point_key_compare +#define i_cmp point_key_cmp #define i_tag pstep #include @@ -155,10 +155,10 @@ main(void) "# # # # # # # # # #\n" "# @ # ##### ##### ##### ######### ##### # ######### # #\n" "# # # # # # #\n" - "#########################################################################\n"), cstr_del(&maze)) + "#########################################################################\n"), cstr_drop(&maze)) { int width = cstr_find(maze, "\n") + 1; - c_autovar (cdeq_point path = astar(&maze, width), cdeq_point_del(&path)) + c_autovar (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) { c_foreach (it, cdeq_point, path) maze.str[point_index(it.ref)] = 'x'; printf("%s", maze.str); diff --git a/examples/bits.c b/examples/bits.c index fbdee3e8..ac59bd32 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -3,13 +3,13 @@ int main() { - c_autovar (cbits set = cbits_with_size(23, true), cbits_del(&set)) { + c_autovar (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { printf("count %zu, %zu\n", cbits_count(set), set.size); cbits s1 = cbits_new("1110100110111"); char buf[256]; cbits_to_str(s1, buf, 0, -1); printf("buf: %s: %zu\n", buf, cbits_count(s1)); - cbits_del(&s1); + cbits_drop(&s1); cbits_reset(&set, 9); cbits_resize(&set, 43, false); @@ -36,7 +36,7 @@ int main() printf("%d", cbits_test(set, i)); puts(""); - c_autovar (cbits s2 = cbits_clone(set), cbits_del(&s2)) { + c_autovar (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { cbits_flip_all(&s2); cbits_set(&s2, 16); cbits_set(&s2, 17); diff --git a/examples/box.c b/examples/box.c index c7763bb8..d400799b 100644 --- a/examples/box.c +++ b/examples/box.c @@ -3,7 +3,7 @@ typedef struct { cstr name, last; } Person; -Person Person_from(const char* name, const char* last) { +Person Person_new(const char* name, const char* last) { return (Person){.name = cstr_from(name), .last = cstr_from(last)}; } @@ -17,44 +17,43 @@ Person Person_clone(Person p) { p.last = cstr_clone(p.last); return p; } -void Person_del(Person* p) { - printf("del: %s %s\n", p->name.str, p->last.str); - c_del(cstr, &p->name, &p->last); + +void Person_drop(Person* p) { + printf("drop: %s %s\n", p->name.str, p->last.str); + c_drop(cstr, &p->name, &p->last); } -#define i_val Person -#define i_cmp Person_cmp -#define i_from Person_clone -#define i_del Person_del -#define i_tag prs +#define i_type PPtr +#define i_val_bind Person // binds Person_cmp, ... #include -#define i_val_ref cbox_prs -#define i_tag prs +#define i_type Persons +#define i_val_bind PPtr // binds PPtr_cmp, ... #include int main() { - c_auto (cvec_prs, vec) - c_auto (cbox_prs, p, q) + c_auto (Persons, vec) + c_auto (PPtr, p, q) { - p = cbox_prs_new(Person_from("Dave", "Cooper")); + p = PPtr_new(Person_new("Dave", "Cooper")); - q = cbox_prs_clone(p); + q = PPtr_clone(p); cstr_assign(&q.get->name, "Dale"); printf("%s %s.\n", p.get->name.str, p.get->last.str); printf("%s %s.\n", q.get->name.str, q.get->last.str); - cvec_prs_push_back(&vec, cbox_prs_new(Person_from("Laura", "Palmer"))); - cvec_prs_push_back(&vec, cbox_prs_new(Person_from("Shelly", "Johnson"))); + Persons_push_back(&vec, PPtr_new(Person_new("Laura", "Palmer"))); + Persons_push_back(&vec, PPtr_new(Person_new("Shelly", "Johnson"))); - c_foreach (i, cvec_prs, vec) + c_foreach (i, Persons, vec) printf("%s: %s\n", i.ref->get->name.str, i.ref->get->last.str); - c_autovar (Person per = Person_from("Laura", "Palmer"), Person_del(&per)) { - const cbox_prs *v = cvec_prs_get(&vec, (cbox_prs){&per}); + // Look-up Shelly! + c_autovar (Person s = Person_new("Shelly", "Johnson"), Person_drop(&s)) { + const PPtr *v = Persons_get(&vec, (PPtr){&s}); if (v) printf("found: %s: %s\n", v->get->name.str, v->get->last.str); } } diff --git a/examples/box2.c b/examples/box2.c index 48266963..5549dade 100644 --- a/examples/box2.c +++ b/examples/box2.c @@ -18,14 +18,17 @@ struct { } typedef Rectangle; #define i_val Point +#define i_opt c_no_cmp #include // cbox_Point #define i_val Rectangle +#define i_opt c_no_cmp #include // cbox_Rectangle // Box in box: -#define i_val_ref cbox_Point // NB: adviced to use i_val_ref when value is a cbox or csptr! - // it will auto-set i_del, i_from, i_cmp for you. +#define i_val_bind cbox_Point // NB: adviced to use i_val_arc when value is a cbox or csptr! + // it will auto-set i_drop, i_from, i_cmp for you. +#define i_opt c_no_cmp #define i_tag BoxPoint #include // cbox_BoxPoint diff --git a/examples/complex.c b/examples/complex.c index b6aef5a8..17a10fad 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -1,35 +1,30 @@ #include -void check_del(float* v) {printf("destroy %g\n", *v);} +void check_drop(float* v) {printf("destroy %g\n", *v);} +#define i_type FloatStack #define i_val float -#define i_valdel check_del -#define i_opt c_no_clone -#define i_tag f +#define i_drop check_drop +#define i_from c_default_clone #include -#define i_val cstack_f -#define i_opt c_no_clone|c_no_compare -#define i_valdel cstack_f_del -#define i_tag arr +#define i_type StackList +#define i_val_bind FloatStack +#define i_opt c_no_cmp #include +#define i_type ListMap #define i_key int -#define i_val clist_arr -#define i_valdel clist_arr_del -#define i_opt c_no_clone -#define i_tag lst +#define i_val_bind StackList #include +#define i_type MapMap #define i_key_str -#define i_val cmap_lst -#define i_valdel cmap_lst_del -#define i_opt c_no_clone -#define i_tag map +#define i_val_bind ListMap #include // c++: -// using cstack_f = std::stack; +// using FloatStack = std::stack; // using map_lst = std::unordered_map>; // using map_map = std::unordered_map; @@ -38,29 +33,29 @@ int main() { int x = 1, y = 3, tableKey = 42; const char* strKey = "first"; - c_auto (cmap_map, myMap) + c_auto (MapMap, mmap) { - cstack_f stk = cstack_f_with_capacity(xdim * ydim); - memset(stk.data, 0, xdim*ydim*sizeof *stk.data); - stk.size = stk.capacity; + FloatStack stack = FloatStack_with_capacity(xdim * ydim); + memset(stack.data, 0, xdim*ydim*sizeof *stack.data); + stack.size = stack.capacity; // Put in some data in stack array - stk.data[x] = 3.1415927f; - printf("stk size: %zu\n", cstack_f_size(stk)); + stack.data[x] = 3.1415927f; + printf("stack size: %zu\n", FloatStack_size(stack)); - clist_arr tableList = clist_arr_init(); - clist_arr_push_back(&tableList, stk); + StackList list = StackList_init(); + StackList_push_back(&list, stack); - cmap_lst listMap = cmap_lst_init(); - cmap_lst_insert(&listMap, tableKey, tableList); - cmap_map_insert(&myMap, cstr_from(strKey), listMap); + ListMap lmap = ListMap_init(); + ListMap_insert(&lmap, tableKey, list); + MapMap_insert(&mmap, cstr_from(strKey), lmap); // Access the data entry - const cmap_lst* mapL = cmap_map_at(&myMap, strKey); - const clist_arr* lstA = cmap_lst_at(mapL, tableKey); - const cstack_f* arr = clist_arr_back(lstA); - printf("value (%d) is: %f\n", x, *cstack_f_at(arr, x)); + const ListMap* lmap_p = MapMap_at(&mmap, strKey); + const StackList* list_p = ListMap_at(lmap_p, tableKey); + const FloatStack* stack_p = StackList_back(list_p); + printf("value (%d) is: %f\n", x, *FloatStack_at(stack_p, x)); - stk.data[x] = 1.41421356f; // change the value in array + stack.data[x] = 1.41421356f; // change the value in array } } diff --git a/examples/cpque.c b/examples/cpque.c index b3ee4adf..0b8a610c 100644 --- a/examples/cpque.c +++ b/examples/cpque.c @@ -13,7 +13,7 @@ static int (*icmp_fn)(const int* x, const int* y); #define imix_less(left, right) ((*(left) ^ 1) < (*(right) ^ 1)) static int imax_cmp(const int* x, const int* y) { return *x - *y; } static int imin_cmp(const int* x, const int* y) { return *y - *x; } -static int imix_cmp(const int* x, const int* y) { return c_less_compare(imix_less, x, y); } +static int imix_cmp(const int* x, const int* y) { return c_less_cmp(imix_less, x, y); } void print_queue(ipque q) { ipque copy = ipque_clone(q); @@ -22,13 +22,13 @@ void print_queue(ipque q) { ipque_pop(©); } puts(""); - ipque_del(©); + ipque_drop(©); } int main() { const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_arraylen(data); - c_auto (ipque, q, q2, q3) // init() and defered del() + c_auto (ipque, q, q2, q3) // init() and defered drop() { icmp_fn = imax_cmp; c_forrange (i, n) diff --git a/examples/csmap_find.c b/examples/csmap_find.c index 78b6bbf5..3ca7ff87 100644 --- a/examples/csmap_find.c +++ b/examples/csmap_find.c @@ -8,7 +8,7 @@ #include #define i_val csmap_istr_rawvalue -#define i_opt c_no_compare +#define i_opt c_no_cmp #define i_tag istr #include diff --git a/examples/csmap_insert.c b/examples/csmap_insert.c index 920cf02d..c3690c83 100644 --- a/examples/csmap_insert.c +++ b/examples/csmap_insert.c @@ -15,7 +15,7 @@ #include #define i_val csmap_ii_rawvalue -#define i_opt c_no_compare +#define i_opt c_no_cmp #define i_tag ii #include diff --git a/examples/cstr_match.c b/examples/cstr_match.c index 041a2d84..dc1423d7 100644 --- a/examples/cstr_match.c +++ b/examples/cstr_match.c @@ -3,7 +3,7 @@ int main() { - c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_del(&ss)) { + c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { size_t pos = cstr_find_n(ss, "brown", 0, 5); printf("%zu [%s]\n", pos, pos == cstr_npos ? "" : &ss.str[pos]); printf("equals: %d\n", cstr_equals(ss, "The quick brown fox jumps over the lazy dog.JPG")); diff --git a/examples/demos.c b/examples/demos.c index 70aa722d..32e5dde0 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -3,7 +3,7 @@ void stringdemo1() { printf("\nSTRINGDEMO1\n"); - c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_del(&cs)) + c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs)) { printf("%s.\n", cs.str); @@ -35,7 +35,7 @@ void stringdemo1() void vectordemo1() { printf("\nVECTORDEMO1\n"); - c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_del(&bignums)) + c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) { cvec_ix_reserve(&bignums, 100); for (size_t i = 10; i <= 100; i += 10) @@ -118,7 +118,7 @@ void setdemo1() c_foreach (i, cset_i, nums) printf("set: %d\n", *i.ref); - cset_i_del(&nums); + cset_i_drop(&nums); } #define i_key int @@ -133,7 +133,7 @@ void mapdemo1() cmap_ii_emplace(&nums, 8, 64); cmap_ii_emplace(&nums, 11, 121); printf("val 8: %d\n", *cmap_ii_at(&nums, 8)); - cmap_ii_del(&nums); + cmap_ii_drop(&nums); } #define i_key_str @@ -181,7 +181,7 @@ void mapdemo3() printf("size %zu\n", cmap_str_size(table)); c_foreach (i, cmap_str, table) printf("entry: %s: %s\n", i.ref->first.str, i.ref->second.str); - cmap_str_del(&table); // frees key and value cstrs, and hash table. + cmap_str_drop(&table); // frees key and value cstrs, and hash table. } #define i_val float @@ -192,7 +192,7 @@ void arraydemo1() { printf("\nARRAYDEMO1\n"); c_autovar (carr3_f arr3 = carr3_f_with_values(30, 20, 10, 0.0f), - carr3_f_del(&arr3)) + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 10.2f; float **arr2 = arr3.data[5]; diff --git a/examples/ex_gauss1.c b/examples/ex_gauss1.c index c96562b6..6725393f 100644 --- a/examples/ex_gauss1.c +++ b/examples/ex_gauss1.c @@ -13,7 +13,7 @@ // Declare int vector with map entries that can be sorted by map keys. struct {int first; size_t second;} typedef mapval; static int compare(mapval *a, mapval *b) { - return c_default_compare(&a->first, &b->first); + return c_default_cmp(&a->first, &b->first); } #define i_val mapval diff --git a/examples/inits.c b/examples/inits.c index 386be86e..a1733caf 100644 --- a/examples/inits.c +++ b/examples/inits.c @@ -12,19 +12,19 @@ #include typedef struct {int x, y;} ipair_t; -inline static int ipair_compare(const ipair_t* a, const ipair_t* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) { + int c = c_default_cmp(&a->x, &b->x); + return c ? c : c_default_cmp(&a->y, &b->y); } #define i_val ipair_t -#define i_cmp ipair_compare +#define i_cmp ipair_cmp #define i_tag ip #include #define i_val ipair_t -#define i_cmp ipair_compare +#define i_cmp ipair_cmp #define i_tag ip #include diff --git a/examples/mapmap.c b/examples/mapmap.c index e22a4f7b..61b55493 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -1,47 +1,67 @@ // unordered_map>: +#define i_type People #define i_key_str #define i_val_str -#define i_tag sect -#include // csmap_sect +#define i_keydrop(p) (printf("kdrop: %s\n", (p)->str), cstr_drop(p)) +#include +#define i_type Departments #define i_key_str -#define i_val csmap_sect -#define i_valdel csmap_sect_del -#define i_valfrom csmap_sect_clone -#define i_tag conf -#include // csmap_conf +#define i_val_bind People +#include -void add(csmap_conf* map, const char* section, const char* entry, const char* value) +#define i_type Stack +#define i_val_bind People_value +#define i_opt c_no_cmp +//#define i_from People_value_clone +//#define i_drop People_value_drop +#include + +void add(Departments* deps, const char* name, const char* email, const char* dep) { - csmap_sect *smap = &csmap_conf_insert(map, cstr_from(section), csmap_sect_init()).ref->second; - csmap_sect_emplace_or_assign(smap, entry, value); + People *people = &Departments_insert(deps, cstr_from(dep), People_init()).ref->second; + People_emplace_or_assign(people, name, email); } -bool contains(csmap_conf* map, const char* section, const char* entry) +Stack contains(Departments* map, const char* name) { - const csmap_conf_value *val = csmap_conf_get(map, section); - return val && csmap_sect_get(&val->second, entry); + Stack stk = Stack_init(); + const People_value* v; + c_foreach (i, Departments, *map) + if ((v = People_get(&i.ref->second, name))) { + Stack_push(&stk, People_value_clone(*v)); + } + return stk; } int main(void) { - c_auto (csmap_conf, map) + c_auto (Departments, map) { - add(&map, "user", "name", "Joe"); - add(&map, "user", "groups", "proj1,proj3"); - add(&map, "group", "proj1", "Energy"); - add(&map, "group", "proj2", "Windy"); - add(&map, "group", "proj3", "Oil"); - add(&map, "admin", "employees", "2302"); - add(&map, "group", "proj2", "Wind"); // Update - - printf("contains: %d\n", contains(&map, "group", "employees")); - printf("contains: %d\n", contains(&map, "admin", "name")); - printf("contains: %d\n", contains(&map, "admin", "employees")); - - c_foreach (i, csmap_conf, map) - c_foreach (j, csmap_sect, i.ref->second) - printf("%s: %s - %s\n", i.ref->first.str, j.ref->first.str, j.ref->second.str); + add(&map, "Anna Kendro", "Anna@myplace.com", "Support"); + add(&map, "Terry Dane", "Terry@myplace.com", "Development"); + add(&map, "Kik Winston", "Kik@myplace.com", "Finance"); + add(&map, "Nancy Drew", "Nancy@live.com", "Development"); + add(&map, "Nick Denton", "Nick@myplace.com", "Finance"); + add(&map, "Stan Whiteword", "Stan@myplace.com", "Marketing"); + add(&map, "Serena Bath", "Serena@myplace.com", "Support"); + add(&map, "Patrick Dust", "Patrick@myplace.com", "Finance"); + add(&map, "Red Winger", "Red@gmail.com", "Marketing"); + add(&map, "Nick Denton", "Nick@yahoo.com", "Support"); + add(&map, "Colin Turth", "Colin@myplace.com", "Support"); + add(&map, "Dennis Kay", "Dennis@mail.com", "Marketing"); + add(&map, "Anne Dickens", "Anne@myplace.com", "Development"); + + c_foreach (i, Departments, map) + c_forpair (name, email, People, i.ref->second) + printf("%s: %s - %s\n", i.ref->first.str, _.name.str, _.email.str); + puts(""); + + c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Nick Denton"))); + c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Patrick Dust"))); + c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Dennis Kay"))); + c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Serena Bath"))); + puts("Done"); } } \ No newline at end of file diff --git a/examples/mmap.c b/examples/mmap.c index 26b271d1..ea08017b 100644 --- a/examples/mmap.c +++ b/examples/mmap.c @@ -1,36 +1,34 @@ // This implements the multimap c++ example found at: // https://en.cppreference.com/w/cpp/container/multimap/insert -// Map of int => clist_str. Note the negation of c_default_compare +// Map of int => clist_str. Note the negation of c_default_cmp #define i_val_str #include +#define i_type Multimap #define i_key int -#define i_val clist_str -#define i_cmp -c_default_compare -#define i_valdel clist_str_del -#define i_valfrom clist_str_clone -#define i_tag mult +#define i_val_bind clist_str +#define i_cmp -c_default_cmp #include -void print(const csmap_mult mmap) +void print(const Multimap mmap) { - c_foreach (e, csmap_mult, mmap) { + c_foreach (e, Multimap, mmap) { c_foreach (s, clist_str, e.ref->second) printf("{%d,%s} ", e.ref->first, s.ref->str); } puts(""); } -void insert(csmap_mult* mmap, int key, const char* str) +void insert(Multimap* mmap, int key, const char* str) { - clist_str *list = &csmap_mult_insert(mmap, key, clist_str_init()).ref->second; + clist_str *list = &Multimap_insert(mmap, key, clist_str_init()).ref->second; clist_str_emplace_back(list, str); } int main() { - c_auto (csmap_mult, mmap) + c_auto (Multimap, mmap) { // list-initialize struct {int i; const char* s;} vals[] = {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}; @@ -53,12 +51,12 @@ int main() print(mmap); // erase all entries with key 5 - csmap_mult_erase(&mmap, 5); + Multimap_erase(&mmap, 5); print(mmap); // find and erase a specific entry clist_str_iter pos; - c_foreach (e, csmap_mult, mmap) + c_foreach (e, Multimap, mmap) if ((pos = clist_str_find(&e.ref->second, "bar")).ref != clist_str_end(&e.ref->second).ref) { clist_str_erase_at(&e.ref->second, pos); break; diff --git a/examples/multimap.c b/examples/multimap.c index 543b8b22..424ae606 100644 --- a/examples/multimap.c +++ b/examples/multimap.c @@ -35,7 +35,7 @@ struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = typedef struct { int year; cstr city, date; } OlympicLocation; -int OlympicLocation_compare(OlympicLocation* a, OlympicLocation* b) { +int OlympicLocation_cmp(OlympicLocation* a, OlympicLocation* b) { return a->year - b->year; } @@ -44,14 +44,14 @@ OlympicLocation OlympicLocation_clone(OlympicLocation loc) { loc.date = cstr_clone(loc.date); return loc; } -void OlympicLocation_del(OlympicLocation* self) { - c_del(cstr, &self->city, &self->date); +void OlympicLocation_drop(OlympicLocation* self) { + c_drop(cstr, &self->city, &self->date); } // Create a clist, can be sorted by year. #define i_val OlympicLocation -#define i_cmp OlympicLocation_compare -#define i_del OlympicLocation_del +#define i_cmp OlympicLocation_cmp +#define i_drop OlympicLocation_drop #define i_from OlympicLocation_clone #define i_tag OL #include @@ -59,7 +59,7 @@ void OlympicLocation_del(OlympicLocation* self) { // Create a csmap where key is country name #define i_key_str #define i_val clist_OL -#define i_valdel clist_OL_del +#define i_valdrop clist_OL_drop #define i_valfrom clist_OL_clone #define i_tag OL #include diff --git a/examples/new_arr.c b/examples/new_arr.c index dc597e4a..a593536e 100644 --- a/examples/new_arr.c +++ b/examples/new_arr.c @@ -15,7 +15,7 @@ int main() int w = 7, h = 5, d = 3; c_autovar (carr2_int volume = carr2_int_init(w, h), - carr2_int_del(&volume)) + carr2_int_drop(&volume)) { int *dat = carr2_int_data(&volume); for (size_t i = 0; i < carr2_int_size(volume); ++i) @@ -32,7 +32,7 @@ int main() } c_autovar (carr3_int volume = carr3_int_init(w, h, d), - carr3_int_del(&volume)) + carr3_int_drop(&volume)) { int *dat = carr3_int_data(&volume); for (size_t i = 0; i < carr3_int_size(volume); ++i) @@ -50,7 +50,7 @@ int main() } c_autovar (carr2_str text2d = carr2_str_with_values(h, d, cstr_init()), - carr2_str_del(&text2d)) + carr2_str_drop(&text2d)) { cstr_assign(&text2d.data[2][1], "hello"); cstr_assign(&text2d.data[4][0], "world"); diff --git a/examples/new_deq.c b/examples/new_deq.c index cc3ff76b..57224869 100644 --- a/examples/new_deq.c +++ b/examples/new_deq.c @@ -16,13 +16,13 @@ struct MyStruct { #include struct Point { int x, y; } typedef Point; -int point_compare(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; } #define i_val Point -#define i_cmp point_compare +#define i_cmp point_cmp #define i_opt c_is_fwd #define i_tag pnt #include diff --git a/examples/new_list.c b/examples/new_list.c index e07030b5..0867c7a6 100644 --- a/examples/new_list.c +++ b/examples/new_list.c @@ -15,13 +15,13 @@ struct MyStruct { #include struct Point { int x, y; } typedef Point; -int point_compare(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; } #define i_val Point -#define i_cmp point_compare +#define i_cmp point_cmp #define i_opt c_is_fwd #define i_tag pnt #include diff --git a/examples/new_map.c b/examples/new_map.c index 8975cd77..953ca793 100644 --- a/examples/new_map.c +++ b/examples/new_map.c @@ -16,15 +16,15 @@ struct MyStruct { // Point => int map struct Point { int x, y; } typedef Point; -int point_compare(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; } // Point => int map #define i_key Point #define i_val int -#define i_cmp point_compare +#define i_cmp point_cmp #define i_opt c_is_fwd #define i_tag pnt #include diff --git a/examples/new_pque.c b/examples/new_pque.c index 5048ea77..1485e630 100644 --- a/examples/new_pque.c +++ b/examples/new_pque.c @@ -16,8 +16,8 @@ struct MyStruct { struct Point { int x, y; } typedef Point; int Point_cmp(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); + int c = a->x - b->x; + return c ? c : a->y - b->y; } #define i_val Point diff --git a/examples/new_queue.c b/examples/new_queue.c index 3ad571bb..9219a1b4 100644 --- a/examples/new_queue.c +++ b/examples/new_queue.c @@ -6,12 +6,12 @@ forward_cqueue(cqueue_pnt, struct Point); struct Point { int x, y; } typedef Point; -int point_compare(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +int point_cmp(const Point* a, const Point* b) { + int c = c_default_cmp(&a->x, &b->x); + return c ? c : c_default_cmp(&a->y, &b->y); } #define i_val Point -#define i_cmp point_compare +#define i_cmp point_cmp #define i_opt c_is_fwd #define i_tag pnt #include diff --git a/examples/new_smap.c b/examples/new_smap.c index 7f0730db..2cb35b99 100644 --- a/examples/new_smap.c +++ b/examples/new_smap.c @@ -15,14 +15,14 @@ struct MyStruct { // Point => int map struct Point { int x, y; } typedef Point; -int point_compare(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; } #define i_key Point #define i_val int -#define i_cmp point_compare +#define i_cmp point_cmp #define i_opt c_is_fwd #define i_tag pnt #include diff --git a/examples/new_sptr.c b/examples/new_sptr.c index 4a715160..d1eed636 100644 --- a/examples/new_sptr.c +++ b/examples/new_sptr.c @@ -2,33 +2,33 @@ struct Person { cstr name, last; } typedef Person; -Person Person_from(const char* name, const char* last) { +Person Person_new(const char* name, const char* last) { return (Person){.name = cstr_from(name), .last = cstr_from(last)}; } -void Person_del(Person* p) { - printf("del: %s %s\n", p->name.str, p->last.str); - c_del(cstr, &p->name, &p->last); +void Person_drop(Person* p) { + printf("drop: %s %s\n", p->name.str, p->last.str); + c_drop(cstr, &p->name, &p->last); } #define i_val Person -#define i_del Person_del -#define i_opt c_no_compare +#define i_drop Person_drop +#define i_opt c_no_cmp #define i_tag person #include // ... #define i_val int -#define i_del(x) printf("del: %d\n", *(x)) +#define i_drop(x) printf("drop: %d\n", *(x)) #include -#define i_val_ref csptr_int +#define i_val_bind csptr_int #define i_tag iptr #include int main(void) { - c_autovar (csptr_person p = csptr_person_new(Person_from("John", "Smiths")), csptr_person_del(&p)) - c_autovar (csptr_person q = csptr_person_clone(p), csptr_person_del(&q)) // share the pointer + c_autovar (csptr_person p = csptr_person_new(Person_new("John", "Smiths")), csptr_person_drop(&p)) + c_autovar (csptr_person q = csptr_person_clone(p), csptr_person_drop(&q)) // share the pointer { printf("%s %s. uses: %lu\n", q.get->name.str, q.get->last.str, *q.use_count); } diff --git a/examples/new_vec.c b/examples/new_vec.c index 62804125..c5570942 100644 --- a/examples/new_vec.c +++ b/examples/new_vec.c @@ -15,13 +15,13 @@ struct MyStruct { #include struct Point { int x, y; } typedef Point; -int point_compare(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +int point_cmp(const Point* a, const Point* b) { + int c = c_default_cmp(&a->x, &b->x); + return c ? c : c_default_cmp(&a->y, &b->y); } #define i_val Point -#define i_cmp point_compare +#define i_cmp point_cmp #define i_opt c_is_fwd #define i_tag pnt #include @@ -37,11 +37,11 @@ int main() { cvec_i32 vec = cvec_i32_init(); cvec_i32_push_back(&vec, 123); - cvec_i32_del(&vec); + cvec_i32_drop(&vec); cvec_float fvec = cvec_float_init(); cvec_float_push_back(&fvec, 123.3); - cvec_float_del(&fvec); + cvec_float_drop(&fvec); cvec_pnt pvec = cvec_pnt_init(); cvec_pnt_push_back(&pvec, (Point){42, 14}); @@ -51,9 +51,9 @@ int main() c_foreach (i, cvec_pnt, pvec) printf(" (%d %d)", i.ref->x, i.ref->y); puts(""); - cvec_pnt_del(&pvec); + cvec_pnt_drop(&pvec); cvec_str svec = cvec_str_init(); cvec_str_emplace_back(&svec, "Hello, friend"); - cvec_str_del(&svec); + cvec_str_drop(&svec); } \ No newline at end of file diff --git a/examples/prime.c b/examples/prime.c index f858831a..0e2ede56 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -27,7 +27,7 @@ int main(void) printf("computing prime numbers up to %zu\n", n); clock_t t1 = clock(); - c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_del(&primes)) { + c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { puts("done"); size_t np = cbits_count(primes); clock_t t2 = clock(); diff --git a/examples/priority.c b/examples/priority.c index 1068cb91..5164d85d 100644 --- a/examples/priority.c +++ b/examples/priority.c @@ -4,7 +4,7 @@ #include #define i_val int64_t -#define i_cmp -c_default_compare // min-heap (increasing values) +#define i_cmp -c_default_cmp // min-heap (increasing values) #define i_tag i #include diff --git a/examples/queue.c b/examples/queue.c index 4acaa4d6..ffd0a1e7 100644 --- a/examples/queue.c +++ b/examples/queue.c @@ -2,7 +2,7 @@ #include #define i_val int -#define i_del(x) printf("drop %d\n", *(x)) +#define i_drop(x) printf("drop %d\n", *(x)) #define i_from c_default_clone #define i_tag i #include diff --git a/examples/rawptr_elements.c b/examples/rawptr_elements.c index c5416822..463a7f35 100644 --- a/examples/rawptr_elements.c +++ b/examples/rawptr_elements.c @@ -6,7 +6,7 @@ struct { double x, y; } typedef Point; // Set of Point pointers: define all template parameters "in-line" // Note it may be simpler to use a cbox for this. #define i_key Point* -#define i_keydel(x) c_free(*(x)) +#define i_keydrop(x) c_free(*(x)) #define i_keyfrom(x) c_new(Point, *(x)) #define i_hash(x, n) c_default_hash(*(x), sizeof *(x)) #define i_equ(x, y) c_memcmp_equalto(*(x), *(y)) @@ -18,7 +18,7 @@ typedef int64_t inttype; #define i_key_str #define i_valraw inttype #define i_val inttype* -#define i_valdel(x) c_free(*(x)) +#define i_valdrop(x) c_free(*(x)) #define i_valfrom(raw) c_new(inttype, raw) #define i_valto(x) **(x) #include diff --git a/examples/read.c b/examples/read.c index 4e670a10..5313cb65 100644 --- a/examples/read.c +++ b/examples/read.c @@ -6,16 +6,16 @@ cvec_str read_file(const char* name) { cvec_str vec = cvec_str_init(); c_autovar (FILE* f = fopen(name, "r"), fclose(f)) - c_autovar (cstr line = cstr_init(), cstr_del(&line)) - while (cstr_getline(&line, f)) - cvec_str_emplace_back(&vec, line.str); + c_autovar (cstr line = cstr_init(), cstr_drop(&line)) + while (cstr_getline(&line, f)) + cvec_str_emplace_back(&vec, line.str); return vec; } int main() { int n = 0; - c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_del(&vec)) + c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) c_foreach (i, cvec_str, vec) printf("%5d: %s\n", ++n, i.ref->str); diff --git a/examples/replace.c b/examples/replace.c index ebb40cc5..0349d9f4 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -13,7 +13,7 @@ int main () // Ustring positions: 0123456789*123456789*12345 cstr s = cstr_from(base); // "this is a test string." cstr m = cstr_clone(s); - c_autodefer (cstr_del(&s), cstr_del(&m)) { + c_autodefer (cstr_drop(&s), cstr_drop(&m)) { cstr_append(&m, m.str); cstr_append(&m, m.str); printf("%s\n", m.str); diff --git a/examples/splitstr.c b/examples/splitstr.c index 8bea911a..789b2c59 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -36,7 +36,7 @@ int main() cstr string = cstr_new("Split,this,,string,now,"); cvec_str vec = string_split(cstr_sv(string), c_sv(",")); - c_autodefer (cvec_str_del(&vec), cstr_del(&string)) + c_autodefer (cvec_str_drop(&vec), cstr_drop(&string)) c_foreach (i, cvec_str, vec) printf("\t\"%s\"\n", i.ref->str); } \ No newline at end of file diff --git a/examples/sptr_demo.c b/examples/sptr_demo.c index c3da5287..a6b33de6 100644 --- a/examples/sptr_demo.c +++ b/examples/sptr_demo.c @@ -1,8 +1,8 @@ #include #include -void int_del(int* x) { - printf("del: %d\n", *x); +void int_drop(int* x) { + printf("drop: %d\n", *x); } // csptr implements its own clone method using reference counting, @@ -10,19 +10,19 @@ void int_del(int* x) { #define i_type iref // set type name to be defined (instead of 'csptr_int') #define i_val int -#define i_del int_del // optional, just to display the elements destroyed +#define i_drop int_drop // optional, just to display the elements destroyed #include // iref -#define i_key_ref iref // note: use i_key_ref instead of i_key for csptr/cbox elements +#define i_key_bind iref // note: use i_key_bind instead of i_key for csptr/cbox elements #include // csset_iref (like: std::set>) -#define i_val_ref iref // note: as above. +#define i_val_bind iref // note: as above. #include // cvec_iref (like: std::vector>) int main() { - c_auto (cvec_iref, vec) // declare and init vec, call cvec_iref_del() at scope exit - c_auto (csset_iref, set) // declare and init set, call csset_iref_del() at scope exit + c_auto (cvec_iref, vec) // declare and init vec, call cvec_iref_drop() at scope exit + c_auto (csset_iref, set) // declare and init set, call csset_iref_drop() at scope exit { const int years[] = {2021, 2012, 2022, 2015}; c_forrange (i, c_arraylen(years)) @@ -47,7 +47,7 @@ int main() printf("\nset:"); c_foreach (i, csset_iref, set) printf(" %d", *i.ref->get); - c_autovar (iref p = iref_clone(vec.data[0]), iref_del(&p)) { + c_autovar (iref p = iref_clone(vec.data[0]), iref_drop(&p)) { printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); } diff --git a/examples/sptr_erase.c b/examples/sptr_erase.c index 4707abb1..d08b9072 100644 --- a/examples/sptr_erase.c +++ b/examples/sptr_erase.c @@ -1,50 +1,51 @@ #include -void show_del(int* x) { printf("del: %d\n", *x); } +void show_drop(int* x) { printf("drop: %d\n", *x); } +#define i_type Arc #define i_val int -#define i_del show_del // this "destroy" func shows which elements are destroyed +#define i_drop show_drop // this "destroy" func shows which elements are destroyed // csptr/cbox will use pointer address comparison of i_val if no i_cmp func is specified, -// or 'i_opt c_no_compare' is defined, otherwise i_cmp is used to compare object values. +// or 'i_opt c_no_cmp' is defined, otherwise i_cmp is used to compare object values. // See the different results by commenting out the next line. -#define i_cmp(x, y) (*(x) - *(y)) -#include // csptr_int: shared pointer to int +//#define i_cmp(x, y) (*(x) - *(y)) +#include // Arc: shared pointer to int -#define i_val_ref csptr_int -#define i_tag intp -#include // cvec_intp: cvec +#define i_type Vec +#define i_val_bind Arc +#include // Vec: cvec int main() { - c_auto (cvec_intp, vec) + c_auto (Vec, vec) { const int v[] = {2012, 1990, 2012, 2019, 2015}; c_forrange (i, c_arraylen(v)) - cvec_intp_push_back(&vec, csptr_int_new(v[i])); + Vec_push_back(&vec, Arc_new(v[i])); // clone the second 2012 and push it back. // note: cloning make sure that vec.data[2] has ref count 2. - cvec_intp_emplace_back(&vec, vec.data[2]); + Vec_emplace_back(&vec, vec.data[2]); printf("vec before erase :"); - c_foreach (i, cvec_intp, vec) + c_foreach (i, Vec, vec) printf(" %d", *i.ref->get); puts(""); // erase vec.data[2]; or first matching value depending on compare. - cvec_intp_iter it; - it = cvec_intp_find(&vec, vec.data[2]); - if (it.ref != cvec_intp_end(&vec).ref) - cvec_intp_erase_at(&vec, it); + Vec_iter it; + it = Vec_find(&vec, vec.data[2]); + if (it.ref != Vec_end(&vec).ref) + Vec_erase_at(&vec, it); int year = 2015; - it = cvec_intp_find(&vec, (csptr_int){&year}); // Ok as tmp only. - if (it.ref != cvec_intp_end(&vec).ref) - cvec_intp_erase_at(&vec, it); + it = Vec_find(&vec, (Arc){&year}); // Ok as tmp only. + if (it.ref != Vec_end(&vec).ref) + Vec_erase_at(&vec, it); printf("vec after erase :"); - c_foreach (i, cvec_intp, vec) + c_foreach (i, Vec, vec) printf(" %d", *i.ref->get); puts("\nDone"); diff --git a/examples/sptr_music.c b/examples/sptr_music.c index fcb7a43f..04ec28cc 100644 --- a/examples/sptr_music.c +++ b/examples/sptr_music.c @@ -9,20 +9,21 @@ struct Song cstr title; } typedef Song; -Song Song_from(const char* artist, const char* title) +Song Song_new(const char* artist, const char* title) { return (Song){cstr_from(artist), cstr_from(title)}; } -void Song_del(Song* s) { - printf("del: %s\n", s->title.str); - c_del(cstr, &s->artist, &s->title); +void Song_drop(Song* s) { + printf("drop: %s\n", s->title.str); + c_drop(cstr, &s->artist, &s->title); } #define i_val Song -#define i_del Song_del +#define i_drop Song_drop +#define i_opt c_no_cmp #define i_tag song #include // define csptr_song -#define i_val_ref csptr_song +#define i_val_bind csptr_song #define i_tag song #include @@ -31,9 +32,9 @@ void example3() c_auto (cvec_song, v, v2) { c_apply(cvec_song, push_back, &v, { - csptr_song_new(Song_from("Bob Dylan", "The Times They Are A Changing")), - csptr_song_new(Song_from("Aretha Franklin", "Bridge Over Troubled Water")), - csptr_song_new(Song_from("Thalia", "Entre El Mar y Una Estrella")) + csptr_song_new(Song_new("Bob Dylan", "The Times They Are A Changing")), + csptr_song_new(Song_new("Aretha Franklin", "Bridge Over Troubled Water")), + csptr_song_new(Song_new("Thalia", "Entre El Mar y Una Estrella")) }); c_foreach (s, cvec_song, v) @@ -41,8 +42,8 @@ void example3() cvec_song_emplace_back(&v2, *s.ref); // note: calls csptr_song_clone() c_apply(cvec_song, push_back, &v2, { - csptr_song_new(Song_from("Michael Jackson", "Billie Jean")), - csptr_song_new(Song_from("Rihanna", "Stay")), + csptr_song_new(Song_new("Michael Jackson", "Billie Jean")), + csptr_song_new(Song_new("Rihanna", "Stay")), }); c_foreach (s, cvec_song, v2) diff --git a/examples/sptr_pthread.c b/examples/sptr_pthread.c index cfb845b6..501fdcef 100644 --- a/examples/sptr_pthread.c +++ b/examples/sptr_pthread.c @@ -11,11 +11,10 @@ struct Base int value; } typedef Base; -void Base_del(Base* b) { printf("Base::~Base()\n"); } - #define i_val Base -#define i_del Base_del +#define i_drop(x) printf("Base::~Base()\n") #define i_tag base +#define i_opt c_no_cmp #include void* thr(csptr_base* lp) @@ -28,7 +27,7 @@ void* thr(csptr_base* lp) " p.get() = %p, p.use_count() = %ld\n", (void*)lp->get, *lp->use_count); } /* atomically decrease ref. */ - csptr_base_del(lp); + csptr_base_drop(lp); return NULL; } diff --git a/examples/sptr_to_maps.c b/examples/sptr_to_maps.c index a66e5b31..69798563 100644 --- a/examples/sptr_to_maps.c +++ b/examples/sptr_to_maps.c @@ -3,22 +3,23 @@ #define i_type Map #define i_key_str // strings #define i_val int -#define i_keydel(p) (printf("del name: %s\n", (p)->str), cstr_del(p)) +#define i_keydrop(p) (printf("drop name: %s\n", (p)->str), cstr_drop(p)) #include #define i_type Arc // (atomic) ref. counted type #define i_val Map -#define i_del(p) (printf("del Arc:\n"), Map_del(p)) +#define i_drop(p) (printf("drop Arc:\n"), Map_drop(p)) // no need for atomic ref. count in single thread: -#define i_opt c_no_atomic +// no compare function available for csmap: +#define i_opt c_no_atomic|c_no_cmp #include #define i_type Stack -#define i_val_ref Arc // define i_val_ref for csptr/cbox value (not i_val) +#define i_val_bind Arc // define i_val_bind for csptr/cbox value (not i_val) #include #define i_type List -#define i_val_ref Arc // as above +#define i_val_bind Arc // as above #include int main() diff --git a/examples/vikings.c b/examples/vikings.c new file mode 100644 index 00000000..87977538 --- /dev/null +++ b/examples/vikings.c @@ -0,0 +1,69 @@ +#include +#include + +typedef struct Viking { + cstr name; + cstr country; +} Viking; + +void Viking_drop(Viking* vk) { + cstr_drop(&vk->name); + cstr_drop(&vk->country); +} + +// Define Viking raw struct with hash, equals, and convertion functions between Viking and RViking structs: + +typedef struct RViking { + const char* name; + const char* country; +} RViking; + +uint64_t RViking_hash(const RViking* raw, size_t ignore) { + uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15); + return hash; +} +static inline bool RViking_equalto(const RViking* rx, const RViking* ry) { + return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; +} + +static inline Viking Viking_from(RViking raw) { // note: parameter is by value + return c_make(Viking){cstr_from(raw.name), cstr_from(raw.country)}; +} +static inline RViking Viking_toraw(const Viking* vk) { + return c_make(RViking){vk->name.str, vk->country.str}; +} + +// With this in place, we define the Viking => int hash map type: +#define i_type Vikings +#define i_key_bind Viking +#define i_val int +#define i_keyraw RViking +// i_key_bind auto-maps these functions: +// #define i_hash Viking_hash +// #define i_equ Viking_equalto +// #define i_keyfrom Viking_from // uses _from because i_keyraw is defined +// #define i_keyto Viking_toraw +// #define i_keydrop Viking_drop +#include + +int main() +{ + c_auto (Vikings, vikings) { + c_apply_pair(Vikings, emplace, &vikings, { + {{"Einar", "Norway"}, 20}, + {{"Olaf", "Denmark"}, 24}, + {{"Harald", "Iceland"}, 12}, + }); + RViking bjorn = {"Bjorn", "Sweden"}; + Vikings_emplace_or_assign(&vikings, bjorn, 10); + + RViking einar = {"Einar", "Norway"}; + Vikings_value *e = Vikings_find(&vikings, einar).ref; + e->second += 3; // add 3 hp points to Einar + Vikings_emplace(&vikings, einar, 0).ref->second += 5; // add 5 more to Einar + + c_forpair (viking, hp, Vikings, vikings) { + printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.hp); + } + } +} \ No newline at end of file diff --git a/include/stc/alt/clist.h b/include/stc/alt/clist.h index 6695a26e..14abc7e4 100644 --- a/include/stc/alt/clist.h +++ b/include/stc/alt/clist.h @@ -49,7 +49,7 @@ puts("sorted"); c_foreach (i, clist_ix, list) if (++n % 10000 == 0) printf("%8d: %10zd\n", n, i.ref->value); - clist_ix_del(&list); + clist_ix_drop(&list); } */ #include @@ -61,13 +61,13 @@ _c_clist_types(clist_VOID, int); STC_API size_t _clist_count(const clist_VOID* self); #define _clist_node(_cx_self, vp) c_container_of(vp, _cx_node, value) -#define _c_using_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw, defTypes) \ +#define _c_using_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw, defTypes) \ \ defTypes( _c_clist_types(_cx_self, i_val); ) \ typedef i_valraw _cx_rawvalue; \ \ STC_API _cx_self _cx_memb(_clone)(_cx_self lst); \ - STC_API void _cx_memb(_del)(_cx_self* self); \ + STC_API void _cx_memb(_drop)(_cx_self* self); \ STC_API void _cx_memb(_push_back)(_cx_self* self, i_val value); \ STC_API void _cx_memb(_push_front)(_cx_self* self, i_val value); \ STC_API void _cx_memb(_emplace_items)(_cx_self *self, const _cx_rawvalue arr[], size_t n); \ @@ -89,7 +89,7 @@ STC_API size_t _clist_count(const clist_VOID* self); STC_INLINE size_t _cx_memb(_count)(_cx_self lst) { return _clist_count((const clist_VOID*) &lst); } \ STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); } \ STC_INLINE i_val _cx_memb(_value_clone)(i_val val) { return i_valfrom(i_valto(&val)); } \ - STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); } \ + STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); } \ STC_INLINE void _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw) \ { _cx_memb(_push_back)(self, i_valfrom(raw)); } \ STC_INLINE void _cx_memb(_emplace_front)(_cx_self* self, i_valraw raw) \ @@ -143,13 +143,13 @@ STC_API size_t _clist_count(const clist_VOID* self); while (n-- && it.ref) _cx_memb(_next)(&it); return it; \ } \ \ - _c_implement_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw) \ + _c_implement_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw) \ struct stc_trailing_semicolon /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw) \ +#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw) \ \ STC_DEF _cx_self \ _cx_memb(_clone)(_cx_self lst) { \ @@ -160,7 +160,7 @@ STC_API size_t _clist_count(const clist_VOID* self); } \ \ STC_DEF void \ - _cx_memb(_del)(_cx_self* self) { \ + _cx_memb(_drop)(_cx_self* self) { \ while (self->last) _cx_memb(_erase_after_)(self, self->last); \ } \ \ @@ -232,7 +232,7 @@ STC_API size_t _clist_count(const clist_VOID* self); node->next = next; \ if (del == next) self->last = node = NULL; \ else if (self->last == del) self->last = node, node = NULL; \ - i_valdel(&del->value); c_free(del); \ + i_valdrop(&del->value); c_free(del); \ return node; \ } \ \ @@ -361,7 +361,7 @@ _clist_mergesort(clist_VOID_node *list, int (*cmp)(const void*, const void*)) { } #else -#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw) +#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw) #endif #endif diff --git a/include/stc/alt/csmap.h b/include/stc/alt/csmap.h index 5b331efb..beccf559 100644 --- a/include/stc/alt/csmap.h +++ b/include/stc/alt/csmap.h @@ -30,7 +30,7 @@ using_csmap(mx, int, char); // Sorted map int main(void) { - c_autovar (csmap_mx m = csmap_mx_init(), csmap_mx_del(&m)) + c_autovar (csmap_mx m = csmap_mx_init(), csmap_mx_drop(&m)) { csmap_mx_insert(&m, 5, 'a'); csmap_mx_insert(&m, 8, 'b'); @@ -91,8 +91,8 @@ int main(void) { \ STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.size == 0; } \ STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cx.size; } \ - STC_INLINE void _cx_memb(_del)(_cx_self* self) { _cx_memb(_del_r_)(self->root); } \ - STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); *self = _cx_memb(_init)(); } \ + STC_INLINE void _cx_memb(_drop)(_cx_self* self) { _cx_memb(_del_r_)(self->root); } \ + STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); } \ STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) {c_swap(_cx_self, *a, *b); } \ STC_INLINE _cx_self _cx_memb(_clone)(_cx_self cx) { return c_make(_cx_self){ _cx_memb(_clone_r_)(cx.root), cx.size}; } \ STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) \ @@ -103,9 +103,9 @@ int main(void) { {_cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } \ \ STC_INLINE void \ - _cx_memb(_value_del)(_cx_value* val) { \ - i_keydel(_i_keyref(val)); \ - _i_MAP_ONLY( i_valdel(&val->second); ) \ + _cx_memb(_value_drop)(_cx_value* val) { \ + i_keydrop(_i_keyref(val)); \ + _i_MAP_ONLY( i_valdrop(&val->second); ) \ } \ \ STC_INLINE void \ @@ -134,7 +134,7 @@ int main(void) { _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { \ _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); \ if (res.inserted) {*_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} \ - else {i_keydel(&key); _i_MAP_ONLY( i_valdel(&mapped); )} \ + else {i_keydrop(&key); _i_MAP_ONLY( i_valdrop(&mapped); )} \ return res; \ } \ \ @@ -143,7 +143,7 @@ int main(void) { _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { \ _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); \ if (res.inserted) res.ref->first = key; \ - else {i_keydel(&key); i_valdel(&res.ref->second); } \ + else {i_keydrop(&key); i_valdrop(&res.ref->second); } \ res.ref->second = mapped; return res; \ } \ \ @@ -156,7 +156,7 @@ int main(void) { _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { \ _cx_result res = _cx_memb(_insert_entry_)(self, rkey); \ if (res.inserted) res.ref->first = i_keyfrom(rkey); \ - else i_valdel(&res.ref->second); \ + else i_valdrop(&res.ref->second); \ res.ref->second = i_valfrom(rmapped); return res; \ } \ \ @@ -191,8 +191,8 @@ int main(void) { } \ \ _c_implement_aatree(_cx_self, C, i_key, i_val, i_cmp, \ - i_valdel, i_valfrom, i_valto, i_valraw, \ - i_keydel, i_keyfrom, i_keyto, i_keyraw) \ + i_valdrop, i_valfrom, i_valto, i_valraw, \ + i_keydrop, i_keyfrom, i_keyto, i_keyraw) \ struct stc_trailing_semicolon /* -------------------------- IMPLEMENTATION ------------------------- */ @@ -204,8 +204,8 @@ _c_aatree_complete_types(csmap_SENTINEL, csmap_); static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_sentinel, 0}; #define _c_implement_aatree(_cx_self, C, i_key, i_val, i_cmp, \ - i_valdel, i_valfrom, i_valto, i_valraw, \ - i_keydel, i_keyfrom, i_keyto, i_keyraw) \ + i_valdrop, i_valfrom, i_valto, i_valraw, \ + i_keydrop, i_keyfrom, i_keyto, i_keyraw) \ STC_DEF _cx_self \ _cx_memb(_init)(void) { \ _cx_self cx = {(_cx_node *) &_aatree_sentinel, 0}; \ @@ -330,7 +330,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti if (c != 0) \ tn->link[c < 0] = _cx_memb(_erase_r_)(tn->link[c < 0], rkey, erased); \ else { \ - if (!*erased) { _cx_memb(_value_del)(&tn->value); *erased = 1; } \ + if (!*erased) { _cx_memb(_value_drop)(&tn->value); *erased = 1; } \ if (tn->link[0]->level && tn->link[1]->level) { \ tx = tn->link[0]; \ while (tx->link[1]->level) \ @@ -395,7 +395,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti if (tn->level != 0) { \ _cx_memb(_del_r_)(tn->link[0]); \ _cx_memb(_del_r_)(tn->link[1]); \ - _cx_memb(_value_del)(&tn->value); \ + _cx_memb(_value_drop)(&tn->value); \ c_free(tn); \ } \ } diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index 76b3a800..bd135b7e 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -41,7 +41,7 @@ typedef union { /**************************** PRIVATE API **********************************/ -enum { SSO_CAP = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 }; +enum { SSO_CAP = sizeof(_cstr_rep_t) - 1 }; #define cstr_is_long(s) (bool)((s)->sso.cap_len & 128) #define cstr_select_(s, memb) (cstr_is_long(s) ? cstr_l_##memb : cstr_s_##memb) @@ -52,18 +52,18 @@ enum { SSO_CAP = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 }; #define cstr_s_end(s) ((s)->sso.data + cstr_s_size(s)) #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8) -#define cstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1)) -#define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1)) + #define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8) + #define cstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1)) + #define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1)) #else -#define cstr_l_cap(s) (~(s)->lon.ncap) -#define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~(cap)) + #define cstr_l_cap(s) (~(s)->lon.ncap) + #define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~(cap)) #endif #define cstr_l_size(s) ((s)->lon.size) #define cstr_l_set_size(s, len) ((s)->lon.data[(s)->lon.size = (len)] = 0) #define cstr_l_data(s) (s)->lon.data #define cstr_l_end(s) ((s)->lon.data + cstr_l_size(s)) -#define cstr_l_del(s) free((s)->lon.data) +#define cstr_l_drop(s) free((s)->lon.data) STC_API char* cstr_init_(cstr* self, size_t len, size_t cap); STC_API void cstr_internal_move_(cstr* self, size_t pos1, size_t pos2); @@ -74,15 +74,16 @@ STC_INLINE void cstr_set_size_(cstr* self, size_t len) { STC_INLINE _cstr_rep_t cstr_rep_(cstr* self) { return cstr_is_long(self) - ? c_make(_cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)} - : c_make(_cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)}; + ? c_make(_cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)} + : c_make(_cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)}; } /**************************** PUBLIC API **********************************/ #define cstr_new(literal) cstr_from_n(literal, sizeof((c_strlit){literal}) - 1) #define cstr_npos (SIZE_MAX >> 1) -#define cstr_null (cstr){.sso = {.cap_len = SSO_CAP}} +#define cstr_null (c_make(cstr){.sso = {.cap_len = SSO_CAP}}) +#define cstr_toraw(self) cstr_str(self) STC_API char* cstr_reserve(cstr* self, size_t cap); STC_API void cstr_shrink_to_fit(cstr* self); @@ -126,8 +127,8 @@ STC_INLINE cstr cstr_clone(cstr s) { return cstr_from_n(rep.data, rep.size); } -STC_INLINE void cstr_del(cstr* self) { - if (cstr_is_long(self)) cstr_l_del(self); +STC_INLINE void cstr_drop(cstr* self) { + if (cstr_is_long(self)) cstr_l_drop(self); } STC_INLINE void cstr_clear(cstr* self) { @@ -170,7 +171,7 @@ STC_INLINE bool cstr_equalto(const cstr* s1, const cstr* s2) { return strcmp(cstr_str(s1), cstr_str(s2)) == 0; } -STC_INLINE int cstr_compare(const cstr* s1, const cstr* s2) { +STC_INLINE int cstr_cmp(const cstr* s1, const cstr* s2) { return strcmp(cstr_str(s1), cstr_str(s2)); } diff --git a/include/stc/alt/sstr.h b/include/stc/alt/sstr.h deleted file mode 100644 index 2ea1033d..00000000 --- a/include/stc/alt/sstr.h +++ /dev/null @@ -1,406 +0,0 @@ -/* MIT License - * - * Copyright (c) 2021 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* A string type with short string optimization in C99 with optimal short string - * utilization (23 characters with 24 bytes string representation). - */ -#ifndef SSTR_INCLUDED -#define SSTR_INCLUDED - -#include -#include -#include -#include - -#ifndef sstr_size_t -typedef size_t sstr_size_t; -#endif -typedef struct { char* data; sstr_size_t size, cap; } sstr_rep_t; -typedef const char sstr_literal_t[]; - -typedef union { - struct { char* data; sstr_size_t size, ncap; } lon; - struct { char data[sizeof(sstr_rep_t)]; } sso; -} sstr; - -/**************************** PRIVATE API **********************************/ - -enum { SSO_CAP = offsetof(sstr, lon.ncap) + sizeof((sstr){{0}}.lon.ncap) - 1 }; -#define sstr_is_long(s) (bool)((s)->sso.data[SSO_CAP] & 128) -#define sstr_select_(s, memb) (sstr_is_long(s) ? sstr_l_##memb : sstr_s_##memb) - -#define sstr_s_cap(s) SSO_CAP -#define sstr_s_size(s) ((sstr_size_t)(SSO_CAP - (s)->sso.data[SSO_CAP])) -#define sstr_s_set_size(s, len) ((s)->sso.data[SSO_CAP] = SSO_CAP - (len), (s)->sso.data[len] = 0) -#define sstr_s_data(s) (s)->sso.data -#define sstr_s_end(s) ((s)->sso.data + sstr_s_size(s)) - -#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8) -#define sstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1)) -#define sstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1)) -#else -#define sstr_l_cap(s) (~(s)->lon.ncap) -#define sstr_l_set_cap(s, cap) ((s)->lon.ncap = ~(cap)) -#endif -#define sstr_l_size(s) ((s)->lon.size) -#define sstr_l_set_size(s, len) ((s)->lon.data[(s)->lon.size = (len)] = 0) -#define sstr_l_data(s) (s)->lon.data -#define sstr_l_end(s) ((s)->lon.data + sstr_l_size(s)) -#define sstr_l_del(s) free((s)->lon.data) - -STC_API char* sstr_init_(sstr* self, sstr_size_t len, sstr_size_t cap); -STC_API void sstr_internal_move_(sstr* self, size_t pos1, size_t pos2); - -STC_INLINE void sstr_set_size_(sstr* self, sstr_size_t len) { - sstr_select_(self, set_size(self, len)); -} - -STC_INLINE sstr_rep_t sstr_rep_(sstr* self) { - return sstr_is_long(self) - ? c_make(sstr_rep_t){self->lon.data, sstr_l_size(self), sstr_l_cap(self)} - : c_make(sstr_rep_t){self->sso.data, sstr_s_size(self), sstr_s_cap(self)}; -} - -/**************************** PUBLIC API **********************************/ - -#define sstr_lit(lit) sstr_from_n(lit, sizeof((sstr_literal_t){lit}) - 1) -#define sstr_npos (~(sstr_size_t)0 >> 1) - -STC_API char* sstr_reserve(sstr* self, sstr_size_t cap); -STC_API void sstr_shrink_to_fit(sstr* self); -STC_API void sstr_resize(sstr* self, sstr_size_t size, char value); -STC_API char* strnstrn(const char *s, const char *needle, size_t slen, size_t nlen); -STC_API sstr_size_t sstr_find_n(sstr s, const char* needle, sstr_size_t pos, sstr_size_t nmax); -STC_API void sstr_assign_n(sstr* self, const char* str, sstr_size_t n); -STC_API void sstr_append_n(sstr* self, const char* str, sstr_size_t n); -STC_API bool sstr_getdelim(sstr *self, int delim, FILE *fp); -STC_API void sstr_erase_n(sstr* self, size_t pos, size_t n); - - -STC_INLINE sstr sstr_init(void) { - sstr s; - sstr_s_set_size(&s, 0); - return s; -} - -STC_INLINE sstr sstr_from_n(const char* str, sstr_size_t n) { - sstr s; - memcpy(sstr_init_(&s, n, n), str, n); - return s; -} - -STC_INLINE sstr sstr_from(const char* str) { - return sstr_from_n(str, strlen(str)); -} - -STC_INLINE sstr sstr_with_size(sstr_size_t size, char value) { - sstr s; - memset(sstr_init_(&s, size, size), value, size); - return s; -} - -STC_INLINE sstr sstr_with_capacity(sstr_size_t cap) { - sstr s; - sstr_init_(&s, 0, cap); - return s; -} - -STC_INLINE sstr sstr_clone(sstr s) { - sstr_rep_t rep = sstr_rep_(&s); - return sstr_from_n(rep.data, rep.size); -} - -STC_INLINE void sstr_del(sstr* self) { - if (sstr_is_long(self)) sstr_l_del(self); -} - -STC_INLINE void sstr_clear(sstr* self) { - sstr_set_size_(self, 0); -} - -STC_INLINE char* sstr_data(sstr* self) { - return sstr_select_(self, data(self)); -} - -STC_INLINE const char* sstr_str(const sstr* self) { - return sstr_select_(self, data(self)); -} - -STC_INLINE bool sstr_empty(sstr s) { - return sstr_select_(&s, size(&s)) == 0; -} - -STC_INLINE sstr_size_t sstr_size(sstr s) { - return sstr_select_(&s, size(&s)); -} - -STC_INLINE sstr_size_t sstr_length(sstr s) { - return sstr_select_(&s, size(&s)); -} - -STC_INLINE sstr_size_t sstr_capacity(sstr s) { - return sstr_select_(&s, cap(&s)); -} - -STC_INLINE bool sstr_equals(sstr s1, const char* str) { - return strcmp(sstr_str(&s1), str) == 0; -} - -STC_INLINE bool sstr_equals_s(sstr s1, sstr s2) { - return strcmp(sstr_str(&s1), sstr_str(&s2)) == 0; -} - -STC_INLINE bool sstr_equalto(const sstr* s1, const sstr* s2) { - return strcmp(sstr_str(s1), sstr_str(s2)) == 0; -} - -STC_INLINE int sstr_compare(const sstr* s1, const sstr* s2) { - return strcmp(sstr_str(s1), sstr_str(s2)); -} - -STC_INLINE sstr_size_t sstr_find(sstr s, const char* needle) { - const char *str = sstr_str(&s), *res = strstr(str, needle); - return res ? res - str : sstr_npos; -} - -STC_INLINE bool sstr_find_s(sstr s, sstr needle) { - return sstr_find(s, sstr_str(&needle)); -} - -STC_INLINE bool sstr_contains(sstr s, const char* needle) { - return strstr(sstr_str(&s), needle) != NULL; -} - -STC_INLINE bool sstr_contains_s(sstr s, sstr needle) { - return strstr(sstr_str(&s), sstr_str(&needle)) != NULL; -} - -STC_INLINE bool sstr_starts_with(sstr s, const char* sub) { - const char* str = sstr_str(&s); - while (*sub && *str == *sub) ++str, ++sub; - return *sub == 0; -} - -STC_INLINE bool sstr_starts_with_s(sstr s, sstr sub) { - return sstr_starts_with(s, sstr_str(&sub)); -} - -STC_INLINE bool sstr_ends_with(sstr s, const char* sub) { - sstr_rep_t rep = sstr_rep_(&s); sstr_size_t n = strlen(sub); - return n <= rep.size && memcmp(rep.data + rep.size - n, sub, n) == 0; -} - -STC_INLINE bool sstr_ends_with_s(sstr s, sstr sub) { - return sstr_ends_with(s, sstr_str(&sub)); -} - -STC_INLINE void sstr_assign(sstr* self, const char* str) { - sstr_assign_n(self, str, strlen(str)); -} - -STC_INLINE void sstr_copy(sstr* self, sstr s) { - sstr_rep_t rep = sstr_rep_(&s); - sstr_assign_n(self, rep.data, rep.size); -} - -STC_INLINE void sstr_append(sstr* self, const char* str) { - sstr_append_n(self, str, strlen(str)); -} - -STC_INLINE void sstr_append_s(sstr* self, sstr s) { - sstr_rep_t rep = sstr_rep_(&s); - sstr_append_n(self, rep.data, rep.size); -} - -STC_INLINE void sstr_replace_n(sstr* self, size_t pos, size_t len, const char* str, size_t n) { - sstr_internal_move_(self, pos + len, pos + n); - memcpy(&sstr_data(self)[pos], str, n); -} - -STC_INLINE void sstr_replace(sstr* self, size_t pos, size_t len, const char* str) { - sstr_replace_n(self, pos, len, str, strlen(str)); -} - -STC_INLINE void sstr_replace_s(sstr* self, size_t pos, size_t len, sstr s) { - sstr_rep_t rep = sstr_rep_(&s); - sstr_replace_n(self, pos, len, rep.data, rep.size); -} - -STC_INLINE void sstr_insert_n(sstr* self, size_t pos, const char* str, size_t n) { - sstr_replace_n(self, pos, 0, str, n); -} - -STC_INLINE void sstr_insert(sstr* self, size_t pos, const char* str) { - sstr_replace_n(self, pos, 0, str, strlen(str)); -} - -STC_INLINE void sstr_insert_s(sstr* self, size_t pos, sstr s) { - sstr_rep_t rep = sstr_rep_(&s); - sstr_replace_n(self, pos, 0, rep.data, rep.size); -} - -STC_INLINE bool sstr_getline(sstr *self, FILE *fp) { - return sstr_getdelim(self, '\n', fp); -} - -/* -------------------------- IMPLEMENTATION ------------------------- */ - -#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) - -STC_DEF void sstr_internal_move_(sstr* self, size_t pos1, size_t pos2) { - if (pos1 == pos2) - return; - sstr_rep_t rep = sstr_rep_(self); - sstr_size_t newlen = rep.size + pos2 - pos1; - if (newlen > rep.cap) - rep.data = sstr_reserve(self, (rep.size*3 >> 1) + pos2 - pos1); - memmove(&rep.data[pos2], &rep.data[pos1], rep.size - pos1); - sstr_set_size_(self, newlen); -} - -STC_DEF char* sstr_init_(sstr* self, sstr_size_t len, sstr_size_t cap) { - if (cap > SSO_CAP) { - self->lon.data = (char *)malloc(cap + 1); - sstr_l_set_size(self, len); - sstr_l_set_cap(self, cap); - return self->lon.data; - } - sstr_s_set_size(self, len); - return self->sso.data; -} - -STC_DEF void sstr_shrink_to_fit(sstr* self) { - sstr_rep_t rep = sstr_rep_(self); - if (rep.size == rep.cap) - return; - if (rep.size > SSO_CAP) { - self->lon.data = (char *)realloc(self->lon.data, sstr_l_size(self) + 1); - sstr_l_set_cap(self, sstr_l_size(self)); - } else if (rep.cap > SSO_CAP) { - memcpy(self->sso.data, rep.data, rep.size + 1); - sstr_s_set_size(self, rep.size); - free(rep.data); - } -} - -STC_DEF char* sstr_reserve(sstr* self, sstr_size_t cap) { - if (sstr_is_long(self)) { - if (cap > sstr_l_cap(self)) { - self->lon.data = (char *)realloc(self->lon.data, cap + 1); - sstr_l_set_cap(self, cap); - } - return self->lon.data; - } - /* from short to long: */ - if (cap > sstr_s_cap(self)) { - char* data = (char *)malloc(cap + 1); - sstr_size_t len = sstr_s_size(self); - memcpy(data, self->sso.data, len); - self->lon.data = data; - sstr_l_set_size(self, len); - sstr_l_set_cap(self, cap); - return data; - } - return self->sso.data; -} - -STC_DEF void sstr_resize(sstr* self, sstr_size_t size, char value) { - sstr_rep_t rep = sstr_rep_(self); - if (size > rep.size) { - if (size > rep.cap) rep.data = sstr_reserve(self, size); - memset(rep.data + rep.size, value, size - rep.size); - } - sstr_set_size_(self, size); -} - -STC_DEF char* strnstrn(const char *s, const char *needle, size_t slen, size_t nlen) { - if (!nlen) return (char *)s; - if (nlen > slen) return NULL; - slen -= nlen; - do { - if (*s == *needle && !memcmp(s, needle, nlen)) return (char *)s; - ++s; - } while (slen--); - return NULL; -} - -STC_DEF sstr_size_t -sstr_find_n(sstr s, const char* needle, sstr_size_t pos, sstr_size_t nmax) { - sstr_rep_t rep = sstr_rep_(&s); - sstr_size_t nlen = (sstr_size_t) strlen(needle); - if (pos > rep.size) return sstr_npos; - char* res = strnstrn(rep.data + pos, needle, rep.size, nmax < nlen ? nmax : nlen); - return res ? res - rep.data : sstr_npos; -} - -STC_DEF void sstr_assign_n(sstr* self, const char* str, sstr_size_t n) { - sstr_rep_t rep = sstr_rep_(self); - if (n > rep.cap) { - rep.data = (char *)realloc(sstr_is_long(self) ? rep.data : NULL, n + 1); - sstr_l_set_cap(self, n); - } - memmove(rep.data, str, n); - sstr_set_size_(self, n); -} - -STC_DEF void sstr_append_n(sstr* self, const char* str, sstr_size_t n) { - sstr_rep_t rep = sstr_rep_(self); - if (rep.size + n > rep.cap) { - sstr_size_t off = (sstr_size_t)(str - rep.data); /* handle self append */ - rep.data = sstr_reserve(self, (rep.size*3 >> 1) + n); - if (off <= rep.size) str = rep.data + off; - } - memcpy(rep.data + rep.size, str, n); - sstr_set_size_(self, rep.size + n); -} - -STC_DEF bool sstr_getdelim(sstr *self, int delim, FILE *fp) { - int c = fgetc(fp); - if (c == EOF) - return false; - sstr_size_t pos = 0; - sstr_rep_t rep = sstr_rep_(self); - for (;;) { - if (c == delim || c == EOF) { - sstr_set_size_(self, pos); - return true; - } - if (pos == rep.cap) { - sstr_set_size_(self, pos); - rep.data = sstr_reserve(self, (rep.cap = (rep.cap*3 >> 1) + 16)); - } - rep.data[pos++] = (char) c; - c = fgetc(fp); - } -} - -STC_DEF void sstr_erase_n(sstr* self, size_t pos, size_t n) { - sstr_rep_t rep = sstr_rep_(self); - if (n > rep.size - pos) n = rep.size - pos; - memmove(&rep.data[pos], &rep.data[pos + n], rep.size - (pos + n)); - sstr_set_size_(self, rep.size - n); -} - -#endif -#endif \ No newline at end of file diff --git a/include/stc/carr2.h b/include/stc/carr2.h index d1feb90b..92964d4d 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -34,7 +34,7 @@ int main() { int w = 7, h = 5; - c_autovar (carr2_int image = carr2_int_init(w, h), carr2_int_del(&image)) + c_autovar (carr2_int image = carr2_int_init(w, h), carr2_int_drop(&image)) { int *dat = carr2_int_data(&image); for (int i = 0; i < carr2_int_size(image); ++i) @@ -63,7 +63,7 @@ _cx_deftypes(_c_carr2_types, _cx_self, i_val); STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, i_val value); STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, _cx_value* storage); STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); #if !c_option(c_no_clone) STC_API _cx_self _cx_memb(_clone)(_cx_self src); STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other); @@ -124,7 +124,7 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { STC_DEF void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } #endif @@ -135,10 +135,11 @@ STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) { return values; } -STC_DEF void _cx_memb(_del)(_cx_self* self) { +STC_DEF void _cx_memb(_drop)(_cx_self* self) { if (!self->data) return; - for (_cx_value* p = self->data[0], *e = p + _cx_memb(_size)(*self); p != e; ++p) - i_valdel(p); + for (_cx_value* p = self->data[0], *q = p + _cx_memb(_size)(*self); p != q; ) { + --q; i_valdrop(q); + } c_free(self->data[0]); /* values */ c_free(self->data); /* pointers */ } diff --git a/include/stc/carr3.h b/include/stc/carr3.h index 4a4a6484..31df5bdf 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -34,7 +34,7 @@ int main() { int w = 7, h = 5, d = 3; - c_autovar (carr3_int image = carr3_int_init(w, h, d), carr3_int_del(&image)) + c_autovar (carr3_int image = carr3_int_init(w, h, d), carr3_int_drop(&image)) { int *dat = carr3_int_data(&image); for (int i = 0; i < carr3_int_size(image); ++i) @@ -65,7 +65,7 @@ _cx_deftypes(_c_carr3_types, _cx_self, i_val); STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, size_t zdim, i_val value); STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); #if !c_option(c_no_clone) STC_API _cx_self _cx_memb(_clone)(_cx_self src); STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other); @@ -130,7 +130,7 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } #endif @@ -141,10 +141,11 @@ STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) { return values; } -STC_DEF void _cx_memb(_del)(_cx_self* self) { +STC_DEF void _cx_memb(_drop)(_cx_self* self) { if (!self->data) return; - for (_cx_value* p = **self->data, *e = p + _cx_memb(_size)(*self); p != e; ++p) - i_valdel(p); + for (_cx_value* p = **self->data, *q = p + _cx_memb(_size)(*self); p != q; ) { + --q; i_valdrop(q); + } c_free(self->data[0][0]); /* data */ c_free(self->data); /* pointers */ } diff --git a/include/stc/cbits.h b/include/stc/cbits.h index b3a70edc..a6ee3948 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -30,7 +30,7 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbits.h" int main() { - c_autovar (cbits bset = cbits_with_size(23, true), cbits_del(&bset)) + c_autovar (cbits bset = cbits_with_size(23, true), cbits_drop(&bset)) { cbits_reset(&bset, 9); cbits_resize(&bset, 43, false); @@ -75,14 +75,14 @@ STC_API bool cbits_disjoint(cbits set, cbits other); STC_INLINE cbits cbits_init() { return c_make(cbits){NULL, 0}; } STC_INLINE cbits cbits_from(const char* s) { return cbits_from_n(s, strlen(s)); } STC_INLINE void cbits_clear(cbits* self) { self->size = 0; } -STC_INLINE void cbits_del(cbits* self) { c_free(self->data64); } +STC_INLINE void cbits_drop(cbits* self) { c_free(self->data64); } STC_INLINE size_t cbits_size(cbits set) { return set.size; } #define cbits_new(literal) \ cbits_from_n(literal, sizeof c_make(c_strlit){literal} - 1) STC_INLINE cbits* cbits_take(cbits* self, cbits other) { - if (self->data64 != other.data64) {cbits_del(self); *self = other;} + if (self->data64 != other.data64) {cbits_drop(self); *self = other;} return self; } diff --git a/include/stc/cbox.h b/include/stc/cbox.h index 89bd272e..51bc81a4 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -26,7 +26,7 @@ typedef struct { cstr name, last; } Person; -Person Person_from(const char* name, const char* last) { +Person Person_new(const char* name, const char* last) { return (Person){.name = cstr_from(name), .last = cstr_from(last)}; } Person Person_clone(Person p) { @@ -34,21 +34,21 @@ Person Person_clone(Person p) { p.last = cstr_clone(p.last); return p; } -void Person_del(Person* p) { - printf("del: %s %s\n", p->name.str, p->last.str); - c_del(cstr, &p->name, &p->last); +void Person_drop(Person* p) { + printf("drop: %s %s\n", p->name.str, p->last.str); + c_drop(cstr, &p->name, &p->last); } #define i_val Person -#define i_valdel Person_del +#define i_valdrop Person_drop #define i_valfrom Person_clone -#define i_opt c_no_compare // compare by .get addresses only +#define i_opt c_no_cmp // compare by .get addresses only #define i_tag prs #include int main() { - c_autovar (cbox_prs p = cbox_prs_new(Person_from("John", "Smiths")), cbox_prs_del(&p)) - c_autovar (cbox_prs q = cbox_prs_clone(p), cbox_prs_del(&q)) + c_autovar (cbox_prs p = cbox_prs_new(Person_new("John", "Smiths")), cbox_prs_drop(&p)) + c_autovar (cbox_prs q = cbox_prs_clone(p), cbox_prs_drop(&q)) { cstr_assign(&q.get->name, "Joe"); @@ -63,6 +63,7 @@ int main() { #include "ccommon.h" #include "forward.h" #include +#include #define cbox_null {NULL} #endif // CBOX_H_INCLUDED @@ -71,6 +72,7 @@ int main() { #define _i_prefix cbox_ #endif #include "template.h" +typedef i_valraw _cx_rawvalue; #if !c_option(c_is_fwd) _cx_deftypes(_c_cbox_types, _cx_self, i_val); @@ -90,8 +92,8 @@ _cx_memb(_new)(i_val val) { // destructor STC_INLINE void -_cx_memb(_del)(_cx_self* self) { - if (self->get) { i_valdel(self->get); c_free(self->get); } +_cx_memb(_drop)(_cx_self* self) { + if (self->get) { i_valdrop(self->get); c_free(self->get); } } STC_INLINE _cx_self @@ -102,19 +104,19 @@ _cx_memb(_move)(_cx_self* self) { STC_INLINE void _cx_memb(_reset)(_cx_self* self) { - _cx_memb(_del)(self); self->get = NULL; + _cx_memb(_drop)(self); self->get = NULL; } // take ownership of *p STC_INLINE void _cx_memb(_reset_with)(_cx_self* self, _cx_value* p) { - _cx_memb(_del)(self); self->get = p; + _cx_memb(_drop)(self); self->get = p; } // take ownership of val STC_INLINE void _cx_memb(_reset_new)(_cx_self* self, i_val val) { - if (self->get) { i_valdel(self->get); *self->get = val; } + if (self->get) { i_valdrop(self->get); *self->get = val; } else self->get = c_new(i_val, val); } @@ -123,11 +125,10 @@ _cx_memb(_reset_new)(_cx_self* self, i_val val) { _cx_memb(_from)(i_valraw raw) { return c_make(_cx_self){c_new(i_val, i_valfrom(raw))}; } - - STC_INLINE void - _cx_memb(_reset_from)(_cx_self* self, i_valraw raw) { - _cx_memb(_reset_new)(self, i_valfrom(raw)); - } + STC_INLINE i_valraw + _cx_memb(_toraw)(const _cx_self* self) { + return i_valto(self->get); + } STC_INLINE _cx_self _cx_memb(_clone)(_cx_self other) { @@ -145,30 +146,32 @@ _cx_memb(_reset_new)(_cx_self* self, i_val val) { STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self other) { - if (other.get != self->get) _cx_memb(_del)(self); + if (other.get != self->get) _cx_memb(_drop)(self); *self = other; } STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* self, size_t n) { - #if (c_option(c_no_compare) || defined _i_default_compare) && SIZE_MAX >> 32 + #if c_option(c_no_cmp) && SIZE_MAX >> 32 return c_hash64(&self->get, 8); - #elif (c_option(c_no_compare) || defined _i_default_compare) + #elif c_option(c_no_cmp) return c_hash32(&self->get, 4); #else - i_valraw raw = i_valto(self->get); - return i_hash(&raw, sizeof raw); + return i_hash(self->get, sizeof *self->get); #endif } STC_INLINE int -_cx_memb(_compare)(const _cx_self* x, const _cx_self* y) { - #if (c_option(c_no_compare) || defined _i_default_compare) - return (int)(x->get - y->get); +_cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) { + #if c_option(c_no_cmp) + return c_default_cmp(&x->get, &y->get); #else - i_valraw rx = i_valto(x->get); - i_valraw ry = i_valto(y->get); - return i_cmp(&rx, &ry); + return i_cmp(x->get, y->get); #endif } -#include "template.h" \ No newline at end of file + +STC_INLINE bool +_cx_memb(_equalto)(const _cx_self* x, const _cx_self* y) { + return !_cx_memb(_cmp)(x, y); +} +#include "template.h" diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 2942873f..d3664077 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -93,33 +93,37 @@ #endif typedef const char c_strlit[]; -#define c_delete(T, ptr) do { T *_c_p = ptr; T##_del(_c_p); c_free(_c_p); } while (0) +#define c_delete(T, ptr) do { T *_c_p = ptr; T##_drop(_c_p); c_free(_c_p); } while (0) #define c_swap(T, x, y) do { T _c_t = x; x = y; y = _c_t; } while (0) #define c_arraylen(a) (sizeof (a)/sizeof (a)[0]) -#define c_less_compare(less, x, y) (less(y, x) - less(x, y)) +#define c_less_cmp(less, x, y) (less(y, x) - less(x, y)) #define c_default_less(x, y) (*(x) < *(y)) -#define c_default_compare(x, y) c_less_compare(c_default_less, x, y) +#define c_default_cmp(x, y) c_less_cmp(c_default_less, x, y) #define c_default_equalto(x, y) (*(x) == *(y)) #define c_memcmp_equalto(x, y) (memcmp(x, y, sizeof *(x)) == 0) -#define c_rawstr_compare(x, y) strcmp(*(x), *(y)) -#define c_rawstr_equalto(x, y) (strcmp(*(x), *(y)) == 0) -#define c_rawstr_hash(x, dummy) c_strhash(*(x)) - #define c_default_clone(x) (x) #define c_default_fromraw(x) (x) // [deprecated] #define c_default_toraw(ptr) (*(ptr)) -#define c_default_del(ptr) ((void) (ptr)) +#define c_default_drop(ptr) ((void) (ptr)) #define c_option(flag) ((i_opt) & (flag)) #define c_is_fwd 1 #define c_no_atomic 2 #define c_no_clone 4 -#define c_no_compare 8 +#define c_no_cmp 8 /* Generic algorithms */ +typedef char* c_mutstr; +typedef const char* c_rawstr; +#define c_rawstr_cmp(x, y) strcmp(*(x), *(y)) +#define c_rawstr_equalto(x, y) (strcmp(*(x), *(y)) == 0) +#define c_rawstr_hash(x, dummy) c_strhash(*(x)) +#define c_rawstr_clone(s) strcpy((char*)c_malloc(strlen(s) + 1), s) +#define c_rawstr_drop(x) c_free((char *) &**(x)) + #define _c_ROTL(x, k) (x << (k) | x >> (8*sizeof(x) - (k))) STC_INLINE uint64_t c_strhash(const char *s) { @@ -168,16 +172,16 @@ STC_INLINE uint64_t c_default_hash(const void* key, size_t len) { #define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) #define c_auto_2(C, a) \ - c_autovar(C a = C##_init(), C##_del(&a)) + c_autovar(C a = C##_init(), C##_drop(&a)) #define c_auto_3(C, a, b) \ c_autovar(c_EXPAND(C a = C##_init(), b = C##_init()), \ - C##_del(&b), C##_del(&a)) + C##_drop(&b), C##_drop(&a)) #define c_auto_4(C, a, b, c) \ c_autovar(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \ - C##_del(&c), C##_del(&b), C##_del(&a)) + C##_drop(&c), C##_drop(&b), C##_drop(&a)) #define c_auto_5(C, a, b, c, d) \ c_autovar(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ - C##_del(&d), C##_del(&c), C##_del(&b), C##_del(&a)) + C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a)) #define c_autobuf(b, type, n) c_autobuf_N(b, type, n, 256) #define c_autobuf_N(b, type, n, BYTES) \ @@ -203,10 +207,10 @@ STC_INLINE uint64_t c_default_hash(const void* key, size_t len) { C##_##method(_c_cx, *_c_i); \ } while (0) -#define c_del(C, ...) do { \ +#define c_drop(C, ...) do { \ C* _c_arr[] = {__VA_ARGS__}; \ for (size_t _c_i = 0; _c_i < c_arraylen(_c_arr); ++_c_i) \ - C##_del(_c_arr[_c_i]); \ + C##_drop(_c_arr[_c_i]); \ } while (0) #if defined(__SIZEOF_INT128__) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index f8cc1d52..050f9e67 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -42,7 +42,7 @@ typedef i_valraw _cx_rawvalue; STC_API _cx_self _cx_memb(_init)(void); STC_API void _cx_memb(_clear)(_cx_self* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value); STC_API bool _cx_memb(_expand_right_half_)(_cx_self* self, size_t idx, size_t n); #ifndef _i_queue @@ -54,9 +54,9 @@ STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* po const _cx_rawvalue* p1, const _cx_rawvalue* p2); #endif // !c_no_clone -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_API _cx_iter _cx_memb(_find_in)(_cx_iter p1, _cx_iter p2, i_valraw raw); -STC_API int _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y); +STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y); #endif STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_val value); STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2); @@ -72,7 +72,7 @@ STC_INLINE i_val _cx_memb(_value_clone)(i_val val) { return i_valfrom(i_valto(&val)); } STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } #endif STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return !cdeq_rep_(&cx)->size; } @@ -83,7 +83,7 @@ STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfro STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); } STC_INLINE void _cx_memb(_pop_front)(_cx_self* self) - { i_valdel(self->data); ++self->data; --cdeq_rep_(self)->size; } + { i_valdrop(self->data); ++self->data; --cdeq_rep_(self)->size; } STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self) { return self->data + cdeq_rep_(self)->size - 1; } STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return self->data; } @@ -106,7 +106,7 @@ _cx_memb(_with_capacity)(const size_t n) { STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) { _cx_value* p = &self->data[--cdeq_rep_(self)->size]; - i_valdel(p); + i_valdrop(p); } STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, const size_t idx) { @@ -175,7 +175,7 @@ _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, i_valraw raw) { } #endif // !c_no_clone -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, i_valraw raw) { @@ -201,9 +201,9 @@ _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, STC_INLINE void _cx_memb(_sort)(_cx_self* self) { - _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_compare)); + _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_cmp)); } -#endif // !c_no_compare +#endif // !c_no_cmp #endif // _i_queue /* -------------------------- IMPLEMENTATION ------------------------- */ @@ -224,8 +224,9 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { struct cdeq_rep* rep = cdeq_rep_(self); if (rep->cap) { - for (_cx_value *p = self->data, *q = p + rep->size; p != q; ++p) - i_valdel(p); + for (_cx_value *p = self->data, *q = p + rep->size; p != q; ) { + --q; i_valdrop(q); + } rep->size = 0; } } @@ -242,7 +243,7 @@ _cx_memb(_shrink_to_fit)(_cx_self *self) { } STC_DEF void -_cx_memb(_del)(_cx_self* self) { +_cx_memb(_drop)(_cx_self* self) { _cx_memb(_clear)(self); if (cdeq_rep_(self)->cap) c_free(cdeq_rep_(self)); @@ -357,7 +358,7 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { const size_t n = p2 - p1; if (n > 0) { _cx_value* p = p1, *end = self->data + cdeq_rep_(self)->size; - for (; p != p2; ++p) i_valdel(p); + for (; p != p2; ++p) { i_valdrop(p); } if (p1 == self->data) self->data += n; else memmove(p1, p2, (end - p2) * sizeof(i_val)); cdeq_rep_(self)->size -= n; @@ -385,7 +386,7 @@ _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, } #endif // !c_option(c_no_clone) -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) { @@ -397,12 +398,12 @@ _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) { } STC_DEF int -_cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y) { +_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { i_valraw rx = i_valto(x); i_valraw ry = i_valto(y); return i_cmp(&rx, &ry); } -#endif // !c_no_compare +#endif // !c_no_cmp #endif // !_i_queue #endif // IMPLEMENTATION #include "template.h" diff --git a/include/stc/clist.h b/include/stc/clist.h index 7cd2df50..c239fdd9 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -91,15 +91,16 @@ typedef i_valraw _cx_rawvalue; STC_API size_t _clist_count(const clist_VOID* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value); STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_val value); STC_API _cx_iter _cx_memb(_insert)(_cx_self* self, _cx_iter it, i_val value); STC_API _cx_iter _cx_memb(_erase_at)(_cx_self* self, _cx_iter it); STC_API _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2); -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_API size_t _cx_memb(_remove)(_cx_self* self, i_valraw val); STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw val); +STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y); #endif STC_API _cx_iter _cx_memb(_splice)(_cx_self* self, _cx_iter it, _cx_self* other); STC_API _cx_self _cx_memb(_split_off)(_cx_self* self, _cx_iter it1, _cx_iter it2); @@ -114,14 +115,13 @@ STC_INLINE _cx_value* _cx_memb(_emplace_front)(_cx_self* self, i_valraw raw) { return _cx_memb(_push_front)(self, i_valfrom(raw)); } STC_INLINE _cx_iter _cx_memb(_emplace)(_cx_self* self, _cx_iter it, i_valraw raw) { return _cx_memb(_insert)(self, it, i_valfrom(raw)); } -STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) - { return i_valfrom(raw); } STC_INLINE i_val _cx_memb(_value_clone)(i_val val) { return i_valfrom(i_valto(&val)); } + STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->last == other.last) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } #endif STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL}; } @@ -129,8 +129,7 @@ STC_INLINE bool _cx_memb(_reserve)(_cx_self* self, size_t n) { return tr STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.last == NULL; } STC_INLINE size_t _cx_memb(_count)(_cx_self cx) { return _clist_count((const clist_VOID*) &cx); } -STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); } -STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); } +STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); } STC_INLINE void _cx_memb(_pop_front)(_cx_self* self) { _cx_memb(_erase_after_)(self, self->last); } STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return &self->last->next->value; } @@ -166,7 +165,7 @@ _cx_memb(_splice_range)(_cx_self* self, _cx_iter it, return _cx_memb(_splice)(self, it, &tmp); } -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, i_valraw val) { return _cx_memb(_find_in)(_cx_memb(_begin)(self), _cx_memb(_end)(self), val); @@ -197,7 +196,7 @@ _cx_memb(_clone)(_cx_self cx) { #endif STC_DEF void -_cx_memb(_del)(_cx_self* self) { +_cx_memb(_drop)(_cx_self* self) { while (self->last) _cx_memb(_erase_after_)(self, self->last); } @@ -250,7 +249,7 @@ _cx_memb(_erase_after_)(_cx_self* self, _cx_node* node) { node->next = next; if (del == next) self->last = node = NULL; else if (self->last == del) self->last = node, node = NULL; - i_valdel(&del->value); c_free(del); + i_valdrop(&del->value); c_free(del); return node; } @@ -280,7 +279,7 @@ _cx_memb(_split_off)(_cx_self* self, _cx_iter it1, _cx_iter it2) { return cx; } -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw val) { @@ -321,7 +320,14 @@ _cx_memb(_sort)(_cx_self* self) { if (self->last) self->last = (_cx_node *) _clist_mergesort((clist_VOID_node *) self->last->next, _cx_memb(_sort_cmp_)); } -#endif // !c_no_compare + +STC_DEF int +_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { + i_valraw rx = i_valto(x); + i_valraw ry = i_valto(y); + return i_cmp(&rx, &ry); +} +#endif // !c_no_cmp #endif // TEMPLATE IMPLEMENTATION @@ -336,7 +342,7 @@ _clist_count(const clist_VOID* self) { return n; } -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) // Singly linked list Mergesort implementation by Simon Tatham. O(n*log n). // https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html @@ -387,7 +393,7 @@ _clist_mergesort(clist_VOID_node *list, int (*cmp)(const clist_VOID_node*, const insize *= 2; } } -#endif // !c_no_compare +#endif // !c_no_cmp #endif // NON-TEMPLATE IMPLEMENTATION #include "template.h" #define CLIST_H_INCLUDED diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 3d1915d3..10e9c586 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -31,7 +31,7 @@ #include int main(void) { - c_autovar (cmap_ichar m = cmap_ichar_init(), cmap_ichar_del(&m)) + c_autovar (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m)) { cmap_ichar_emplace(&m, 5, 'a'); cmap_ichar_emplace(&m, 8, 'b'); @@ -91,7 +91,7 @@ STC_API _cx_self _cx_memb(_with_capacity)(size_t cap); #if !c_option(c_no_clone) STC_API _cx_self _cx_memb(_clone)(_cx_self map); #endif -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); STC_API void _cx_memb(_clear)(_cx_self* self); STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t capacity); STC_API chash_bucket_t _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr); @@ -121,7 +121,7 @@ STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) return _cx_memb(_insert_or_assign)(self, key, mapped); } - STC_INLINE const _cx_mapped* + STC_INLINE _cx_mapped* _cx_memb(_at)(const _cx_self* self, i_keyraw rkey) { chash_bucket_t b = _cx_memb(_bucket_)(self, &rkey); assert(self->_hashx[b.idx]); @@ -132,13 +132,14 @@ STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) #if !c_option(c_no_clone) STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->table == other.table) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } -STC_INLINE void -_cx_memb(_value_clone)(_cx_value* _dst, _cx_value* _val) { - *_i_keyref(_dst) = i_keyfrom(i_keyto(_i_keyref(_val))); - _i_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); ) +STC_INLINE _cx_value +_cx_memb(_value_clone)(_cx_value _val) { + *_i_keyref(&_val) = i_keyfrom(i_keyto(_i_keyref(&_val))); + _i_MAP_ONLY( _val.second = i_valfrom(i_valto(&_val.second)); ) + return _val; } STC_INLINE _cx_result @@ -159,16 +160,16 @@ _cx_memb(_value_toraw)(_cx_value* val) { } STC_INLINE void -_cx_memb(_value_del)(_cx_value* _val) { - i_keydel(_i_keyref(_val)); - _i_MAP_ONLY( i_valdel(&_val->second); ) +_cx_memb(_value_drop)(_cx_value* _val) { + i_keydrop(_i_keyref(_val)); + _i_MAP_ONLY( i_valdrop(&_val->second); ) } STC_INLINE _cx_result _cx_memb(_insert)(_cx_self* self, i_key _key _i_MAP_ONLY(, i_val _mapped)) { _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key)); if (_res.inserted) { *_i_keyref(_res.ref) = _key; _i_MAP_ONLY( _res.ref->second = _mapped; )} - else { i_keydel(&_key); _i_MAP_ONLY( i_valdel(&_mapped); )} + else { i_keydrop(&_key); _i_MAP_ONLY( i_valdrop(&_mapped); )} return _res; } @@ -249,10 +250,10 @@ STC_INLINE void _cx_memb(_wipe_)(_cx_self* self) { if (self->size == 0) return; _cx_value* e = self->table, *end = e + self->bucket_count; uint8_t *hx = self->_hashx; - for (; e != end; ++e) if (*hx++) _cx_memb(_value_del)(e); + for (; e != end; ++e) if (*hx++) _cx_memb(_value_drop)(e); } -STC_DEF void _cx_memb(_del)(_cx_self* self) { +STC_DEF void _cx_memb(_drop)(_cx_self* self) { _cx_memb(_wipe_)(self); c_free(self->_hashx); c_free((void *) self->table); @@ -269,7 +270,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped) { _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key)); if (_res.inserted) _res.ref->first = _key; - else { i_keydel(&_key); i_valdel(&_res.ref->second); } + else { i_keydrop(&_key); i_valdrop(&_res.ref->second); } _res.ref->second = _mapped; return _res; } #if !c_option(c_no_clone) @@ -277,7 +278,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { _cx_result _res = _cx_memb(_insert_entry_)(self, rkey); if (_res.inserted) _res.ref->first = i_keyfrom(rkey); - else i_valdel(&_res.ref->second); + else i_valdrop(&_res.ref->second); _res.ref->second = i_valfrom(rmapped); return _res; } #endif @@ -323,7 +324,7 @@ _cx_memb(_clone)(_cx_self m) { }; _cx_value *e = m.table, *end = e + m.bucket_count, *dst = clone.table; for (uint8_t *hx = m._hashx; e != end; ++hx, ++e, ++dst) - if (*hx) _cx_memb(_value_clone)(dst, e); + if (*hx) *dst = _cx_memb(_value_clone)(*e); return clone; } #endif @@ -363,7 +364,7 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { const _cx_size _cap = self->bucket_count; _cx_value* _slot = self->table; uint8_t* _hashx = self->_hashx; - _cx_memb(_value_del)(&_slot[i]); + _cx_memb(_value_drop)(&_slot[i]); for (;;) { /* delete without leaving tombstone */ if (++j == _cap) j = 0; if (! _hashx[j]) diff --git a/include/stc/cpque.h b/include/stc/cpque.h index 49aa2406..87be1e73 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -55,7 +55,7 @@ STC_INLINE bool _cx_memb(_resize)(_cx_self* self, const size_t len, i_val null) { if (!_cx_memb(_reserve)(self, len)) return false; const size_t n = self->size; - for (size_t i = len; i < n; ++i) i_valdel(&self->data[i]); + for (size_t i = len; i < n; ++i) { i_valdrop(&self->data[i]); } for (size_t i = n; i < len; ++i) self->data[i] = null; self->size = len; return true; @@ -71,10 +71,10 @@ STC_INLINE _cx_self _cx_memb(_with_capacity)(size_t cap) { STC_INLINE void _cx_memb(_clear)(_cx_self* self) { size_t i = self->size; self->size = 0; - while (i--) i_valdel(&self->data[i]); + while (i--) { i_valdrop(&self->data[i]); } } -STC_INLINE void _cx_memb(_del)(_cx_self* self) +STC_INLINE void _cx_memb(_drop)(_cx_self* self) { _cx_memb(_clear)(self); c_free(self->data); } STC_INLINE size_t _cx_memb(_size)(_cx_self q) @@ -97,7 +97,7 @@ STC_API _cx_self _cx_memb(_clone)(_cx_self q); STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_value val) @@ -139,7 +139,7 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self q) { STC_DEF void _cx_memb(_erase_at)(_cx_self* self, size_t idx) { - i_valdel(&self->data[idx]); + i_valdrop(&self->data[idx]); size_t n = --self->size; self->data[idx] = self->data[n]; _cx_memb(_sift_down_)(self->data - 1, idx + 1, n); diff --git a/include/stc/cset.h b/include/stc/cset.h index d74a8ccc..91e703da 100644 --- a/include/stc/cset.h +++ b/include/stc/cset.h @@ -35,7 +35,7 @@ int main(void) { c_foreach (i, cset_sx, s) printf("set %d\n", *i.ref); - cset_sx_del(&s); + cset_sx_drop(&s); } */ diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 101e7399..6ba220ab 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -32,7 +32,7 @@ #include int main(void) { - c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_del(&m)) + c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) { csmap_sx_emplace(&m, "Testing one", 1.234); csmap_sx_emplace(&m, "Testing two", 12.34); @@ -97,7 +97,7 @@ STC_API _cx_self _cx_memb(_init)(void); #if !c_option(c_no_clone) STC_API _cx_self _cx_memb(_clone)(_cx_self tree); #endif -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap); STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out); STC_API _cx_iter _cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey); @@ -112,7 +112,7 @@ STC_API void _cx_memb(_next)(_cx_iter* it); STC_INLINE bool _cx_memb(_empty)(_cx_self tree) { return _csmap_rep(&tree)->size == 0; } STC_INLINE size_t _cx_memb(_size)(_cx_self tree) { return _csmap_rep(&tree)->size; } STC_INLINE size_t _cx_memb(_capacity)(_cx_self tree) { return _csmap_rep(&tree)->cap; } -STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); *self = _cx_memb(_init)(); } +STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); } STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); } STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it) != NULL; } @@ -134,10 +134,16 @@ _cx_memb(_value_toraw)(_cx_value* val) { _i_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} ); } +STC_INLINE int +_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { + _cx_rawkey rx = i_keyto(_i_keyref(x)), ry = i_keyto(_i_keyref(y)); + return i_cmp(&rx, &ry); +} + STC_INLINE void -_cx_memb(_value_del)(_cx_value* val) { - i_keydel(_i_keyref(val)); - _i_MAP_ONLY( i_valdel(&val->second); ) +_cx_memb(_value_drop)(_cx_value* val) { + i_keydrop(_i_keyref(val)); + _i_MAP_ONLY( i_valdrop(&val->second); ) } #ifndef _i_isset @@ -150,7 +156,7 @@ _cx_memb(_value_del)(_cx_value* val) { _cx_memb(_put)(_cx_self* self, i_key key, i_val mapped) { return _cx_memb(_insert_or_assign)(self, key, mapped); } - STC_INLINE const _cx_mapped* + STC_INLINE _cx_mapped* _cx_memb(_at)(const _cx_self* self, i_keyraw rkey) { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } #endif @@ -166,13 +172,14 @@ _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) { STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->nodes == other.nodes) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } -STC_INLINE void -_cx_memb(_value_clone)(_cx_value* dst, _cx_value* val) { - *_i_keyref(dst) = i_keyfrom(i_keyto(_i_keyref(val))); - _i_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); ) +STC_INLINE _cx_value +_cx_memb(_value_clone)(_cx_value _val) { + *_i_keyref(&_val) = i_keyfrom(i_keyto(_i_keyref(&_val))); + _i_MAP_ONLY( _val.second = i_valfrom(i_valto(&_val.second)); ) + return _val; } STC_INLINE _cx_result @@ -190,7 +197,7 @@ STC_INLINE _cx_result _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); if (res.inserted) { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} - else { i_keydel(&key); _i_MAP_ONLY( i_valdel(&mapped); )} + else { i_keydrop(&key); _i_MAP_ONLY( i_valdrop(&mapped); )} return res; } @@ -279,7 +286,7 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); if (res.inserted) res.ref->first = key; - else { i_keydel(&key); i_valdel(&res.ref->second); } + else { i_keydrop(&key); i_valdrop(&res.ref->second); } res.ref->second = mapped; return res; } #if !c_option(c_no_clone) @@ -287,7 +294,7 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { _cx_result res = _cx_memb(_insert_entry_)(self, rkey); if (res.inserted) res.ref->first = i_keyfrom(rkey); - else i_valdel(&res.ref->second); + else i_valdrop(&res.ref->second); res.ref->second = i_valfrom(rmapped); return res; } #endif @@ -404,7 +411,7 @@ _cx_memb(_erase_r_)(_cx_node *d, _cx_size tn, const _cx_rawkey* rkey, int *erase d[tn].link[c < 0] = _cx_memb(_erase_r_)(d, d[tn].link[c < 0], rkey, erased); else { if (!(*erased)++) - _cx_memb(_value_del)(&d[tn].value); + _cx_memb(_value_drop)(&d[tn].value); if (d[tn].link[0] && d[tn].link[1]) { tx = d[tn].link[0]; while (d[tx].link[1]) @@ -470,7 +477,7 @@ STC_DEF _cx_size _cx_memb(_clone_r_)(_cx_self* self, _cx_node* src, _cx_size sn) { if (sn == 0) return 0; _cx_size tx, tn = _cx_memb(_node_new_)(self, src[sn].level); - _cx_memb(_value_clone)(&self->nodes[tn].value, &src[sn].value); + self->nodes[tn].value = _cx_memb(_value_clone)(src[sn].value); tx = _cx_memb(_clone_r_)(self, src, src[sn].link[0]); self->nodes[tn].link[0] = tx; tx = _cx_memb(_clone_r_)(self, src, src[sn].link[1]); self->nodes[tn].link[1] = tx; return tn; @@ -491,12 +498,12 @@ _cx_memb(_del_r_)(_cx_node* d, _cx_size tn) { if (tn) { _cx_memb(_del_r_)(d, d[tn].link[0]); _cx_memb(_del_r_)(d, d[tn].link[1]); - _cx_memb(_value_del)(&d[tn].value); + _cx_memb(_value_drop)(&d[tn].value); } } STC_DEF void -_cx_memb(_del)(_cx_self* self) { +_cx_memb(_drop)(_cx_self* self) { if (_csmap_rep(self)->root) { _cx_memb(_del_r_)(self->nodes, (_cx_size) _csmap_rep(self)->root); c_free(_csmap_rep(self)); diff --git a/include/stc/csptr.h b/include/stc/csptr.h index 4753ef12..b66cd4d7 100644 --- a/include/stc/csptr.h +++ b/include/stc/csptr.h @@ -26,25 +26,25 @@ typedef struct { cstr name, last; } Person; -Person Person_from(const char* name, const char* last) { +Person Person_new(const char* name, const char* last) { return (Person){.name = cstr_from(name), .last = cstr_from(last)}; } -void Person_del(Person* p) { - printf("del: %s %s\n", p->name.str, p->last.str); - c_del(cstr, &p->name, &p->last); +void Person_drop(Person* p) { + printf("drop: %s %s\n", p->name.str, p->last.str); + c_drop(cstr, &p->name, &p->last); } #define i_tag person #define i_val Person -#define i_valdel Person_del +#define i_valdrop Person_drop #include int main() { - csptr_person p = csptr_person_new(Person_from("John", "Smiths")); + csptr_person p = csptr_person_new(Person_new("John", "Smiths")); csptr_person q = csptr_person_clone(p); // share the pointer printf("%s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count); - c_del(csptr_person, &p, &q); + c_drop(csptr_person, &p, &q); } */ @@ -76,6 +76,7 @@ int main() { #endif #define _i_has_internal_clone #include "template.h" +typedef i_valraw _cx_rawvalue; #if !c_option(c_no_atomic) #define _i_atomic_inc(v) c_atomic_inc(v) @@ -132,9 +133,9 @@ _cx_memb(_move)(_cx_self* self) { } STC_INLINE void -_cx_memb(_del)(_cx_self* self) { +_cx_memb(_drop)(_cx_self* self) { if (self->use_count && _i_atomic_dec_and_test(self->use_count)) { - i_valdel(self->get); + i_valdrop(self->get); if (self->get != &((_cx_csptr_rep *)self->use_count)->value) c_free(self->get); c_free(self->use_count); @@ -143,19 +144,19 @@ _cx_memb(_del)(_cx_self* self) { STC_INLINE void _cx_memb(_reset)(_cx_self* self) { - _cx_memb(_del)(self); + _cx_memb(_drop)(self); self->use_count = NULL, self->get = NULL; } STC_INLINE void _cx_memb(_reset_with)(_cx_self* self, _cx_value* p) { - _cx_memb(_del)(self); + _cx_memb(_drop)(self); *self = _cx_memb(_with)(p); } STC_INLINE void _cx_memb(_reset_new)(_cx_self* self, i_val val) { - _cx_memb(_del)(self); + _cx_memb(_drop)(self); *self = _cx_memb(_new)(val); } @@ -164,47 +165,48 @@ _cx_memb(_reset_new)(_cx_self* self, i_val val) { return _cx_memb(_new)(i_valfrom(raw)); } - STC_INLINE void - _cx_memb(_reset_from)(_cx_self* self, i_valraw raw) { - _cx_memb(_del)(self); - *self = _cx_memb(_new)(i_valfrom(raw)); + STC_INLINE i_valraw + _cx_memb(_toraw)(const _cx_self* self) { + return i_valto(self->get); } #endif STC_INLINE void _cx_memb(_copy)(_cx_self* self, _cx_self ptr) { if (ptr.use_count) _i_atomic_inc(ptr.use_count); - _cx_memb(_del)(self); *self = ptr; + _cx_memb(_drop)(self); *self = ptr; } STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self ptr) { - if (self->get != ptr.get) _cx_memb(_del)(self); + if (self->get != ptr.get) _cx_memb(_drop)(self); *self = ptr; } STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* self, size_t n) { - #if (c_option(c_no_compare) || defined _i_default_compare) && SIZE_MAX >> 32 + #if c_option(c_no_cmp) && SIZE_MAX >> 32 return c_hash64(&self->get, 8); - #elif (c_option(c_no_compare) || defined _i_default_compare) + #elif c_option(c_no_cmp) return c_hash32(&self->get, 4); #else - i_valraw raw = i_valto(self->get); - return i_hash(&raw, sizeof raw); + return i_hash(self->get, sizeof *self->get); #endif } STC_INLINE int -_cx_memb(_compare)(const _cx_self* x, const _cx_self* y) { - #if (c_option(c_no_compare) || defined _i_default_compare) - return (int)(x->get - y->get); +_cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) { + #if c_option(c_no_cmp) + return c_default_cmp(&x->get, &y->get); #else - i_valraw rx = i_valto(x->get); - i_valraw ry = i_valto(y->get); - return i_cmp(&rx, &ry); + return i_cmp(x->get, y->get); #endif } + +STC_INLINE bool +_cx_memb(_equalto)(const _cx_self* x, const _cx_self* y) { + return !_cx_memb(_cmp)(x, y); +} #undef _i_atomic_inc #undef _i_atomic_dec_and_test -#include "template.h" \ No newline at end of file +#include "template.h" diff --git a/include/stc/csset.h b/include/stc/csset.h index e4558192..07cf4b17 100644 --- a/include/stc/csset.h +++ b/include/stc/csset.h @@ -38,7 +38,7 @@ int main(void) { c_foreach (k, csset_i, s) printf("set %d\n", *k.ref); - csset_i_del(&s); + csset_i_drop(&s); } */ diff --git a/include/stc/cstack.h b/include/stc/cstack.h index c1170f79..d43afe29 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -54,11 +54,11 @@ STC_INLINE _cx_self _cx_memb(_with_size)(size_t size, i_val fill) { STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_value *p = self->data + self->size; - while (p-- != self->data) i_valdel(p); + while (p-- != self->data) { i_valdrop(p); } self->size = 0; } -STC_INLINE void _cx_memb(_del)(_cx_self* self) +STC_INLINE void _cx_memb(_drop)(_cx_self* self) { _cx_memb(_clear)(self); c_free(self->data); } STC_INLINE size_t _cx_memb(_size)(_cx_self v) @@ -74,7 +74,7 @@ STC_INLINE _cx_value* _cx_memb(_top)(const _cx_self* self) { return &self->data[self->size - 1]; } STC_INLINE void _cx_memb(_pop)(_cx_self* self) - { _cx_value* p = &self->data[--self->size]; i_valdel(p); } + { _cx_value* p = &self->data[--self->size]; i_valdrop(p); } STC_INLINE bool _cx_memb(_reserve)(_cx_self* self, size_t n) { if (n < self->size) return true; @@ -107,7 +107,7 @@ STC_INLINE _cx_self _cx_memb(_clone)(_cx_self v) { STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val) diff --git a/include/stc/cstr.h b/include/stc/cstr.h index a46de3c3..730f4d16 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -68,6 +68,7 @@ STC_API int c_strncasecmp(const char* s1, const char* s2, size_t nma STC_INLINE cstr cstr_init() { return cstr_null; } #define cstr_str(self) (self)->str +#define cstr_toraw(self) (self)->str #define cstr_new(literal) \ cstr_from_n(literal, sizeof c_make(c_strlit){literal} - 1) STC_INLINE cstr cstr_from(const char* str) @@ -77,7 +78,7 @@ STC_INLINE size_t cstr_size(cstr s) { return _cstr_rep(&s)->size; } STC_INLINE size_t cstr_length(cstr s) { return _cstr_rep(&s)->size; } STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_rep(&s)->cap; } STC_INLINE bool cstr_empty(cstr s) { return _cstr_rep(&s)->size == 0; } -STC_INLINE void cstr_del(cstr* self) +STC_INLINE void cstr_drop(cstr* self) { if (_cstr_rep(self)->cap) c_free(_cstr_rep(self)); } STC_INLINE cstr cstr_clone(cstr s) { return cstr_from_n(s.str, _cstr_rep(&s)->size); } @@ -166,7 +167,7 @@ cstr_ends_with(cstr s, const char* sub) { } /* container adaptor functions: */ -#define cstr_compare(xp, yp) strcmp((xp)->str, (yp)->str) +#define cstr_cmp(xp, yp) strcmp((xp)->str, (yp)->str) #define cstr_equalto(xp, yp) (strcmp((xp)->str, (yp)->str) == 0) #define cstr_hash(xp, dummy) c_strhash((xp)->str) @@ -249,7 +250,7 @@ cstr_printf(cstr* self, const char* fmt, ...) { va_start(args, fmt); int n = cstr_vfmt(&ret, fmt, args); va_end(args); - cstr_del(self); + cstr_drop(self); *self = ret; return n; } diff --git a/include/stc/csview.h b/include/stc/csview.h index 872b6e1e..ac120e15 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -114,9 +114,13 @@ STC_INLINE bool cstr_ends_with_v(cstr s, csview sub) /* ---- Container helper functions ---- */ -#define csview_compare(xp, yp) strcmp((xp)->str, (yp)->str) +STC_INLINE int csview_cmp(const csview* x, const csview* y) { + const size_t m = x->size < y->size ? x->size : y->size; + const int c = memcmp(x->str, y->str, m); + return c ? c : x->size - y->size; + } #define csview_hash(xp, dummy) c_strhash((xp)->str) -#define csview_equalto(xp, yp) (strcmp((xp)->str, (yp)->str) == 0) +#define csview_equalto(xp, yp) (csview_cmp(xp, yp) == 0) /* -------------------------- IMPLEMENTATION ------------------------- */ diff --git a/include/stc/cvec.h b/include/stc/cvec.h index f64f7840..01143d25 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -46,15 +46,15 @@ struct MyStruct { int main() { cvec_i32 vec = cvec_i32_init(); cvec_i32_push_back(&vec, 123); - cvec_i32_del(&vec); + cvec_i32_drop(&vec); cvec_float fvec = cvec_float_init(); cvec_float_push_back(&fvec, 123.3); - cvec_float_del(&fvec); + cvec_float_drop(&fvec); cvec_str svec = cvec_str_init(); cvec_str_emplace_back(&svec, "Hello, friend"); - cvec_str_del(&svec); + cvec_str_drop(&svec); } */ @@ -79,7 +79,7 @@ struct cvec_rep { size_t size, cap; void* data[]; }; typedef i_valraw _cx_rawvalue; STC_API _cx_self _cx_memb(_init)(void); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); STC_API void _cx_memb(_clear)(_cx_self* self); STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap); STC_API bool _cx_memb(_resize)(_cx_self* self, size_t size, i_val null); @@ -87,8 +87,8 @@ STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value); STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2); STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2); -#if !c_option(c_no_compare) -STC_API int _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y); +#if !c_option(c_no_cmp) +STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y); STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw raw); STC_API _cx_iter _cx_memb(_bsearch_in)(_cx_iter it1, _cx_iter it2, i_valraw raw); #endif @@ -107,7 +107,7 @@ STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw) STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } STC_INLINE _cx_iter _cx_memb(_emplace)(_cx_self* self, const size_t idx, i_valraw raw) { @@ -136,7 +136,7 @@ STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return self->da STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self) { return self->data + cvec_rep_(self)->size - 1; } STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) - { _cx_value* p = &self->data[--cvec_rep_(self)->size]; i_valdel(p); } + { _cx_value* p = &self->data[--cvec_rep_(self)->size]; i_valdrop(p); } STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { return c_make(_cx_iter){self->data}; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) @@ -197,7 +197,7 @@ _cx_memb(_at)(const _cx_self* self, const size_t idx) { return self->data + idx; } -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, i_valraw raw) { @@ -226,9 +226,9 @@ _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, } STC_INLINE void _cx_memb(_sort)(_cx_self* self) { - _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_compare)); + _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_cmp)); } -#endif // !c_no_compare +#endif // !c_no_cmp /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp) @@ -246,14 +246,15 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { struct cvec_rep* rep = cvec_rep_(self); if (rep->cap) { - for (_cx_value *p = self->data, *q = p + rep->size; p != q; ++p) - i_valdel(p); + for (_cx_value *p = self->data, *q = p + rep->size; p != q; ) { + --q; i_valdrop(q); + } rep->size = 0; } } STC_DEF void -_cx_memb(_del)(_cx_self* self) { +_cx_memb(_drop)(_cx_self* self) { _cx_memb(_clear)(self); if (cvec_rep_(self)->cap) c_free(cvec_rep_(self)); @@ -263,7 +264,7 @@ STC_DEF bool _cx_memb(_reserve)(_cx_self* self, const size_t cap) { struct cvec_rep* rep = cvec_rep_(self); const size_t len = rep->size; - if (cap > rep->cap || cap && cap == len) { + if (cap > rep->cap || (cap && cap == len)) { rep = (struct cvec_rep*) c_realloc(rep->cap ? rep : NULL, offsetof(struct cvec_rep, data) + cap*sizeof(i_val)); if (!rep) return false; @@ -279,7 +280,7 @@ _cx_memb(_resize)(_cx_self* self, const size_t len, i_val null) { if (!_cx_memb(_reserve)(self, len)) return false; struct cvec_rep *rep = cvec_rep_(self); const size_t n = rep->size; - for (size_t i = len; i < n; ++i) i_valdel(&self->data[i]); + for (size_t i = len; i < n; ++i) { i_valdrop(&self->data[i]); } for (size_t i = n; i < len; ++i) self->data[i] = null; if (rep->cap) rep->size = len; return true; @@ -320,7 +321,7 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { intptr_t len = p2 - p1; if (len > 0) { _cx_value* p = p1, *end = self->data + cvec_rep_(self)->size; - for (; p != p2; ++p) i_valdel(p); + for (; p != p2; ++p) { i_valdrop(p); } memmove(p1, p2, (end - p2) * sizeof(i_val)); cvec_rep_(self)->size -= len; } @@ -356,7 +357,7 @@ _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, } #endif -#if !c_option(c_no_compare) +#if !c_option(c_no_cmp) STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) { @@ -381,12 +382,12 @@ _cx_memb(_bsearch_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) { } STC_DEF int -_cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y) { +_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { i_valraw rx = i_valto(x); i_valraw ry = i_valto(y); return i_cmp(&rx, &ry); } -#endif // !c_no_compare +#endif // !c_no_cmp #endif #include "template.h" #define CVEC_H_INCLUDED diff --git a/include/stc/template.h b/include/stc/template.h index 85c4a940..61befb2b 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -40,19 +40,13 @@ #define _cx_size _cx_memb(_size_t) #endif -#if defined i_valraw && !(defined i_valto && defined i_valfrom) - #error "if i_valraw or i_valto defined, i_valfrom must be defined" -#endif -#if defined i_keyraw && !(defined i_keyto && defined i_keyfrom) - #error "if i_keyraw or i_keyto defined, i_keyfrom a must be defined" -#endif -#ifdef i_key_csptr // [deprecated] - #define i_key_ref i_key_csptr - #error "i_key_csptr no longer supported: use new name i_key_ref" +#if defined i_key_csptr || defined i_key_ref // [deprecated] + #define i_key_bind i_key_csptr + #error "i_key_csptr/ref no longer supported: use new name i_key_bind" #endif -#ifdef i_val_csptr // [deprecated] - #define i_val_ref i_val_csptr - #error "i_val_csptr no longer supported: use new name i_val_ref" +#if defined i_val_csptr || defined i_val_ref // [deprecated] + #define i_val_bind i_val_csptr + #error "i_val_sptr/ref no longer supported: use new name i_val_bind" #endif #ifdef i_cnt // [deprecated] #define i_type i_cnt @@ -69,46 +63,53 @@ #include "cstr.h" #endif -#if defined i_key_ref - #define i_key i_key_ref - #define i_keyfrom c_PASTE(i_key, _clone) - #ifndef i_cmp - #define i_cmp c_PASTE(i_key, _compare) - #endif - #ifndef i_hash - #define i_hash c_PASTE(i_key, _hash) - #endif - #ifndef i_keydel - #define i_keydel c_PASTE(i_key, _del) - #endif - -#elif defined i_key_str - - #define i_key cstr - #define i_keyfrom cstr_from - #define i_keyto cstr_str - #define i_keyraw const char* +#ifdef i_key_str + #define i_key_bind cstr + #define i_keyraw c_rawstr #ifndef i_tag #define i_tag str #endif - #ifndef i_cmp - #define i_cmp c_rawstr_compare +#endif + +#ifdef i_key_bind + #define i_key i_key_bind + #ifndef i_keyraw + #ifndef i_keyfrom + #define i_keyfrom c_PASTE(i_key, _clone) + #endif + #else + #ifndef i_keyfrom + #define i_keyfrom c_PASTE(i_key, _from) + #endif + #ifndef i_keyto + #define i_keyto c_PASTE(i_key, _toraw) + #endif + #endif + #ifndef i_cmp + #define i_cmp c_PASTE(i_keyraw, _cmp) + #endif + #ifndef i_equ + #define i_equ c_PASTE(i_keyraw, _equalto) #endif #ifndef i_hash - #define i_hash c_rawstr_hash + #define i_hash c_PASTE(i_keyraw, _hash) #endif - #if !defined i_keydel - #define i_keydel cstr_del + #ifndef i_keydrop + #define i_keydrop c_PASTE(i_key, _drop) #endif #endif -/* Resolve i_del and i_from here */ -#if defined i_del && defined i_isset - #define i_keydel i_del -#elif defined i_del && !defined i_key - #define i_valdel i_del -#elif defined i_del - #error "i_del not supported for maps, define i_keydel / i_valdel instead." +#if defined i_keyraw && !(defined i_keyto && defined i_keyfrom) + #error "if i_keyraw defined, i_keyfrom and i_keyto must be defined" +#endif + +/* Resolve i_drop and i_from here */ +#if defined i_drop && defined i_isset + #define i_keydrop i_drop +#elif defined i_drop && !defined i_key + #define i_valdrop i_drop +#elif defined i_drop + #error "i_drop not supported for maps, define i_keydrop / i_valdrop instead." #endif #if defined i_from && defined i_isset #define i_keyfrom i_from @@ -118,33 +119,40 @@ #error "i_from not supported for maps, define i_keyfrom / i_valfrom instead." #endif -#if defined i_val_ref - #define i_val i_val_ref - #define i_valfrom c_PASTE(i_val, _clone) - #if !defined i_cmp && !defined i_key - #define i_cmp c_PASTE(i_val, _compare) - #endif - #if !defined i_valdel - #define i_valdel c_PASTE(i_val, _del) +#ifdef i_val_str + #define i_val_bind cstr + #define i_valraw c_rawstr + #if !defined i_tag && !defined i_key + #define i_tag str #endif +#endif -#elif defined i_val_str - - #define i_val cstr - #define i_valfrom cstr_from - #define i_valto cstr_str - #define i_valraw const char* - #if !defined i_tag && !defined i_key - #define i_tag str +#ifdef i_val_bind + #define i_val i_val_bind + #ifndef i_valraw + #ifndef i_valfrom + #define i_valfrom c_PASTE(i_val, _clone) + #endif + #else + #ifndef i_valfrom + #define i_valfrom c_PASTE(i_val, _from) + #endif + #ifndef i_valto + #define i_valto c_PASTE(i_val, _toraw) + #endif #endif #if !defined i_cmp && !defined i_key - #define i_cmp c_rawstr_compare + #define i_cmp c_PASTE(i_valraw, _cmp) #endif - #if !defined i_valdel - #define i_valdel cstr_del + #ifndef i_valdrop + #define i_valdrop c_PASTE(i_val, _drop) #endif #endif +#if defined i_valraw && !(defined i_valto && defined i_valfrom) + #error "if i_valraw defined, i_valfrom and i_valto must be defined" +#endif + #ifdef i_key #ifdef _i_isset #define i_val i_key @@ -152,8 +160,8 @@ #ifndef i_tag #define i_tag i_key #endif - #if !defined _i_has_internal_clone && defined i_keydel && !defined i_keyfrom && !c_option(c_no_clone) - #error "i_keydel defined but not i_keyfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'" + #if !defined _i_has_internal_clone && defined i_keydrop && !defined i_keyfrom && !c_option(c_no_clone) + #error "i_keydrop defined but not i_keyfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'" #endif #if !defined i_keyfrom #define i_keyfrom c_default_clone @@ -167,8 +175,8 @@ #elif !defined i_equ #define i_equ c_default_equalto #endif - #ifndef i_keydel - #define i_keydel c_default_del + #ifndef i_keydrop + #define i_keydrop c_default_drop #endif #elif defined _i_isset #error "i_key define is missing." @@ -177,8 +185,8 @@ #ifndef i_tag #define i_tag i_val #endif -#if !defined _i_has_internal_clone && defined i_valdel && !defined i_valfrom && !c_option(c_no_clone) - #error "i_valdel/i_del defined but not i_valfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'" +#if !defined _i_has_internal_clone && defined i_valdrop && !defined i_valfrom && !c_option(c_no_clone) + #error "i_valdrop/i_drop defined but not i_valfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'" #endif #if !defined i_valfrom #define i_valfrom c_default_clone @@ -187,12 +195,11 @@ #define i_valraw i_val #define i_valto c_default_toraw #endif -#ifndef i_valdel - #define i_valdel c_default_del +#ifndef i_valdrop + #define i_valdrop c_default_drop #endif #ifndef i_cmp - #define _i_default_compare - #define i_cmp c_default_compare + #define i_cmp c_default_cmp #endif #ifndef i_hash #define i_hash c_default_hash @@ -205,29 +212,28 @@ #undef i_imp #undef i_opt #undef i_cmp -#undef i_del +#undef i_drop #undef i_equ #undef i_hash #undef i_from #undef i_val #undef i_val_str -#undef i_val_ref -#undef i_valdel +#undef i_val_bind +#undef i_valdrop #undef i_valraw #undef i_valfrom #undef i_valto #undef i_key #undef i_key_str -#undef i_key_ref -#undef i_keydel +#undef i_key_bind +#undef i_keydrop #undef i_keyraw #undef i_keyfrom #undef i_keyto #undef _i_prefix -#undef _i_default_compare #undef _i_has_internal_clone #undef _i_template #endif -- cgit v1.2.3