From 28596b49a281d69ce2e28e0c5d7cec9620e0dc80 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 7 Jun 2021 20:49:19 +0200 Subject: Improved csptr: cstr_make() as fast as std::shared_ptr::make_shared (single malloc). Added assign(), copy(). --- docs/csptr_api.md | 15 +++++++++------ include/stc/csptr.h | 28 +++++++++++++++++++++++----- include/stc/csview.h | 4 ++-- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/docs/csptr_api.md b/docs/csptr_api.md index 0acc8b21..6665b23b 100644 --- a/docs/csptr_api.md +++ b/docs/csptr_api.md @@ -36,14 +36,17 @@ Use *csptr_X_clone(p)* when sharing ownership of the pointed-to object. See exam The *csptr_X_compare()*, *csptr_X_equals()* and *csptr_X_del()* methods are defined based on the *valeCompare* and *valueDel* arguments passed to the **using**-macro. ```c -csptr_X csptr_X_from(csptr_X_value_t* ptr); // constructor -csptr_X csptr_X_make(csptr_X_value_t val); // make_shared +csptr_X csptr_X_from(Value* p); // constructor +csptr_X csptr_X_make(Value val); // make_shared void csptr_X_reset(csptr_X* self); -void csptr_X_reset_with(csptr_X* self, csptr_X_value_t* ptr); +void csptr_X_reset_with(csptr_X* self, Value* p); -csptr_X csptr_X_clone(csptr_X sptr); // share the pointer (increase use count) -void csptr_X_move(csptr_X* self); // transfer ownership instead of sharing. -void csptr_X_del(csptr_X* self); // destructor: decrease use count, destroy at 0 +csptr_X_value_t* csptr_X_assign(csptr_X* self, Value val); // assign new sptr with value +csptr_X_value_t* csptr_X_copy(csptr_X* self, csptr_X ptr); // assign a shared copy + +csptr_X csptr_X_clone(csptr_X ptr); // share the pointer (increase use count) +void csptr_X_move(csptr_X* self); // transfer ownership instead of sharing. +void csptr_X_del(csptr_X* self); // destructor: decrease use count, destroy at 0 int csptr_X_compare(csptr_X* x, csptr_X* y); bool csptr_X_equals(csptr_X* x, csptr_X* y); 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); \ } \ } \ \ @@ -155,6 +158,21 @@ typedef long atomic_count_t; *self = CX##_from(p); \ 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) { \ diff --git a/include/stc/csview.h b/include/stc/csview.h index f9bc11ca..3d517535 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -105,9 +105,9 @@ STC_INLINE cstr cstr_from_v(csview sv) STC_INLINE csview cstr_to_v(const cstr* self) { return c_make(csview){self->str, _cstr_rep(self)->size}; } STC_INLINE csview cstr_substr(cstr s, intptr_t pos, size_t n) - { return csview_substr(csview_from_s(s), pos, n); }; + { return csview_substr(csview_from_s(s), pos, n); } STC_INLINE csview cstr_slice(cstr s, intptr_t p1, intptr_t p2) - { return csview_slice(csview_from_s(s), p1, p2); }; + { return csview_slice(csview_from_s(s), p1, p2); } STC_INLINE cstr* cstr_assign_v(cstr* self, csview sv) { return cstr_assign_n(self, sv.str, sv.size); } STC_INLINE cstr* cstr_append_v(cstr* self, csview sv) -- cgit v1.2.3