summaryrefslogtreecommitdiffhomepage
path: root/include/stc/carc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/stc/carc.h')
-rw-r--r--include/stc/carc.h147
1 files changed, 78 insertions, 69 deletions
diff --git a/include/stc/carc.h b/include/stc/carc.h
index 8ef80b12..b617e1ca 100644
--- a/include/stc/carc.h
+++ b/include/stc/carc.h
@@ -22,6 +22,7 @@
*/
/* carc: atomic reference counted shared_ptr
+#define i_implement
#include <stc/cstr.h>
typedef struct { cstr name, last; } Person;
@@ -29,6 +30,11 @@ typedef struct { cstr name, last; } Person;
Person Person_make(const char* name, const char* last) {
return (Person){.name = cstr_from(name), .last = cstr_from(last)};
}
+Person Person_clone(Person p) {
+ p.name = cstr_clone(p.name);
+ p.last = cstr_clone(p.last);
+ return p;
+}
void Person_drop(Person* p) {
printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last));
cstr_drop(&p->name);
@@ -36,11 +42,10 @@ void Person_drop(Person* p) {
}
#define i_type ArcPers
-#define i_key Person
-#define i_keydrop Person_drop
+#define i_valclass Person // clone, drop, cmp, hash
#include <stc/carc.h>
-int main() {
+int main(void) {
ArcPers p = ArcPers_from(Person_make("John", "Smiths"));
ArcPers q = ArcPers_clone(p); // share the pointer
@@ -48,10 +53,11 @@ int main() {
c_drop(ArcPers, &p, &q);
}
*/
-#include "ccommon.h"
+#include "priv/linkage.h"
#ifndef CARC_H_INCLUDED
#define CARC_H_INCLUDED
+#include "ccommon.h"
#include "forward.h"
#include <stdlib.h>
@@ -71,19 +77,18 @@ int main() {
#define c_atomic_dec_and_test(v) (atomic_fetch_sub(v, 1) == 1)
#endif
-#define carc_NULL {NULL, NULL}
+#define carc_null {0}
#endif // CARC_H_INCLUDED
-#ifndef _i_prefix
#define _i_prefix carc_
-#endif
-#ifdef i_eq
-#define _i_eq
-#endif
+#define _i_carc
#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
@@ -91,123 +96,127 @@ typedef i_keyraw _cx_raw;
#define _i_atomic_dec_and_test(v) !(--*(v))
#endif
#ifndef i_is_forward
-_cx_deftypes(_c_carc_types, _cx_self, i_key);
+_cx_DEFTYPES(_c_carc_types, _cx_Self, i_key);
#endif
-struct _cx_memb(_rep_) { catomic_long counter; i_key value; };
+struct _cx_MEMB(_rep_) { catomic_long counter; i_key value; };
-STC_INLINE _cx_self _cx_memb(_init)(void)
- { return c_LITERAL(_cx_self){NULL, NULL}; }
+STC_INLINE _cx_Self _cx_MEMB(_init)(void)
+ { return c_LITERAL(_cx_Self){NULL, NULL}; }
-STC_INLINE long _cx_memb(_use_count)(const _cx_self* self)
+STC_INLINE long _cx_MEMB(_use_count)(const _cx_Self* self)
{ return self->use_count ? *self->use_count : 0; }
-STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) {
- _cx_self ptr = {p};
+STC_INLINE _cx_Self _cx_MEMB(_from_ptr)(_cx_value* p) {
+ _cx_Self ptr = {p};
if (p)
*(ptr.use_count = _i_alloc(catomic_long)) = 1;
return ptr;
}
// c++: std::make_shared<_cx_value>(val)
-STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) {
- _cx_self ptr;
- struct _cx_memb(_rep_)* rep = _i_alloc(struct _cx_memb(_rep_));
+STC_INLINE _cx_Self _cx_MEMB(_make)(_cx_value val) {
+ _cx_Self ptr;
+ struct _cx_MEMB(_rep_)* rep = _i_alloc(struct _cx_MEMB(_rep_));
*(ptr.use_count = &rep->counter) = 1;
*(ptr.get = &rep->value) = val;
return ptr;
}
-STC_INLINE _cx_raw _cx_memb(_toraw)(const _cx_self* self)
+STC_INLINE _cx_raw _cx_MEMB(_toraw)(const _cx_Self* self)
{ return i_keyto(self->get); }
-STC_INLINE _cx_self _cx_memb(_move)(_cx_self* self) {
- _cx_self ptr = *self;
+STC_INLINE _cx_Self _cx_MEMB(_move)(_cx_Self* self) {
+ _cx_Self ptr = *self;
self->get = NULL, self->use_count = NULL;
return ptr;
}
-STC_INLINE void _cx_memb(_drop)(_cx_self* self) {
+STC_INLINE void _cx_MEMB(_drop)(_cx_Self* self) {
if (self->use_count && _i_atomic_dec_and_test(self->use_count)) {
i_keydrop(self->get);
- if ((char *)self->get != (char *)self->use_count + offsetof(struct _cx_memb(_rep_), value))
+ if ((char *)self->get != (char *)self->use_count + offsetof(struct _cx_MEMB(_rep_), value))
i_free(self->get);
i_free((long*)self->use_count);
}
}
-STC_INLINE void _cx_memb(_reset)(_cx_self* self) {
- _cx_memb(_drop)(self);
+STC_INLINE void _cx_MEMB(_reset)(_cx_Self* self) {
+ _cx_MEMB(_drop)(self);
self->use_count = NULL, self->get = NULL;
}
-STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) {
- _cx_memb(_drop)(self);
- *self = _cx_memb(_from_ptr)(p);
+STC_INLINE void _cx_MEMB(_reset_to)(_cx_Self* self, _cx_value* p) {
+ _cx_MEMB(_drop)(self);
+ *self = _cx_MEMB(_from_ptr)(p);
}
#ifndef i_no_emplace
-STC_INLINE _cx_self _cx_memb(_from)(_cx_raw raw)
- { return _cx_memb(_make)(i_keyfrom(raw)); }
+STC_INLINE _cx_Self _cx_MEMB(_from)(_cx_raw raw)
+ { return _cx_MEMB(_make)(i_keyfrom(raw)); }
#else
-STC_INLINE _cx_self _cx_memb(_from)(_cx_value val)
- { return _cx_memb(_make)(val); }
+STC_INLINE _cx_Self _cx_MEMB(_from)(_cx_value val)
+ { return _cx_MEMB(_make)(val); }
#endif
// does not use i_keyclone, so OK to always define.
-STC_INLINE _cx_self _cx_memb(_clone)(_cx_self ptr) {
+STC_INLINE _cx_Self _cx_MEMB(_clone)(_cx_Self ptr) {
if (ptr.use_count)
_i_atomic_inc(ptr.use_count);
return ptr;
}
// take ownership of unowned
-STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self unowned) {
- _cx_memb(_drop)(self);
+STC_INLINE void _cx_MEMB(_take)(_cx_Self* self, _cx_Self unowned) {
+ _cx_MEMB(_drop)(self);
*self = unowned;
}
// share ownership with ptr
-STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self ptr) {
+STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self ptr) {
if (ptr.use_count)
_i_atomic_inc(ptr.use_count);
- _cx_memb(_drop)(self);
+ _cx_MEMB(_drop)(self);
*self = ptr;
}
-#ifndef i_no_cmp
-STC_INLINE int _cx_memb(_raw_cmp)(const _cx_raw* rx, const _cx_raw* ry)
- { return i_cmp(rx, ry); }
+#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));
-}
-#endif
+ 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));
+ }
-#ifdef _i_eq
-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(_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));
-}
-#elif !defined i_no_cmp
-STC_INLINE bool _cx_memb(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry)
- { return i_cmp(rx, ry) == 0; }
+ 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));
+ }
-STC_INLINE bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other)
- { return _cx_memb(_cmp)(self, other) == 0; }
-#endif
+ #ifndef i_no_hash
+ STC_INLINE uint64_t _cx_MEMB(_raw_hash)(const _cx_raw* rx)
+ { return i_hash(rx); }
-#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
-STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* self)
- { _cx_raw rx = i_keyto(self->get); return i_hash((&rx)); }
-#endif
+#else
-#undef _i_eq
+ 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_no_atomic
#undef _i_atomic_inc
#undef _i_atomic_dec_and_test
-#include "priv/template2.h"
+#undef _i_carc