summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-05-24 21:12:56 +0200
committerTyge Løvset <[email protected]>2022-05-24 21:12:56 +0200
commitebc7316ac3859bc5e2f01c85bee86d6adea45898 (patch)
treefb653c49e223cca40aea3fc2d734cd69b608b46d /include
parent966100106830f990bc3e1b40a5b5c39b64d5e9b0 (diff)
downloadSTC-modified-ebc7316ac3859bc5e2f01c85bee86d6adea45898.tar.gz
STC-modified-ebc7316ac3859bc5e2f01c85bee86d6adea45898.zip
API change: cbits now uses container pointers args in all member functions, except clone() ... for now. All containers may get same treatment! which will be a rather big API change. This was needed after testing fixed size cbits performance with pass-by-value: was very slow for large bitsets: now faster than std::bitset<>. Also reverted previous cbits_set_value(): much faster because it is branchless.
Diffstat (limited to 'include')
-rw-r--r--include/stc/cbits.h89
-rw-r--r--include/stc/ccommon.h6
2 files changed, 49 insertions, 46 deletions
diff --git a/include/stc/cbits.h b/include/stc/cbits.h
index 3dc78b7d..9eb52cf6 100644
--- a/include/stc/cbits.h
+++ b/include/stc/cbits.h
@@ -34,8 +34,8 @@ int main() {
cbits_reset(&bset, 9);
cbits_resize(&bset, 43, false);
- printf("%4zu: ", cbits_size(bset));
- c_forrange (i, cbits_size(bset))
+ printf("%4zu: ", cbits_size(&bset));
+ c_forrange (i, cbits_size(&bset))
printf("%d", cbits_at(&bset, i));
puts("");
cbits_set(&bset, 28);
@@ -44,8 +44,8 @@ int main() {
cbits_resize(&bset, 102, true);
cbits_set_value(&bset, 99, false);
- printf("%4zu: ", cbits_size(bset));
- c_forrange (i, cbits_size(bset))
+ printf("%4zu: ", cbits_size(&bset));
+ c_forrange (i, cbits_size(&bset))
printf("%d", cbits_at(&bset, i));
puts("");
}
@@ -73,7 +73,7 @@ int main() {
#if !defined i_len
STC_API void cbits_resize(i_type* self, size_t size, bool value);
-STC_API i_type* cbits_copy(i_type* self, i_type other);
+STC_API i_type* cbits_copy(i_type* self, const i_type* other);
#endif
STC_API bool _cbits_subset_of(const uint64_t* set, const uint64_t* other, size_t sz);
STC_API bool _cbits_disjoint(const uint64_t* set, const uint64_t* other, size_t sz);
@@ -81,13 +81,13 @@ STC_API size_t _cbits_count(const uint64_t* set, const size_t sz);
STC_API char* _cbits_to_str(const uint64_t* set, const size_t sz,
char* out, size_t start, intptr_t stop);
-STC_INLINE size_t _i_memb(_size)(i_type set);
+STC_INLINE size_t _i_memb(_size)(const i_type* self);
STC_INLINE void _i_memb(_set_all)(i_type *self, const bool value)
- { memset(self->data64, value? ~0 : 0, _cbits_bytes(_i_memb(_size)(*self))); }
+ { memset(self->data64, value? ~0 : 0, _cbits_bytes(_i_memb(_size)(self))); }
STC_INLINE void _i_memb(_set_pattern)(i_type *self, const uint64_t pattern) {
- size_t n = _cbits_words(_i_memb(_size)(*self));
+ size_t n = _cbits_words(_i_memb(_size)(self));
while (n--) self->data64[n] = pattern;
}
@@ -96,7 +96,7 @@ STC_INLINE void _i_memb(_set_pattern)(i_type *self, const uint64_t pattern) {
#define _i_assert(x) (void)0
STC_INLINE i_type _i_memb(_init)(void) { return c_make(i_type){0}; }
STC_INLINE void _i_memb(_drop)(i_type* self) {}
-STC_INLINE size_t _i_memb(_size)(i_type set) { return i_len; }
+STC_INLINE size_t _i_memb(_size)(const i_type* self) { return i_len; }
STC_INLINE i_type _i_memb(_move)(i_type* self) { return *self; }
STC_INLINE i_type* _i_memb(_take)(i_type* self, i_type other)
@@ -125,7 +125,7 @@ STC_INLINE i_type _i_memb(_with_pattern)(const size_t size, const uint64_t patte
#define _i_assert(x) assert(x)
STC_INLINE i_type cbits_init(void) { return c_make(i_type){NULL}; }
STC_INLINE void cbits_drop(i_type* self) { c_free(self->data64); }
-STC_INLINE size_t cbits_size(i_type set) { return set._size; }
+STC_INLINE size_t cbits_size(const i_type* self) { return self->_size; }
STC_INLINE i_type cbits_move(i_type* self) {
i_type tmp = *self;
@@ -160,11 +160,11 @@ STC_INLINE i_type cbits_with_pattern(const size_t size, const uint64_t pattern)
}
#endif
-STC_INLINE bool _i_memb(_test)(i_type set, const size_t i)
- { return (set.data64[i>>6] & _cbits_bit(i)) != 0; }
+STC_INLINE bool _i_memb(_test)(const i_type* self, const size_t i)
+ { return (self->data64[i>>6] & _cbits_bit(i)) != 0; }
-STC_INLINE bool _i_memb(_at)(i_type set, const size_t i)
- { return (set.data64[i>>6] & _cbits_bit(i)) != 0; }
+STC_INLINE bool _i_memb(_at)(const i_type* self, const size_t i)
+ { return (self->data64[i>>6] & _cbits_bit(i)) != 0; }
STC_INLINE void _i_memb(_set)(i_type *self, const size_t i)
{ self->data64[i>>6] |= _cbits_bit(i); }
@@ -172,14 +172,15 @@ STC_INLINE void _i_memb(_set)(i_type *self, const size_t i)
STC_INLINE void _i_memb(_reset)(i_type *self, const size_t i)
{ self->data64[i>>6] &= ~_cbits_bit(i); }
-STC_INLINE void _i_memb(_set_value)(i_type *self, const size_t i, const bool value)
- { value ? _i_memb(_set)(self, i) : _i_memb(_reset)(self, i); }
+STC_INLINE void _i_memb(_set_value)(i_type *self, const size_t i, const bool b) {
+ self->data64[i>>6] ^= ((uint64_t)-(int)b ^ self->data64[i>>6]) & _cbits_bit(i);
+}
STC_INLINE void _i_memb(_flip)(i_type *self, const size_t i)
{ self->data64[i>>6] ^= _cbits_bit(i); }
STC_INLINE void _i_memb(_flip_all)(i_type *self) {
- size_t n = _cbits_words(_i_memb(_size)(*self));
+ size_t n = _cbits_words(_i_memb(_size)(self));
while (n--) self->data64[n] ^= ~(uint64_t)0;
}
@@ -191,22 +192,22 @@ STC_INLINE i_type _i_memb(_from)(const char* str) {
}
/* Intersection */
-STC_INLINE void _i_memb(_intersect)(i_type *self, i_type other) {
- _i_assert(self->_size == other._size);
- size_t n = _cbits_words(_i_memb(_size)(*self));
- while (n--) self->data64[n] &= other.data64[n];
+STC_INLINE void _i_memb(_intersect)(i_type *self, const i_type* other) {
+ _i_assert(self->_size == other->_size);
+ size_t n = _cbits_words(_i_memb(_size)(self));
+ while (n--) self->data64[n] &= other->data64[n];
}
/* Union */
-STC_INLINE void _i_memb(_union)(i_type *self, i_type other) {
- _i_assert(self->_size == other._size);
- size_t n = _cbits_words(_i_memb(_size)(*self));
- while (n--) self->data64[n] |= other.data64[n];
+STC_INLINE void _i_memb(_union)(i_type *self, const i_type* other) {
+ _i_assert(self->_size == other->_size);
+ size_t n = _cbits_words(_i_memb(_size)(self));
+ while (n--) self->data64[n] |= other->data64[n];
}
/* Exclusive disjunction */
-STC_INLINE void _i_memb(_xor)(i_type *self, i_type other) {
- _i_assert(self->_size == other._size);
- size_t n = _cbits_words(_i_memb(_size)(*self));
- while (n--) self->data64[n] ^= other.data64[n];
+STC_INLINE void _i_memb(_xor)(i_type *self, const i_type* other) {
+ _i_assert(self->_size == other->_size);
+ size_t n = _cbits_words(_i_memb(_size)(self));
+ while (n--) self->data64[n] ^= other->data64[n];
}
#if defined(__GNUC__) || defined(__clang__)
@@ -223,31 +224,31 @@ STC_INLINE void _i_memb(_xor)(i_type *self, i_type other) {
}
#endif
-STC_INLINE size_t _i_memb(_count)(i_type set)
- { return _cbits_count(set.data64, _i_memb(_size)(set)); }
+STC_INLINE size_t _i_memb(_count)(const i_type* self)
+ { return _cbits_count(self->data64, _i_memb(_size)(self)); }
-STC_INLINE char* _i_memb(_to_str)(i_type set, char* out, size_t start, intptr_t stop)
- { return _cbits_to_str(set.data64, _i_memb(_size)(set), out, start, stop); }
+STC_INLINE char* _i_memb(_to_str)(const i_type* self, char* out, size_t start, intptr_t stop)
+ { return _cbits_to_str(self->data64, _i_memb(_size)(self), out, start, stop); }
-STC_INLINE bool _i_memb(_subset_of)(i_type set, i_type other) {
- _i_assert(set._size == other._size);
- return _cbits_subset_of(set.data64, other.data64, _i_memb(_size)(set));
+STC_INLINE bool _i_memb(_subset_of)(const i_type* self, const i_type* other) {
+ _i_assert(self->_size == other->_size);
+ return _cbits_subset_of(self->data64, other->data64, _i_memb(_size)(self));
}
-STC_INLINE bool _i_memb(_disjoint)(i_type set, i_type other) {
- _i_assert(set._size == other._size);
- return _cbits_disjoint(set.data64, other.data64, _i_memb(_size)(set));
+STC_INLINE bool _i_memb(_disjoint)(const i_type* self, const i_type* other) {
+ _i_assert(self->_size == other->_size);
+ return _cbits_disjoint(self->data64, other->data64, _i_memb(_size)(self));
}
#if defined(i_implement)
#if !defined i_len
-STC_DEF i_type* cbits_copy(i_type* self, i_type other) {
- if (self->data64 == other.data64)
+STC_DEF i_type* cbits_copy(i_type* self, const i_type* other) {
+ if (self->data64 == other->data64)
return self;
- if (self->_size != other._size)
- return _i_memb(_take)(self, _i_memb(_clone)(other));
- memcpy(self->data64, other.data64, _cbits_bytes(other._size));
+ if (self->_size != other->_size)
+ return _i_memb(_take)(self, _i_memb(_clone)(*other));
+ memcpy(self->data64, other->data64, _cbits_bytes(other->_size));
return self;
}
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index ffdd0215..a0fa58fb 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -108,6 +108,7 @@
#define c_no_cmp (1<<3)
#define c_static (1<<4)
#define c_header (1<<5)
+#define c_implement (1<<6)
/* Generic algorithms */
@@ -254,7 +255,7 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
#undef _i_static
#undef i_implement
-#if !c_option(c_static) && (c_option(c_header) || defined(STC_HEADER) || \
+#if !c_option(c_static) && (c_option(c_header|c_implement) || defined(STC_HEADER) || \
defined(STC_IMPLEMENT) || defined(STC_IMPLEMENTATION))
# define STC_API extern
# define STC_DEF
@@ -263,6 +264,7 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
# define STC_API static inline
# define STC_DEF static inline
#endif
-#if defined(_i_static) || defined(STC_IMPLEMENT) || defined(STC_IMPLEMENTATION)
+#if defined(_i_static) || c_option(c_implement) || defined(STC_IMPLEMENT) \
+ || defined(STC_IMPLEMENTATION)
# define i_implement
#endif