diff options
| author | Tyge Løvset <[email protected]> | 2021-12-02 14:39:42 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-12-02 14:39:42 +0100 |
| commit | 323f21d57aaf30ffd43d6b67146bc887ad206298 (patch) | |
| tree | 3e4045251b0a0d0fb55e152ce728da6b5a3e875b /include/stc/cmap.h | |
| parent | f857d8215a266673e25356779f740100fe362025 (diff) | |
| download | STC-modified-323f21d57aaf30ffd43d6b67146bc887ad206298.tar.gz STC-modified-323f21d57aaf30ffd43d6b67146bc887ad206298.zip | |
Breaking changes for i_fwd and i_cmp_none:
- Removed: i_cmp_none and i_fwd (replaced by c_no_compare and c_is_fwd args to i_opt).
- Added compile-time disabling of clonable and comparable container elements, controlled by i_opt (c_no_clone | c_no_compare)
- Added i_opt: can define multiple compile-time options: c_no_compare, c_no_clone, c_no_atomic, c_is_fwd: may be combined with | separator.
- Except for csptr, when i_del / i_valdel / i_keydel is defined, also i_from / i_keyfrom / i_valfrom must be defined or i_opt c_no_clone.
- For struct elements, either i_cmp must be defined (as before), or define i_opt c_no_compare for non-associative containers.
Diffstat (limited to 'include/stc/cmap.h')
| -rw-r--r-- | include/stc/cmap.h | 111 |
1 files changed, 60 insertions, 51 deletions
diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 979f1b44..3d1915d3 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -58,37 +58,39 @@ int main(void) { typedef struct { MAP_SIZE_T idx; uint_fast8_t hx; } chash_bucket_t;
#endif // CMAP_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix cmap_
+#ifndef _i_prefix
+#define _i_prefix cmap_
#endif
-#ifdef i_isset
- #define cx_MAP_ONLY c_false
- #define cx_SET_ONLY c_true
- #define cx_keyref(vp) (vp)
+#ifdef _i_isset
+ #define _i_MAP_ONLY c_false
+ #define _i_SET_ONLY c_true
+ #define _i_keyref(vp) (vp)
#else
- #define cx_MAP_ONLY c_true
- #define cx_SET_ONLY c_false
- #define cx_keyref(vp) (&(vp)->first)
+ #define _i_MAP_ONLY c_true
+ #define _i_SET_ONLY c_false
+ #define _i_keyref(vp) (&(vp)->first)
#endif
#include "template.h"
-#ifndef i_fwd
-_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, cx_MAP_ONLY, cx_SET_ONLY);
+#if !c_option(c_is_fwd)
+_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, _i_MAP_ONLY, _i_SET_ONLY);
#endif
-cx_MAP_ONLY( struct _cx_value {
+_i_MAP_ONLY( struct _cx_value {
_cx_key first;
_cx_mapped second;
}; )
typedef i_keyraw _cx_rawkey;
typedef i_valraw _cx_memb(_rawmapped);
-typedef cx_SET_ONLY( i_keyraw )
- cx_MAP_ONLY( struct { i_keyraw first;
+typedef _i_SET_ONLY( i_keyraw )
+ _i_MAP_ONLY( struct { i_keyraw first;
i_valraw second; } )
_cx_rawvalue;
STC_API _cx_self _cx_memb(_with_capacity)(size_t cap);
+#if !c_option(c_no_clone)
STC_API _cx_self _cx_memb(_clone)(_cx_self map);
+#endif
STC_API void _cx_memb(_del)(_cx_self* self);
STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t capacity);
@@ -108,9 +110,11 @@ STC_INLINE void _cx_memb(_swap)(_cx_self *map1, _cx_self *map2) {c_swap( STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey)
{ return self->size && self->_hashx[_cx_memb(_bucket_)(self, &rkey).idx]; }
-cx_MAP_ONLY(
- STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped);
+#ifndef _i_isset
+ #if !c_option(c_no_clone)
STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped);
+ #endif
+ STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped);
STC_INLINE _cx_result /* short-form, like operator[]: */
_cx_memb(_put)(_cx_self* self, i_key key, i_val mapped) {
@@ -123,41 +127,48 @@ cx_MAP_ONLY( assert(self->_hashx[b.idx]);
return &self->table[b.idx].second;
}
-)
-
-STC_INLINE void
-_cx_memb(_value_clone)(_cx_value* _dst, _cx_value* _val) {
- *cx_keyref(_dst) = i_keyfrom(i_keyto(cx_keyref(_val)));
- cx_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); )
-}
+#endif
-STC_INLINE _cx_rawvalue
-_cx_memb(_value_toraw)(_cx_value* val) {
- return cx_SET_ONLY( i_keyto(val) )
- cx_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} );
+#if !c_option(c_no_clone)
+STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
+ if (self->table == other.table) return;
+ _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
}
STC_INLINE void
-_cx_memb(_value_del)(_cx_value* _val) {
- i_keydel(cx_keyref(_val));
- cx_MAP_ONLY( i_valdel(&_val->second); )
+_cx_memb(_value_clone)(_cx_value* _dst, _cx_value* _val) {
+ *_i_keyref(_dst) = i_keyfrom(i_keyto(_i_keyref(_val)));
+ _i_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); )
}
STC_INLINE _cx_result
-_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey cx_MAP_ONLY(, i_valraw rmapped)) {
+_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) {
_cx_result _res = _cx_memb(_insert_entry_)(self, rkey);
if (_res.inserted) {
- *cx_keyref(_res.ref) = i_keyfrom(rkey);
- cx_MAP_ONLY( _res.ref->second = i_valfrom(rmapped); )
+ *_i_keyref(_res.ref) = i_keyfrom(rkey);
+ _i_MAP_ONLY( _res.ref->second = i_valfrom(rmapped); )
}
return _res;
}
+#endif // !c_no_clone
+
+STC_INLINE _cx_rawvalue
+_cx_memb(_value_toraw)(_cx_value* val) {
+ return _i_SET_ONLY( i_keyto(val) )
+ _i_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} );
+}
+
+STC_INLINE void
+_cx_memb(_value_del)(_cx_value* _val) {
+ i_keydel(_i_keyref(_val));
+ _i_MAP_ONLY( i_valdel(&_val->second); )
+}
STC_INLINE _cx_result
-_cx_memb(_insert)(_cx_self* self, i_key _key cx_MAP_ONLY(, i_val _mapped)) {
+_cx_memb(_insert)(_cx_self* self, i_key _key _i_MAP_ONLY(, i_val _mapped)) {
_cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key));
- if (_res.inserted) { *cx_keyref(_res.ref) = _key; cx_MAP_ONLY( _res.ref->second = _mapped; )}
- else { i_keydel(&_key); cx_MAP_ONLY( i_valdel(&_mapped); )}
+ if (_res.inserted) { *_i_keyref(_res.ref) = _key; _i_MAP_ONLY( _res.ref->second = _mapped; )}
+ else { i_keydel(&_key); _i_MAP_ONLY( i_valdel(&_mapped); )}
return _res;
}
@@ -253,12 +264,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { memset(self->_hashx, 0, self->bucket_count);
}
-STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->table == other.table) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
-}
-
-cx_MAP_ONLY(
+#if !defined _i_isset
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));
@@ -266,7 +272,7 @@ cx_MAP_ONLY( else { i_keydel(&_key); i_valdel(&_res.ref->second); }
_res.ref->second = _mapped; return _res;
}
-
+ #if !c_option(c_no_clone)
STC_DEF _cx_result
_cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) {
_cx_result _res = _cx_memb(_insert_entry_)(self, rkey);
@@ -274,7 +280,8 @@ cx_MAP_ONLY( else i_valdel(&_res.ref->second);
_res.ref->second = i_valfrom(rmapped); return _res;
}
-)
+ #endif
+#endif
STC_DEF chash_bucket_t
_cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) {
@@ -284,7 +291,7 @@ _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) { const uint8_t* _hashx = self->_hashx;
while ((_hx = _hashx[b.idx])) {
if (_hx == b.hx) {
- _cx_rawkey _raw = i_keyto(cx_keyref(self->table + b.idx));
+ _cx_rawkey _raw = i_keyto(_i_keyref(self->table + b.idx));
if (i_equ(&_raw, rkeyptr)) break;
}
if (++b.idx == _cap) b.idx = 0;
@@ -305,6 +312,7 @@ _cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey) { return res;
}
+#if !c_option(c_no_clone)
STC_DEF _cx_self
_cx_memb(_clone)(_cx_self m) {
_cx_self clone = {
@@ -318,6 +326,7 @@ _cx_memb(_clone)(_cx_self m) { if (*hx) _cx_memb(_value_clone)(dst, e);
return clone;
}
+#endif
STC_DEF bool
_cx_memb(_reserve)(_cx_self* self, const size_t _newcap) {
@@ -337,7 +346,7 @@ _cx_memb(_reserve)(_cx_self* self, const size_t _newcap) { _cx_value* e = _tmp.table, *_slot = self->table;
uint8_t* _hashx = self->_hashx;
for (size_t i = 0; i < _oldbuckets; ++i, ++e) if (_tmp._hashx[i]) {
- _cx_rawkey _raw = i_keyto(cx_keyref(e));
+ _cx_rawkey _raw = i_keyto(_i_keyref(e));
chash_bucket_t b = _cx_memb(_bucket_)(self, &_raw);
_slot[b.idx] = *e;
_hashx[b.idx] = (uint8_t) b.hx;
@@ -359,7 +368,7 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { if (++j == _cap) j = 0;
if (! _hashx[j])
break;
- _cx_rawkey _raw = i_keyto(cx_keyref(_slot + j));
+ _cx_rawkey _raw = i_keyto(_i_keyref(_slot + j));
k = c_PASTE(fastrange_,MAP_SIZE_T)(i_hash(&_raw, sizeof _raw), _cap);
if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */
_slot[i] = _slot[j], _hashx[i] = _hashx[j], i = j;
@@ -369,9 +378,9 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { }
#endif // TEMPLATED IMPLEMENTATION
-#undef i_isset
-#undef cx_keyref
-#undef cx_MAP_ONLY
-#undef cx_SET_ONLY
+#undef _i_isset
+#undef _i_keyref
+#undef _i_MAP_ONLY
+#undef _i_SET_ONLY
#include "template.h"
#define CMAP_H_INCLUDED
|
