diff options
| author | Tyge Løvset <[email protected]> | 2021-06-07 20:49:19 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-06-07 20:49:19 +0200 |
| commit | 28596b49a281d69ce2e28e0c5d7cec9620e0dc80 (patch) | |
| tree | 9a351d2d3969e5fd9f5dbad4507fa1be359ce5c6 | |
| parent | 4569cf7843c510615542afe8bce237be53d79a9f (diff) | |
| download | STC-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().
| -rw-r--r-- | docs/csptr_api.md | 15 | ||||
| -rw-r--r-- | include/stc/csptr.h | 28 | ||||
| -rw-r--r-- | 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); \
} \
} \
\
@@ -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); \
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)
|
