summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-03-30 16:44:07 +0200
committerTyge Løvset <[email protected]>2021-03-30 16:44:07 +0200
commit48eb33996632d99f917e7c4432c2891b5bf29c54 (patch)
tree5ef8967d46bc5fb123423f5fbcb6607f198cd3e5
parent4a06fde5c006b609f910474949b9e097ec8479c8 (diff)
downloadSTC-modified-48eb33996632d99f917e7c4432c2891b5bf29c54.tar.gz
STC-modified-48eb33996632d99f917e7c4432c2891b5bf29c54.zip
Removed the cptr raw pointer. Only keep csptr: shared_ptr. Renamed cptr.h to csptr.h.
-rw-r--r--README.md4
-rw-r--r--docs/cptr_api.md256
-rw-r--r--docs/csptr_api.md190
-rw-r--r--examples/prime.c12
-rw-r--r--stc/csptr.h (renamed from stc/cptr.h)92
5 files changed, 213 insertions, 341 deletions
diff --git a/README.md b/README.md
index 35d46238..d27771d7 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ It is a compact, header-only library with the all the major "standard" data cont
- [***clist*** - **std::forward_list** alike type](docs/clist_api.md)
- [***cmap*** - **std::unordered_map** alike type](docs/cmap_api.md)
- [***cpque*** - **std::priority_queue** alike (adapter) type](docs/cpque_api.md)
-- [***cptr*** - **std::shared_ptr** alike support](docs/cptr_api.md)
+- [***csptr*** - **std::shared_ptr** alike support](docs/csptr_api.md)
- [***cqueue*** - **std::queue** alike (adapter) type](docs/cqueue_api.md)
- [***cset*** - **std::unordered_set** alike type](docs/cset_api.md)
- [***csmap*** - **std::map** sorted map alike type](docs/csmap_api.md)
@@ -32,7 +32,7 @@ Highlights
----------
- **User friendly** - Just include the headers and you are good. The API and functionality is very close to c++ STL, and is fully listed in the docs. The ***using***-declaration instantiates the container type to use. You may pass *optional* arguments to it for customization of element- *comparison*, *destruction*, *cloning*, *conversion types*, and more.
- **Unparalleled performance** - The containers are about equal and often much faster than the c++ STL containers.
-- **Fully memory managed** - All containers will destruct keys/values via destructor passed as macro parameters to the ***using***-declaration. Also, smart-pointers are supported and can be stored in containers, see ***csptr***.
+- **Fully memory managed** - All containers will destruct keys/values via destructor passed as macro parameters to the ***using***-declaration. Also, shared pointers are supported and can be stored in containers, see ***csptr***.
- **Fully type safe** - Because of templating, it avoids error-prone casting of container types and elements back and forth from the containers.
- **Uniform, easy-to-learn API** - Methods to ***construct***, ***initialize***, ***iterate*** and ***destruct*** have uniform and intuitive usage across the various containers.
- **Small footprint** - Small source code and generated executables. The executable from the example below using six different containers is *27 kb in size* compiled with TinyC.
diff --git a/docs/cptr_api.md b/docs/cptr_api.md
deleted file mode 100644
index 3583bc62..00000000
--- a/docs/cptr_api.md
+++ /dev/null
@@ -1,256 +0,0 @@
-# STC [cptr](../stc/cptr.h): Smart Pointers
-
-**cptr** (managed raw pointer) and **csptr** (shared pointer) enables memory managed pointers in containers.
-
-The pointed-to elements are automatically destructed and deleted when the container is destructed. **csptr** elements are only deleted if there are no other shared references to the element. **csptr** uses thread-safe atomic use-count, through the *csptr_X_clone()* and *csptr_X_del()* methods.
-
- See the c++ classes [std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr) for a functional reference.
-
-## Header file and declaration
-
-```c
-#include <stc/cptr.h>
-
-using_cptr(X, Value);
-using_cptr(X, Value, valueCompare);
-using_cptr(X, Value, valueCompare, valueDel);
-
-using_csptr(X, Value);
-using_csptr(X, Value, valueCompare);
-using_csptr(X, Value, valueCompare, valueDel);
-```
-The macro `using_cptr()` must be instantiated in the global scope. `X` is a type tag name and will
-affect the names of all cptr types and methods. E.g. declaring `using_cptr(v4, Vec4);`,
-`X` should be replaced by `v4` in all of the following documentation.
-
-## Methods
-
-The *del()* and *compare()* methods are defined based on the arguments passed to the **using**-macro. For **csptr**, use *csptr_X_clone(p)* when sharing ownership of the pointed-to object. See examples below.
-
-### Managed raw pointer
-```c
-cptr_X cptr_X_init(void);
-cptr_X cptr_X_clone(cptr_X ptr);
-void cptr_X_reset(cptr_X* self, cptr_X_value_t* ptr);
-void cptr_X_del(cptr_X* self); // destructor
-int cptr_X_compare(cptr_X* x, cptr_X* y);
-```
-### Shared pointer
-```c
-csptr_X csptr_X_from(csptr_X_value_t* ptr);
-csptr_X csptr_X_make(csptr_X_value_t val);
-void csptr_X_reset(csptr_X* self, csptr_X_value_t* ptr);
-csptr_X csptr_X_clone(csptr_X sptr); // share the pointer (increase use count)
-void csptr_X_del(csptr_X* self); // destructor: decrease use count, destroy if 0
-int csptr_X_compare(csptr_X* x, csptr_X* y);
-```
-
-## Types
-
-| Type name | Type definition | Used to represent... |
-|:-------------------|:----------------------|:------------------------|
-| `cptr_X` | `cptr_X_value_t *` | The cptr type |
-| `cptr_X_value_t` | `Value` | The cptr element type |
-
-
-| Type name | Type definition | Used to represent... |
-|:--------------------|:--------------------------------------------------------------|:-------------------------|
-| `csptr_X` | `struct { csptr_X_value_t* get; atomic_count_t* use_count; }` | The csptr type |
-| `csptr_X_value_t` | `Value` | The csptr element type |
-| `atomic_count_t` | `long` | The reference counter |
-
-## Example
-
-Managed raw pointers (cptr) in a cvec.
-```c
-#include <stc/cptr.h>
-#include <stc/cvec.h>
-#include <stc/cstr.h>
-
-typedef struct { cstr name, last; } Person;
-
-Person* Person_make(Person* p, const char* name, const char* last) {
- p->name = cstr_from(name), p->last = cstr_from(last);
- return p;
-}
-void Person_del(Person* p) {
- printf("Destroy: %s %s\n", p->name.str, p->last.str);
- c_del(cstr, &p->name, &p->last);
-}
-// declare managed pointer and cvec with pointers
-using_cptr(pe, Person, c_no_compare, Person_del);
-using_cvec(pe, Person*, c_no_compare, cptr_pe_del, c_no_clone);
-
-int main() {
- cvec_pe vec = cvec_pe_init();
- cvec_pe_push_back(&vec, Person_make(c_new(Person), "John", "Smiths"));
- cvec_pe_push_back(&vec, Person_make(c_new(Person), "Jane", "Doe"));
-
- c_foreach (i, cvec_pe, vec)
- printf("%s %s\n", (*i.ref)->name.str, (*i.ref)->last.str);
- cvec_pe_del(&vec);
-}
-```
-Output:
-```
-John Smiths
-Jane Doe
-Destroy: John Smiths
-Destroy: Jane Doe
-```
-### Example 2
-
-Simple shared pointer (csptr) usage.
-```c
-#include <stc/cptr.h>
-#include <stc/cstr.h>
-
-typedef struct { cstr name, last; } Person;
-
-Person* Person_make(Person* p, const char* name, const char* last) {
- p->name = cstr_from(name), p->last = cstr_from(last);
- return p;
-}
-void Person_del(Person* p) {
- printf("Destroy: %s %s\n", p->name.str, p->last.str);
- c_del(cstr, &p->name, &p->last);
-}
-
-using_csptr(pe, Person, c_no_compare, Person_del);
-
-int main() {
- csptr_pe p = csptr_pe_from(Person_make(c_new(Person), "John", "Smiths"));
- csptr_pe q = csptr_pe_clone(p); // means: share the pointer
-
- printf("Person: %s %s. uses: %zu\n", p.get->name.str, p.get->last.str, *p.use_count);
- csptr_pe_del(&p);
-
- printf("Last man standing: %s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count);
- csptr_pe_del(&q);
-}
-```
-Output:
-```
-Person: John Smiths. uses: 2
-Last man standing: John Smiths. uses: 1
-Destroy: John Smiths
-```
-
-### Example 3
-
-Advanced: Three different ways to store Person in vectors: 1) `cvec<Person>`, 2) `cvec<Person *>`, and 3) `cvec<csptr<Person>>`.
-```c
-#include <stc/cptr.h>
-#include <stc/cstr.h>
-#include <stc/cvec.h>
-
-typedef struct { cstr name, last; } Person;
-
-Person* Person_make(Person* p, const char* name, const char* last) {
- p->name = cstr_from(name), p->last = cstr_from(last);
- return p;
-}
-int Person_compare(const Person* p, const Person* q) {
- int cmp = strcmp(p->name.str, q->name.str);
- return cmp == 0 ? strcmp(p->last.str, q->last.str) : cmp;
-}
-void Person_del(Person* p) {
- printf("del: %s\n", p->name.str);
- c_del(cstr, &p->name, &p->last);
-}
-
-// 1. cvec of Person struct; emplace and cloning disabled.
-using_cvec(pe, Person, Person_compare, Person_del, c_no_clone);
-
-// 2. cvec of raw/owned pointers to Person; emplace and cloning disabled.
-using_cptr(pe, Person, Person_compare, Person_del);
-using_cvec(pp, Person*, cptr_pe_compare, cptr_pe_del, c_no_clone);
-
-// 3. cvec of shared-ptr to Person - with emplace_back() and cloning cvec ENABLED.
-using_csptr(pe, Person, Person_compare, Person_del);
-using_cvec(ps, csptr_pe, csptr_pe_compare, csptr_pe_del, csptr_pe_clone);
-
-const char* names[] = {
- "Joe", "Jordan",
- "Annie", "Aniston",
- "Jane", "Jacobs"
-};
-
-int main() {
- cvec_pe vec1 = cvec_pe_init();
- cvec_pp vec2 = cvec_pp_init();
- cvec_ps vec3 = cvec_ps_init();
-
- for (int i = 0; i < 6; i += 2) {
- Person tmp;
- cvec_pe_push_back(&vec1, *Person_make(&tmp, names[i], names[i+1]));
- cvec_pp_push_back(&vec2, Person_make(c_new(Person), names[i], names[i+1]));
- cvec_ps_push_back(&vec3, csptr_pe_from(Person_make(c_new(Person), names[i], names[i+1])));
- }
- puts("1. Sorted vec1 of Person:");
- cvec_pe_sort(&vec1);
- c_foreach (i, cvec_pe, vec1)
- printf(" %s %s\n", i.ref->name.str, i.ref->last.str);
-
- puts("\n2. Sorted vec2 of pointer to Person:");
- cvec_pp_sort(&vec2);
- c_foreach (i, cvec_pp, vec2)
- printf(" %s %s\n", (*i.ref)->name.str, (*i.ref)->last.str);
-
- // Append a shared copy of vec3.data[0]. Will only be destructed once!
- cvec_ps_emplace_back(&vec3, vec3.data[0]);
- //cvec_ps_push_back(&vec3, csptr_pe_clone(vec3.data[0])); // alternativ
- puts("\n3. Sorted vec3 of shared-pointer to Person:");
- cvec_ps_sort(&vec3);
- c_foreach (i, cvec_ps, vec3)
- printf(" %s %s\n", i.ref->get->name.str, i.ref->get->last.str);
-
- // Share vec3.data[1] with elem1 variable.
- csptr_pe elem1 = csptr_pe_clone(vec3.data[1]);
-
- puts("\nDestroy vec1:");
- cvec_pe_del(&vec1);
- puts("\nDestroy vec2:");
- cvec_pp_del(&vec2);
- puts("\nDestroy vec3:");
- cvec_ps_del(&vec3);
-
- puts("\nDestroy elem1:");
- csptr_pe_del(&elem1);
-}
-```
-Output:
-```
-1. Sorted vec1 of Person:
- Annie Aniston
- Jane Jacobs
- Joe Jordan
-
-2. Sorted vec2 of pointer to Person:
- Annie Aniston
- Jane Jacobs
- Joe Jordan
-
-3. Sorted vec3 of shared-pointer to Person:
- Annie Aniston
- Jane Jacobs
- Joe Jordan
- Joe Jordan
-
-Destroy vec1:
-del: Annie
-del: Jane
-del: Joe
-
-Destroy vec2:
-del: Annie
-del: Jane
-del: Joe
-
-Destroy vec3:
-del: Annie
-del: Joe
-
-Destroy elem1:
-del: Jane
-```
diff --git a/docs/csptr_api.md b/docs/csptr_api.md
new file mode 100644
index 00000000..9669d97b
--- /dev/null
+++ b/docs/csptr_api.md
@@ -0,0 +1,190 @@
+# STC [csptr](../stc/csptr.h): Shared Pointers
+
+**csptr** is a smart pointer that retains shared ownership of an object through a pointer.
+Several **csptr** objects may own the same object. The object is destroyed and its memory
+deallocated when either of the following happens:
+
+- the last remaining **csptr** owning the object is destroyed with *csptr_X_del()*;
+- the last remaining **csptr** owning the object is assigned another pointer via *csptr_X_clone()*, *csptr_X_move()* or by *csptr_X_reset()*.
+
+The object is destroyed using *csptr_X_del()* or a custom deleter that is supplied to **csptr**
+in the using-statement.
+
+A **csptr** may also own no objects, in which case it is called empty.
+
+All **csptr** functions can be called by multiple threads on different instances of **csptr** without
+additional synchronization even if these instances are copies and share ownership of the same object.
+**csptr** uses thread-safe atomic reference counting, through the *csptr_X_clone()* and *csptr_X_del()* methods.
+
+See the c++ classes [std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr) for a functional reference.
+
+## Header file and declaration
+
+```c
+#include <stc/csptr.h>
+
+using_csptr(X, Value);
+using_csptr(X, Value, valueCompare);
+using_csptr(X, Value, valueCompare, valueDel);
+```
+The macro `using_csptr()` must be instantiated in the global scope. `X` is a type tag name and will affect the names of all csptr types and methods. E.g. declaring `using_csptr(v4, Vec4)`, `X` should be replaced by `v4` in all of the following documentation.
+
+## Methods
+
+Use *csptr_X_clone(p)* when sharing ownership of the pointed-to object. See examples below.
+
+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
+void csptr_X_reset(csptr_X* self);
+void csptr_X_reset_to(csptr_X* self, csptr_X_value_t* ptr);
+
+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
+
+int csptr_X_compare(csptr_X* x, csptr_X* y);
+bool csptr_X_equals(csptr_X* x, csptr_X* y);
+```
+
+## Types
+
+| Type name | Type definition | Used to represent... |
+|:--------------------|:--------------------------------------------------------------|:-------------------------|
+| `csptr_X` | `struct { csptr_X_value_t* get; atomic_count_t* use_count; }` | The csptr type |
+| `csptr_X_value_t` | `Value` | The csptr element type |
+| `atomic_count_t` | `long` | The reference counter |
+
+## Example
+
+```c
+#include <stc/csptr.h>
+#include <stc/cstr.h>
+
+typedef struct { cstr name, last; } Person;
+
+Person* Person_make(Person* p, const char* name, const char* last) {
+ p->name = cstr_from(name), p->last = cstr_from(last);
+ return p;
+}
+void Person_del(Person* p) {
+ printf("Destroy: %s %s\n", p->name.str, p->last.str);
+ c_del(cstr, &p->name, &p->last);
+}
+
+using_csptr(pe, Person, c_no_compare, Person_del);
+
+int main() {
+ csptr_pe p = csptr_pe_from(Person_make(c_new(Person), "John", "Smiths"));
+ csptr_pe q = csptr_pe_clone(p); // means: share the pointer
+
+ printf("Person: %s %s. uses: %zu\n", p.get->name.str, p.get->last.str, *p.use_count);
+ csptr_pe_del(&p);
+
+ printf("Last man standing: %s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count);
+ csptr_pe_del(&q);
+}
+```
+Output:
+```
+Person: John Smiths. uses: 2
+Last man standing: John Smiths. uses: 1
+Destroy: John Smiths
+```
+
+### Example 2
+
+Advanced: Two different ways to store Person in vectors: 1) `cvec<Person>`, 2) `cvec< csptr<Person> >`.
+```c
+#include <stc/csptr.h>
+#include <stc/cstr.h>
+#include <stc/cvec.h>
+
+typedef struct { cstr name, last; } Person;
+
+Person* Person_make(Person* p, const char* name, const char* last) {
+ p->name = cstr_from(name), p->last = cstr_from(last);
+ return p;
+}
+int Person_compare(const Person* p, const Person* q) {
+ int cmp = strcmp(p->name.str, q->name.str);
+ return cmp == 0 ? strcmp(p->last.str, q->last.str) : cmp;
+}
+void Person_del(Person* p) {
+ printf("del: %s\n", p->name.str);
+ c_del(cstr, &p->name, &p->last);
+}
+
+// 1. cvec of Person struct; emplace and cloning disabled.
+using_cvec(pe, Person, Person_compare, Person_del, c_no_clone);
+
+// 2. cvec of shared-ptr to Person - with emplace_back() and cloning cvec ENABLED.
+using_csptr(pe, Person, Person_compare, Person_del);
+using_cvec(ps, csptr_pe, csptr_pe_compare, csptr_pe_del, csptr_pe_clone);
+
+const char* names[] = {
+ "Joe", "Jordan",
+ "Annie", "Aniston",
+ "Jane", "Jacobs"
+};
+
+int main() {
+ cvec_pe vec1 = cvec_pe_init();
+ cvec_ps vec2 = cvec_ps_init();
+
+ for (int i = 0; i < 6; i += 2) {
+ Person tmp;
+ cvec_pe_push_back(&vec1, *Person_make(&tmp, names[i], names[i+1]));
+ cvec_ps_push_back(&vec2, csptr_pe_from(Person_make(c_new(Person), names[i], names[i+1])));
+ }
+ puts("1. Sorted vec1 of Person:");
+ cvec_pe_sort(&vec1);
+ c_foreach (i, cvec_pe, vec1)
+ printf(" %s %s\n", i.ref->name.str, i.ref->last.str);
+
+ // Append a shared copy of vec2.data[0]. Will only be destructed once!
+ cvec_ps_emplace_back(&vec2, vec2.data[0]); // emplace will internally call csptr_ps_clone()!
+ puts("\n2. Sorted vec2 of shared-pointer to Person:");
+ cvec_ps_sort(&vec2);
+ c_foreach (i, cvec_ps, vec2)
+ printf(" %s %s\n", i.ref->get->name.str, i.ref->get->last.str);
+
+ // Share vec2.data[1] with elem1 variable.
+ csptr_pe elem1 = csptr_pe_clone(vec2.data[1]);
+
+ puts("\nDestroy vec1:");
+ cvec_pe_del(&vec1);
+ puts("\nDestroy vec2:");
+ cvec_ps_del(&vec2);
+
+ puts("\nDestroy elem1:");
+ csptr_pe_del(&elem1);
+}
+```
+Output:
+```
+1. Sorted vec1 of Person:
+ Annie Aniston
+ Jane Jacobs
+ Joe Jordan
+
+2. Sorted vec2 of shared-pointer to Person:
+ Annie Aniston
+ Jane Jacobs
+ Joe Jordan
+ Joe Jordan
+
+Destroy vec1:
+del: Annie
+del: Jane
+del: Joe
+
+Destroy vec2:
+del: Annie
+del: Joe
+
+Destroy elem1:
+del: Jane
+```
diff --git a/examples/prime.c b/examples/prime.c
index 39418c49..5c6b5065 100644
--- a/examples/prime.c
+++ b/examples/prime.c
@@ -5,11 +5,11 @@
cbits sieveOfEratosthenes(size_t n)
{
- cbits bits = cbits_with_size(n>>1, true);
- size_t q = (size_t) sqrt(n);
-
- for (size_t i = 3; i <= q; i += 2) {
- for (size_t j = i; j < n; j += 2) {
+ cbits bits = cbits_with_size(n/2 + 1, true);
+ size_t q = (size_t) sqrt(n) + 1;
+ for (size_t i = 3; i < q; i += 2) {
+ size_t j = i;
+ for (; j < n; j += 2) {
if (cbits_test(bits, j>>1)) {
i = j;
break;
@@ -23,7 +23,7 @@ cbits sieveOfEratosthenes(size_t n)
int main(void)
{
- size_t n = 100000000;
+ size_t n = 1000000000;
printf("computing prime numbers up to %zu\n", n);
clock_t t1 = clock();
diff --git a/stc/cptr.h b/stc/csptr.h
index 0cb51841..feb89b5a 100644
--- a/stc/cptr.h
+++ b/stc/csptr.h
@@ -20,84 +20,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifndef CPTR_H_INCLUDED
-#define CPTR_H_INCLUDED
+#ifndef CSPTR_H_INCLUDED
+#define CSPTR_H_INCLUDED
-/* cptr: std::unique_ptr -like type */
-/*
-#include <stc/cptr.h>
-#include <stc/cstr.h>
-#include <stc/cvec.h>
-
-typedef struct { cstr name, last; } Person;
-
-Person* Person_make(Person* p, const char* name, const char* last) {
- p->name = cstr_from(name), p->last = cstr_from(last);
- return p;
-}
-void Person_del(Person* p) {
- printf("del: %s\n", p->name.str);
- c_del(cstr, &p->name, &p->last);
-}
-int Person_compare(const Person* p, const Person* q) {
- int cmp = strcmp(p->name.str, q->name.str);
- return cmp == 0 ? strcmp(p->last.str, q->last.str) : cmp;
-}
-
-using_cptr(pe, Person, Person_compare, Person_del);
-using_cvec(pe, Person*, cptr_pe_compare, cptr_pe_del, c_no_clone);
-
-int main() {
- cvec_pe vec = cvec_pe_init();
- cvec_pe_push_back(&vec, Person_make(c_new(Person), "John", "Smiths"));
- cvec_pe_push_back(&vec, Person_make(c_new(Person), "Jane", "Doe"));
-
- c_foreach (i, cvec_pe, vec)
- printf("%s %s\n", (*i.ref)->name.str, (*i.ref)->last.str);
- cvec_pe_del(&vec);
-}
-*/
#include "ccommon.h"
-#define using_cptr(...) c_MACRO_OVERLOAD(using_cptr, __VA_ARGS__)
-
-#define using_cptr_2(X, Value) \
- using_cptr_3(X, Value, c_default_compare)
-
-#define using_cptr_3(X, Value, valueCompare) \
- using_cptr_4(X, Value, valueCompare, c_trivial_del)
-
-#define using_cptr_4(X, Value, valueCompare, valueDel) \
- typedef Value cptr_##X##_value_t; \
- typedef cptr_##X##_value_t *cptr_##X; \
-\
- STC_INLINE void \
- cptr_##X##_del(cptr_##X* self) { \
- valueDel(*self); \
- c_free(*self); \
- } \
-\
- STC_INLINE void \
- cptr_##X##_reset(cptr_##X* self, cptr_##X##_value_t* p) { \
- cptr_##X##_del(self); \
- *self = p; \
- } \
-\
- STC_INLINE int \
- cptr_##X##_compare(cptr_##X* x, cptr_##X* y) { \
- return valueCompare(*x, *y); \
- } \
- STC_INLINE int \
- cptr_##X##_equals(cptr_##X* x, cptr_##X* y) { \
- return valueCompare(*x, *y) == 0; \
- } \
- typedef cptr_##X cptr_##X##_t
-
-
-
/* csptr: std::shared_ptr -like type:
-#include <stc/cptr.h>
+#include <stc/csptr.h>
#include <stc/cstr.h>
typedef struct { cstr name, last; } Person;
@@ -152,6 +82,8 @@ typedef long atomic_count_t;
}
#endif
+#define csptr_null {NULL, NULL}
+
#define using_csptr(...) c_MACRO_OVERLOAD(using_csptr, __VA_ARGS__)
#define using_csptr_2(X, Value) \
@@ -182,8 +114,9 @@ typedef long atomic_count_t;
} \
STC_INLINE csptr_##X \
csptr_##X##_move(csptr_##X* self) { \
- csptr_##X x = *self; self->use_count = NULL; \
- return x; \
+ csptr_##X ptr = *self; \
+ self->get = NULL, self->use_count = NULL; \
+ return ptr; \
} \
\
STC_INLINE void \
@@ -195,7 +128,12 @@ typedef long atomic_count_t;
} \
} \
STC_INLINE void \
- csptr_##X##_reset(csptr_##X* self, csptr_##X##_value_t* p) { \
+ csptr_##X##_reset(csptr_##X* self) { \
+ csptr_##X##_del(self); \
+ self->use_count = NULL, self->get = NULL; \
+ } \
+ STC_INLINE void \
+ csptr_##X##_reset_to(csptr_##X* self, csptr_##X##_value_t* p) { \
csptr_##X##_del(self); \
*self = csptr_##X##_from(p); \
} \
@@ -204,7 +142,7 @@ typedef long atomic_count_t;
csptr_##X##_compare(csptr_##X* x, csptr_##X* y) { \
return valueCompare(x->get, y->get); \
} \
- STC_INLINE int \
+ STC_INLINE bool \
csptr_##X##_equals(csptr_##X* x, csptr_##X* y) { \
return valueCompare(x->get, y->get) == 0; \
} \