diff options
| -rw-r--r-- | README.md | 9 | ||||
| -rw-r--r-- | include/stc/carc.h | 49 | ||||
| -rw-r--r-- | include/stc/cbox.h | 50 | ||||
| -rw-r--r-- | include/stc/priv/template.h | 64 | ||||
| -rw-r--r-- | include/stc/priv/template2.h | 1 |
5 files changed, 83 insertions, 90 deletions
@@ -194,8 +194,13 @@ int main(void) Floats_drop(&nums); } ``` -For user-defined struct elements, `i_cmp` compare function should be defined because the default `<` and `==` -only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching*. Similarily, if an element destructor `i_keydrop` is defined, `i_keyclone` function is required. +Comparison/lookup functions are enabled by default for associative containers and priority queue (cmap, cset, csmap, csset, cpque). To enable it for the remaining containers, define `i_cmp` or `i_less` (and optionally `i_eq`) on the element type. If the element is an integral type, simply define `i_use_cmp` to use `<` and `==` operators for comparisons. + +Note that for `#define i_keyclass Type`, defining `i_use_cmp` means that *Type_cmp()* function is expected to exist (along with *Type_clone()* and *Type_drop()*). + +To summarize, `i_use_cmp` is only needed to enable comparison (sort/search) functions when defining cstack, cvec, cqueue, cdeq, carc, cbox. With built-in types, it enables the comparison operators, whereas for keyclass types, it binds comparison to its Type_cmp() function. + +If an element destructor `i_keydrop` is defined, `i_keyclone` function is required. *Alternatively `#define i_opt c_no_clone` to disable container cloning.* Let's make a vector of vectors, which can be cloned. All of its element vectors will be destroyed when destroying the Vec2D. diff --git a/include/stc/carc.h b/include/stc/carc.h index e1dfe14e..e987f453 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -180,37 +180,38 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self ptr) { 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)); + } + 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)); + } + #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); } #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 +#else + + 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); } +#endif // i_use_cmp #undef _i_atomic_inc #undef _i_atomic_dec_and_test diff --git a/include/stc/cbox.h b/include/stc/cbox.h index b799c24c..37daa69e 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -44,7 +44,6 @@ void Person_drop(Person* p) { #define i_type PBox #define i_valclass Person // bind Person clone+drop fn's -#define i_no_cmp // no cmp/hash is defined #include <stc/cbox.h> int main(void) { @@ -163,37 +162,38 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self* moved) { 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)); + } + 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)); + } + #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); } #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 +#else + + 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); } +#endif // i_use_cmp #include "priv/template2.h" #undef _i_cbox diff --git a/include/stc/priv/template.h b/include/stc/priv/template.h index fae9093e..3b8a5b39 100644 --- a/include/stc/priv/template.h +++ b/include/stc/priv/template.h @@ -93,9 +93,6 @@ #if c_option(c_is_forward) #define i_is_forward #endif -#if c_option(c_no_cmp) - #define i_no_cmp -#endif #if c_option(c_no_hash) #define i_no_hash #endif @@ -127,7 +124,7 @@ #elif defined i_keyboxed #define i_keyclass i_keyboxed #define i_rawclass c_PASTE(i_keyboxed, _raw) - #if !defined i_no_cmp && defined i_use_cmp + #if defined i_use_cmp #define i_eq c_PASTE(i_keyboxed, _raw_eq) #endif #endif @@ -152,34 +149,27 @@ #ifndef i_keydrop #define i_keydrop c_PASTE(i_key, _drop) #endif + #if !defined i_keyraw && (defined i_cmp || defined i_less || defined i_eq || defined i_hash) + #define i_use_cmp + #endif #endif #if defined i_rawclass && defined i_use_cmp - #if !(defined i_cmp || defined i_less || defined i_no_cmp) + #if !(defined i_cmp || defined i_less) #define i_cmp c_PASTE(i_keyraw, _cmp) #endif - #if !(defined i_hash || defined i_no_hash || defined i_no_cmp) + #if !(defined i_hash || defined i_no_hash) #define i_hash c_PASTE(i_keyraw, _hash) #endif #endif -#if !defined i_keyraw && !defined i_no_clone - #if !defined i_keyfrom && defined i_keyclone - #define i_keyfrom i_keyclone - #elif !defined i_keyclone && defined i_keyfrom - #define i_keyclone i_keyfrom - #endif +#if defined i_cmp || defined i_less || defined i_use_cmp + #define _i_has_cmp #endif - -#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_use_cmp - #define _i_has_eq - #endif +#if defined i_eq || defined i_use_cmp + #define _i_has_eq #endif -#if !(defined i_hash || defined i_no_hash || defined i_no_cmp) +#if !(defined i_hash || defined i_no_hash) #define i_hash c_default_hash #endif @@ -218,23 +208,21 @@ #define i_keydrop c_default_drop #endif -#ifndef i_no_cmp - // i_eq, i_less, i_cmp - #if !defined i_eq && (defined i_cmp || defined i_less) - #define i_eq(x, y) !(i_cmp(x, y)) - #elif !defined i_eq - #define i_eq(x, y) *x == *y - #endif - #if defined i_cmp && defined i_less - #error "Only one of i_cmp and i_less may be defined" - #elif defined i_cmp - #define i_less(x, y) (i_cmp(x, y)) < 0 - #elif !defined i_less - #define i_less(x, y) *x < *y - #endif - #ifndef i_cmp - #define i_cmp(x, y) (i_less(y, x)) - (i_less(x, y)) - #endif +// i_eq, i_less, i_cmp +#if !defined i_eq && (defined i_cmp || defined i_less) + #define i_eq(x, y) !(i_cmp(x, y)) +#elif !defined i_eq + #define i_eq(x, y) *x == *y +#endif +#if defined i_cmp && defined i_less + #error "Only one of i_cmp and i_less may be defined" +#elif defined i_cmp + #define i_less(x, y) (i_cmp(x, y)) < 0 +#elif !defined i_less + #define i_less(x, y) *x < *y +#endif +#ifndef i_cmp + #define i_cmp(x, y) (i_less(y, x)) - (i_less(x, y)) #endif #if defined _i_ismap // ---- process cmap/csmap value i_val, ... ---- diff --git a/include/stc/priv/template2.h b/include/stc/priv/template2.h index 1e0d4a2e..44254601 100644 --- a/include/stc/priv/template2.h +++ b/include/stc/priv/template2.h @@ -68,7 +68,6 @@ #undef i_free #undef i_use_cmp -#undef i_no_cmp #undef i_no_hash #undef i_no_clone #undef i_no_emplace |
