summaryrefslogtreecommitdiffhomepage
path: root/include/stc/csptr.h
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-06-07 20:49:19 +0200
committerTyge Løvset <[email protected]>2021-06-07 20:49:19 +0200
commit28596b49a281d69ce2e28e0c5d7cec9620e0dc80 (patch)
tree9a351d2d3969e5fd9f5dbad4507fa1be359ce5c6 /include/stc/csptr.h
parent4569cf7843c510615542afe8bce237be53d79a9f (diff)
downloadSTC-modified-28596b49a281d69ce2e28e0c5d7cec9620e0dc80.tar.gz
STC-modified-28596b49a281d69ce2e28e0c5d7cec9620e0dc80.zip
Improved csptr: cstr_make() as fast as std::shared_ptr::make_shared (single malloc). Added assign(), copy().
Diffstat (limited to 'include/stc/csptr.h')
-rw-r--r--include/stc/csptr.h28
1 files changed, 23 insertions, 5 deletions
diff --git a/include/stc/csptr.h b/include/stc/csptr.h
index 6e682360..76057b5b 100644
--- a/include/stc/csptr.h
+++ b/include/stc/csptr.h
@@ -82,8 +82,10 @@ typedef long atomic_count_t;
}
#endif
+#define forward_csptr(X, Value) _csptr_types(csptr_##X, Value)
#define csptr_null {NULL, NULL}
+
#define using_csptr(...) c_MACRO_OVERLOAD(using_csptr, __VA_ARGS__)
#define using_csptr_2(X, Value) \
@@ -95,8 +97,6 @@ typedef long atomic_count_t;
#define using_csptr_5(X, Value, valueCompare, valueDel, defineTypes) \
_c_using_csptr(csptr_##X, Value, valueCompare, valueDel, defineTypes)
-#define forward_csptr(X, Value) _csptr_types(csptr_##X, Value)
-
#define _csptr_types(CX, Value) \
typedef Value CX##_value_t; \
\
@@ -107,6 +107,7 @@ typedef long atomic_count_t;
#define _c_using_csptr(CX, Value, valueCompare, valueDel, defineTypes) \
defineTypes( _csptr_types(CX, Value); ) \
+ struct CX##_rep_ {atomic_count_t cnt; CX##_value_t val;}; \
\
STC_INLINE CX \
CX##_from(CX##_value_t* p) { \
@@ -117,8 +118,10 @@ typedef long atomic_count_t;
\
STC_INLINE CX \
CX##_make(CX##_value_t val) { \
- CX ptr = {c_new(CX##_value_t), c_new(atomic_count_t)}; \
- *ptr.get = val, *ptr.use_count = 1; return ptr; \
+ CX ptr; struct CX##_rep_ *rep = c_new(struct CX##_rep_); \
+ *(ptr.use_count = &rep->cnt) = 1; \
+ *(ptr.get = &rep->val) = val; \
+ return ptr; \
} \
\
STC_INLINE CX \
@@ -138,8 +141,8 @@ typedef long atomic_count_t;
CX##_del(CX* self) { \
if (self->use_count && atomic_decrement(self->use_count) == 0) { \
valueDel(self->get); \
+ if (self->get != &((struct CX##_rep_*)self->use_count)->val) c_free(self->get); \
c_free(self->use_count); \
- c_free(self->get); \
} \
} \
\
@@ -156,6 +159,21 @@ typedef long atomic_count_t;
return self->get; \
} \
\
+ STC_INLINE CX##_value_t* \
+ CX##_assign(CX* self, CX##_value_t val) { \
+ CX##_del(self); \
+ *self = CX##_make(val); \
+ return self->get; \
+ } \
+\
+ STC_INLINE CX##_value_t* \
+ CX##_copy(CX* self, CX ptr) { \
+ CX##_del(self); \
+ if (ptr.use_count) atomic_increment(ptr.use_count); \
+ *self = ptr; \
+ return self->get; \
+ } \
+\
STC_INLINE int \
CX##_compare(CX* x, CX* y) { \
return valueCompare(x->get, y->get); \