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(). --- include/stc/csptr.h | 28 +++++++++++++++++++++++----- include/stc/csview.h | 4 ++-- 2 files changed, 25 insertions(+), 7 deletions(-) (limited to 'include') 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