summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-12-22 12:35:36 +0100
committerTyge Løvset <[email protected]>2021-12-22 12:35:36 +0100
commit79c83eba7933f49e766dbeb85f9c40ee17e06edf (patch)
treee43a84d18b79956a8e22b9403358811b6865f344
parent7a30e2853792870a1d85087861e46a1ae1ca6b0e (diff)
downloadSTC-modified-79c83eba7933f49e766dbeb85f9c40ee17e06edf.tar.gz
STC-modified-79c83eba7933f49e766dbeb85f9c40ee17e06edf.zip
Renamed csptr to carc. i_key/val_ref renamed to i_key/val_sptr. Change inspired by Rust Arc/Rc. cbox name is taken from Rust Box type.
-rw-r--r--README.md73
-rw-r--r--docs/cbox_api.md10
-rw-r--r--docs/csptr_api.md96
-rw-r--r--examples/box.c3
-rw-r--r--examples/box2.c8
-rw-r--r--examples/new_sptr.c16
-rw-r--r--examples/sptr.c4
-rw-r--r--examples/sptr_demo.c10
-rw-r--r--examples/sptr_erase.c8
-rw-r--r--examples/sptr_music.c4
-rw-r--r--examples/sptr_pthread.c20
-rw-r--r--examples/sptr_to_maps.c8
-rw-r--r--include/stc/carc.h (renamed from include/stc/csptr.h)30
-rw-r--r--include/stc/ccommon.h2
-rw-r--r--include/stc/forward.h4
-rw-r--r--include/stc/template.h16
16 files changed, 164 insertions, 148 deletions
diff --git a/README.md b/README.md
index e8d9d34b..624796bb 100644
--- a/README.md
+++ b/README.md
@@ -5,19 +5,20 @@ STC - Smart Template Containers for C
News
----
-### Version 3.0 released
-There are new general `i_key_bind` / `i_val_bind` template parameters which auto-binds a set of functions
-to the type specified, and can be used in place of `i_key` / `i_val`. Use the `_bind` variant for elements
+### Version 3 released
+A lot of enhancements, additions and bugfixes. There are also a number of breaking changes (mostly renamings),
+see migrate guide below.
+
+Added are new general `i_key_bind`/`i_val_bind` template parameters which auto-binds a set of functions
+to the type specified, and may be used in place of `i_key`/`i_val`. Use the `_bind` variant for elements
of Type which have following functions defined: *Type_cmp*, *Type_clone*, *Type_drop*, *Type_hash*,
and *Type_eq*. Only the functions required by the particular container needs to be defined. e.g. **cmap**
-and **cset** are the only types that requires *Type_hash* and *Type_eq* to be defined.
-You may override these by defining `i_cmp`, `i_drop`, etc. Template parameters with `i_val` / `i_key` may
-still be defined as before, which is often easier for simple element types.
+and **cset** are the only types that require *Type_hash* and *Type_eq* to be defined.
-Migration guide from version 2 to 3. Replace (regular expresion) in VS Code:
+### Migration guide from version 2 to 3.
+Replace (regular expression) in VS Code:
- `_del\b` → `_drop`
- `_compare\b` → `_cmp`
-- `csptr` → `cref`
- `_rawvalue\b` → `_raw`
- `_equ\b` → `_eq`
@@ -26,24 +27,25 @@ Replace (whole word + match case):
- `i_valdel` → `i_valdrop`
- `i_cnt` → `i_type`
- `cstr_lit` → `cstr_new`
-- `csptr_X_make` → `csptr_X_new`
+- `csptr_X_make` → `carc_X_from`
- `i_key_csptr` → `i_key_sptr`
- `i_val_csptr` → `i_val_sptr`
- `c_apply` → `c_apply_OLD` // replaced by new `c_apply`
- `c_apply_pair` → `c_apply_pair_OLD` // replaced by new `c_apply`
-### Final version 2.1
+Non-regex, global match case replace:
+- `csptr` → `carc`
+
+### Brief summary of changes
- Strings: Renamed constructor *cstr_lit()* to `cstr_new(lit)`. Renamed *cstr_assign_fmt()* to `cstr_printf()`.
-- Added [**cbox**](docs/cbox_api.md) type: container of one element, similar to [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr)
-- Added [example for **csptr**](examples/sptr_to_maps.c).
+- Added [**cbox**](docs/cbox_api.md) type: smart pointer, similar to [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr). Also renamed `csptr` to `carc` (atomic reference counted) smart pointer.
+- Added [example for **carc**](examples/sptr_to_maps.c).
- Added [**c_forpair**](docs/ccommon_api.md) macro: for-loop with "structured binding".
-- Renamed: *csptr_X_make()* to *csptr_X_new()*. Corresponding **cbox** method is *cbox_X_new()*.
+- Renamed: *csptr_X_make()* to *carc_X_from()*. Corresponding **cbox** method is *cbox_X_from()*.
- Renamed: *c_default_fromraw(raw)* to *c_default_clone(raw)*.
-- Renamed: `i_key_csptr` / `i_val_csptr`. Use `i_key_sptr` / `i_val_sptr` for **csptr** and **cbox**.
+- Renamed: `i_key_csptr`/`i_val_csptr` to `i_key_sptr`/`i_val_sptr` for both **carc** and **cbox** values in containers.
- Renamed: `i_cnt` to `i_type` for defining the complete container type name.
- Added `i_opt` template parameter: compile-time options: `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_fwd`; may be combined with `|`
-
-### Version 2.0. Two main breaking changes from V1.X.
- Uses a different way to instantiate templated containers, which is incompatible with v1.X.
Introduction
@@ -67,7 +69,7 @@ which by the compiler is seen as different code because of macro name substituti
- [***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 type](docs/cpque_api.md)
-- [***csptr*** - **std::shared_ptr** alike support](docs/csptr_api.md)
+- [***carc*** - **std::shared_ptr** alike support](docs/carc_api.md)
- [***cqueue*** - **std::queue** alike 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)
@@ -87,7 +89,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.
- **Templates** - Use `#define i_{arg}` to specify container template arguments. There are templates for element-*type*, -*comparison*, -*destruction*, -*cloning*, -*conversion types*, and more.
- **Unparalleled performance** - Some containers are much faster than the c++ STL containers, the rest are about equal in speed.
-- **Fully memory managed** - All containers will destruct keys/values via destructor defined as macro parameters before including the container header. Also, shared pointers are supported and can be stored in containers, see ***csptr***.
+- **Fully memory managed** - All containers will destruct keys/values via destructor defined as macro parameters before including the container header. Also, shared pointers are supported and can be stored in containers, see ***carc***.
- **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 with six different containers is *22 kb in size* compiled with gcc -Os on linux.
@@ -114,19 +116,30 @@ The usage of the containers is similar to the c++ standard containers in STL, so
are familiar with them. All containers are generic/templated, except for **cstr** and **cbits**.
No casting is used, so containers are type-safe like templates in c++. A basic usage example:
```c
-#define i_val float
-#include <stc/cvec.h>
+#define i_type FVec // if not defined, vector type would be cvec_float
+#define i_val float // element type
+#include <stc/cvec.h> // defines the FVec type
int main(void) {
- cvec_float vec = cvec_float_init();
- cvec_float_push_back(&vec, 10.f);
- cvec_float_push_back(&vec, 20.f);
- cvec_float_push_back(&vec, 30.f);
-
- c_foreach (i, cvec_float, vec)
- printf(" %g", *i.ref);
+ FVec vec = FVec_init();
+ FVec_push_back(&vec, 10.f);
+ FVec_push_back(&vec, 20.f);
+ FVec_push_back(&vec, 30.f);
+
+ for (size_t i = 0; i < FVec_size(vec); ++i)
+ printf(" %g", vec.data[i]);
+ FVec_drop(&vec); // free memory
+}
+```
+However, a "better" way to write the same is:
+```c
+int main(void) {
+ c_auto (FVec, vec) { // RAII
+ c_apply(v, FVec_push_back(&vec, v), float, {10.f, 20.f, 30.f});
- cvec_float_drop(&vec);
+ c_foreach (i, FVec, vec) // generic iteration and element access
+ printf(" %g", *i.ref);
+ }
}
```
In order to include two **cvec**s with different element types, include cvec.h twice. For struct, a `i_cmp`
@@ -195,7 +208,7 @@ int main(void) {
{
// add some elements to each container
c_apply(v, cset_int_insert(&set, v), int, {10, 20, 30});
- c_apply(v, cvec_pnt_push_back(&vec, v), int, { {10, 1}, {20, 2}, {30, 3} });
+ c_apply(v, cvec_pnt_push_back(&vec, v), cvec_pnt_raw, { {10, 1}, {20, 2}, {30, 3} });
c_apply(v, cdeq_int_push_back(&deq, v), int, {10, 20, 30});
c_apply(v, clist_int_push_back(&lst, v), int, {10, 20, 30});
c_apply(v, cstack_int_push(&stk, v), int, {10, 20, 30});
@@ -440,4 +453,4 @@ Memory efficiency
- **cmap**: Type size: 4 pointers. *cmap* uses one table of keys+value, and one table of precomputed hash-value/used bucket, which occupies only one byte per bucket. The closed hashing has a default max load factor of 85%, and hash table scales by 1.6x when reaching that.
- **csmap**: Type size: 1 pointer. *csmap* manages its own array of tree-nodes for allocation efficiency. Each node uses only two 32-bit ints for child nodes, and one byte for `level`.
- **carr2**, **carr3**: Type size: 1 pointer plus dimension variables. Arrays are allocated as one contiguous block of heap memory, and one allocation for pointers of indices to the array.
-- **csptr**: Type size: 2 pointers, one for the data and one for the reference counter.
+- **carc**: Type size: 2 pointers, one for the data and one for the reference counter.
diff --git a/docs/cbox_api.md b/docs/cbox_api.md
index 011beea2..e05e69f0 100644
--- a/docs/cbox_api.md
+++ b/docs/cbox_api.md
@@ -1,4 +1,4 @@
-# STC [cbox](../include/stc/cbox.h): (Boxed) Heap Allocated Objects
+# STC [cbox](../include/stc/cbox.h): Smart Pointer (Boxed object)
**cbox** is a A box is a smart pointer to a heap allocated value of type X. A **cbox** can
be empty. The *cbox_X_cmp()*, *cbox_X_drop()* methods are defined based on the `i_cmp`
@@ -21,7 +21,7 @@ See similar c++ class [std::unique_ptr](https://en.cppreference.com/w/cpp/memory
#define i_val // value: REQUIRED
#define i_cmp // three-way compare two i_val* : REQUIRED IF i_val is a non-integral type
#define i_drop // destroy value func - defaults to empty destruct
-#define i_from // create from raw/clone func - REQUIRED if i_drop is defined,
+#define i_from // create from raw/clone func - REQUIRED if i_drop is defined,
// unless 'i_opt c_no_clone' is defined.
#define i_tag // type name tag, defaults to i_val
#include <stc/cbox.h>
@@ -76,7 +76,7 @@ void int_drop(int* x) {
// both for the cbox type and the container of cbox elements. It will also
// disable emplace container functions.
//
-// This applies to all container types, except those with csptr elements, as they
+// This applies to all container types, except those with carc elements, as they
// define cloning internally.
#define i_val int
@@ -84,11 +84,11 @@ void int_drop(int* x) {
#define i_from c_default_clone
#include <stc/cbox.h> // cbox_int
-#define i_key_bind cbox_int // note: use i_key_bind instead of i_key
+#define i_key_sptr cbox_int // note: use i_key_sptr instead of i_key
#define i_tag int // tag otherwise defaults to 'ref'
#include <stc/csset.h> // csset_int (like: std::set<std::unique_ptr<int>>)
-#define i_val_bind cbox_int // note: use i_val_bind instead of i_val
+#define i_val_sptr cbox_int // note: use i_val_sptr instead of i_val
#define i_tag int // tag otherwise defaults to 'ref'
#include <stc/cvec.h> // cvec_int (like: std::vector<std::unique_ptr<int>>)
diff --git a/docs/csptr_api.md b/docs/csptr_api.md
index 95575417..e33bf410 100644
--- a/docs/csptr_api.md
+++ b/docs/csptr_api.md
@@ -1,23 +1,24 @@
-# STC [csptr](../include/stc/csptr.h): Atomic Reference Counted
+# STC [carc](../include/stc/carc.h): Atomic Reference Counted Smart Pointer
-**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 the last remaining **csptr** owning the object is destroyed with *csptr_X_drop()*;
+**carc** is a smart pointer that retains shared ownership of an object through a pointer.
+Several **carc** objects may own the same object. The object is destroyed and its memory
+deallocated when the last remaining **carc** owning the object is destroyed with *carc_X_drop()*;
-The object is destroyed using *csptr_X_drop()*. A **csptr** may also own no objects, in which
-case it is called empty. The *csptr_X_cmp()*, *csptr_X_drop()* methods are defined based on
-the `i_cmp` and `i_valdrop` macros specified. Use *csptr_X_clone(p)* when sharing ownership of
+The object is destroyed using *carc_X_drop()*. A **carc** may also own no objects, in which
+case it is called empty. The *carc_X_cmp()*, *carc_X_drop()* methods are defined based on
+the `i_cmp` and `i_valdrop` macros specified. Use *carc_X_clone(p)* when sharing ownership of
the pointed-to object.
-All **csptr** functions can be called by multiple threads on different instances of **csptr** without
+All **carc** functions can be called by multiple threads on different instances of **carc** 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_drop()* methods.
+**carc** uses thread-safe atomic reference counting, through the *carc_X_clone()* and *carc_X_drop()* methods.
-When declaring a container with shared pointers, define `i_val_bind` as the csptr type, see example.
+When declaring a container with shared pointers, define `i_val_bind` as the carc type, see example.
-For containers, make sure to pass the result of create functions *csptr_X_new()* **only** to *insert()*,
-*push_back()*, and *push()* functions. Use *emplace()* method for sharing existing **csptr**s between
-containers or other existing shared pointers, as they internally clone/share the input.
+Make sure to pass the result of create functions like *carc_X_from()* **only** to *insert()*,
+*push_back()*, and *push()* functions, as it is *moved* into the container. Use *emplace()*
+method for sharing existing **carc**s between containers or other existing shared pointers,
+as they clone/share the input internally.
See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr) for a functional reference, or Rust [std::sync::Arc](https://doc.rust-lang.org/std/sync/struct.Arc.html) / [std::rc::Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html).
@@ -29,41 +30,42 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory
#define i_drop // destroy value func - defaults to empty destruct
#define i_tag // defaults to i_val
#define i_opt c_no_atomic // Non-atomic reference counting, like Rust Rc.
-#include <stc/csptr.h>
+#include <stc/carc.h>
```
`X` should be replaced by the value of `i_tag` in all of the following documentation.
## Methods
```c
-csptr_X csptr_X_init(); // empty shared pointer
-csptr_X csptr_X_new(i_valraw raw); // like csptr_X_from(), but construct owned value from raw.
-csptr_X csptr_X_from(i_val val); // create new heap allocated object. Take ownership of val.
-csptr_X csptr_X_from_ptr(i_val* p); // create a csptr from raw pointer. Takes ownership of p.
-
-csptr_X csptr_X_clone(csptr_X other); // return other with increased use count
-csptr_X csptr_X_move(csptr_X* self); // transfer ownership to another csptr.
-void csptr_X_take(csptr_X* self, csptr_X other); // take ownership of other.
-void csptr_X_copy(csptr_X* self, csptr_X other); // copy shared (increase use count)
-
-void csptr_X_drop(csptr_X* self); // destruct (decrease use count, free at 0)
-long csptr_X_use_count(csptr_X ptr);
-
-void csptr_X_reset(csptr_X* self);
-void csptr_X_reset_from(csptr_X* self, i_val val); // assign new csptr with value. Takes ownership of val.
-
-uint64_t csptr_X_value_hash(const i_val* x, size_t n); // hash value
-int csptr_X_value_cmp(const i_val* x, const i_val* y); // compares pointer addresses if 'i_opt c_no_cmp'
- // is defined. Otherwise uses 'i_cmp' or default compare.
-bool csptr_X_value_eq(const i_val* x, const i_val* y); // cbox_X_value_cmp == 0
+carc_X carc_X_init(); // empty shared pointer
+carc_X carc_X_new(i_valraw raw); // like carc_X_from(), but construct owned value from raw.
+carc_X carc_X_from(i_val val); // create new heap allocated object. Take ownership of val.
+carc_X carc_X_from_ptr(i_val* p); // create a carc from raw pointer. Takes ownership of p.
+
+carc_X carc_X_clone(carc_X other); // return other with increased use count
+carc_X carc_X_move(carc_X* self); // transfer ownership to another carc.
+void carc_X_take(carc_X* self, carc_X other); // take ownership of other.
+void carc_X_copy(carc_X* self, carc_X other); // copy shared (increase use count)
+
+void carc_X_drop(carc_X* self); // destruct (decrease use count, free at 0)
+long carc_X_use_count(carc_X ptr);
+
+void carc_X_reset(carc_X* self);
+void carc_X_reset_from(carc_X* self, i_val val); // assign new carc with value. Takes ownership of val.
+
+uint64_t carc_X_value_hash(const i_val* x, size_t n); // hash value
+int carc_X_value_cmp(const i_val* x, const i_val* y); // compares pointer addresses if 'i_opt c_no_cmp'
+ // is defined. Otherwise uses 'i_cmp' or default compare.
+bool carc_X_value_eq(const i_val* x, const i_val* y); // cbox_X_value_cmp == 0
```
## Types and constants
-| Type name | Type definition | Used to represent... |
-|:-------------------|:---------------------------------------------------|:------------------------|
-| `csptr_null` | `{NULL, NULL}` | Init nullptr const |
-| `csptr_X` | `struct { csptr_X_value* get; long* use_count; }` | The csptr type |
-| `csptr_X_value` | `i_val` | The csptr element type |
+| Type name | Type definition | Used to represent... |
+|:------------------|:--------------------------------------------------|:-----------------------|
+| `carc_null` | `{NULL, NULL}` | Init nullptr const |
+| `carc_X` | `struct { carc_X_value* get; long* use_count; }` | The carc type |
+| `carc_X_value` | `i_val` | The carc element type |
+| `carc_X_raw` | `i_valraw` | Convertion type |
## Example
@@ -83,14 +85,14 @@ bool csptr_X_value_eq(const i_val* x, const i_val* y); // cbox_X_value
// no comparison of Maps needed (or available), and
// no need for atomic ref. count in single thread:
#define i_opt c_no_cmp|c_no_atomic
-#include <stc/csptr.h>
+#include <stc/carc.h>
#define i_type Stack
-#define i_val_bind Arc // define i_val_bind for csptr / cbox value, not i_val
+#define i_val_sptr Arc // define i_val_sptr for carc/cbox value, not i_val or i_val_bind
#include <stc/cstack.h>
#define i_type List
-#define i_val_bind Arc // as above
+#define i_val_sptr Arc // as above
#include <stc/clist.h>
int main()
@@ -100,28 +102,28 @@ int main()
{
// POPULATE the stack with shared pointers to Map:
Map *map;
- map = Stack_push(&stack, Arc_new(Map_init()))->get;
+ map = Stack_push(&stack, Arc_from(Map_init()))->get;
c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, {
{"Joey", 1990}, {"Mary", 1995}, {"Joanna", 1992}
});
- map = Stack_push(&stack, Arc_new(Map_init()))->get;
+ map = Stack_push(&stack, Arc_from(Map_init()))->get;
c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, {
{"Rosanna", 2001}, {"Brad", 1999}, {"Jack", 1980}
});
// POPULATE the list:
- map = List_push_back(&list, Arc_new(Map_init()))->get;
+ map = List_push_back(&list, Arc_from(Map_init()))->get;
c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, {
{"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003}
});
- // Share two Maps from the stack with the list using emplace (clones the csptr):
+ // Share two Maps from the stack with the list using emplace (clones the carc):
List_emplace_back(&list, stack.data[0]);
List_emplace_back(&list, stack.data[1]);
// Clone (deep copy) a Map from the stack to the list
// List will contain two shared and two unshared maps.
- map = List_push_back(&list, Arc_new(Map_clone(*stack.data[1].get)))->get;
+ map = List_push_back(&list, Arc_from(Map_clone(*stack.data[1].get)))->get;
// Add one more element to the cloned map:
Map_emplace_or_assign(map, "CLONED", 2021);
diff --git a/examples/box.c b/examples/box.c
index ae10a89f..d97545b6 100644
--- a/examples/box.c
+++ b/examples/box.c
@@ -28,10 +28,9 @@ void Person_drop(Person* p) {
#include <stc/cbox.h>
#define i_type Persons
-#define i_val_ref PBox // binds PBox_cmp, ...
+#define i_val_sptr PBox // informs that PBox is a smart pointer.
#include <stc/cvec.h>
-
int main()
{
c_auto (Persons, vec)
diff --git a/examples/box2.c b/examples/box2.c
index 5549dade..d79ea32d 100644
--- a/examples/box2.c
+++ b/examples/box2.c
@@ -26,8 +26,8 @@ struct {
#include <stc/cbox.h> // cbox_Rectangle
// Box in box:
-#define i_val_bind cbox_Point // NB: adviced to use i_val_arc when value is a cbox or csptr!
- // it will auto-set i_drop, i_from, i_cmp for you.
+#define i_val_sptr cbox_Point // NB: adviced to use i_val_sptr when value is a cbox or carc!
+ // it will auto-set i_drop, i_from, i_cmp for you.
#define i_opt c_no_cmp
#define i_tag BoxPoint
#include <stc/cbox.h> // cbox_BoxPoint
@@ -62,10 +62,10 @@ int main(void) {
});
// The output of functions can be boxed
- boxed_point = cbox_Point_new(origin());
+ boxed_point = cbox_Point_from(origin());
// Double indirection
- box_in_a_box = cbox_BoxPoint_new(boxed_origin());
+ box_in_a_box = cbox_BoxPoint_from(boxed_origin());
printf("Point occupies %zu bytes on the stack\n",
sizeof(point));
diff --git a/examples/new_sptr.c b/examples/new_sptr.c
index ce31478e..045eef77 100644
--- a/examples/new_sptr.c
+++ b/examples/new_sptr.c
@@ -14,29 +14,29 @@ void Person_drop(Person* p) {
#define i_drop Person_drop
#define i_opt c_no_cmp
#define i_tag person
-#include <stc/csptr.h>
+#include <stc/carc.h>
// ...
#define i_val int
#define i_drop(x) printf("drop: %d\n", *(x))
-#include <stc/csptr.h>
+#include <stc/carc.h>
-#define i_val_bind csptr_int
+#define i_val_bind carc_int
#define i_tag iptr
#include <stc/cstack.h>
int main(void) {
- c_autovar (csptr_person p = csptr_person_from(Person_new("John", "Smiths")), csptr_person_drop(&p))
- c_autovar (csptr_person q = csptr_person_clone(p), csptr_person_drop(&q)) // share the pointer
+ c_autovar (carc_person p = carc_person_from(Person_new("John", "Smiths")), carc_person_drop(&p))
+ c_autovar (carc_person q = carc_person_clone(p), carc_person_drop(&q)) // share the pointer
{
printf("%s %s. uses: %lu\n", q.get->name.str, q.get->last.str, *q.use_count);
}
c_auto (cstack_iptr, stk) {
- cstack_iptr_push(&stk, csptr_int_from(10));
- cstack_iptr_push(&stk, csptr_int_from(20));
- cstack_iptr_push(&stk, csptr_int_from(30));
+ cstack_iptr_push(&stk, carc_int_from(10));
+ cstack_iptr_push(&stk, carc_int_from(20));
+ cstack_iptr_push(&stk, carc_int_from(30));
cstack_iptr_emplace(&stk, *cstack_iptr_top(&stk));
cstack_iptr_emplace(&stk, *cstack_iptr_begin(&stk).ref);
diff --git a/examples/sptr.c b/examples/sptr.c
index e1d734e0..0c22bd68 100644
--- a/examples/sptr.c
+++ b/examples/sptr.c
@@ -25,10 +25,10 @@ void Person_drop(Person* p) {
#define i_type PSPtr
#define i_val_bind Person // binds Person_cmp, ...
-#include <stc/csptr.h>
+#include <stc/carc.h>
#define i_type Persons
-#define i_val_ref PSPtr // binds PSPtr_cmp, ...
+#define i_val_sptr PSPtr // binds PSPtr_cmp, ...
#include <stc/cvec.h>
diff --git a/examples/sptr_demo.c b/examples/sptr_demo.c
index a5c642b0..8626e2d4 100644
--- a/examples/sptr_demo.c
+++ b/examples/sptr_demo.c
@@ -5,18 +5,18 @@ void int_drop(int* x) {
printf("drop: %d\n", *x);
}
-// csptr implements its own clone method using reference counting,
+// carc implements its own clone method using reference counting,
// so 'i_valfrom' need not be defined (will be ignored).
-#define i_type iref // set type name to be defined (instead of 'csptr_int')
+#define i_type iref // set type name to be defined (instead of 'carc_int')
#define i_val int
#define i_drop int_drop // optional, just to display the elements destroyed
-#include <stc/csptr.h> // iref
+#include <stc/carc.h> // iref
-#define i_key_ref iref // note: use i_key_bind instead of i_key for csptr/cbox elements
+#define i_key_sptr iref // note: use i_key_bind instead of i_key for carc/cbox elements
#include <stc/csset.h> // csset_iref (like: std::set<std::shared_ptr<int>>)
-#define i_val_ref iref // note: as above.
+#define i_val_sptr iref // note: as above.
#include <stc/cvec.h> // cvec_iref (like: std::vector<std::shared_ptr<int>>)
int main()
diff --git a/examples/sptr_erase.c b/examples/sptr_erase.c
index fbb141b4..d40d8fe7 100644
--- a/examples/sptr_erase.c
+++ b/examples/sptr_erase.c
@@ -5,14 +5,14 @@ void show_drop(int* x) { printf("drop: %d\n", *x); }
#define i_type Arc
#define i_val int
#define i_drop show_drop
-// csptr/cbox will use pointer address comparison of i_val
+// carc/cbox will use pointer address comparison of i_val
// if 'i_opt c_no_cmp' is defined, otherwise i_cmp is used
-// to compare object values. See the twodifferences by
+// to compare object values. See the two differences by
// commenting out the next line.
-#include <stc/csptr.h> // Shared pointer to int
+#include <stc/carc.h> // Shared pointer to int
#define i_type Vec
-#define i_val_ref Arc
+#define i_val_sptr Arc
#include <stc/cvec.h> // Vec: cvec<Arc>
diff --git a/examples/sptr_music.c b/examples/sptr_music.c
index 1d58cc46..42bb3455 100644
--- a/examples/sptr_music.c
+++ b/examples/sptr_music.c
@@ -21,10 +21,10 @@ void Song_drop(Song* s) {
#define i_val Song
#define i_drop Song_drop
#define i_opt c_no_cmp
-#include <stc/csptr.h>
+#include <stc/carc.h>
#define i_type SongVec
-#define i_val_ref SongPtr
+#define i_val_sptr SongPtr
#include <stc/cvec.h>
void example3()
diff --git a/examples/sptr_pthread.c b/examples/sptr_pthread.c
index d71ce97d..d81d9810 100644
--- a/examples/sptr_pthread.c
+++ b/examples/sptr_pthread.c
@@ -11,13 +11,13 @@ struct Base
int value;
} typedef Base;
+#define i_type BaseRc
#define i_val Base
-#define i_drop(x) printf("Base::~Base()\n")
-#define i_tag base
+#define i_valdrop(x) printf("Drop Base: %d\n", (x)->value)
#define i_opt c_no_cmp
-#include <stc/csptr.h>
+#include <stc/carc.h>
-void* thr(csptr_base* lp)
+void* thr(BaseRc* lp)
{
sleep(1);
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
@@ -25,30 +25,32 @@ void* thr(csptr_base* lp)
{
printf("local pointer in a thread:\n"
" p.get() = %p, p.use_count() = %ld\n", (void*)lp->get, *lp->use_count);
+ /* safe to modify base here */
+ lp->get->value += 1;
}
/* atomically decrease ref. */
- csptr_base_drop(lp);
+ BaseRc_drop(lp);
return NULL;
}
int main()
{
- csptr_base p = csptr_base_from((Base){42});
+ BaseRc p = BaseRc_from((Base){0});
printf("Created a Base\n"
" p.get() = %p, p.use_count() = %ld\n", (void*)p.get, *p.use_count);
enum {N = 3};
pthread_t t[N];
- csptr_base c[N];
+ BaseRc c[N];
c_forrange (i, N) {
- c[i] = csptr_base_clone(p);
+ c[i] = BaseRc_clone(p);
pthread_create(&t[i], NULL, (void*(*)(void*))thr, &c[i]);
}
printf("Shared ownership between %d threads and released\n"
"ownership from main:\n"
" p.get() = %p, p.use_count() = %ld\n", N, (void*)p.get, *p.use_count);
- csptr_base_reset(&p);
+ BaseRc_reset(&p);
c_forrange (i, N) pthread_join(t[i], NULL);
printf("All threads completed, the last one deleted Base\n");
diff --git a/examples/sptr_to_maps.c b/examples/sptr_to_maps.c
index 64866ba3..0873d297 100644
--- a/examples/sptr_to_maps.c
+++ b/examples/sptr_to_maps.c
@@ -12,14 +12,14 @@
// no need for atomic ref. count in single thread:
// no compare function available for csmap:
#define i_opt c_no_atomic|c_no_cmp
-#include <stc/csptr.h>
+#include <stc/carc.h>
#define i_type Stack
-#define i_val_ref Arc // define i_val_bind for csptr/cbox value (not i_val)
+#define i_val_sptr Arc // define i_val_bind for carc/cbox value (not i_val)
#include <stc/cstack.h>
#define i_type List
-#define i_val_ref Arc // as above
+#define i_val_sptr Arc // as above
#include <stc/clist.h>
int main()
@@ -44,7 +44,7 @@ int main()
{"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003}
});
- // Share two Maps from the stack with the list using emplace (clone the csptr):
+ // Share two Maps from the stack with the list using emplace (clone the carc):
List_push_back(&list, Arc_clone(stack.data[0]));
List_push_back(&list, Arc_clone(stack.data[1]));
diff --git a/include/stc/csptr.h b/include/stc/carc.h
index 0718a4cc..505b47d9 100644
--- a/include/stc/csptr.h
+++ b/include/stc/carc.h
@@ -21,7 +21,7 @@
* SOFTWARE.
*/
-/* csptr: shared_ptr type
+/* carc: atomic reference counted shared_ptr
#include <stc/cstr.h>
typedef struct { cstr name, last; } Person;
@@ -37,19 +37,19 @@ void Person_drop(Person* p) {
#define i_tag person
#define i_val Person
#define i_valdrop Person_drop
-#include <stc/csptr.h>
+#include <stc/carc.h>
int main() {
- csptr_person p = csptr_person_new(Person_new("John", "Smiths"));
- csptr_person q = csptr_person_clone(p); // share the pointer
+ carc_person p = carc_person_from(Person_new("John", "Smiths"));
+ carc_person q = carc_person_clone(p); // share the pointer
printf("%s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count);
- c_drop(csptr_person, &p, &q);
+ c_drop(carc_person, &p, &q);
}
*/
-#ifndef CSPTR_H_INCLUDED
-#define CSPTR_H_INCLUDED
+#ifndef CARC_H_INCLUDED
+#define CARC_H_INCLUDED
#include "ccommon.h"
#include "forward.h"
#include <stdlib.h>
@@ -67,12 +67,12 @@ int main() {
#define c_atomic_dec_and_test(v) (atomic_fetch_sub(v, 1) == 1)
#endif
-#define csptr_null {NULL, NULL}
-#define _cx_csptr_rep struct _cx_memb(_rep_)
-#endif // CSPTR_H_INCLUDED
+#define carc_null {NULL, NULL}
+#define _cx_carc_rep struct _cx_memb(_rep_)
+#endif // CARC_H_INCLUDED
#ifndef _i_prefix
-#define _i_prefix csptr_
+#define _i_prefix carc_
#endif
#define _i_has_internal_clone
#include "template.h"
@@ -86,9 +86,9 @@ typedef i_valraw _cx_raw;
#define _i_atomic_dec_and_test(v) !(--*(v))
#endif
#if !c_option(c_is_fwd)
-_cx_deftypes(_c_csptr_types, _cx_self, i_val);
+_cx_deftypes(_c_carc_types, _cx_self, i_val);
#endif
-_cx_csptr_rep { long counter; i_val value; };
+_cx_carc_rep { long counter; i_val value; };
STC_INLINE _cx_self
_cx_memb(_init)(void) { return c_make(_cx_self){NULL, NULL}; }
@@ -105,7 +105,7 @@ _cx_memb(_from_ptr)(_cx_value* p) {
STC_INLINE _cx_self
_cx_memb(_from)(i_val val) {
- _cx_self ptr; _cx_csptr_rep *rep = c_alloc(_cx_csptr_rep);
+ _cx_self ptr; _cx_carc_rep *rep = c_alloc(_cx_carc_rep);
*(ptr.use_count = &rep->counter) = 1;
*(ptr.get = &rep->value) = val;
return ptr;
@@ -126,7 +126,7 @@ STC_INLINE void
_cx_memb(_drop)(_cx_self* self) {
if (self->use_count && _i_atomic_dec_and_test(self->use_count)) {
i_valdrop(self->get);
- if (self->get != &((_cx_csptr_rep *)self->use_count)->value)
+ if (self->get != &((_cx_carc_rep *)self->use_count)->value)
c_free(self->get);
c_free(self->use_count);
}
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index ac6e9d31..4e2ee97d 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -199,7 +199,7 @@ STC_INLINE uint64_t c_default_hash(const void* key, size_t len) {
for (size_t index = 0; index < _n; ++index) \
{ const T v = _c_arr[index]; method; } \
} while (0)
-#define c_apply_it(v, method, C, ...) do { \
+#define c_apply_cnt(v, method, C, ...) do { \
size_t index = 0; \
c_foreach (_it, C, __VA_ARGS__) \
{ const C##_value v = *_it.ref; method; ++index; } \
diff --git a/include/stc/forward.h b/include/stc/forward.h
index bf2ba698..9a37297e 100644
--- a/include/stc/forward.h
+++ b/include/stc/forward.h
@@ -34,7 +34,7 @@
#define forward_cset(CX, KEY) _c_chash_types(CX, cset, KEY, KEY, c_false, c_true)
#define forward_csset(CX, KEY) _c_aatree_types(CX, KEY, KEY, c_false, c_true)
#define forward_cbox(CX, VAL) _c_cbox_types(CX, VAL)
-#define forward_csptr(CX, VAL) _c_csptr_types(CX, VAL)
+#define forward_carc(CX, VAL) _c_carc_types(CX, VAL)
#define forward_cpque(CX, VAL) _c_cpque_types(CX, VAL)
#define forward_cstack(CX, VAL) _c_cstack_types(CX, VAL)
#define forward_cqueue(CX, VAL) _c_cdeq_types(CX, VAL)
@@ -132,7 +132,7 @@
SELF##_value* get; \
} SELF
-#define _c_csptr_types(SELF, VAL) \
+#define _c_carc_types(SELF, VAL) \
typedef VAL SELF##_value; \
\
typedef struct { \
diff --git a/include/stc/template.h b/include/stc/template.h
index 1d1551fa..5efe3772 100644
--- a/include/stc/template.h
+++ b/include/stc/template.h
@@ -61,9 +61,9 @@
#ifndef i_tag
#define i_tag str
#endif
-#elif defined i_key_ref
- #define i_key_bind i_key_ref
- #define i_keyraw c_PASTE(i_key_ref, _value)
+#elif defined i_key_sptr
+ #define i_key_bind i_key_sptr
+ #define i_keyraw c_PASTE(i_key_sptr, _value)
#endif
#ifdef i_key_bind
@@ -120,9 +120,9 @@
#if !defined i_tag && !defined i_key
#define i_tag str
#endif
-#elif defined i_val_ref
- #define i_val_bind i_val_ref
- #define i_valraw c_PASTE(i_val_ref, _value)
+#elif defined i_val_sptr
+ #define i_val_bind i_val_sptr
+ #define i_valraw c_PASTE(i_val_sptr, _value)
#endif
#ifdef i_val_bind
@@ -219,7 +219,7 @@
#undef i_val
#undef i_val_str
-#undef i_val_ref
+#undef i_val_sptr
#undef i_val_bind
#undef i_valraw
#undef i_valfrom
@@ -228,7 +228,7 @@
#undef i_key
#undef i_key_str
-#undef i_key_ref
+#undef i_key_sptr
#undef i_key_bind
#undef i_keyraw
#undef i_keyfrom