From 900295256d825fc323149cd223c49787f32a3696 Mon Sep 17 00:00:00 2001 From: tylov Date: Thu, 20 Jul 2023 15:09:10 +0200 Subject: Moved examples to sub-directories. Added cotask1.c cotask2.c examples. --- misc/examples/smartpointers/arc_containers.c | 81 ++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 misc/examples/smartpointers/arc_containers.c (limited to 'misc/examples/smartpointers/arc_containers.c') diff --git a/misc/examples/smartpointers/arc_containers.c b/misc/examples/smartpointers/arc_containers.c new file mode 100644 index 00000000..2fb04c56 --- /dev/null +++ b/misc/examples/smartpointers/arc_containers.c @@ -0,0 +1,81 @@ +// Create a stack and a list of shared pointers to maps, +// and demonstrate sharing and cloning of maps. +#define i_implement +#include +#include +#define i_type Map +#define i_key_str // strings +#define i_val int +#define i_keydrop(p) (printf("drop name: %s\n", cstr_str(p)), cstr_drop(p)) +#include + +#define i_type Arc // (atomic) ref. counted type +#define i_key Map +#define i_keydrop(p) (printf("drop Arc:\n"), Map_drop(p)) +// no need for atomic ref. count in single thread: +#define i_opt c_no_atomic +#include + +#define i_type Stack +#define i_keyboxed Arc // define i_keyboxed for carc/cbox value (not i_key) +#include + +#define i_type List +#define i_keyboxed Arc // as above +#include + +int main(void) +{ + Stack stack = {0}; + List list = {0}; + c_defer( + Stack_drop(&stack), + List_drop(&list) + ){ + // POPULATE stack with shared pointers to Maps: + Map *map; + map = Stack_push(&stack, Arc_from(Map_init()))->get; + Map_emplace(map, "Joey", 1990); + Map_emplace(map, "Mary", 1995); + Map_emplace(map, "Joanna", 1992); + + map = Stack_push(&stack, Arc_from(Map_init()))->get; + Map_emplace(map, "Rosanna", 2001); + Map_emplace(map, "Brad", 1999); + Map_emplace(map, "Jack", 1980); + + // POPULATE list: + map = List_push_back(&list, Arc_from(Map_init()))->get; + Map_emplace(map, "Steve", 1979); + Map_emplace(map, "Rick", 1974); + Map_emplace(map, "Tracy", 2003); + + // Share two Maps from the stack with the list using emplace (clone the carc): + List_push_back(&list, Arc_clone(stack.data[0])); + List_push_back(&list, Arc_clone(stack.data[1])); + + // Clone (deep copy) a Map from the stack to the list + // List will contain two shared and two unshared maps. + map = List_push_back(&list, Arc_from(Map_clone(*stack.data[1].get)))->get; + + // Add one more element to the cloned map: + Map_emplace_or_assign(map, "CLONED", 2021); + + // Add one more element to the shared map: + Map_emplace_or_assign(stack.data[1].get, "SHARED", 2021); + + puts("STACKS"); + c_foreach (i, Stack, stack) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + + puts("LIST"); + c_foreach (i, List, list) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + } +} -- cgit v1.2.3 From d7fba27af452de2d709767e615fa2e90d6b3a391 Mon Sep 17 00:00:00 2001 From: tylov Date: Wed, 26 Jul 2023 21:23:15 +0200 Subject: Added cmap_emplace_key() / csmap_emplace_key() More docs. --- README.md | 29 +++++----- docs/algorithm_api.md | 4 +- docs/cmap_api.md | 8 ++- docs/csmap_api.md | 1 + include/stc/algo/filter.h | 2 +- include/stc/cmap.h | 87 +++++++++++++++------------- include/stc/csmap.h | 30 ++++++---- include/stc/forward.h | 1 + misc/examples/smartpointers/arc_containers.c | 1 - misc/tests/cspan_test.c | 4 +- 10 files changed, 95 insertions(+), 72 deletions(-) (limited to 'misc/examples/smartpointers/arc_containers.c') diff --git a/README.md b/README.md index 9b6698e5..d66a7f1c 100644 --- a/README.md +++ b/README.md @@ -619,23 +619,24 @@ STC is generally very memory efficient. Memory usage for the different container # Version History ## Version 4.3 -- Some breaking changes. -- **coroutines**: much improved with some new API and added features. -- **cspan**: Rewritten to add support for **column-major** order (fortran) multidim spans and transposed views. -- Removed default comparison for **clist**, **cvec** and **cdeq** (like cstack and cqueue). - - Define `i_cmp_native` to enable built-in i_key types comparisons (<, ==). - - Use of `i_keyclass` still expects comparison functions defined. - - Use of `i_keyboxed` compares hosted pointers instead of pointed to values if comparisons not defined. -- **cstr** and **csview** now uses *shared linking* by default. Implement by either defining `i_implement` or `i_static` before including. +- Some breaking changes: + - **cstr** and **csview** now uses *shared linking* by default. Implement by either defining `i_implement` or `i_static` before including. + - Changes in `coroutine.h`: much improved with some new API and added features. + - Renamed stc/calgo.h => `` + - Removed deprecated stc/crandom.h. Use `` with the new API. + - Removed default comparison for **clist**, **cvec** and **cdeq**: + - Define `i_cmp_native` to enable comparison for built-in i_key types (<, ==). + - Use of `i_keyclass` still expects comparison functions to be defined. + - Use of `i_keyboxed` compares hosted pointers instead of pointed to values if comparisons not defined. + - Renamed input enum flags for ***cregex***-functions. +- **cspan**: Changed representation of strides to add **column-major** order (fortran) multidimensional spans and transposed views. - All new faster and smaller **cqueue** and **cdeq** implementations, using a circular buffer. -- Renamed i_extern => `i_import`. - - Define `i_import` before `#include ` will also define utf8 case conversions. +- Renamed i_extern => `i_import` (i_extern deprecated). + - Define `i_import` before `#include ` will also define full utf8 case conversions. - Define `i_import` before `#include ` will also define cstr + utf8 tables. -- Renamed c_make() => ***c_init()*** macro for initializing containers with element lists. -- Renamed input enum flags for ***cregex***-functions. -- Removed deprecated . Use `` with the new API. +- Renamed c_make() => ***c_init()*** macro for initializing containers with element lists. c_make deprecated. - Removed deprecated uppercase flow-control macro names. -- Improved default string hash function. +- Other smaller additions, bug fixes and improved documentation. ## Version 4.2 - New home! And online single headers for https://godbolt.org diff --git a/docs/algorithm_api.md b/docs/algorithm_api.md index 490771b5..40ff32d6 100644 --- a/docs/algorithm_api.md +++ b/docs/algorithm_api.md @@ -130,7 +130,7 @@ Iterate a container or a crange with chained `&&` filtering. [ [Run this example](https://godbolt.org/z/n9aYrYPv8) ] ```c -#include +#include #include bool isPrime(long long i) { @@ -309,8 +309,6 @@ The **checkauto** utility described below, ensures that the `c_auto*` macros are | `continue` | Exit a defer-block without resource leak | ```c -#include // or -... // `c_defer` executes the expression(s) when leaving scope. // Note: does not require inclusion of "raii.h". cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world"); diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 17f27662..4e6da57d 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -71,7 +71,8 @@ cmap_X_result cmap_X_insert_or_assign(cmap_X* self, i_key key, i_val map cmap_X_result cmap_X_push(cmap_X* self, cmap_X_value entry); // similar to insert cmap_X_result cmap_X_emplace(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // no change if rkey in map -cmap_X_result cmap_X_emplace_or_assign(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // always update +cmap_X_result cmap_X_emplace_or_assign(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // always update mapped +cmap_X_result cmap_X_emplace_key(cmap_X* self, i_keyraw rkey); // see example 1. int cmap_X_erase(cmap_X* self, i_keyraw rkey); // return 0 or 1 cmap_X_iter cmap_X_erase_at(cmap_X* self, cmap_X_iter it); // return iter after it @@ -138,6 +139,11 @@ int main(void) cmap_str_emplace(&umap, "BLACK", "#000000"); cmap_str_emplace(&umap, "WHITE", "#FFFFFF"); + // Insert only if "CYAN" is not in the map: create mapped value when needed only. + cmap_str_result res = cmap_str_emplace_key(&umap, "CYAN"); + if (res.inserted) + res.ref->second = cstr_from("#00FFFF"); // must assign second if key was inserted. + // Output values by key printf("The HEX of color RED is:[%s]\n", cstr_str(cmap_str_at(&umap, "RED"))); printf("The HEX of color BLACK is:[%s]\n", cstr_str(cmap_str_at(&umap, "BLACK"))); diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 164b0f8a..d739283b 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -72,6 +72,7 @@ csmap_X_result csmap_X_push(csmap_X* self, csmap_X_value entry); csmap_X_result csmap_X_emplace(csmap_X* self, i_keyraw rkey, i_valraw rmapped); // no change if rkey in map csmap_X_result csmap_X_emplace_or_assign(csmap_X* self, i_keyraw rkey, i_valraw rmapped); // always update rmapped +csmap_X_result csmap_X_emplace_key(csmap_X* self, i_keyraw rkey); // if key not in map, mapped is left unassigned int csmap_X_erase(csmap_X* self, i_keyraw rkey); csmap_X_iter csmap_X_erase_at(csmap_X* self, csmap_X_iter it); // returns iter after it diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index 1a62c3e1..320cd50d 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -24,7 +24,7 @@ #include #define i_val int #include -#include +#include int main(void) { diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 513a8b93..2dd8cbe6 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -55,7 +55,6 @@ int main(void) { #include #include struct chash_slot { uint8_t hashx; }; -typedef struct { intptr_t idx; uint8_t hashx, found; } chash_bucket; #endif // CMAP_H_INCLUDED #ifndef _i_prefix @@ -94,7 +93,7 @@ STC_API _cx_Self _cx_MEMB(_clone)(_cx_Self map); 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, intptr_t capacity); -STC_API chash_bucket _cx_MEMB(_bucket_)(const _cx_Self* self, const _cx_keyraw* rkeyptr); +STC_API _cx_result _cx_MEMB(_bucket_)(const _cx_Self* self, const _cx_keyraw* rkeyptr); STC_API _cx_result _cx_MEMB(_insert_entry_)(_cx_Self* self, _cx_keyraw rkey); STC_API void _cx_MEMB(_erase_entry)(_cx_Self* self, _cx_value* val); STC_API float _cx_MEMB(_max_load_factor)(const _cx_Self* self); @@ -106,9 +105,9 @@ STC_INLINE bool _cx_MEMB(_empty)(const _cx_Self* map) { return !map->siz STC_INLINE intptr_t _cx_MEMB(_size)(const _cx_Self* map) { return (intptr_t)map->size; } STC_INLINE intptr_t _cx_MEMB(_bucket_count)(_cx_Self* map) { return map->bucket_count; } STC_INLINE bool _cx_MEMB(_contains)(const _cx_Self* self, _cx_keyraw rkey) - { return self->size && _cx_MEMB(_bucket_)(self, &rkey).found; } + { return self->size && !_cx_MEMB(_bucket_)(self, &rkey).inserted; } -#ifndef _i_isset +#ifdef _i_ismap STC_API _cx_result _cx_MEMB(_insert_or_assign)(_cx_Self* self, i_key key, i_val mapped); #if !defined i_no_emplace STC_API _cx_result _cx_MEMB(_emplace_or_assign)(_cx_Self* self, _cx_keyraw rkey, i_valraw rmapped); @@ -116,14 +115,15 @@ STC_INLINE bool _cx_MEMB(_contains)(const _cx_Self* self, _cx_keyraw rke STC_INLINE const _cx_mapped* _cx_MEMB(_at)(const _cx_Self* self, _cx_keyraw rkey) { - chash_bucket b = _cx_MEMB(_bucket_)(self, &rkey); - c_assert(b.found); - return &self->data[b.idx].second; + _cx_result b = _cx_MEMB(_bucket_)(self, &rkey); + c_assert(!b.inserted); + return &b.ref->second; } + STC_INLINE _cx_mapped* _cx_MEMB(_at_mut)(_cx_Self* self, _cx_keyraw rkey) { return (_cx_mapped*)_cx_MEMB(_at)(self, rkey); } -#endif // !_i_isset +#endif // _i_ismap #if !defined i_no_clone STC_INLINE void _cx_MEMB(_copy)(_cx_Self *self, const _cx_Self* other) { @@ -151,6 +151,16 @@ _cx_MEMB(_emplace)(_cx_Self* self, _cx_keyraw rkey _i_MAP_ONLY(, i_valraw rmappe } return _res; } + +#ifdef _i_ismap + STC_INLINE _cx_result + _cx_MEMB(_emplace_key)(_cx_Self* self, _cx_keyraw rkey) { + _cx_result _res = _cx_MEMB(_insert_entry_)(self, rkey); + if (_res.inserted) + _res.ref->first = i_keyfrom(rkey); + return _res; + } +#endif // _i_ismap #endif // !i_no_emplace STC_INLINE _cx_raw _cx_MEMB(_value_toraw)(const _cx_value* val) { @@ -215,19 +225,19 @@ STC_INLINE _cx_iter _cx_MEMB(_advance)(_cx_iter it, size_t n) { STC_INLINE _cx_iter _cx_MEMB(_find)(const _cx_Self* self, _cx_keyraw rkey) { - chash_bucket b; - if (self->size && (b = _cx_MEMB(_bucket_)(self, &rkey)).found) - return c_LITERAL(_cx_iter){self->data + b.idx, + _cx_result b; + if (self->size && !(b = _cx_MEMB(_bucket_)(self, &rkey)).inserted) + return c_LITERAL(_cx_iter){b.ref, self->data + self->bucket_count, - self->slot + b.idx}; + self->slot + (b.ref - self->data)}; return _cx_MEMB(_end)(self); } STC_INLINE const _cx_value* _cx_MEMB(_get)(const _cx_Self* self, _cx_keyraw rkey) { - chash_bucket b; - if (self->size && (b = _cx_MEMB(_bucket_)(self, &rkey)).found) - return self->data + b.idx; + _cx_result b; + if (self->size && !(b = _cx_MEMB(_bucket_)(self, &rkey)).inserted) + return b.ref; return NULL; } @@ -237,10 +247,10 @@ _cx_MEMB(_get_mut)(_cx_Self* self, _cx_keyraw rkey) STC_INLINE int _cx_MEMB(_erase)(_cx_Self* self, _cx_keyraw rkey) { - chash_bucket b = {0}; - if (self->size && (b = _cx_MEMB(_bucket_)(self, &rkey)).found) - _cx_MEMB(_erase_entry)(self, self->data + b.idx); - return b.found; + _cx_result b; + if (self->size && !(b = _cx_MEMB(_bucket_)(self, &rkey)).inserted) + { _cx_MEMB(_erase_entry)(self, b.ref); return 1; } + return 0; } STC_INLINE _cx_iter @@ -313,7 +323,7 @@ STC_DEF void _cx_MEMB(_clear)(_cx_Self* self) { c_memset(self->slot, 0, c_sizeof(chash_slot)*self->bucket_count); } -#ifndef _i_isset +#ifdef _i_ismap STC_DEF _cx_result _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))); @@ -340,42 +350,41 @@ STC_DEF void _cx_MEMB(_clear)(_cx_Self* self) { return _res; } #endif // !i_no_emplace -#endif // !_i_isset +#endif // _i_ismap -STC_DEF chash_bucket +STC_DEF _cx_result _cx_MEMB(_bucket_)(const _cx_Self* self, const _cx_keyraw* rkeyptr) { const uint64_t _hash = i_hash(rkeyptr); intptr_t _cap = self->bucket_count; - chash_bucket b = {fastrange_2(_hash, _cap), (uint8_t)(_hash | 0x80)}; + intptr_t _idx = fastrange_2(_hash, _cap); + _cx_result b = {NULL, true, (uint8_t)(_hash | 0x80)}; const chash_slot* s = self->slot; - while (s[b.idx].hashx) { - if (s[b.idx].hashx == b.hashx) { - const _cx_keyraw _raw = i_keyto(_i_keyref(self->data + b.idx)); + while (s[_idx].hashx) { + if (s[_idx].hashx == b.hashx) { + const _cx_keyraw _raw = i_keyto(_i_keyref(self->data + _idx)); if (i_eq((&_raw), rkeyptr)) { - b.found = true; + b.inserted = false; break; } } - if (++b.idx == _cap) b.idx = 0; + if (++_idx == _cap) _idx = 0; } + b.ref = self->data + _idx; return b; } STC_DEF _cx_result _cx_MEMB(_insert_entry_)(_cx_Self* self, _cx_keyraw rkey) { - _cx_result res = {NULL}; if (self->size >= (intptr_t)((float)self->bucket_count * (i_max_load_factor))) if (!_cx_MEMB(_reserve)(self, (intptr_t)(self->size*3/2 + 2))) - return res; + return c_LITERAL(_cx_result){NULL}; - chash_bucket b = _cx_MEMB(_bucket_)(self, &rkey); - res.ref = &self->data[b.idx]; - if (!b.found) { - self->slot[b.idx].hashx = b.hashx; - res.inserted = true; + _cx_result b = _cx_MEMB(_bucket_)(self, &rkey); + if (b.inserted) { + self->slot[b.ref - self->data].hashx = b.hashx; ++self->size; } - return res; + return b; } #if !defined i_no_clone @@ -417,9 +426,9 @@ _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t _newcap) { const chash_slot* s = self->slot; for (intptr_t i = 0; i < _oldbucks; ++i, ++d) if ((s++)->hashx) { _cx_keyraw r = i_keyto(_i_keyref(d)); - chash_bucket b = _cx_MEMB(_bucket_)(&m, &r); - m.slot[b.idx].hashx = b.hashx; - m.data[b.idx] = *d; // move + _cx_result b = _cx_MEMB(_bucket_)(&m, &r); + m.slot[b.ref - m.data].hashx = b.hashx; + *b.ref = *d; // move } c_swap(_cx_Self, self, &m); } diff --git a/include/stc/csmap.h b/include/stc/csmap.h index f4d33a4d..d2e1d1fc 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -170,19 +170,29 @@ _cx_MEMB(_shrink_to_fit)(_cx_Self *self) { } #endif // !i_no_clone -#ifndef _i_isset +STC_API _cx_result _cx_MEMB(_insert_entry_)(_cx_Self* self, _cx_keyraw rkey); + +#ifdef _i_ismap STC_API _cx_result _cx_MEMB(_insert_or_assign)(_cx_Self* self, i_key key, i_val mapped); #if !defined i_no_emplace STC_API _cx_result _cx_MEMB(_emplace_or_assign)(_cx_Self* self, _cx_keyraw rkey, i_valraw rmapped); - #endif + STC_INLINE _cx_result + _cx_MEMB(_emplace_key)(_cx_Self* self, _cx_keyraw rkey) { + _cx_result res = _cx_MEMB(_insert_entry_)(self, rkey); + if (res.inserted) + res.ref->first = i_keyfrom(rkey); + return res; + } + #endif STC_INLINE const _cx_mapped* _cx_MEMB(_at)(const _cx_Self* self, _cx_keyraw rkey) { _cx_iter it; return &_cx_MEMB(_find_it)(self, rkey, &it)->second; } + STC_INLINE _cx_mapped* _cx_MEMB(_at_mut)(_cx_Self* self, _cx_keyraw rkey) { _cx_iter it; return &_cx_MEMB(_find_it)(self, rkey, &it)->second; } -#endif // !_i_isset +#endif // _i_ismap STC_INLINE _cx_iter _cx_MEMB(_end)(const _cx_Self* self) { @@ -209,8 +219,6 @@ _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { return true; } -static _cx_result _cx_MEMB(_insert_entry_)(_cx_Self* self, _cx_keyraw rkey); - 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))); @@ -326,7 +334,7 @@ _cx_MEMB(_new_node_)(_cx_Self* self, int level) { return tn; } -#ifndef _i_isset +#ifdef _i_ismap STC_DEF _cx_result _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))); @@ -353,7 +361,7 @@ _cx_MEMB(_new_node_)(_cx_Self* self, int level) { return _res; } #endif // !i_no_emplace -#endif // !_i_isset +#endif // !_i_ismap STC_DEF _cx_value* _cx_MEMB(_find_it)(const _cx_Self* self, _cx_keyraw rkey, _cx_iter* out) { @@ -407,7 +415,7 @@ _cx_MEMB(_split_)(_cx_node *d, int32_t tn) { return tn; } -static int32_t +STC_DEF int32_t _cx_MEMB(_insert_entry_i_)(_cx_Self* self, int32_t tn, const _cx_keyraw* rkey, _cx_result* _res) { int32_t up[64], tx = tn; _cx_node* d = self->nodes; @@ -439,7 +447,7 @@ _cx_MEMB(_insert_entry_i_)(_cx_Self* self, int32_t tn, const _cx_keyraw* rkey, _ return up[0]; } -static _cx_result +STC_DEF _cx_result _cx_MEMB(_insert_entry_)(_cx_Self* self, _cx_keyraw rkey) { _cx_result res = {NULL}; int32_t tn = _cx_MEMB(_insert_entry_i_)(self, self->root, &rkey, &res); @@ -448,7 +456,7 @@ _cx_MEMB(_insert_entry_)(_cx_Self* self, _cx_keyraw rkey) { return res; } -static int32_t +STC_DEF int32_t _cx_MEMB(_erase_r_)(_cx_Self *self, int32_t tn, const _cx_keyraw* rkey, int *erased) { _cx_node *d = self->nodes; if (tn == 0) @@ -533,7 +541,7 @@ _cx_MEMB(_erase_range)(_cx_Self* self, _cx_iter it1, _cx_iter it2) { } #if !defined i_no_clone -static int32_t +STC_DEF int32_t _cx_MEMB(_clone_r_)(_cx_Self* self, _cx_node* src, int32_t sn) { if (sn == 0) return 0; diff --git a/include/stc/forward.h b/include/stc/forward.h index 484a8b63..085205cf 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -120,6 +120,7 @@ typedef struct chash_slot chash_slot; typedef struct { \ SELF##_value *ref; \ bool inserted; \ + uint8_t hashx; \ } SELF##_result; \ \ typedef struct { \ diff --git a/misc/examples/smartpointers/arc_containers.c b/misc/examples/smartpointers/arc_containers.c index 2fb04c56..6209005d 100644 --- a/misc/examples/smartpointers/arc_containers.c +++ b/misc/examples/smartpointers/arc_containers.c @@ -2,7 +2,6 @@ // and demonstrate sharing and cloning of maps. #define i_implement #include -#include #define i_type Map #define i_key_str // strings #define i_val int diff --git a/misc/tests/cspan_test.c b/misc/tests/cspan_test.c index d7ca9b64..ce267b14 100644 --- a/misc/tests/cspan_test.c +++ b/misc/tests/cspan_test.c @@ -1,6 +1,5 @@ #include #include -#include #include "ctest.h" using_cspan3(intspan, int); @@ -48,7 +47,8 @@ CTEST(cspan, slice) { #include CTEST(cspan, slice2) { - c_auto (cstack_int, stack) + cstack_int stack = {0}; + c_defer (cstack_int_drop(&stack)) { c_forrange (i, 10*20*30) cstack_int_push(&stack, i); -- cgit v1.2.3 From be5651c9fc3d3ecd2d9d24e6e4763260ef86de41 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 10 Aug 2023 21:17:48 +0200 Subject: Update template.h - also renamed i_cmp_native => i_use_cmp --- README.md | 4 +- docs/carc_api.md | 2 +- docs/cbox_api.md | 2 +- docs/cdeq_api.md | 2 +- docs/clist_api.md | 2 +- docs/cvec_api.md | 4 +- include/stc/carc.h | 64 ++++++++++++--------------- include/stc/cbox.h | 65 ++++++++++++---------------- include/stc/ccommon.h | 2 +- include/stc/priv/template.h | 29 ++++++------- include/stc/priv/template2.h | 2 +- misc/examples/linkedlists/intrusive.c | 2 +- misc/examples/linkedlists/list.c | 2 +- misc/examples/linkedlists/new_list.c | 2 +- misc/examples/mixed/astar.c | 1 - misc/examples/mixed/complex.c | 1 - misc/examples/mixed/demos.c | 3 +- misc/examples/smartpointers/arc_containers.c | 4 +- misc/examples/smartpointers/arc_demo.c | 3 +- misc/examples/smartpointers/arcvec_erase.c | 3 +- misc/examples/smartpointers/box.c | 1 + misc/examples/smartpointers/box2.c | 1 - misc/examples/smartpointers/music_arc.c | 4 +- misc/examples/smartpointers/new_sptr.c | 3 +- misc/examples/smartpointers/person_arc.c | 3 +- misc/examples/sortedmaps/csmap_insert.c | 1 - misc/examples/sortedmaps/multimap.c | 1 + misc/examples/vectors/lower_bound.c | 2 +- 28 files changed, 99 insertions(+), 116 deletions(-) (limited to 'misc/examples/smartpointers/arc_containers.c') diff --git a/README.md b/README.md index 69c51417..48ccdd6f 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ struct Point { float x, y; }; #include // cvec_pnt: vector of struct Point #define i_key int -#define i_cmp_native // enable sort/search. Use native `<` and `==` operators +#define i_use_cmp // enable sort/search. Use native `<` and `==` operators #include // clist_int: singly linked list #define i_key int @@ -658,7 +658,7 @@ STC is generally very memory efficient. Memory usage for the different container - Removed deprecated . Use `` with the new API. - Reverted names _unif and _norm back to `_uniform` and `_normal`. - Removed default comparison for **clist**, **cvec** and **cdeq**: - - Define `i_cmp_native` to enable comparison for built-in i_key types (<, ==). + - Define `i_use_cmp` to enable comparison for built-in i_key types (<, ==). - Use of `i_keyclass` still expects comparison functions to be defined. - Use of `i_keyboxed` compares stored pointers instead of pointed to values if comparison not defined. - Renamed input enum flags for ***cregex***-functions. diff --git a/docs/carc_api.md b/docs/carc_api.md index fb79019a..3e394378 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -25,7 +25,7 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory #define i_cmp // three-way compareison. REQUIRED IF i_key is a non-integral type // Note that containers of carcs will "inherit" i_cmp // when using carc in containers with i_valboxed MyArc - ie. the i_type. -#define i_cmp_native // define instead of i_cmp only when i_key is an integral/native-type. +#define i_use_cmp // define instead of i_cmp only when i_key is an integral/native-type. #define i_keydrop // destroy element func - defaults to empty destruct #define i_keyclone // REQUIRED if i_keydrop is defined, unless 'i_opt c_no_clone' is defined. diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 0e6fca64..c683d9ef 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -19,7 +19,7 @@ See similar c++ class [std::unique_ptr](https://en.cppreference.com/w/cpp/memory #define i_cmp // three-way compareison. REQUIRED IF i_key is a non-integral type // Note that containers of carcs will "inherit" i_cmp // when using carc in containers with i_valboxed MyArc - ie. the i_type. -#define i_cmp_native // define instead of i_cmp only when i_key is an integral/native-type. +#define i_use_cmp // define instead of i_cmp only when i_key is an integral/native-type. #define i_keydrop // destroy element func - defaults to empty destruct #define i_keyclone // REQUIRED if i_keydrop is defined, unless 'i_opt c_no_clone' is defined. diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index c544f213..3ce58e78 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -13,7 +13,7 @@ See the c++ class [std::deque](https://en.cppreference.com/w/cpp/container/deque #define i_key // element type: REQUIRED. Note: i_val* may be specified instead of i_key*. #define i_type // cdeq container type name #define i_cmp // three-way compare of two i_keyraw*. -#define i_cmp_native // define instead of i_cmp only when i_key is an integral/native-type. +#define i_use_cmp // define instead of i_cmp only when i_key is an integral/native-type. #define i_keydrop // destroy value func - defaults to empty destruct #define i_keyclone // REQUIRED IF i_keydrop is defined diff --git a/docs/clist_api.md b/docs/clist_api.md index d8d614c2..a24d813b 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -25,7 +25,7 @@ See the c++ class [std::list](https://en.cppreference.com/w/cpp/container/list) #define i_key // element type: REQUIRED. Note: i_val* may be specified instead of i_key*. #define i_type // clist container type name #define i_cmp // three-way compare two i_keyraw* -#define i_cmp_native // define instead of i_cmp only when i_key is an integral/native-type. +#define i_use_cmp // define instead of i_cmp only when i_key is an integral/native-type. #define i_keydrop // destroy value func - defaults to empty destruct #define i_keyclone // REQUIRED IF i_keydrop defined diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 3f827df6..8997ed51 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -15,7 +15,7 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect #define i_type // container type name #define i_key // element type: REQUIRED. Note: i_val* may be specified instead of i_key*. #define i_cmp // three-way compare two i_keyraw* -#define i_cmp_native // define instead of i_cmp only when i_key is an integral/native-type. +#define i_use_cmp // define instead of i_cmp only when i_key is an integral/native-type. #define i_keydrop // destroy value func - defaults to empty destruct #define i_keyclone // REQUIRED IF i_keydrop defined @@ -224,4 +224,4 @@ int main(void) { c_drop(UVec, &vec, &vec2); // cleanup } -``` \ No newline at end of file +``` diff --git a/include/stc/carc.h b/include/stc/carc.h index 9ba2ddd1..e1dfe14e 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -176,50 +176,40 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self ptr) { *self = ptr; } -#if defined _i_has_cmp +#if defined i_use_cmp STC_INLINE int _cx_MEMB(_raw_cmp)(const _cx_raw* rx, const _cx_raw* ry) { return i_cmp(rx, ry); } - STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { - _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); - return i_cmp((&rx), (&ry)); - } -#else - STC_INLINE int _cx_MEMB(_raw_cmp)(const _cx_raw* rx, const _cx_raw* ry) - { return c_default_cmp(&rx, &ry); } - - STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { - return c_default_cmp(&self->get, &other->get); - } -#endif -#if defined _i_has_eq || defined _i_has_cmp STC_INLINE bool _cx_MEMB(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) { return i_eq(rx, ry); } - - STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { - _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); - return i_eq((&rx), (&ry)); - } -#else - STC_INLINE bool _cx_MEMB(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) - { return rx == ry; } - - STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { - return self->get == other->get; - } -#endif -#if defined i_hash + #ifndef i_no_hash STC_INLINE uint64_t _cx_MEMB(_raw_hash)(const _cx_raw* rx) { return i_hash(rx); } - - STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) - { _cx_raw rx = i_keyto(self->get); return i_hash(&rx); } -#else - STC_INLINE uint64_t _cx_MEMB(_raw_hash)(const _cx_raw* rx) - { return c_default_hash(&rx); } - - STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) - { return c_default_hash(&self->get); } + #endif // i_no_hash + + #if defined i_ptr_cmp + STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { + return c_default_cmp(&self->get, &other->get); + } + STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { + return self->get == other->get; + } + STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) + { return c_default_hash(&self->get); } + #else + STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); + return i_cmp((&rx), (&ry)); + } + STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); + return i_eq((&rx), (&ry)); + } + #ifndef i_no_hash + STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) + { _cx_raw rx = i_keyto(self->get); return i_hash(&rx); } + #endif // i_no_hash + #endif // i_ptr_cmp #endif #undef _i_atomic_inc diff --git a/include/stc/cbox.h b/include/stc/cbox.h index 25d41b92..b799c24c 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -159,50 +159,41 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self* moved) { moved->get = NULL; } -#if defined _i_has_cmp +#if defined i_use_cmp STC_INLINE int _cx_MEMB(_raw_cmp)(const _cx_raw* rx, const _cx_raw* ry) { return i_cmp(rx, ry); } - STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { - _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); - return i_cmp((&rx), (&ry)); - } -#else - STC_INLINE int _cx_MEMB(_raw_cmp)(const _cx_raw* rx, const _cx_raw* ry) - { return c_default_cmp(&rx, &ry); } - - STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { - return c_default_cmp(&self->get, &other->get); - } -#endif -#if defined _i_has_eq || defined _i_has_cmp STC_INLINE bool _cx_MEMB(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) { return i_eq(rx, ry); } - - STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { - _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); - return i_eq((&rx), (&ry)); - } -#else - STC_INLINE bool _cx_MEMB(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) - { return rx == ry; } - - STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { - return self->get == other->get; - } -#endif -#if defined i_hash + #ifndef i_no_hash STC_INLINE uint64_t _cx_MEMB(_raw_hash)(const _cx_raw* rx) { return i_hash(rx); } - - STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) - { _cx_raw rx = i_keyto(self->get); return i_hash(&rx); } -#else - STC_INLINE uint64_t _cx_MEMB(_raw_hash)(const _cx_raw* rx) - { return c_default_hash(&rx); } - - STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) - { return c_default_hash(&self->get); } + #endif // i_no_hash + + #if defined i_ptr_cmp + STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { + return c_default_cmp(&self->get, &other->get); + } + STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { + return self->get == other->get; + } + STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) + { return c_default_hash(&self->get); } + #else + STC_INLINE int _cx_MEMB(_cmp)(const _cx_Self* self, const _cx_Self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); + return i_cmp((&rx), (&ry)); + } + STC_INLINE bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); + return i_eq((&rx), (&ry)); + } + #ifndef i_no_hash + STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self) + { _cx_raw rx = i_keyto(self->get); return i_hash(&rx); } + #endif // i_no_hash + #endif // i_ptr_cmp #endif + #include "priv/template2.h" #undef _i_cbox diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 2528b94f..b37ad1da 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -117,7 +117,7 @@ typedef long long _llong; #define c_no_clone (1<<2) #define c_no_emplace (1<<3) #define c_no_cmp (1<<4) -#define c_native_cmp (1<<5) +#define c_use_cmp (1<<5) #define c_no_hash (1<<6) /* Function macros and others */ diff --git a/include/stc/priv/template.h b/include/stc/priv/template.h index 49b4d8da..fae9093e 100644 --- a/include/stc/priv/template.h +++ b/include/stc/priv/template.h @@ -102,8 +102,8 @@ #if c_option(c_no_emplace) #define i_no_emplace #endif -#if c_option(c_native_cmp) - #define i_cmp_native +#if c_option(c_use_cmp) || defined _i_ismap || defined _i_isset || defined _i_ispque + #define i_use_cmp #endif #if c_option(c_no_clone) || defined _i_carc #define i_no_clone @@ -127,7 +127,7 @@ #elif defined i_keyboxed #define i_keyclass i_keyboxed #define i_rawclass c_PASTE(i_keyboxed, _raw) - #ifndef i_no_cmp + #if !defined i_no_cmp && defined i_use_cmp #define i_eq c_PASTE(i_keyboxed, _raw_eq) #endif #endif @@ -138,7 +138,7 @@ #define i_rawclass i_key #endif -#ifdef i_keyclass +#if defined i_keyclass #define i_key i_keyclass #ifndef i_keyclone #define i_keyclone c_PASTE(i_key, _clone) @@ -154,8 +154,8 @@ #endif #endif -#ifdef i_rawclass - #if !(defined i_cmp || defined i_no_cmp) +#if defined i_rawclass && defined i_use_cmp + #if !(defined i_cmp || defined i_less || defined i_no_cmp) #define i_cmp c_PASTE(i_keyraw, _cmp) #endif #if !(defined i_hash || defined i_no_hash || defined i_no_cmp) @@ -171,26 +171,29 @@ #endif #endif -#ifndef i_no_cmp - #if defined i_cmp || defined i_less || defined i_cmp_native +#if !defined i_no_cmp + #if defined i_cmp || defined i_less || defined i_use_cmp #define _i_has_cmp #endif - #if defined i_eq || defined i_cmp_native + #if defined i_eq || defined i_use_cmp #define _i_has_eq #endif #endif +#if !(defined i_hash || defined i_no_hash || defined i_no_cmp) + #define i_hash c_default_hash +#endif #if !defined i_key #error "No i_key or i_val defined" #elif defined i_keyraw ^ defined i_keyto #error "Both i_keyraw/i_valraw and i_keyto/i_valto must be defined, if any" #elif !defined i_no_clone && (defined i_keyclone ^ defined i_keydrop) - #error "Both i_keyclone/i_valclone and i_keydrop/i_valdrop must be defined, if any" + #error "Both i_keyclone/i_valclone and i_keydrop/i_valdrop must be defined, if any (unless i_no_clone defined)." #elif defined i_from || defined i_drop #error "i_from / i_drop not supported. Define i_keyfrom/i_valfrom and/or i_keydrop/i_valdrop instead" #elif defined i_keyraw && defined _i_ishash && !(defined i_hash && (defined _i_has_cmp || defined i_eq)) #error "For cmap/cset, both i_hash and i_eq (or i_less or i_cmp) must be defined when i_keyraw is defined." -#elif defined i_keyraw && (defined _i_ismap || defined _i_isset || defined _i_ispque) && !defined _i_has_cmp +#elif defined i_keyraw && defined i_use_cmp && !defined _i_has_cmp #error "For csmap/csset/cpque, i_cmp or i_less must be defined when i_keyraw is defined." #endif @@ -234,10 +237,6 @@ #endif #endif -#if !defined i_hash && (!(defined _i_cbox || defined _i_carc) || defined i_cmp_native) - #define i_hash c_default_hash -#endif - #if defined _i_ismap // ---- process cmap/csmap value i_val, ... ---- #ifdef i_val_str diff --git a/include/stc/priv/template2.h b/include/stc/priv/template2.h index 351defde..1e0d4a2e 100644 --- a/include/stc/priv/template2.h +++ b/include/stc/priv/template2.h @@ -67,7 +67,7 @@ #undef i_realloc #undef i_free -#undef i_cmp_native +#undef i_use_cmp #undef i_no_cmp #undef i_no_hash #undef i_no_clone diff --git a/misc/examples/linkedlists/intrusive.c b/misc/examples/linkedlists/intrusive.c index c7402d09..edb072c7 100644 --- a/misc/examples/linkedlists/intrusive.c +++ b/misc/examples/linkedlists/intrusive.c @@ -4,7 +4,7 @@ #define i_type List #define i_key int -#define i_cmp_native +#define i_use_cmp #include void printList(List list) { diff --git a/misc/examples/linkedlists/list.c b/misc/examples/linkedlists/list.c index 518cc09b..e83dc6b2 100644 --- a/misc/examples/linkedlists/list.c +++ b/misc/examples/linkedlists/list.c @@ -5,7 +5,7 @@ #define i_type DList #define i_key double -#define i_cmp_native +#define i_use_cmp #include int main(void) { diff --git a/misc/examples/linkedlists/new_list.c b/misc/examples/linkedlists/new_list.c index 2112bf1f..7518929a 100644 --- a/misc/examples/linkedlists/new_list.c +++ b/misc/examples/linkedlists/new_list.c @@ -27,7 +27,7 @@ int point_cmp(const Point* a, const Point* b) { #include #define i_key float -#define i_cmp_native // use < and == operators for comparison +#define i_use_cmp // use < and == operators for comparison #include void MyStruct_drop(MyStruct* s); diff --git a/misc/examples/mixed/astar.c b/misc/examples/mixed/astar.c index 590b7952..d15a9ed7 100644 --- a/misc/examples/mixed/astar.c +++ b/misc/examples/mixed/astar.c @@ -61,7 +61,6 @@ point_key_cmp(const point* a, const point* b) #include #define i_key point -#define i_opt c_no_cmp #include #define i_key point diff --git a/misc/examples/mixed/complex.c b/misc/examples/mixed/complex.c index 4eb1574b..9fcbc417 100644 --- a/misc/examples/mixed/complex.c +++ b/misc/examples/mixed/complex.c @@ -14,7 +14,6 @@ #define i_type StackList #define i_keyclass FloatStack // "class" picks up _clone, _drop, _cmp -#define i_opt c_no_cmp // exclude FloatStack_cmp(): not defined #include #define i_type ListMap diff --git a/misc/examples/mixed/demos.c b/misc/examples/mixed/demos.c index 7f5091fd..43c9a7ae 100644 --- a/misc/examples/mixed/demos.c +++ b/misc/examples/mixed/demos.c @@ -53,6 +53,7 @@ void vectordemo1(void) } #define i_key_str +#define i_use_cmp #include void vectordemo2(void) @@ -74,7 +75,7 @@ void vectordemo2(void) #define i_key int #define i_tag ix -#define i_cmp_native +#define i_use_cmp #include void listdemo1(void) diff --git a/misc/examples/smartpointers/arc_containers.c b/misc/examples/smartpointers/arc_containers.c index 6209005d..c2bff56f 100644 --- a/misc/examples/smartpointers/arc_containers.c +++ b/misc/examples/smartpointers/arc_containers.c @@ -12,11 +12,11 @@ #define i_key Map #define i_keydrop(p) (printf("drop Arc:\n"), Map_drop(p)) // no need for atomic ref. count in single thread: -#define i_opt c_no_atomic +#define i_opt c_no_atomic|c_no_cmp #include #define i_type Stack -#define i_keyboxed Arc // define i_keyboxed for carc/cbox value (not i_key) +#define i_keyboxed Arc // use i_keyboxed for carc/cbox key #include #define i_type List diff --git a/misc/examples/smartpointers/arc_demo.c b/misc/examples/smartpointers/arc_demo.c index 929a48a1..a66d84b0 100644 --- a/misc/examples/smartpointers/arc_demo.c +++ b/misc/examples/smartpointers/arc_demo.c @@ -11,13 +11,14 @@ void int_drop(int* x) { #define i_type Arc // set type name to be defined (instead of 'carc_int') #define i_key int #define i_keydrop int_drop // optional, just to display the elements destroyed -#define i_cmp_native // use int comparison (x < y, x == y). +#define i_use_cmp // use int comparison (x < y, x == y). #include // Arc #define i_keyboxed Arc // note: use i_keyboxed instead of i_key for carc/cbox elements #include // csset_Arc (like: std::set>) #define i_keyboxed Arc // note: as above. +#define i_use_cmp #include // cvec_Arc (like: std::vector>) int main(void) diff --git a/misc/examples/smartpointers/arcvec_erase.c b/misc/examples/smartpointers/arcvec_erase.c index 9d757533..0526b6a0 100644 --- a/misc/examples/smartpointers/arcvec_erase.c +++ b/misc/examples/smartpointers/arcvec_erase.c @@ -5,11 +5,12 @@ void show_drop(int* x) { printf("drop: %d\n", *x); } #define i_type Arc #define i_key int #define i_keydrop show_drop -#define i_cmp_native // enable sort/search for int type +#define i_use_cmp // enable sort/search for int type #include // Shared pointer to int #define i_type Vec #define i_keyboxed Arc +#define i_use_cmp #include // Vec: cvec diff --git a/misc/examples/smartpointers/box.c b/misc/examples/smartpointers/box.c index 94d126c0..5c8018d4 100644 --- a/misc/examples/smartpointers/box.c +++ b/misc/examples/smartpointers/box.c @@ -30,6 +30,7 @@ void Person_drop(Person* p) { #define i_type PBox #define i_keyclass Person // "class" binds _cmp, _clone, _drop functions. +#define i_use_cmp #include #define i_type Persons diff --git a/misc/examples/smartpointers/box2.c b/misc/examples/smartpointers/box2.c index eaab1c47..9b782c74 100644 --- a/misc/examples/smartpointers/box2.c +++ b/misc/examples/smartpointers/box2.c @@ -22,7 +22,6 @@ typedef struct { // Box in box: #define i_type BoxBoxPoint #define i_keyboxed cbox_Point // NB: use i_keyboxed when value is a cbox or carc! -#define i_no_cmp #include // BoxBoxPoint Point origin(void) { diff --git a/misc/examples/smartpointers/music_arc.c b/misc/examples/smartpointers/music_arc.c index 13d368c3..e9ebbbfe 100644 --- a/misc/examples/smartpointers/music_arc.c +++ b/misc/examples/smartpointers/music_arc.c @@ -23,7 +23,7 @@ void Song_drop(Song* s) { // Define the shared pointer: #define i_type SongArc #define i_keyclass Song -#define i_no_hash // no hash fn for Song, fallback hash pointer to Song. +#define i_opt c_use_cmp|c_no_hash #include // ... and a vector of them @@ -64,4 +64,4 @@ void example3(void) int main(void) { example3(); -} +} \ No newline at end of file diff --git a/misc/examples/smartpointers/new_sptr.c b/misc/examples/smartpointers/new_sptr.c index 3c6fa16c..50e28ae2 100644 --- a/misc/examples/smartpointers/new_sptr.c +++ b/misc/examples/smartpointers/new_sptr.c @@ -10,12 +10,13 @@ uint64_t Person_hash(const Person* p); #define i_type PersonArc #define i_keyclass Person // "class" assume _clone, _drop, _cmp, _hash is defined. +#define i_use_cmp #include #define i_type IPtr #define i_key int #define i_keydrop(x) printf("drop: %d\n", *x) -#define i_cmp_native +#define i_use_cmp #include #define i_type IPStack diff --git a/misc/examples/smartpointers/person_arc.c b/misc/examples/smartpointers/person_arc.c index 38c883a7..11040cd2 100644 --- a/misc/examples/smartpointers/person_arc.c +++ b/misc/examples/smartpointers/person_arc.c @@ -31,11 +31,12 @@ void Person_drop(Person* p) { #define i_type PSPtr #define i_keyclass Person // ensure Person_drop -#define i_cmp Person_cmp // specify object cmp, instead of ptr cmp for arc. +#define i_use_cmp #include #define i_type Persons #define i_keyboxed PSPtr // binds PSPtr_cmp, PSPtr_drop... +#define i_use_cmp #include diff --git a/misc/examples/sortedmaps/csmap_insert.c b/misc/examples/sortedmaps/csmap_insert.c index c9f02891..04b8ddc6 100644 --- a/misc/examples/sortedmaps/csmap_insert.c +++ b/misc/examples/sortedmaps/csmap_insert.c @@ -13,7 +13,6 @@ #include #define i_key csmap_ii_raw -#define i_opt c_no_cmp #define i_tag ii #include diff --git a/misc/examples/sortedmaps/multimap.c b/misc/examples/sortedmaps/multimap.c index 1068a5dc..a4490f91 100644 --- a/misc/examples/sortedmaps/multimap.c +++ b/misc/examples/sortedmaps/multimap.c @@ -41,6 +41,7 @@ void OlympicLoc_drop(OlympicLoc* self); // Create a clist, can be sorted by year. #define i_keyclass OlympicLoc // binds _cmp, _clone and _drop. +#define i_use_cmp #define i_tag OL #include diff --git a/misc/examples/vectors/lower_bound.c b/misc/examples/vectors/lower_bound.c index bea828f2..09cf2008 100644 --- a/misc/examples/vectors/lower_bound.c +++ b/misc/examples/vectors/lower_bound.c @@ -1,7 +1,7 @@ #include #define i_key int -#define i_cmp_native +#define i_use_cmp #include #define i_key int -- cgit v1.2.3 From 31ba4b2a36dee10b7e5d58561a2c0291cff6faeb Mon Sep 17 00:00:00 2001 From: tylov Date: Fri, 11 Aug 2023 22:43:59 +0200 Subject: Finalized converting to i_use_cmp (vs i_no_cmp) --- README.md | 10 ++++------ docs/cbox_api.md | 2 +- include/stc/carc.h | 9 ++++++--- include/stc/ccommon.h | 3 +-- misc/examples/smartpointers/arc_containers.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) (limited to 'misc/examples/smartpointers/arc_containers.c') diff --git a/README.md b/README.md index fbdbd9fc..722d2559 100644 --- a/README.md +++ b/README.md @@ -215,7 +215,6 @@ Let's make a vector of vectors, which can be cloned. All of its element vectors #define i_type Vec2D #define i_keyclass Vec // Use i_keyclass instead i_key when element type has "members" _clone(), _drop() and _cmp(). -#define i_opt c_no_cmp // Disable cmp (search/sort) for Vec2D because Vec_cmp() does not exist. #include int main(void) @@ -370,14 +369,14 @@ The list of template parameters: - `i_key` *Type* - Element key type. **[required]**. Note: `i_val` *may* be used instead for non-maps (not recommended). - `i_val` *Type* - Element value type. **[required for]** cmap/csmap as the mapped value type. -- `i_cmp` *Func* - Three-way comparison of two *i_keyraw*\* or *i_valraw*\* - **[required for]** non-integral *i_keyraw* elements unless *i_opt* is defined with *c_no_cmp*. +- `i_cmp` *Func* - Three-way comparison of two *i_keyraw*\* or *i_valraw*\* - **[required for]** non-integral *i_keyraw* elements. - `i_hash` *Func* - Hash function taking *i_keyraw*\* - defaults to *c_default_hash*. **[required for]** ***cmap/cset*** with non-POD *i_keyraw* elements. - `i_eq` *Func* - Equality comparison of two *i_keyraw*\* - defaults to *!i_cmp*. Companion with *i_hash*. Properties: - `i_tag` *Name* - Container type name tag. Defaults to *i_key* name. - `i_type` *Name* - Full container type name. Alternative to *i_tag*. -- `i_opt` *Flags* - Boolean properties: may combine *c_no_cmp*, *c_no_clone*, *c_no_atomic*, *c_is_forward*, *c_static*, *c_header* with the *|* separator. +- `i_opt` *Flags* - Boolean properties: may combine *c_no_clone*, *c_no_atomic*, *c_is_forward*, *c_static*, *c_header* with the *|* separator. Key: - `i_keydrop` *Func* - Destroy map/set key func - defaults to empty destructor. @@ -398,7 +397,7 @@ Specials: Meta-template parameters. Use instead of `i_key` / `i_val`. If `i_keyraw` is defined, it sets `i_keyto` = *Type_toraw()* and `i_keyfrom` = *Type_from()*. Only functions required by the container type is required to be defined. E.g.: - *Type_hash()* and *Type_eq()* are only required by **cmap**, **cset** and smart pointers. - - *Type_cmp()* is not used by **cstack** and **cmap/cset**, or if *#define i_opt c_no_cmp* is specified. + - *Type_cmp()* is not used by **cstack** and **cmap/cset**. - *Type_clone()* is not used if *#define i_opt c_no_clone* is specified. - `i_key_str` - Sets `i_keyclass` = *cstr*, `i_tag` = *str*, and `i_keyraw` = *const char*\*. Defines both type convertion `i_keyfrom`, `i_keyto`, and sets `i_cmp`, `i_eq`, `i_hash` functions with *const char\*\** as argument. @@ -409,7 +408,6 @@ NB: Do not use when defining carc/cbox types themselves. - `i_valclass` *Type*, `i_val_str`, `i_val_ssv`, `i_valboxed` - Similar rules as for ***key***. **Notes**: -- Instead of defining `i_cmp`, you may define *i_opt c_no_cmp* to disable *searching and sorting* functions. - Instead of defining `i_*clone`, you may define *i_opt c_no_clone* to disable *clone* functionality. - For `i_keyclass`, if *i_keyraw* is defined along with it, *i_keyfrom* may also be defined to enable the *emplace*-functions. NB: the signature for ***cmp***, ***eq***, and ***hash*** uses *i_keyraw* as input. @@ -764,6 +762,6 @@ Major changes: - Replaced: *csview_first_token()* and *csview_next_token()* with one function: `csview_token()`. - Added: **checkauto** tool for checking that c-source files uses `c_auto*` macros correctly. - Added: general `i_keyclass` / `i_valclass` template parameters which auto-binds template functions. -- Added: `i_opt` template parameter: compile-time options: `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_forward`; may be combined with `|` +- Added: `i_opt` template parameter: compile-time options: `c_no_clone`, `c_no_atomic`, `c_is_forward`; may be combined with `|` - Added: [**cbox**](docs/cbox_api.md) type: smart pointer, similar to [Rust Box](https://doc.rust-lang.org/rust-by-example/std/box.html) and [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr). - Added: [**c_forpair**](docs/algorithm_api.md) macro: for-loop with "structured binding" diff --git a/docs/cbox_api.md b/docs/cbox_api.md index c683d9ef..7d25aed8 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -34,7 +34,7 @@ See similar c++ class [std::unique_ptr](https://en.cppreference.com/w/cpp/memory #include ``` `X` should be replaced by the value of `i_tag` in all of the following documentation. -Define `i_opt` with `c_no_cmp` if comparison between i_key's is not needed/available. Will then +Unless `c_use_cmp` is defined, comparison between i_key'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 diff --git a/include/stc/carc.h b/include/stc/carc.h index e987f453..1b1c22eb 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -43,7 +43,6 @@ void Person_drop(Person* p) { #define i_type ArcPers #define i_valclass Person // clone, drop, cmp, hash -#define i_opt c_no_cmp|c_no_hash // exclude cmp, hash #include int main(void) { @@ -86,7 +85,10 @@ int main(void) { #include "priv/template.h" typedef i_keyraw _cx_raw; -#if !c_option(c_no_atomic) +#if c_option(c_no_atomic) + #define i_no_atomic +#endif +#if !defined i_no_atomic #define _i_atomic_inc(v) c_atomic_inc(v) #define _i_atomic_dec_and_test(v) c_atomic_dec_and_test(v) #else @@ -213,7 +215,8 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self ptr) { { return c_default_hash(&self->get); } #endif // i_use_cmp +#include "priv/template2.h" +#undef i_no_atomic #undef _i_atomic_inc #undef _i_atomic_dec_and_test -#include "priv/template2.h" #undef _i_carc diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index b37ad1da..45fa01c6 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -116,9 +116,8 @@ typedef long long _llong; #define c_no_atomic (1<<1) #define c_no_clone (1<<2) #define c_no_emplace (1<<3) -#define c_no_cmp (1<<4) +#define c_no_hash (1<<4) #define c_use_cmp (1<<5) -#define c_no_hash (1<<6) /* Function macros and others */ #define c_litstrlen(literal) (c_sizeof("" literal) - 1) diff --git a/misc/examples/smartpointers/arc_containers.c b/misc/examples/smartpointers/arc_containers.c index c2bff56f..79211d2b 100644 --- a/misc/examples/smartpointers/arc_containers.c +++ b/misc/examples/smartpointers/arc_containers.c @@ -12,7 +12,7 @@ #define i_key Map #define i_keydrop(p) (printf("drop Arc:\n"), Map_drop(p)) // no need for atomic ref. count in single thread: -#define i_opt c_no_atomic|c_no_cmp +#define i_opt c_no_atomic #include #define i_type Stack -- cgit v1.2.3