From b24dd76490733666f7f7b3147c5c64a75c973ac6 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 20 Feb 2021 15:50:36 +0100 Subject: Rewamp of cmap/csmap API. More to come. --- README.md | 2 +- benchmarks/cmap_benchmark2.cpp | 4 +- benchmarks/cmap_benchmark3.cpp | 6 +- benchmarks/csmap_benchmark2.cpp | 6 +- docs/carray_api.md | 4 +- docs/cdeq_api.md | 15 ++--- docs/clist_api.md | 49 +++++++++-------- docs/cmap_api.md | 79 +++++++++++++-------------- docs/cpque_api.md | 5 +- docs/cqueue_api.md | 5 +- docs/cset_api.md | 18 +++--- docs/csmap_api.md | 73 ++++++++++++------------- docs/csset_api.md | 15 +++-- docs/cstack_api.md | 5 +- docs/cvec_api.md | 19 ++++--- examples/advanced.c | 11 ++-- examples/complex.c | 12 ++-- examples/demos.c | 16 +++--- examples/inits.c | 10 ++-- examples/mapmap.c | 16 +++--- examples/phonebook.c | 2 +- examples/stc_astar.c | 4 +- stc/carray.h | 3 + stc/cdeq.h | 6 +- stc/clist.h | 6 +- stc/cmap.h | 118 +++++++++++++++++++++++++--------------- stc/cptr.h | 2 - stc/csmap.h | 103 +++++++++++++++++++++-------------- stc/cvec.h | 6 +- 29 files changed, 331 insertions(+), 289 deletions(-) diff --git a/README.md b/README.md index bddfb96f..f23aa394 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ conditionally inserted. The **emplace()** and **put()** methods constructs cstr- when required: ```c cmap_str_emplace(&map, "Hello", "world"); // no cstr is constructed if "Hello" is already in the map. -cmap_str_put(&map, "Hello", "world!!"); // similar, but cstr_from("world!!") call is always made in put. +cmap_str_emplace_put(&map, "Hello", "world!!"); // similar, but cstr_from("world!!") call is always made in put. it = cmap_str_find(&map, "Hello"); // no cstr constructed for lookup, although keys are cstr-type. ``` In the **cmap_str_insert()** example at the top of this section, both the key and mapped value are first constructed, diff --git a/benchmarks/cmap_benchmark2.cpp b/benchmarks/cmap_benchmark2.cpp index baa929a2..2678ac4d 100644 --- a/benchmarks/cmap_benchmark2.cpp +++ b/benchmarks/cmap_benchmark2.cpp @@ -236,7 +236,7 @@ static void ins_and_access_cmap_s(picobench::state& s) picobench::scope scope(s); c_forrange (s.iterations()) { randomize(str.str, cstr_size(str)); - cmap_str_put(&map, str.str, str.str); + cmap_str_emplace_put(&map, str.str, str.str); randomize(str.str, cstr_size(str)); cmap_str_iter_t it = cmap_str_find(&map, str.str); if (it.ref) { @@ -303,7 +303,7 @@ static void iterate_cmap_x(picobench::state& s) // measure insert then iterate whole map c_forrange (n, s.iterations()) { - cmap_x_put(&map, stc64_random(), n); + cmap_x_emplace_put(&map, stc64_random(), n); if (!(n & K)) c_foreach (i, cmap_x, map) result += i.ref->second; } diff --git a/benchmarks/cmap_benchmark3.cpp b/benchmarks/cmap_benchmark3.cpp index 1f5c6fa1..2990619e 100644 --- a/benchmarks/cmap_benchmark3.cpp +++ b/benchmarks/cmap_benchmark3.cpp @@ -35,7 +35,7 @@ stc64_t rng; #define CMAP_SETUP(X, Key, Value) cmap_##X map = cmap_##X##_init() \ ; cmap_##X##_set_load_factors(&map, 0.0, max_load_factor) -#define CMAP_PUT(X, key, val) cmap_##X##_put(&map, key, val).first->second +#define CMAP_PUT(X, key, val) cmap_##X##_emplace_put(&map, key, val).first->second #define CMAP_EMPLACE(X, key, val) cmap_##X##_emplace(&map, key, val).first->second #define CMAP_ERASE(X, key) cmap_##X##_erase(&map, key) #define CMAP_FIND(X, key) (cmap_##X##_find(map, key) != NULL) @@ -47,8 +47,8 @@ stc64_t rng; #define CMAP_DTOR(X) cmap_##X##_del(&map) #define KMAP_SETUP(X, Key, Value) khash_t(ii)* map = kh_init(ii); khiter_t ki; int ret -#define KMAP_PUT(X, key, val) (*(ki = kh_put(ii, map, key, &ret), map->vals[ki] = val, &map->vals[ki])) -#define KMAP_EMPLACE(X, key, val) (ki = kh_put(ii, map, key, &ret), ret ? (map->vals[ki] = val, 0) : 0, map->vals[ki]) +#define KMAP_PUT(X, key, val) (*(ki = kh_emplace_put(ii, map, key, &ret), map->vals[ki] = val, &map->vals[ki])) +#define KMAP_EMPLACE(X, key, val) (ki = kh_emplace_put(ii, map, key, &ret), ret ? (map->vals[ki] = val, 0) : 0, map->vals[ki]) #define KMAP_ERASE(X, key) ((ki = kh_get(ii, map, key)) != kh_end(map) ? kh_del(ii, map, ki), 1 : 0) #define KMAP_FIND(X, key) (kh_get(ii, map, key) != kh_end(map)) #define KMAP_SIZE(X) kh_size(map) diff --git a/benchmarks/csmap_benchmark2.cpp b/benchmarks/csmap_benchmark2.cpp index 5ef23862..08953868 100644 --- a/benchmarks/csmap_benchmark2.cpp +++ b/benchmarks/csmap_benchmark2.cpp @@ -127,7 +127,7 @@ static void ins_and_erase_csmap_i(picobench::state& s) csmap_i_clear(&map); stc64_srandom(seed); c_forrange (i, s.iterations()) - csmap_i_put(&map, stc64_random() & mask, i); + csmap_i_emplace_put(&map, stc64_random() & mask, i); stc64_srandom(seed); c_forrange (s.iterations()) @@ -222,7 +222,7 @@ static void ins_and_access_csmap_s(picobench::state& s) picobench::scope scope(s); c_forrange (s.iterations()) { randomize(str.str, cstr_size(str)); - csmap_s_put(&map, str.str, cstr_clone(str)); + csmap_s_emplace_put(&map, str.str, cstr_clone(str)); randomize(str.str, cstr_size(str)); csmap_s_iter_t it = csmap_s_find(&map, str.str); if (it.ref) { @@ -282,7 +282,7 @@ static void iterate_csmap_x(picobench::state& s) // measure insert then iterate whole map c_forrange (n, s.iterations()) { - csmap_x_put(&map, stc64_random(), n); + csmap_x_emplace_put(&map, stc64_random(), n); if (!(n & K)) c_foreach (i, csmap_x, map) result += i.ref->second; } diff --git a/docs/carray_api.md b/docs/carray_api.md index 55d1f670..1e70d996 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -9,8 +9,8 @@ See the c++ class [boost::multi_array](https://www.boost.org/doc/libs/release/li ## Declaration ```c -using_carray(X, Value, valueDestroy=c_default_del, - valueClone=c_default_clone) +using_carray(X, Value); +using_carray(X, Value, valueDestroy); ``` The macro `using_carray()` can be instantiated with 2 or 4 arguments in the global scope. Default values are given above for args not specified. `X` and `N` are type tags and diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 9aa8cd4b..8061cbdd 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -8,12 +8,12 @@ See the c++ class [std::deque](https://en.cppreference.com/w/cpp/container/deque ## Declaration ```c -using_cdeq(X, Value, valueCompareRaw=c_default_compare, - valueDestroy=c_default_del, - valueFromRaw=c_default_clone, - valueToRaw=c_default_to_raw, - RawValue=Value) -using_cdeq_str() +using_cdeq(X, Value); +using_cdeq(X, Value, valueCompareRaw); +using_cdeq(X, Value, valueCompareRaw, valueDestroy); +using_cdeq(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue); + +using_cdeq_str(); ``` The macro `using_cdeq()` can be instantiated with 2, 3, 5, or 7 arguments in the global scope. Defaults values are given above for args not specified. `X` is a type tag name and @@ -60,11 +60,12 @@ cdeq_X_iter_t cdeq_X_find(const cdeq_X* self, RawValue raw); cdeq_X_iter_t cdeq_X_find_in_range(const cdeq_X* self, cdeq_X_iter_t first, cdeq_X_iter_t finish, RawValue raw); -void cdeq_X_push_n(cdeq_X *self, const cdeq_X_rawvalue_t arr[], size_t size); void cdeq_X_push_front(cdeq_X* self, Value value); void cdeq_X_push_back(cdeq_X* self, Value value); void cdeq_X_emplace_front(cdeq_X* self, RawValue raw); void cdeq_X_emplace_back(cdeq_X* self, RawValue raw); +void cdeq_X_push_n(cdeq_X *self, const cdeq_X_rawvalue_t arr[], size_t size); + void cdeq_X_pop_front(cdeq_X* self); void cdeq_X_pop_back(cdeq_X* self); diff --git a/docs/clist_api.md b/docs/clist_api.md index d693a052..c69d61d3 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -17,11 +17,11 @@ See the c++ class [std::forward_list](https://en.cppreference.com/w/cpp/containe ## Declaration ```c -using_clist(X, Value, valueCompareRaw=c_default_compare, - valueDestroy=c_default_del, - valueFromRaw=c_default_clone, - valueToRaw=c_default_to_raw, - RawValue=Value) +using_clist(X, Value); +using_clist(X, Value, valueCompareRaw); +using_clist(X, Value, valueCompareRaw, valueDestroy); +using_clist(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue); + using_clist_str() ``` The macro `using_clist()` can be instantiated with 2, 3, 5, or 7 arguments in the global scope. @@ -54,17 +54,18 @@ size_t clist_X_size(clist_X list); // note: O(n) clist_X_value_t* clist_X_front(clist_X* self); clist_X_value_t* clist_X_back(clist_X* self); -void clist_X_emplace_front(clist_X* self, RawValue raw); void clist_X_push_front(clist_X* self, Value value); -void clist_X_pop_front(clist_X* self); +void clist_X_emplace_front(clist_X* self, RawValue raw); - // non-std: push back, complexity O(1) -void clist_X_push_n(clist_X *self, const clist_X_rawvalue_t arr[], size_t size); -void clist_X_emplace_back(clist_X* self, RawValue ref); + // non-std: void clist_X_push_back(clist_X* self, Value value); +void clist_X_emplace_back(clist_X* self, RawValue raw); +void clist_X_push_n(clist_X *self, const clist_X_rawvalue_t arr[], size_t size); + +void clist_X_pop_front(clist_X* self); +clist_X_iter_t clist_X_insert_after(clist_X* self, clist_X_iter_t it, Value value); clist_X_iter_t clist_X_emplace_after(clist_X* self, clist_X_iter_t it, RawValue raw); -clist_X_iter_t clist_X_insert_after(clist_X* self, clist_X_iter_t it, Value raw); clist_X_iter_t clist_X_erase_after(clist_X* self, clist_X_iter_t it); clist_X_iter_t clist_X_erase_range_after(clist_X* self, clist_X_iter_t it1, clist_X_iter_t it2); @@ -173,19 +174,19 @@ using_clist(i, int); int main () { - c_init (clist_i, L, {10, 20, 30, 40, 50}); - // 10 20 30 40 50 - clist_i_iter_t it = clist_i_begin(&L); // ^ - it = clist_i_erase_after(&L, it); // 10 30 40 50 - // ^ - clist_i_iter_t end = clist_i_end(&L); // - it = clist_i_erase_range_after(&L, it, end); // 10 30 - // ^ - printf("mylist contains:"); - c_foreach (x, clist_i, L) printf(" %d", *x.ref); - puts(""); - - clist_i_del(&L); + c_init (clist_i, L, {10, 20, 30, 40, 50}); + // 10 20 30 40 50 + clist_i_iter_t it = clist_i_begin(&L); // ^ + it = clist_i_erase_after(&L, it); // 10 30 40 50 + // ^ + clist_i_iter_t end = clist_i_end(&L); // + it = clist_i_erase_range_after(&L, it, end); // 10 30 + // ^ + printf("mylist contains:"); + c_foreach (x, clist_i, L) printf(" %d", *x.ref); + puts(""); + + clist_i_del(&L); } ``` Output: diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 04cfccf8..1b953f1d 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -9,43 +9,37 @@ See the c++ class [std::unordered_map](https://en.cppreference.com/w/cpp/contain ## Declaration ```c -using_cmap(X, Key, Mapped, keyEqualsRaw=c_default_equals, - keyHashRaw=c_default_hash, - mappedDestroy=c_default_del, - mappedClone=c_default_clone, - keyDestroy=c_default_del, - keyFromRaw=c_default_clone, - keyToRaw=c_default_to_raw, - RawKey=Key) - -using_cmap_strkey(X, Mapped, mappedDestroy=c_default_del, - mappedClone=c_default_clone) - -using_cmap_strval(X, Key, keyEquals=c_default_equals, - keyHash=c_default_hash, - keyDestroy=c_default_del, - keyFromRaw=c_default_clone, - keyToRaw=c_default_to_raw, - RawKey=Key) -using_cmap_str() +using_cmap(X, Key, Mapped); +using_cmap(X, Key, Mapped, keyEquals, keyHash); +using_cmap(X, Key, Mapped, keyEquals, keyHash, mappedDestroy); +using_cmap(X, Key, Mapped, keyEquals, keyHash, mappedDestroy, mappedFromRaw, mappedToRaw, RawMapped); +using_cmap(X, Key, Mapped, keyEqualsRaw, keyHashRaw, mappedDestroy, mappedFromRaw, mappedToRaw, RawMapped, + keyDestroy, keyFromRaw, keyToRaw, RawKey); +using_cmap_keyarg(X, Key, Mapped, keyEquals, keyHash, keyDestroy); +using_cmap_keyarg(X, Key, Mapped, keyEqualsRaw, keyHashRaw, keyDestroy, keyFromRaw, keyToRaw, RawKey); + +using_cmap_strkey(X, Mapped); // cmap(str, cstr, Mapped, ...) +using_cmap_strkey(X, Mapped, mappedDestroy); +using_cmap_strkey(X, Mapped, mappedDestroy, mappedFromRaw, mappedToRaw, RawMapped); + +using_cmap_strval(X, Key); // cmap(str, Key, cstr, ...) +using_cmap_strval(X, Key, keyEquals, keyHash); +using_cmap_strval(X, Key, keyEquals, keyHash, keyDestroy); +using_cmap_strval(X, Key, keyEqualsRaw, keyHashRaw, keyDestroy, keyFromRaw, keyToRaw, RawKey); + +using_cmap_str() // cmap(str, cstr, cstr, ...) ``` -The macro `using_cmap()` can be instantiated with 3, 5, 7, 9, or 11 arguments in the global scope. +The `using_cmap()` macro family must be instantiated in the global scope. Default values are given above for args not specified. `X` is a type tag name and will affect the names of all cmap types and methods. E.g. declaring `using_cmap(my, int);`, `X` should be replaced by `my` in all of the following documentation. -`using_cmap_strkey()` and `using_cmap_strval()` are special macros defined by -`using_cmap()`. The macro `using_cmap_str()` is a shorthand for -```c -using_cmap(str, cstr_t, cstr_t, cstr_del, ...) // uses char* as "raw" types -``` - ## Header file All cmap definitions and prototypes may be included in your C source file by including a single header file. ```c -#include "stc/cmap.h" +#include ``` ## Methods @@ -69,12 +63,13 @@ size_t cmap_X_bucket_count(cmap_X map); cmap_X_iter_t cmap_X_find(const cmap_X* self, RawKey rkey); bool cmap_X_contains(const cmap_X* self, RawKey rkey); -void cmap_X_push_n(cmap_X* self, const cmap_X_rawvalue_t arr[], size_t size); +cmap_X_result_t cmap_X_insert(cmap_X* self, Key key, Mapped mapped); // no change if key in map +cmap_X_result_t cmap_X_insert_or_assign(cmap_X* self, Key key, Mapped mapped); // always update mapped cmap_X_result_t cmap_X_emplace(cmap_X* self, RawKey rkey, RawMapped rmapped); // no change if rkey in map -cmap_X_result_t cmap_X_put(cmap_X* self, RawKey rkey, RawMapped rmapped); // std::map::operator[] -cmap_X_result_t cmap_X_insert(cmap_X* self, Key key, Mapped mapped); // like emplace, other params -cmap_X_result_t cmap_X_insert_or_assign(cmap_X* self, Key key, Mapped mapped); // like put, other params -cmap_X_mapped_t* cmap_X_at(const cmap_X* self, RawKey rkey); // rkey must be in map +cmap_X_result_t cmap_X_emplace_put(cmap_X* self, RawKey rkey, RawMapped rmapped); // always update rmapped +void cmap_X_push_n(cmap_X* self, const cmap_X_rawvalue_t arr[], size_t size); + +cmap_X_mapped_t* cmap_X_at(const cmap_X* self, RawKey rkey); // rkey must be in map. size_t cmap_X_erase(cmap_X* self, RawKey rkey); void cmap_X_erase_entry(cmap_X* self, cmap_X_value_t* entry); @@ -175,7 +170,7 @@ int main() {110, "Blue"}, }); /* put replaces existing mapped value: */ - cmap_id_put(&idnames, 110, "White"); + cmap_id_emplace_put(&idnames, 110, "White"); /* put a constructed mapped value into map: */ cmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); /* emplace inserts only when key does not exist: */ @@ -209,10 +204,10 @@ int main() { cmap_v3 vecs = cmap_v3_init(); - cmap_v3_put(&vecs, (Vec3i){100, 0, 0}, 1); - cmap_v3_put(&vecs, (Vec3i){ 0, 100, 0}, 2); - cmap_v3_put(&vecs, (Vec3i){ 0, 0, 100}, 3); - cmap_v3_put(&vecs, (Vec3i){100, 100, 100}, 4); + cmap_v3_emplace_put(&vecs, (Vec3i){100, 0, 0}, 1); + cmap_v3_emplace_put(&vecs, (Vec3i){ 0, 100, 0}, 2); + cmap_v3_emplace_put(&vecs, (Vec3i){ 0, 0, 100}, 3); + cmap_v3_emplace_put(&vecs, (Vec3i){100, 100, 100}, 4); c_foreach (i, cmap_v3, vecs) printf("{ %3d, %3d, %3d }: %d\n", i.ref->first.x, i.ref->first.y, i.ref->first.z, i.ref->second); @@ -240,10 +235,10 @@ using_cmap(iv, int, Vec3i); int main() { cmap_iv vecs = cmap_iv_init(); - cmap_iv_put(&vecs, 1, (Vec3i){100, 0, 0}); - cmap_iv_put(&vecs, 2, (Vec3i){ 0, 100, 0}); - cmap_iv_put(&vecs, 3, (Vec3i){ 0, 0, 100}); - cmap_iv_put(&vecs, 4, (Vec3i){100, 100, 100}); + cmap_iv_emplace_put(&vecs, 1, (Vec3i){100, 0, 0}); + cmap_iv_emplace_put(&vecs, 2, (Vec3i){ 0, 100, 0}); + cmap_iv_emplace_put(&vecs, 3, (Vec3i){ 0, 0, 100}); + cmap_iv_emplace_put(&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); @@ -312,7 +307,7 @@ int main() { {"Olaf", "Denmark"}, 24 }, { {"Harald", "Iceland"}, 12 }, }); - cmap_vk_put(&vikings, (VikingRaw){"Bjorn", "Sweden"}, 10); + cmap_vk_emplace_put(&vikings, (VikingRaw){"Bjorn", "Sweden"}, 10); VikingRaw lookup = {"Einar", "Norway"}; diff --git a/docs/cpque_api.md b/docs/cpque_api.md index a1762fbe..badc6315 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -39,9 +39,10 @@ bool cpque_X_empty(cpque_X pq); const cpque_X_value_t* cpque_X_top(const cpque_X* self); -void cpque_X_push_n(cpque_X *self, const cpque_X_rawvalue_t arr[], size_t size); -void cpque_X_emplace(cpque_X* self, cpque_X_rawvalue_t raw); void cpque_X_push(cpque_X* self, cpque_X_value_t value); +void cpque_X_emplace(cpque_X* self, cpque_X_rawvalue_t raw); +void cpque_X_push_n(cpque_X *self, const cpque_X_rawvalue_t arr[], size_t size); + void cpque_X_pop(cpque_X* self); void cpque_X_erase_at(cpque_X* self, size_t idx); diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md index fee5bee4..653f9bfd 100644 --- a/docs/cqueue_api.md +++ b/docs/cqueue_api.md @@ -34,9 +34,10 @@ bool cqueue_X_empty(cqueue_X q); cqueue_X_value_t* cqueue_X_front(cqueue_X* self); cqueue_X_value_t* cqueue_X_back(cqueue_X* self); -void cqueue_X_push_n(cqueue_X *self, const cqueue_X_rawvalue_t arr[], size_t size); -void cqueue_X_emplace(cqueue_X* self, cqueue_X_rawvalue_t raw); void cqueue_X_push(cqueue_X* self, cqueue_X_value_t value); +void cqueue_X_emplace(cqueue_X* self, cqueue_X_rawvalue_t raw); +void cqueue_X_push_n(cqueue_X *self, const cqueue_X_rawvalue_t arr[], size_t size); + void cqueue_X_pop(cqueue_X* self); cqueue_X_iter_t cqueue_X_begin(cqueue_X* self); diff --git a/docs/cset_api.md b/docs/cset_api.md index 03a0e765..d2064cf2 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -7,13 +7,11 @@ A **cset** is an associative container that contains a set of unique objects of ## Declaration ```c -using_cset(X, Key, keyEqualsRaw=c_default_equals, - keyHashRaw=c_default_hash, - keyDestroy=c_default_del, - keyFromRaw=c_default_clone, - keyToRaw=c_default_to_raw, - RawKey=Key) -using_cset_str() +using_cset(X, Key); +using_cset(X, Key, keyEqualsRaw, keyHashRaw); +using_cset(X, Key, keyEqualsRaw, keyHashRaw, keyDestroy); +using_cset(X, Key, keyEqualsRaw, keyHashRaw, keyDestroy, keyFromRaw, keyToRaw, RawKey); +using_cset_str(); ``` The macro `using_cset()` can be instantiated with 2, 4, 6, or 8 arguments in the global scope. Default values are given above for args not specified. `X` is a type tag name and @@ -51,13 +49,13 @@ size_t cset_X_capacity(cset_X set); cset_X_iter_t cset_X_find(const cset_X* self, RawKey rkey); bool cset_X_contains(const cset_X* self, RawKey rkey); -void cset_X_push_n(cset_X* self, const RawKey arr[], size_t size); -cset_X_result_t cset_X_emplace(cset_X* self, RawKey rkey); cset_X_result_t cset_X_insert(cset_X* self, Key key); +cset_X_result_t cset_X_emplace(cset_X* self, RawKey rkey); +void cset_X_push_n(cset_X* self, const RawKey arr[], size_t size); size_t cset_X_erase(cset_X* self, RawKey rkey); -void cset_X_erase_entry(cset_X* self, cset_X_key_t* key); cset_X_iter_t cset_X_erase_at(cset_X* self, cset_X_iter_t pos); +void cset_X_erase_entry(cset_X* self, cset_X_key_t* key); cset_X_iter_t cset_X_begin(cset_X* self); cset_X_iter_t cset_X_end(cset_X* self); diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 72f90f08..ffbf7db4 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -8,41 +8,37 @@ See the c++ class [std::map](https://en.cppreference.com/w/cpp/container/map) fo ## Declaration ```c -using_csmap(X, Key, Mapped, keyCompareRaw=c_default_compare, - mappedDestroy=c_default_del, - mappedClone=c_default_clone, - keyDestroy=c_default_del, - keyFromRaw=c_default_clone, - keyToRaw=c_default_to_raw, - RawKey=Key) - -using_csmap_strkey(X, Mapped, mappedDestroy=c_default_del, - mappedClone=c_default_clone) - -using_csmap_strval(X, Key, keyCompare=c_default_compare, - keyDestroy=c_default_del, - keyFromRaw=c_default_clone, - keyToRaw=c_default_to_raw, - RawKey=Key) -using_csmap_str() +using_csmap(X, Key, Mapped); +using_csmap(X, Key, Mapped, keyCompare); +using_csmap(X, Key, Mapped, keyCompare, mappedDestroy); +using_csmap(X, Key, Mapped, keyCompare, mappedDestroy, mappedFromRaw, mappedToRaw, RawMapped); +using_csmap(X, Key, Mapped, keyCompareRaw, mappedDestroy, mappedFromRaw, mappedToRaw, RawMapped, + keyDestroy, keyFromRaw, keyToRaw, RawKey); +using_csmap_keyarg(X, Key, Mapped, keyCompare, keyDestroy); +using_csmap_keyarg(X, Key, Mapped, keyCompareRaw, keyDestroy, keyFromRaw, keyToRaw, RawKey); + +using_csmap_strkey(X, Mapped); // csmap(str, cstr, Mapped, ...) +using_csmap_strkey(X, Mapped, mappedDestroy); +using_csmap_strkey(X, Mapped, mappedDestroy, mappedFromRaw, mappedToRaw, RawMapped); + +using_csmap_strval(X, Key); // csmap(str, Key, cstr, ...) +using_csmap_strval(X, Key, keyCompare); +using_csmap_strval(X, Key, keyCompare, keyDestroy); +using_csmap_strval(X, Key, keyCompareRaw, keyDestroy, keyFromRaw, keyToRaw, RawKey); + +using_csmap_str(); // csmap(str, cstr, cstr, ...) ``` -The macro `using_csmap()` can be instantiated with 3, 4, 6, 8, or 10 arguments in the global scope. +The `using_csmap()` macro family must be instantiated in the global scope. Default values are given above for args not specified. `X` is a type tag name and will affect the names of all csmap types and methods. E.g. declaring `using_csmap(my, int);`, `X` should be replaced by `my` in all of the following documentation. -`using_csmap_strkey()` and `using_csmap_strval()` are special macros defined by -`using_csmap()`. The macro `using_csmap_str()` is a shorthand for -```c -using_csmap(str, cstr, cstr, cstr_compare_raw, cstr_del, cstr_from, ...) -``` - ## Header file All csmap definitions and prototypes may be included in your C source file by including a single header file. ```c -#include "stc/csmap.h" +#include ``` ## Methods @@ -60,11 +56,12 @@ csmap_X_iter_t csmap_X_find(const csmap_X* self, RawKey rkey); csmap_X_value_t* csmap_X_find_it(const csmap_X* self, RawKey rkey, csmap_X_iter_t* out); // return NULL if not found bool csmap_X_contains(const csmap_X* self, RawKey rkey); -void csmap_X_push_n(csmap_X* self, const csmap_X_rawvalue_t arr[], size_t size); +csmap_X_result_t csmap_X_insert(csmap_X* self, Key key, Mapped mapped); // no change if key in map +csmap_X_result_t csmap_X_insert_or_assign(csmap_X* self, Key key, Mapped mapped); // always update mapped csmap_X_result_t csmap_X_emplace(csmap_X* self, RawKey rkey, RawMapped rmapped); // no change if rkey in map -csmap_X_result_t csmap_X_put(csmap_X* self, RawKey rkey, RawMapped rmapped); // std::map::operator[] -csmap_X_result_t csmap_X_insert(csmap_X* self, Key key, Mapped mapped); // like emplace, other params -csmap_X_result_t csmap_X_insert_or_assign(csmap_X* self, Key key, Mapped mapped); // like put, other params +csmap_X_result_t csmap_X_emplace_put(csmap_X* self, RawKey rkey, RawMapped rmapped); // always update rmapped +void csmap_X_push_n(csmap_X* self, const csmap_X_rawvalue_t arr[], size_t size); + csmap_X_mapped_t* csmap_X_at(const csmap_X* self, RawKey rkey); // rkey must be in map. size_t csmap_X_erase(csmap_X* self, RawKey rkey); @@ -152,7 +149,7 @@ int main() {110, "Blue"}, }); /* put replaces existing mapped value: */ - csmap_id_put(&idnames, 110, "White"); + csmap_id_emplace_put(&idnames, 110, "White"); /* put a constructed mapped value into map: */ csmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); /* emplace inserts only when key does not exist: */ @@ -192,10 +189,10 @@ int main() { csmap_vi vecs = csmap_vi_init(); - csmap_vi_put(&vecs, (Vec3i){100, 0, 0}, 1); - csmap_vi_put(&vecs, (Vec3i){ 0, 100, 0}, 2); - csmap_vi_put(&vecs, (Vec3i){ 0, 0, 100}, 3); - csmap_vi_put(&vecs, (Vec3i){100, 100, 100}, 4); + csmap_vi_emplace_put(&vecs, (Vec3i){100, 0, 0}, 1); + csmap_vi_emplace_put(&vecs, (Vec3i){ 0, 100, 0}, 2); + csmap_vi_emplace_put(&vecs, (Vec3i){ 0, 0, 100}, 3); + csmap_vi_emplace_put(&vecs, (Vec3i){100, 100, 100}, 4); c_foreach (i, csmap_vi, vecs) printf("{ %3d, %3d, %3d }: %d\n", i.ref->first.x, i.ref->first.y, i.ref->first.z, i.ref->second); @@ -223,10 +220,10 @@ using_csmap(iv, int, Vec3i); int main() { csmap_iv vecs = csmap_iv_init(); - csmap_iv_put(&vecs, 1, (Vec3i){100, 0, 0}); - csmap_iv_put(&vecs, 2, (Vec3i){ 0, 100, 0}); - csmap_iv_put(&vecs, 3, (Vec3i){ 0, 0, 100}); - csmap_iv_put(&vecs, 4, (Vec3i){100, 100, 100}); + csmap_iv_emplace_put(&vecs, 1, (Vec3i){100, 0, 0}); + csmap_iv_emplace_put(&vecs, 2, (Vec3i){ 0, 100, 0}); + csmap_iv_emplace_put(&vecs, 3, (Vec3i){ 0, 0, 100}); + csmap_iv_emplace_put(&vecs, 4, (Vec3i){100, 100, 100}); c_foreach (i, csmap_iv, vecs) printf("%d: { %3d, %3d, %3d }\n", i.ref->first, i.ref->second.x, i.ref->second.y, i.ref->second.z); diff --git a/docs/csset_api.md b/docs/csset_api.md index 33eecd1b..79c01b72 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -8,12 +8,11 @@ See the c++ class [std::set](https://en.cppreference.com/w/cpp/container/set) fo ## Declaration ```c -using_csset(X, Key, keyCompare=c_default_compare, - keyDestroy=c_default_del, - keyFromRaw=c_default_clone, - keyToRaw=c_default_to_raw, - RawKey=Key) -using_csset_str() +using_csset(X, Key); +using_csset(X, Key, keyCompare); +using_csset(X, Key, keyCompare, keyDestroy); +using_csset(X, Key, keyCompare, keyDestroy, keyFromRaw, keyToRaw, RawKey); +using_csset_str(); ``` The macro `using_csset()` can be instantiated with 2, 3, 5, or 7 arguments in the global scope. Default values are given above for args not specified. `X` is a type tag name and @@ -45,9 +44,9 @@ csset_X_iter_t csset_X_find(const csset_X* self, RawKey rkey); csset_X_value_t* csset_X_find_it(const csset_X* self, RawKey rkey, csset_X_iter_t* out); bool csset_X_contains(const csset_X* self, RawKey rkey); -void csset_X_push_n(csset_X* self, const RawKey arr[], size_t size); -csset_X_result_t csset_X_emplace(csset_X* self, RawKey rkey); csset_X_result_t csset_X_insert(csset_X* self, Key key); +csset_X_result_t csset_X_emplace(csset_X* self, RawKey rkey); +void csset_X_push_n(csset_X* self, const RawKey arr[], size_t size); size_t csset_X_erase(csset_X* self, RawKey rkey); csset_X_iter_t csset_X_erase_at(csset_X* self, csset_X_iter_t pos); diff --git a/docs/cstack_api.md b/docs/cstack_api.md index 3028f6cb..86b0e42a 100644 --- a/docs/cstack_api.md +++ b/docs/cstack_api.md @@ -34,9 +34,10 @@ size_t cstack_X_size(cstack_X st); bool cstack_X_empty(cstack_X st); cstack_X_value_t* cstack_X_top(cstack_X* self); -void cstack_X_push_n(cstack_X *self, const cstack_X_rawvalue_t arr[], size_t size); -void cstack_X_emplace(cstack_X* self, cstack_X_rawvalue_t raw); void cstack_X_push(cstack_X* self, cstack_X_value_t value); +void cstack_X_emplace(cstack_X* self, cstack_X_rawvalue_t raw); +void cstack_X_push_n(cstack_X *self, const cstack_X_rawvalue_t arr[], size_t size); + void cstack_X_pop(cstack_X* self); cstack_X_iter_t cstack_X_begin(cstack_X* self); diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 7c523f02..ef5c9f99 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -12,11 +12,11 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect ## Declaration ```c -using_cvec(X, Value, valueCompareRaw=c_default_compare, - valueDestroy=c_default_del, - valueFromRaw=c_default_clone, - valueToRaw=c_default_to_raw, - RawValue=Value) +using_cvec(X, Value); +using_cvec(X, Value, valueCompareRaw); +using_cvec(X, Value, valueCompareRaw, valueDestroy); +using_cvec(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue); + using_cvec_str() ``` The macro `using_cvec()` can be instantiated with 2, 3, 5, or 7 arguments in the global scope. @@ -60,19 +60,20 @@ cvec_X_value_t* cvec_X_at(cvec_X* self, size_t idx); cvec_X_value_t* cvec_X_front(cvec_X* self); cvec_X_value_t* cvec_X_back(cvec_X* self); -void cvec_X_push_n(cvec_X *self, const cvec_X_rawvalue_t arr[], size_t size); -void cvec_X_emplace_back(cvec_X* self, RawValue raw); void cvec_X_push_back(cvec_X* self, Value value); +void cvec_X_emplace_back(cvec_X* self, RawValue raw); +void cvec_X_push_n(cvec_X *self, const cvec_X_rawvalue_t arr[], size_t size); + void cvec_X_pop_back(cvec_X* self); -cvec_X_iter_t cvec_X_emplace(cvec_X* self, size_t idx, RawValue raw); -cvec_X_iter_t cvec_X_emplace_at(cvec_X* self, cvec_X_iter_t pos, RawValue raw); cvec_X_iter_t cvec_X_insert(cvec_X* self, size_t idx, Value value); cvec_X_iter_t cvec_X_insert_at(cvec_X* self, cvec_X_iter_t pos, Value value); cvec_X_iter_t cvec_X_insert_range(cvec_X* self, cvec_X_iter_t pos, cvec_X_iter_t first, cvec_X_iter_t finish); cvec_X_iter_t cvec_X_insert_range_p(cvec_X* self, cvec_X_value_t* pos, const cvec_X_value_t* pfirst, const cvec_X_value_t* pfinish); +cvec_X_iter_t cvec_X_emplace(cvec_X* self, size_t idx, RawValue raw); +cvec_X_iter_t cvec_X_emplace_at(cvec_X* self, cvec_X_iter_t pos, RawValue raw); cvec_X_iter_t cvec_X_erase(cvec_X* self, size_t idx, size_t n); cvec_X_iter_t cvec_X_erase_at(cvec_X* self, cvec_X_iter_t pos); diff --git a/examples/advanced.c b/examples/advanced.c index 9b1b1275..8d045b3a 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -12,7 +12,6 @@ void viking_del(Viking* vk) { cstr_del(&vk->country); } - // Define Viking raw struct with hash, equals, and convertion functions between Viking and VikingRaw structs: typedef struct VikingRaw { @@ -31,16 +30,14 @@ static inline int vikingraw_equals(const VikingRaw* rx, const VikingRaw* ry) { static inline Viking viking_fromRaw(VikingRaw raw) { // note: parameter is by value Viking vk = {cstr_from(raw.name), cstr_from(raw.country)}; return vk; } - static inline VikingRaw viking_toRaw(Viking* vk) { VikingRaw raw = {vk->name.str, vk->country.str}; return raw; } -// With this in place, we use the full using_cmap() macro to define {Viking -> int} hash map type: +// With this in place, we use the using_cmap_keyarg() macro to define {Viking -> int} hash map type: -using_cmap(vk, Viking, int, vikingraw_equals, vikingraw_hash, - c_default_del, c_default_clone, - viking_del, viking_fromRaw, viking_toRaw, VikingRaw); +using_cmap_keyarg(vk, Viking, int, vikingraw_equals, vikingraw_hash, + viking_del, viking_fromRaw, viking_toRaw, VikingRaw); int main() { @@ -50,7 +47,7 @@ int main() { {"Olaf", "Denmark"}, 24}, { {"Harald", "Iceland"}, 12}, }); - cmap_vk_put(&vikings, (VikingRaw){"Bjorn", "Sweden"}, 10); + cmap_vk_emplace_put(&vikings, (VikingRaw){"Bjorn", "Sweden"}, 10); VikingRaw lookup = {"Einar", "Norway"}; diff --git a/examples/complex.c b/examples/complex.c index d7ea016e..05d74557 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -5,10 +5,10 @@ void check_del(float* v) {printf("destroy %g\n", *v);} -using_carray(f, float, check_del, c_default_clone); // normally omit the last 2 arguments - float type need no destroy. -using_clist(a, carray2f, c_no_compare, carray2f_del, carray2f_clone); -using_cmap(l, int, clist_a, c_default_equals, c_default_hash, clist_a_del, clist_a_clone); -using_cmap_strkey(s, cmap_l, cmap_l_del, cmap_l_clone); +using_carray(f, float, check_del); +using_clist(a, carray2f, c_no_compare, carray2f_del); +using_cmap(l, int, clist_a, c_default_equals, c_default_hash, clist_a_del); +using_cmap_strkey(s, cmap_l, cmap_l_del); int main() { int xdim = 4, ydim = 6; @@ -26,8 +26,8 @@ int main() { // Put in some data. *carray2f_at(&arr_a, y, x) = 3.1415927f; // aa[y][x] clist_a_push_back(&tableList, arr_a); - cmap_l_put(&listMap, tableKey, tableList); - cmap_s_put(&myMap, strKey, listMap); + cmap_l_insert(&listMap, tableKey, tableList); + cmap_s_insert(&myMap, cstr_from(strKey), listMap); // Access the data entry carray2f arr_b = *clist_a_back(&cmap_l_find(&cmap_s_find(&myMap, strKey).ref->second, tableKey).ref->second); diff --git a/examples/demos.c b/examples/demos.c index 55de0c14..db284ea9 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -124,8 +124,8 @@ void mapdemo1() { printf("\nMAPDEMO1\n"); cmap_ii nums = cmap_ii_init(); - cmap_ii_put(&nums, 8, 64); - cmap_ii_put(&nums, 11, 121); + cmap_ii_emplace_put(&nums, 8, 64); + cmap_ii_emplace_put(&nums, 11, 121); printf("val 8: %d\n", *cmap_ii_at(&nums, 8)); cmap_ii_del(&nums); } @@ -137,9 +137,9 @@ void mapdemo2() { printf("\nMAPDEMO2\n"); cmap_si nums = cmap_si_init(); - cmap_si_put(&nums, "Hello", 64); - cmap_si_put(&nums, "Groovy", 121); - cmap_si_put(&nums, "Groovy", 200); // overwrite previous + cmap_si_emplace_put(&nums, "Hello", 64); + cmap_si_emplace_put(&nums, "Groovy", 121); + cmap_si_emplace_put(&nums, "Groovy", 200); // overwrite previous // iterate the map: for (cmap_si_iter_t i = cmap_si_begin(&nums); i.ref != cmap_si_end(&nums).ref; cmap_si_next(&i)) @@ -159,9 +159,9 @@ void mapdemo3() { printf("\nMAPDEMO3\n"); cmap_str table = cmap_str_init(); - cmap_str_put(&table, "Map", "test"); - cmap_str_put(&table, "Make", "my"); - cmap_str_put(&table, "Sunny", "day"); + cmap_str_emplace_put(&table, "Map", "test"); + cmap_str_emplace_put(&table, "Make", "my"); + cmap_str_emplace_put(&table, "Sunny", "day"); cmap_str_value_t *e = cmap_str_find(&table, "Make").ref; c_foreach (i, cmap_str, table) printf("entry: %s: %s\n", i.ref->first.str, i.ref->second.str); diff --git a/examples/inits.c b/examples/inits.c index 2c138a43..6e2d1bd9 100644 --- a/examples/inits.c +++ b/examples/inits.c @@ -5,7 +5,7 @@ #include #include -using_cmap(id, int, cstr, c_default_equals, c_default_hash, cstr_del, cstr_clone); // Map of int -> cstr +using_cmap(id, int, cstr, c_default_equals, c_default_hash, cstr_del); // Map of int -> cstr using_cmap_strkey(cnt, int); typedef struct {int x, y;} ipair_t; @@ -46,11 +46,9 @@ int main(void) int year = 2020; cmap_id idnames = cmap_id_init(); - c_push_items(&idnames, cmap_id, { - {100, cstr_from("Hello")}, - {110, cstr_from("World")}, - {120, cstr_from_fmt("Howdy, -%d-", year)}, - }); + cmap_id_insert(&idnames, 100, cstr_from("Hello")); + cmap_id_insert(&idnames, 110, cstr_from("World")); + cmap_id_insert(&idnames, 120, cstr_from_fmt("Howdy, -%d-", year)); c_foreach (i, cmap_id, idnames) printf("%d: %s\n", i.ref->first, i.ref->second.str); diff --git a/examples/mapmap.c b/examples/mapmap.c index 7782f5bf..c55104c9 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -4,19 +4,19 @@ #include using_cmap_str(); -using_cmap_strkey(cfg, cmap_str, cmap_str_del, cmap_str_clone); +using_cmap_strkey(cfg, cmap_str, cmap_str_del); int main(void) { cmap_cfg config = cmap_cfg_init(); cmap_str init = cmap_str_init(); - cmap_str_put(&cmap_cfg_emplace(&config, "user", init).first->second, "name", "Joe"); - cmap_str_put(&cmap_cfg_emplace(&config, "user", init).first->second, "groups", "proj1,proj3"); - cmap_str_put(&cmap_cfg_emplace(&config, "group", init).first->second, "proj1", "Energy"); - cmap_str_put(&cmap_cfg_emplace(&config, "group", init).first->second, "proj2", "Windy"); - cmap_str_put(&cmap_cfg_emplace(&config, "group", init).first->second, "proj3", "Oil"); - cmap_str_put(&cmap_cfg_emplace(&config, "admin", init).first->second, "employees", "2302"); + cmap_str_emplace(&cmap_cfg_insert(&config, cstr_from("user"), init).first->second, "name", "Joe"); + cmap_str_emplace(&cmap_cfg_insert(&config, cstr_from("user"), init).first->second, "groups", "proj1,proj3"); + cmap_str_emplace(&cmap_cfg_insert(&config, cstr_from("group"), init).first->second, "proj1", "Energy"); + cmap_str_emplace(&cmap_cfg_insert(&config, cstr_from("group"), init).first->second, "proj2", "Windy"); + cmap_str_emplace(&cmap_cfg_insert(&config, cstr_from("group"), init).first->second, "proj3", "Oil"); + cmap_str_emplace(&cmap_cfg_insert(&config, cstr_from("admin"), init).first->second, "employees", "2302"); - cmap_str_put(&cmap_cfg_emplace(&config, "group", init).first->second, "proj2", "Wind"); // Update + cmap_str_emplace_put(&cmap_cfg_insert(&config, cstr_from("group"), init).first->second, "proj2", "Wind"); // Update c_foreach (i, cmap_cfg, config) c_foreach (j, cmap_str, i.ref->second) diff --git a/examples/phonebook.c b/examples/phonebook.c index 395716bc..34364bcb 100644 --- a/examples/phonebook.c +++ b/examples/phonebook.c @@ -67,7 +67,7 @@ int main(int argc, char **argv) printf("\nPhone book after erasing Tariq and Elliott:\n"); print_phone_book(phone_book); - cmap_str_put(&phone_book, "Zak Byers", "(555) 396-188"); + cmap_str_emplace_put(&phone_book, "Zak Byers", "(555) 396-188"); printf("\nPhone book after update phone of Zak Byers:\n"); print_phone_book(phone_book); diff --git a/examples/stc_astar.c b/examples/stc_astar.c index 91d475e9..e7bb86e5 100644 --- a/examples/stc_astar.c +++ b/examples/stc_astar.c @@ -106,10 +106,10 @@ astar(cstr maze, int width) csmap_mc_value_t* cost = csmap_mc_find(&cost_so_far, next).ref; if (!cost || new_cost < cost->second) { - csmap_mc_put(&cost_so_far, next, new_cost); // update (put) + csmap_mc_emplace_put(&cost_so_far, next, new_cost); // update (put) next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y); cpque_mp_push(&frontier, next); - csmap_ms_put(&came_from, next, current); + csmap_ms_emplace_put(&came_from, next, current); } } } diff --git a/stc/carray.h b/stc/carray.h index f1833424..6a42510f 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -50,6 +50,9 @@ int main() #define using_carray_2(X, Value) \ using_carray_4(X, Value, c_default_del, c_default_clone) +#define using_carray_3(X, Value, valueDestroy) \ + using_carray_4(X, Value, valueDestroy, c_no_clone) + #define using_carray_4(X, Value, valueDestroy, valueClone) \ \ typedef Value carray1##X##_value_t; \ diff --git a/stc/cdeq.h b/stc/cdeq.h index d450f62d..340b5021 100644 --- a/stc/cdeq.h +++ b/stc/cdeq.h @@ -31,9 +31,9 @@ #define using_cdeq_2(X, Value) \ using_cdeq_3(X, Value, c_default_compare) #define using_cdeq_3(X, Value, valueCompare) \ - using_cdeq_5(X, Value, valueCompare, c_default_del, c_default_clone) -#define using_cdeq_5(X, Value, valueCompare, valueDestroy, valueClone) \ - using_cdeq_7(X, Value, valueCompare, valueDestroy, valueClone, c_default_to_raw, Value) + using_cdeq_7(X, Value, valueCompare, c_default_del, c_default_clone, c_default_to_raw, Value) +#define using_cdeq_4(X, Value, valueCompare, valueDestroy) \ + using_cdeq_7(X, Value, valueCompare, valueDestroy, c_no_clone, c_default_to_raw, Value) #define using_cdeq_str() \ using_cdeq_7(str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_to_raw, const char*) diff --git a/stc/clist.h b/stc/clist.h index e777ebc8..11f8d0e0 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -59,9 +59,9 @@ #define using_clist_2(X, Value) \ using_clist_3(X, Value, c_default_compare) #define using_clist_3(X, Value, valueCompare) \ - using_clist_5(X, Value, valueCompare, c_default_del, c_default_clone) -#define using_clist_5(X, Value, valueCompare, valueDestroy, valueClone) \ - using_clist_7(X, Value, valueCompare, valueDestroy, valueClone, c_default_to_raw, Value) + using_clist_7(X, Value, valueCompare, c_default_del, c_default_clone, c_default_to_raw, Value) +#define using_clist_4(X, Value, valueCompare, valueDestroy) \ + using_clist_7(X, Value, valueCompare, valueDestroy, c_no_clone, c_default_to_raw, Value) #define using_clist_str() \ using_clist_7(str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_to_raw, const char*) diff --git a/stc/cmap.h b/stc/cmap.h index bd2f41f6..0d4bb9fe 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -39,12 +39,12 @@ int main(void) { cset_sx_del(&s); cmap_mx m = cmap_mx_init(); - cmap_mx_put(&m, 5, 'a'); - cmap_mx_put(&m, 8, 'b'); - cmap_mx_put(&m, 12, 'c'); + cmap_mx_emplace_put(&m, 5, 'a'); + cmap_mx_emplace_put(&m, 8, 'b'); + cmap_mx_emplace_put(&m, 12, 'c'); cmap_mx_iter_t it = cmap_mx_find(&m, 10); // none char val = cmap_mx_find(&m, 5).ref->second; - cmap_mx_put(&m, 5, 'd'); // update + cmap_mx_emplace_put(&m, 5, 'd'); // update cmap_mx_erase(&m, 8); c_foreach (i, cmap_mx, m) printf("map %d: %c\n", i.ref->first, i.ref->second); @@ -58,26 +58,41 @@ int main(void) { #define _cmap_inits {NULL, NULL, 0, 0, 0.15f, 0.85f} typedef struct {size_t idx; uint32_t hx;} chash_bucket_t; -#define using_cmap(...) \ - c_MACRO_OVERLOAD(using_cmap, __VA_ARGS__) +#define using_cmap(...) c_MACRO_OVERLOAD(using_cmap, __VA_ARGS__) #define using_cmap_3(X, Key, Mapped) \ using_cmap_5(X, Key, Mapped, c_default_equals, c_default_hash) #define using_cmap_5(X, Key, Mapped, keyEquals, keyHash) \ - using_cmap_7(X, Key, Mapped, keyEquals, keyHash, c_default_del, c_default_clone) + using_cmap_9(X, Key, Mapped, keyEquals, keyHash, \ + c_default_del, c_default_clone, c_default_to_raw, Mapped) -#define using_cmap_7(X, Key, Mapped, keyEquals, keyHash, mappedDel, mappedClone) \ - using_cmap_9(X, Key, Mapped, keyEquals, keyHash, mappedDel, mappedClone, c_default_del, c_default_clone) +#define using_cmap_6(X, Key, Mapped, keyEquals, keyHash, mappedDel) \ + using_cmap_9(X, Key, Mapped, keyEquals, keyHash, \ + mappedDel, c_no_clone, c_default_to_raw, Mapped) -#define using_cmap_9(X, Key, Mapped, keyEquals, keyHash, mappedDel, mappedClone, keyDel, keyClone) \ - using_cmap_11(X, Key, Mapped, keyEquals, keyHash, mappedDel, mappedClone, \ - keyDel, keyClone, c_default_to_raw, Key) +#define using_cmap_9(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ + _using_CHASH(X, cmap, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + c_default_del, c_default_clone, c_default_to_raw, Key) -#define using_cmap_11(X, Key, Mapped, keyEqualsRaw, keyHashRaw, mappedDel, mappedClone, \ +#define using_cmap_13(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_CHASH(X, cmap, Key, Mapped, keyEqualsRaw, keyHashRaw, mappedDel, mappedClone, \ - keyDel, keyFromRaw, keyToRaw, RawKey, c_default_to_raw, Mapped) + _using_CHASH(X, cmap, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) + +#define using_cmap_keyarg(...) c_MACRO_OVERLOAD(using_cmap_keyarg, __VA_ARGS__) +#define using_cmap_keyarg_6(X, Key, Mapped, keyEquals, keyHash, keyDel) \ + using_cmap_keyarg_9(X, Key, Mapped, keyEquals, keyHash, \ + keyDel, c_no_clone, c_default_to_raw, Key) +#define using_cmap_keyarg_9(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ + _using_CHASH(X, cmap, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + c_default_del, c_default_clone, c_default_to_raw, Mapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) /* cset: */ #define using_cset(...) \ @@ -87,28 +102,40 @@ typedef struct {size_t idx; uint32_t hx;} chash_bucket_t; using_cset_4(X, Key, c_default_equals, c_default_hash) #define using_cset_4(X, Key, keyEquals, keyHash) \ - using_cset_6(X, Key, keyEquals, keyHash, c_default_del, c_default_clone) + using_cset_8(X, Key, keyEquals, keyHash, c_default_del, c_default_clone, c_default_to_raw, Key) -#define using_cset_6(X, Key, keyEquals, keyHash, keyDel, keyClone) \ - using_cset_8(X, Key, keyEquals, keyHash, keyDel, keyClone, c_default_to_raw, Key) +#define using_cset_5(X, Key, keyEquals, keyHash, keyDel) \ + using_cset_8(X, Key, keyEquals, keyHash, keyDel, c_no_clone, c_default_to_raw, Key) #define using_cset_8(X, Key, keyEqualsRaw, keyHashRaw, keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_CHASH(X, cset, Key, Key, keyEqualsRaw, keyHashRaw, _UNUSED_, _UNUSED_, \ - keyDel, keyFromRaw, keyToRaw, RawKey, _UNUSED_, void) + _using_CHASH(X, cset, Key, Key, keyEqualsRaw, keyHashRaw, \ + _UNUSED_, _UNUSED_, _UNUSED_, void, \ + keyDel, keyFromRaw, keyToRaw, RawKey) /* cset_str, cmap_str, cmap_strkey, cmap_strval: */ #define using_cset_str() \ - _using_CHASH_strkey(str, cset, cstr_t, _UNUSED_, _UNUSED_) + _using_CHASH_strkey(str, cset, cstr_t, _UNUSED_, _UNUSED_, _UNUSED_, void) #define using_cmap_str() \ - _using_CHASH(str, cmap, cstr_t, cstr_t, cstr_equals_raw, cstr_hash_raw, cstr_del, cstr_from, \ - cstr_del, cstr_from, cstr_to_raw, const char*, cstr_to_raw, const char*) + _using_CHASH(str, cmap, cstr_t, cstr_t, cstr_equals_raw, cstr_hash_raw, \ + cstr_del, cstr_from, cstr_to_raw, const char*, \ + cstr_del, cstr_from, cstr_to_raw, const char*) #define using_cmap_strkey(...) \ c_MACRO_OVERLOAD(using_cmap_strkey, __VA_ARGS__) + #define using_cmap_strkey_2(X, Mapped) \ - _using_CHASH_strkey(X, cmap, Mapped, c_default_del, c_default_clone) -#define using_cmap_strkey_4(X, Mapped, mappedDel, mappedClone) \ - _using_CHASH_strkey(X, cmap, Mapped, mappedDel, mappedClone) + _using_CHASH_strkey(X, cmap, Mapped, c_default_del, c_default_clone, c_default_to_raw, Mapped) + +#define using_cmap_strkey_3(X, Mapped, mappedDel) \ + _using_CHASH_strkey(X, cmap, Mapped, mappedDel, c_no_clone, c_default_to_raw, Mapped) + +#define using_cmap_strkey_6(X, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ + _using_CHASH_strkey(X, cmap, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) + +#define _using_CHASH_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ + _using_CHASH(X, C, cstr_t, Mapped, cstr_equals_raw, cstr_hash_raw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + cstr_del, cstr_from, cstr_to_raw, const char*) #define using_cmap_strval(...) \ c_MACRO_OVERLOAD(using_cmap_strval, __VA_ARGS__) @@ -117,18 +144,15 @@ typedef struct {size_t idx; uint32_t hx;} chash_bucket_t; using_cmap_strval_4(X, Key, c_default_equals, c_default_hash) #define using_cmap_strval_4(X, Key, keyEquals, keyHash) \ - using_cmap_strval_6(X, Key, keyEquals, keyHash, c_default_del, c_default_clone) + using_cmap_strval_8(X, Key, keyEquals, keyHash, c_default_del, c_default_clone, c_default_to_raw, Key) -#define using_cmap_strval_6(X, Key, keyEquals, keyHash, keyDel, keyClone) \ - using_cmap_strval_8(X, Key, keyEquals, keyHash, keyDel, keyClone, c_default_to_raw, Key) +#define using_cmap_strval_5(X, Key, keyEquals, keyHash, keyDel) \ + using_cmap_strval_8(X, Key, keyEquals, keyHash, keyDel, c_no_clone, c_default_to_raw, Key) #define using_cmap_strval_8(X, Key, keyEquals, keyHash, keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_CHASH(X, cmap, Key, cstr_t, keyEquals, keyHash, cstr_del, cstr_from, \ - keyDel, keyFromRaw, keyToRaw, RawKey, cstr_to_raw, const char*) - -#define _using_CHASH_strkey(X, C, Mapped, mappedDel, mappedClone) \ - _using_CHASH(X, C, cstr_t, Mapped, cstr_equals_raw, cstr_hash_raw, mappedDel, mappedClone, \ - cstr_del, cstr_from, cstr_to_raw, const char*, c_default_to_raw, Mapped) + _using_CHASH(X, cmap, Key, cstr_t, keyEquals, keyHash, \ + cstr_del, cstr_from, cstr_to_raw, const char*, \ + keyDel, keyFromRaw, keyToRaw, RawKey) #define SET_ONLY_cset(...) __VA_ARGS__ #define SET_ONLY_cmap(...) @@ -140,8 +164,9 @@ typedef struct {size_t idx; uint32_t hx;} chash_bucket_t; #define CMAP_SIZE_T uint32_t #endif -#define _using_CHASH(X, C, Key, Mapped, keyEqualsRaw, keyHashRaw, mappedDel, mappedFromRaw, \ - keyDel, keyFromRaw, keyToRaw, RawKey, mappedToRaw, RawMapped) \ +#define _using_CHASH(X, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ typedef Key C##_##X##_key_t; \ typedef Mapped C##_##X##_mapped_t; \ typedef RawKey C##_##X##_rawkey_t; \ @@ -237,7 +262,7 @@ typedef struct {size_t idx; uint32_t hx;} chash_bucket_t; return res; \ } \ STC_INLINE C##_##X##_result_t \ - C##_##X##_put(C##_##X* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \ + C##_##X##_emplace_put(C##_##X* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \ C##_##X##_result_t res = C##_##X##_insert_entry_(self, rkey); \ if (res.second) *KEY_REF_##C(res.first) = keyFromRaw(rkey); \ MAP_ONLY_##C( else mappedDel(&res.first->second); \ @@ -247,7 +272,7 @@ typedef struct {size_t idx; uint32_t hx;} chash_bucket_t; STC_INLINE void \ C##_##X##_push_n(C##_##X* self, const C##_##X##_rawvalue_t arr[], size_t n) { \ for (size_t i=0; i #include -#define using_csmap(...) \ - c_MACRO_OVERLOAD(using_csmap, __VA_ARGS__) +#define using_csmap(...) c_MACRO_OVERLOAD(using_csmap, __VA_ARGS__) #define using_csmap_3(X, Key, Mapped) \ using_csmap_4(X, Key, Mapped, c_default_compare) #define using_csmap_4(X, Key, Mapped, keyCompare) \ - using_csmap_6(X, Key, Mapped, keyCompare, c_default_del, c_default_clone) + using_csmap_8(X, Key, Mapped, keyCompare, c_default_del, c_default_clone, c_default_to_raw, Mapped) -#define using_csmap_6(X, Key, Mapped, keyCompare, mappedDel, mappedClone) \ - using_csmap_8(X, Key, Mapped, keyCompare, mappedDel, mappedClone, c_default_del, c_default_clone) +#define using_csmap_5(X, Key, Mapped, keyCompare, mappedDel) \ + using_csmap_8(X, Key, Mapped, keyCompare, mappedDel, c_no_clone, c_default_to_raw, Mapped) -#define using_csmap_8(X, Key, Mapped, keyCompare, mappedDel, mappedClone, keyDel, keyClone) \ - using_csmap_10(X, Key, Mapped, keyCompare, mappedDel, mappedClone, \ - keyDel, keyClone, c_default_to_raw, Key) +#define using_csmap_8(X, Key, Mapped, keyCompare, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ + using_csmap_12(X, Key, Mapped, keyCompare, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + c_default_del, c_default_clone, c_default_to_raw, Key) -#define using_csmap_10(X, Key, Mapped, keyCompareRaw, mappedDel, mappedClone, \ +#define using_csmap_12(X, Key, Mapped, keyCompareRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_AATREE(X, csmap, Key, Mapped, keyCompareRaw, mappedDel, keyDel, \ - keyFromRaw, keyToRaw, RawKey, mappedClone, c_default_to_raw, Mapped) + _using_AATREE(X, csmap, Key, Mapped, keyCompareRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) + +#define using_csmap_keyarg(...) c_MACRO_OVERLOAD(using_csmap_keyarg, __VA_ARGS__) +#define using_csmap_keyarg_5(X, Key, Mapped, keyCompare, keyDel) \ + using_csmap_keyarg_8(X, Key, Mapped, keyCompare, \ + keyDel, c_no_clone, c_default_to_raw, Key) +#define using_csmap_keyarg_8(X, Key, Mapped, keyCompareRaw, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ + _using_AATREE(X, csmap, Key, Mapped, keyCompareRaw, \ + c_default_del, c_default_clone, c_default_to_raw, Mapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) /* csset: */ #define using_csset(...) \ @@ -72,34 +84,40 @@ int main(void) { using_csset_3(X, Key, c_default_compare) #define using_csset_3(X, Key, keyCompare) \ - using_csset_5(X, Key, keyCompare, c_default_del, c_default_clone) + using_csset_7(X, Key, keyCompare, c_default_del, c_default_clone, c_default_to_raw, Key) -#define using_csset_5(X, Key, keyCompare, keyDel, keyClone) \ - using_csset_7(X, Key, keyCompare, keyDel, keyClone, c_default_to_raw, Key) +#define using_csset_4(X, Key, keyCompare, keyDel) \ + using_csset_7(X, Key, keyCompare, keyDel, c_no_clone, c_default_to_raw, Key) #define using_csset_7(X, Key, keyCompareRaw, keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_AATREE(X, csset, Key, Key, keyCompareRaw, _UNUSED_, keyDel, \ - keyFromRaw, keyToRaw, RawKey, _UNUSED_, _UNUSED_, void) + _using_AATREE(X, csset, Key, Key, keyCompareRaw, \ + _UNUSED_, _UNUSED_, _UNUSED_, void, \ + keyDel, keyFromRaw, keyToRaw, RawKey) /* csset_str, csmap_str, csmap_strkey, csmap_strval: */ #define using_csset_str() \ - _using_AATREE_strkey(str, csset, cstr_t, _UNUSED_, _UNUSED_) + _using_AATREE_strkey(str, csset, cstr_t, _UNUSED_, _UNUSED_, _UNUSED_, void) #define using_csmap_str() \ - _using_AATREE(str, csmap, cstr_t, cstr_t, cstr_compare_raw, cstr_del, cstr_del, \ - cstr_from, cstr_to_raw, const char*, cstr_from, cstr_to_raw, const char*) + _using_AATREE(str, csmap, cstr_t, cstr_t, cstr_compare_raw, \ + cstr_del, cstr_from, cstr_to_raw, const char*, \ + cstr_del, cstr_from, cstr_to_raw, const char*) #define using_csmap_strkey(...) \ c_MACRO_OVERLOAD(using_csmap_strkey, __VA_ARGS__) #define using_csmap_strkey_2(X, Mapped) \ - _using_AATREE_strkey(X, csmap, Mapped, c_default_del, c_default_clone) + _using_AATREE_strkey(X, csmap, Mapped, c_default_del, c_default_clone, c_default_to_raw, Mapped) + +#define using_csmap_strkey_3(X, Mapped, mappedDel) \ + _using_AATREE_strkey(X, csmap, Mapped, mappedDel, c_no_clone, c_default_to_raw, Mapped) -#define using_csmap_strkey_4(X, Mapped, mappedDel, mappedClone) \ - _using_AATREE_strkey(X, csmap, Mapped, mappedDel, mappedClone) +#define using_csmap_strkey_6(X, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ + _using_AATREE_strkey(X, csmap, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) -#define _using_AATREE_strkey(X, C, Mapped, mappedDel, mappedClone) \ - _using_AATREE(X, C, cstr_t, Mapped, cstr_compare_raw, mappedDel, cstr_del, \ - cstr_from, cstr_to_raw, const char*, mappedClone, c_default_to_raw, Mapped) +#define _using_AATREE_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ + _using_AATREE(X, C, cstr_t, Mapped, cstr_compare_raw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + cstr_del, cstr_from, cstr_to_raw, const char*) #define using_csmap_strval(...) \ c_MACRO_OVERLOAD(using_csmap_strval, __VA_ARGS__) @@ -108,14 +126,15 @@ int main(void) { using_csmap_strval_3(X, Key, c_default_compare) #define using_csmap_strval_3(X, Key, keyCompare) \ - using_csmap_strval_5(X, Key, keyCompare, c_default_del, c_default_clone) + using_csmap_strval_7(X, Key, keyCompare, c_default_del, c_default_clone, c_default_to_raw, Key) -#define using_csmap_strval_5(X, Key, keyCompare, keyDel, keyClone) \ - using_csmap_strval_7(X, Key, keyCompare, keyDel, keyClone, c_default_to_raw, Key) +#define using_csmap_strval_4(X, Key, keyCompare, keyDel) \ + using_csmap_strval_7(X, Key, keyCompare, keyDel, c_no_clone, c_default_to_raw, Key) #define using_csmap_strval_7(X, Key, keyCompare, keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_AATREE(X, csmap, Key, cstr_t, keyCompare, cstr_del, keyDel, \ - keyFromRaw, keyToRaw, RawKey, cstr_from, cstr_to_raw, const char*) + _using_AATREE(X, csmap, Key, cstr_t, keyCompare, \ + cstr_del, cstr_from, cstr_to_raw, const char*, \ + keyDel, keyFromRaw, keyToRaw, RawKey) #define SET_ONLY_csset(...) __VA_ARGS__ #define SET_ONLY_csmap(...) @@ -130,8 +149,9 @@ int main(void) { struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; #define _csmap_rep(self) c_container_of((self)->nodes, struct csmap_rep, nodes) -#define _using_AATREE(X, C, Key, Mapped, keyCompareRaw, mappedDel, keyDel, \ - keyFromRaw, keyToRaw, RawKey, mappedFromRaw, mappedToRaw, RawMapped) \ +#define _using_AATREE(X, C, Key, Mapped, keyCompareRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ typedef Key C##_##X##_key_t; \ typedef Mapped C##_##X##_mapped_t; \ typedef RawKey C##_##X##_rawkey_t; \ @@ -234,7 +254,7 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; return res; \ } \ STC_INLINE C##_##X##_result_t \ - C##_##X##_put(C##_##X* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \ + C##_##X##_emplace_put(C##_##X* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \ C##_##X##_result_t res = C##_##X##_insert_entry_(self, rkey); \ if (res.second) *KEY_REF_##C(res.first) = keyFromRaw(rkey); \ MAP_ONLY_##C( else mappedDel(&res.first->second); \ @@ -244,7 +264,7 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; STC_INLINE void \ C##_##X##_push_n(C##_##X* self, const C##_##X##_rawvalue_t arr[], size_t n) { \ for (size_t i=0; i