diff options
| author | Tyge Løvset <[email protected]> | 2021-12-19 12:21:44 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-12-19 12:21:44 +0100 |
| commit | 92b950333c6c7002bdbf1b60af44a249dc0cef9c (patch) | |
| tree | 4b1acfcdba0bd940f829c53910587e27b5e0af90 | |
| parent | 183a89859ba9914ee0546e4482b40be199e52292 (diff) | |
| download | STC-modified-92b950333c6c7002bdbf1b60af44a249dc0cef9c.tar.gz STC-modified-92b950333c6c7002bdbf1b60af44a249dc0cef9c.zip | |
First commit for Version 3 of STC. Main changes are consistent rename of '_del' to '_drop' and '_compare' to '_cmp'.
Also i_key_ref (earlier i_key_sptr) and i_val_ref replaced by more general i_key_bind/i_val_bind.
88 files changed, 982 insertions, 1305 deletions
@@ -5,23 +5,36 @@ STC - Smart Template Containers for C News ---- +### Version 3.0 released. Migration guide for breaking changes from version 2.X: +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 of Type which have following functions defined: *Type_cmp*, *Type_clone*, *Type_drop*, *Type_equalto*, and *Type_hash*. Only the functions required by the particular container needs to be defined, e.g. only **cmap** and **cset** require *Type_equalto* and *Type_hash* to be defined. +You may still define template parameters with `i_val` / `i_key` as before, which is easier for simple element types. + +Regex replace in VS Code: +- `_del\b` → `_drop` +- `_compare\b` → `_cmp` + +Whole word + Match case: +- `i_keydel` → `i_keydrop` +- `i_valdel` → `i_valdrop` +- `i_cnt` → `i_type` +- `i_key_csptr` → `i_key_bind` +- `i_val_csptr` → `i_val_bind` +- `cstr_lit` → `cstr_new` +- `csptr_X_make` → `csptr_X_new` + +### Final version 2.1 - 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 [**c_forpair**](docs/ccommon_api.md) macro: for-loop with "structured binding". - Deprecated *csptr_X_make()*. Renamed to *csptr_X_new()*. Corresponding **cbox** method is *cbox_X_new()*. - Deprecated *c_default_fromraw(raw)*. Renamed to *c_default_clone(raw)*. -- Deprecated `i_key_csptr` / `i_val_csptr`. Use `i_key_ref` / `i_val_ref` when specifying containers with **csptr** or **cbox** elements. -- Deprecated `i_cnt`. Use `i_type` instead to define the full container type name. +- Deprecated `i_key_csptr` / `i_val_csptr`. Use `i_key_bind` / `i_val_bind` +- Deprecated `i_cnt`. Use `i_type` instead to define 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 `|` -Previous: -- Added `i_opt` template parameter: compile-time options: `c_no_compare`, `c_no_clone`, `c_no_atomic`, `c_is_fwd`; may be combined with `|` -- Removed: i_cmp_none and i_fwd: replaced by `c_no_compare` and `c_is_fwd` args to `i_opt`. - -VERSION 2.0 released. Two main breaking changes from V1.X. +### Version 2.0. Two main breaking changes from V1.X. - Uses a different way to instantiate templated containers, which is incompatible with v1.X. -- New **c_auto**, **c_autovar**, and **c_autoscope** macros. These are for automatic scope resource management, aka RAII. -- The new template instantiation style has multiple advantages, e.g. implementation does not contain long macro definitions for code generation. Also, specifying template arguments is more user friendly and flexible. Introduction ------------ @@ -101,24 +114,24 @@ int main(void) { c_foreach (i, cvec_float, vec) printf(" %g", *i.ref); - cvec_float_del(&vec); + cvec_float_drop(&vec); } ``` In order to include two **cvec**s with different element types, include cvec.h twice. For struct, a `i_cmp` compare function is required to enable sorting and searching (`<` and `==` operators is default and works -for integral types only). Alternatively, `#define i_opt c_no_compare` to disable methods using comparison. +for integral types only). Alternatively, `#define i_opt c_no_cmp` to disable methods using comparison. -Similarly, if a destructor `i_del` is defined, either define a `i_valfrom` construct/clone function +Similarly, if a destructor `i_drop` is defined, either define a `i_valfrom` construct/clone function or `#define i_opt c_no_clone` to disable cloning and emplace methods. Unless these requirements are met, compile errors are generated. ```c #define i_val struct One -#define i_opt c_no_compare +#define i_opt c_no_cmp #define i_tag one #include <stc/cvec.h> #define i_val struct Two -#define i_opt c_no_compare +#define i_opt c_no_cmp #define i_tag two #include <stc/cvec.h> ... @@ -133,16 +146,16 @@ With six different containers: struct Point { float x, y; }; -int Point_compare(const struct Point* a, const struct Point* b) { - int cmp = c_default_compare(&a->x, &b->x); - return cmp ? cmp : c_default_compare(&a->y, &b->y); +int Point_cmp(const struct Point* a, const struct Point* b) { + int cmp = c_default_cmp(&a->x, &b->x); + return cmp ? cmp : c_default_cmp(&a->y, &b->y); } #define i_key int #include <stc/cset.h> // cset_int: unordered set #define i_val struct Point -#define i_cmp Point_compare +#define i_cmp Point_cmp #define i_tag pnt #include <stc/cvec.h> // cvec_pnt: vector of struct Point @@ -160,7 +173,7 @@ int Point_compare(const struct Point* a, const struct Point* b) { #include <stc/csmap.h> // csmap_int: sorted map int => int int main(void) { - // define six containers with automatic call of init and del (destruction after scope exit) + // define six containers with automatic call of init and drop (destruction after scope exit) c_auto (cset_int, set) c_auto (cvec_pnt, vec) c_auto (cdeq_int, deq) @@ -267,28 +280,28 @@ The list of template parameters: - `i_tag` - Container type tag. Defaults to same as `i_key` - `i_type` - Full container type name (optional, alternative to `i_tag`). -- `i_opt` - Boolean properties: may combine `c_no_compare`, `c_no_clone`, `c_no_atomic`, `c_is_fwd` with `|` separator. +- `i_opt` - Boolean properties: may combine `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_fwd` with `|` separator. - `i_key` - Maps key type. **[required]** for cmap/csmap. - `i_val` - The container **[required]** element type. For cmap/csmap, it is the mapped value. - `i_cmp` - Three-way comparison of two `i_keyraw`, **[required]** for non-integral `i_keyraw`. - `i_equ` - Equality comparison of two `i_keyraw`- defaults to `!i_cmp`. -- `i_keydel` - Destroy map key func - defaults to empty destructor. +- `i_keydrop` - Destroy map key func - defaults to empty destructor. - `i_keyraw` - Convertion "raw" type - defaults to `i_key` type. -- `i_keyfrom` - Convertion func `i_keyraw` => `i_key` - defaults to simple copy. **[required]** if `i_keydel` is defined. +- `i_keyfrom` - Convertion func `i_keyraw` => `i_key` - defaults to simple copy. **[required]** if `i_keydrop` is defined. - `i_keyto` - Convertion func `i_key` => `i_keyraw` - defaults to simple copy. -- `i_valdel` - Destroy mapped or value func - defaults to empty destruct. +- `i_valdrop` - Destroy mapped or value func - defaults to empty destruct. - `i_valraw` - Convertion "raw" type - defaults to `i_val` type. - `i_valfrom` - Convertion func `i_valraw` => `i_val` - defaults to simple copy. - `i_valto` - Convertion func `i_val` => `i_valraw` - defaults to simple copy. -Instead of defining `i_cmp`, you may define `i_opt c_no_compare` to disable methods using comparison. +Instead of defining `i_cmp`, you may define `i_opt c_no_cmp` to disable methods using comparison. Instead of defining `i_valfrom`, you may define `i_opt c_no_clone` to disable methods using deep copy. -If a destructor `i_del` is defined, then define either `i_valfrom` or `i_opt c_no_clone`, otherwise +If a destructor `i_drop` is defined, then define either `i_valfrom` or `i_opt c_no_clone`, otherwise compile errors are generated. The *emplace* versus non-emplace container methods @@ -318,8 +331,8 @@ and non-emplace methods: #define i_val_str // special macro to enable container of cstr #include <stc/cvec.h> // vector of string (cstr) ... -c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_del(&vec) -c_autovar (cstr s = cstr_new("a string literal"), cstr_del(&s)) // c_autovar is a more general c_auto. +c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_drop(&vec) +c_autovar (cstr s = cstr_new("a string literal"), cstr_drop(&s)) // c_autovar is a more general c_auto. { const char* hello = "Hello"; cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* diff --git a/benchmarks/picobench/picobench_cmap.cpp b/benchmarks/picobench/picobench_cmap.cpp index 330c5e51..a045cb7c 100644 --- a/benchmarks/picobench/picobench_cmap.cpp +++ b/benchmarks/picobench/picobench_cmap.cpp @@ -91,7 +91,7 @@ static void ins_and_erase_cmap_i(picobench::state& s) c_forrange (s.iterations())
cmap_i_erase(&map, stc64_random());
s.set_result(cmap_i_size(map));
- cmap_i_del(&map);
+ cmap_i_drop(&map);
}
static void ins_and_erase_cmap_x(picobench::state& s)
@@ -111,7 +111,7 @@ static void ins_and_erase_cmap_x(picobench::state& s) c_forrange (s.iterations())
cmap_x_erase(&map, stc64_random());
s.set_result(cmap_x_size(map));
- cmap_x_del(&map);
+ cmap_x_drop(&map);
}
#define P samples(S1).iterations({N1/4})
@@ -153,7 +153,7 @@ static void ins_and_access_cmap_i(picobench::state& s) c_forrange (N1)
result += ++cmap_i_emplace(&map, stc64_random() & mask, 0).ref->second;
s.set_result(result);
- cmap_i_del(&map);
+ cmap_i_drop(&map);
}
#define P samples(S1).iterations({N1, N1, N1, N1}).args({18, 23, 25, 31})
@@ -212,8 +212,8 @@ static void ins_and_access_cmap_s(picobench::state& s) result += cmap_str_erase(&map, str.str);
}
s.set_result(result + cmap_str_size(map));
- cstr_del(&str);
- cmap_str_del(&map);
+ cstr_drop(&str);
+ cmap_str_drop(&map);
}
#define P samples(S1).iterations({N1/5, N1/5, N1/5, N1/10, N1/40}).args({13, 7, 8, 100, 1000})
@@ -285,7 +285,7 @@ static void iterate_cmap_x(picobench::state& s) result += i.ref->second;
}
s.set_result(result);
- cmap_x_del(&map);
+ cmap_x_drop(&map);
}
diff --git a/benchmarks/picobench/picobench_csmap.cpp b/benchmarks/picobench/picobench_csmap.cpp index 7a0addad..90681cd5 100644 --- a/benchmarks/picobench/picobench_csmap.cpp +++ b/benchmarks/picobench/picobench_csmap.cpp @@ -52,7 +52,7 @@ static void ctor_and_ins_one_csmap_i(picobench::state& s) csmap_i map = csmap_i_init();
csmap_i_emplace(&map, n, 0);
result += csmap_i_size(map);
- csmap_i_del(&map);
+ csmap_i_drop(&map);
}
s.set_result(result);
}
@@ -86,7 +86,7 @@ static void insert_csmap_i(picobench::state& s) c_forrange (n, s.iterations())
csmap_i_emplace(&map, stc64_random() & 0xfffffff, n);
s.set_result(csmap_i_size(map));
- csmap_i_del(&map);
+ csmap_i_drop(&map);
}
#define P samples(S1).iterations({N1})
@@ -142,7 +142,7 @@ static void ins_and_erase_csmap_i(picobench::state& s) c_forrange (s.iterations())
csmap_i_erase(&map, stc64_random() & mask);
s.set_result(result);
- csmap_i_del(&map);
+ csmap_i_drop(&map);
}
#define P samples(S1).iterations({N1/2, N1/2, N1/2, N1/2}).args({18, 23, 25, 31})
@@ -183,7 +183,7 @@ static void ins_and_access_csmap_i(picobench::state& s) if (val) csmap_i_erase(&map, val->first);
}
s.set_result(result + csmap_i_size(map));
- csmap_i_del(&map);
+ csmap_i_drop(&map);
}
#define P samples(S1).iterations({N1, N1, N1, N1}).args({18, 23, 25, 31})
@@ -243,8 +243,8 @@ static void ins_and_access_csmap_s(picobench::state& s) }*/
}
s.set_result(result + csmap_str_size(map));
- cstr_del(&str);
- csmap_str_del(&map);
+ cstr_drop(&str);
+ csmap_str_drop(&map);
}
#define P samples(S1).iterations({N1/5, N1/5, N1/5, N1/10, N1/40}).args({13, 7, 8, 100, 1000})
@@ -309,7 +309,7 @@ static void iterate_csmap_x(picobench::state& s) result += i.ref->second;
}
s.set_result(result);
- csmap_x_del(&map);
+ csmap_x_drop(&map);
}
diff --git a/benchmarks/plotbench/cdeq_benchmark.cpp b/benchmarks/plotbench/cdeq_benchmark.cpp index 6db167b0..f57da6b2 100644 --- a/benchmarks/plotbench/cdeq_benchmark.cpp +++ b/benchmarks/plotbench/cdeq_benchmark.cpp @@ -81,7 +81,7 @@ Sample test_stc_deque() { c_forrange (cdeq_x_size(con)/2) { cdeq_x_pop_front(&con); cdeq_x_pop_back(&con); }
s.test[ERASE].t2 = clock();
s.test[ERASE].sum = cdeq_x_size(con);
- cdeq_x_del(&con);
+ cdeq_x_drop(&con);
}{
stc64_srandom(seed);
container con = cdeq_x_init();
@@ -98,7 +98,7 @@ Sample test_stc_deque() { s.test[ITER].t2 = clock();
s.test[ITER].sum = sum;
s.test[DESTRUCT].t1 = clock();
- cdeq_x_del(&con);
+ cdeq_x_drop(&con);
}
s.test[DESTRUCT].t2 = clock();
s.test[DESTRUCT].sum = 0;
diff --git a/benchmarks/plotbench/clist_benchmark.cpp b/benchmarks/plotbench/clist_benchmark.cpp index 676d31e7..eaa18201 100644 --- a/benchmarks/plotbench/clist_benchmark.cpp +++ b/benchmarks/plotbench/clist_benchmark.cpp @@ -78,7 +78,7 @@ Sample test_stc_forward_list() { c_forrange (N) clist_x_pop_front(&con);
s.test[ERASE].t2 = clock();
s.test[ERASE].sum = 0;
- clist_x_del(&con);
+ clist_x_drop(&con);
}{
stc64_srandom(seed);
container con = clist_x_init();
@@ -95,7 +95,7 @@ Sample test_stc_forward_list() { s.test[ITER].t2 = clock();
s.test[ITER].sum = sum;
s.test[DESTRUCT].t1 = clock();
- clist_x_del(&con);
+ clist_x_drop(&con);
}
s.test[DESTRUCT].t2 = clock();
s.test[DESTRUCT].sum = 0;
diff --git a/benchmarks/plotbench/cmap_benchmark.cpp b/benchmarks/plotbench/cmap_benchmark.cpp index 4c9c6c16..16aec8c0 100644 --- a/benchmarks/plotbench/cmap_benchmark.cpp +++ b/benchmarks/plotbench/cmap_benchmark.cpp @@ -82,7 +82,7 @@ Sample test_stc_unordered_map() { c_forrange (N) cmap_x_erase(&con, stc64_random() & mask1);
s.test[ERASE].t2 = clock();
s.test[ERASE].sum = cmap_x_size(con);
- cmap_x_del(&con);
+ cmap_x_drop(&con);
}{
container con = cmap_x_init();
stc64_srandom(seed);
@@ -103,7 +103,7 @@ Sample test_stc_unordered_map() { s.test[ITER].t2 = clock();
s.test[ITER].sum = sum;
s.test[DESTRUCT].t1 = clock();
- cmap_x_del(&con);
+ cmap_x_drop(&con);
}
s.test[DESTRUCT].t2 = clock();
s.test[DESTRUCT].sum = 0;
diff --git a/benchmarks/plotbench/cpque_benchmark.cpp b/benchmarks/plotbench/cpque_benchmark.cpp index 19a9c701..33e55719 100644 --- a/benchmarks/plotbench/cpque_benchmark.cpp +++ b/benchmarks/plotbench/cpque_benchmark.cpp @@ -3,7 +3,7 @@ #include <stc/crandom.h>
#define i_val float
-#define i_cmp -c_default_compare
+#define i_cmp -c_default_cmp
#define i_tag f
#include <stc/cpque.h>
@@ -14,11 +14,12 @@ int main() int N = 10000000, M = 10;
cpque_f pq = cpque_f_init();
+ cpque_f_resize(&pq, N, 0.0f);
rng = stc64_init(seed);
clock_t start = clock();
- c_forrange (i, int, N)
- cpque_f_push_back(&pq, (float) stc64_randf(&rng)*100000);
+ c_forrange (i, N)
+ pq.data[i] = (float) stc64_randf(&rng)*100000;
cpque_f_make_heap(&pq);
printf("Built priority queue: %f secs\n", (clock() - start) / (float) CLOCKS_PER_SEC);
@@ -44,5 +45,5 @@ int main() }
puts("");
- cpque_f_del(&pq);
+ cpque_f_drop(&pq);
}
diff --git a/benchmarks/plotbench/csmap_benchmark.cpp b/benchmarks/plotbench/csmap_benchmark.cpp index 47762791..4d1621e3 100644 --- a/benchmarks/plotbench/csmap_benchmark.cpp +++ b/benchmarks/plotbench/csmap_benchmark.cpp @@ -82,7 +82,7 @@ Sample test_stc_map() { c_forrange (N) csmap_x_erase(&con, stc64_random() & mask1);
s.test[ERASE].t2 = clock();
s.test[ERASE].sum = csmap_x_size(con);
- csmap_x_del(&con);
+ csmap_x_drop(&con);
}{
container con = csmap_x_init();
stc64_srandom(seed);
@@ -103,7 +103,7 @@ Sample test_stc_map() { s.test[ITER].t2 = clock();
s.test[ITER].sum = sum;
s.test[DESTRUCT].t1 = clock();
- csmap_x_del(&con);
+ csmap_x_drop(&con);
}
s.test[DESTRUCT].t2 = clock();
s.test[DESTRUCT].sum = 0;
diff --git a/benchmarks/plotbench/cvec_benchmark.cpp b/benchmarks/plotbench/cvec_benchmark.cpp index c4648e34..21e7a229 100644 --- a/benchmarks/plotbench/cvec_benchmark.cpp +++ b/benchmarks/plotbench/cvec_benchmark.cpp @@ -77,7 +77,7 @@ Sample test_stc_vector() { c_forrange (N) { cvec_x_pop_back(&con); }
s.test[ERASE].t2 = clock();
s.test[ERASE].sum = cvec_x_size(con);
- cvec_x_del(&con);
+ cvec_x_drop(&con);
}{
stc64_srandom(seed);
container con = cvec_x_init();
@@ -94,7 +94,7 @@ Sample test_stc_vector() { s.test[ITER].t2 = clock();
s.test[ITER].sum = sum;
s.test[DESTRUCT].t1 = clock();
- cvec_x_del(&con);
+ cvec_x_drop(&con);
}
s.test[DESTRUCT].t2 = clock();
s.test[DESTRUCT].sum = 0;
diff --git a/benchmarks/shootout_hashmaps.cpp b/benchmarks/shootout_hashmaps.cpp index 40e0e579..6439c548 100644 --- a/benchmarks/shootout_hashmaps.cpp +++ b/benchmarks/shootout_hashmaps.cpp @@ -47,7 +47,7 @@ size_t seed; #define CMAP_SIZE(X) cmap_##X##_size(map) #define CMAP_BUCKETS(X) cmap_##X##_bucket_count(map) #define CMAP_CLEAR(X) cmap_##X##_clear(&map) -#define CMAP_DTOR(X) cmap_##X##_del(&map) +#define CMAP_DTOR(X) cmap_##X##_drop(&map) #define KMAP_SETUP(X, Key, Value) khash_t(X)* map = kh_init(X); khiter_t ki; int ret #define KMAP_PUT(X, key, val) (*(ki = kh_put(X, map, key, &ret), map->vals[ki] = val, map->vals+ki)) diff --git a/docs/carray_api.md b/docs/carray_api.md index 5e26f658..3ac6d650 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -10,8 +10,8 @@ See the c++ class [boost::multi_array](https://www.boost.org/doc/libs/release/li ```c #define i_val // value: REQUIRED -#define i_del // destroy value func - defaults to empty destruct -#define i_valfrom // func Raw => i_val - defaults to plain copy +#define i_drop // destroy value func - defaults to empty destruct +#define i_from // func Raw => i_val - defaults to plain copy #define i_valto // func i_val => Raw - defaults to plain copy #define i_tag // defaults to i_val @@ -29,7 +29,7 @@ carr2_X carr2_X_with_storage(size_t xdim, size_t ydim, i_val* array) carr2_X carr2_X_clone(carr2_X arr); void carr2_X_copy(carr2_X* self, carr2_X other); i_val* carr2_X_release(carr2_X* self); // release storage (not freed) -void carr2_X_del(carr2_X* self); +void carr2_X_drop(carr2_X* self); size_t carr2_X_size(carr2_X arr); i_val* carr2_X_data(carr2_X* self); // access storage data @@ -48,7 +48,7 @@ carr3_X carr3_X_with_storage(size_t xdim, size_t ydim, size_t zdim, carr3_X carr3_X_clone(carr3_X arr); void carr3_X_copy(carr3_X* self, carr3_X other); i_val* carr3_X_release(carr3_X* self); // release storage (not freed) -void carr3_X_del(carr3_X* self); +void carr3_X_drop(carr3_X* self); size_t carr3_X_size(carr3_X arr); i_val* carr3_X_data(carr3_X* self); // storage data @@ -91,7 +91,7 @@ int main() int xd = 30, yd = 20, zd = 10; // define arr3[30][20][10], initialized with zeros. c_autovar (carr3_f arr3 = carr3_f_with_values(xd, yd, zd, 0.0f), - carr3_f_del(&arr3)) { + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 3.14f; float *arr1 = arr3.data[5][4]; @@ -104,7 +104,7 @@ int main() // Ex2 int w = 256, h = 128; - c_autovar (carr2_i image = carr2_i_init(w, h), carr2_i_del(&image)) { + c_autovar (carr2_i image = carr2_i_init(w, h), carr2_i_drop(&image)) { int n = 0; c_foreach (i, carr2_i, image) { uint32_t t = n++ % 256; diff --git a/docs/cbits_api.md b/docs/cbits_api.md index b369b5d1..f6077d20 100644 --- a/docs/cbits_api.md +++ b/docs/cbits_api.md @@ -27,7 +27,7 @@ cbits cbits_clone(cbits other); void cbits_clear(cbits* self); cbits* cbits_copy(cbits* self, cbits other); void cbits_resize(cbits* self, size_t size, bool value); -void cbits_del(cbits* self); +void cbits_drop(cbits* self); cbits* cbits_take(cbits* self, cbits other); // give other to self cbits cbits_move(cbits* self); // transfer self to caller @@ -103,7 +103,7 @@ int main(void) if (cbits_test(primes, i>>1)) printf(" %zu", i); puts(""); - cbits_del(&primes); + cbits_drop(&primes); } ``` Output: diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 83cec830..8580e7d7 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -1,12 +1,12 @@ # STC [cbox](../include/stc/cbox.h): (Boxed) Heap Allocated Objects **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_compare()*, *cbox_X_del()* methods are defined based on the `i_cmp` -and `i_valdel` macros specified. Use *cbox_X_clone(p)* to make a deep copy, which uses the +be empty. The *cbox_X_cmp()*, *cbox_X_drop()* methods are defined based on the `i_cmp` +and `i_valdrop` macros specified. Use *cbox_X_clone(p)* to make a deep copy, which uses the `i_valfrom` macro if defined. -When declaring a container of **cbox** values, it is recommended to define `i_val_ref` to the -cbox type instead of defining `i_val`. This will auto-set `i_del`, `i_from`, and `i_cmp` using +When declaring a container of **cbox** values, it is recommended to define `i_val_bind` to the +cbox type instead of defining `i_val`. This will auto-set `i_drop`, `i_from`, and `i_cmp` using functions defined by the specified **cbox**. For containers, make sure to pass the result of create functions like *cbox_X_new()* **only** to @@ -20,21 +20,21 @@ See similar c++ class [std::unique_ptr](https://en.cppreference.com/w/cpp/memory ```c #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_del // destroy value func - defaults to empty destruct -#define i_from // create from raw/clone func - REQUIRED if i_del is defined, +#define i_drop // destroy value func - defaults to empty destruct +#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> ``` `X` should be replaced by the value of `i_tag` in all of the following documentation. -Define `i_opt` with `c_no_compare` if comparison between i_val's is not needed/available. Will then +Define `i_opt` with `c_no_cmp` if comparison between i_val's is not needed/available. Will then compare the pointer addresses when used. Additionally, `c_no_clone` or `i_is_fwd` may be defined. ## Methods ```c cbox_X cbox_X_init(); // return an empty cbox cbox_X cbox_X_new(i_val val); // allocate new heap object with val. Take ownership of val. -cbox_X cbox_X_from(i_rawval raw); // like cbox_X_new(), but create owned value from raw. +cbox_X cbox_X_from(i_valraw raw); // like cbox_X_new(), but create owned value from raw. cbox_X cbox_X_with(i_val* p); // create a cbox from a pointer. Takes ownership of p. cbox_X cbox_X_clone(cbox_X other); // return deep copied clone @@ -42,14 +42,14 @@ cbox_X cbox_X_move(cbox_X* self); // transfer owners void cbox_X_take(cbox_X* self, cbox_X other); // take ownership of other. void cbox_X_copy(cbox_X* self, cbox_X other); // deep copy to self -void cbox_X_del(cbox_X* self); // destruct the contained object and free's it. +void cbox_X_drop(cbox_X* self); // destruct the contained object and free's it. void cbox_X_reset(cbox_X* self); void cbox_X_reset_new(cbox_X* self, i_val val); // assign new cbox with value. Takes ownership of val. -void cbox_X_reset_from(cbox_X* self, i_rawval raw); // make and assign new cbox from raw value. +void cbox_X_reset_from(cbox_X* self, i_valraw raw); // make and assign new cbox from raw value. void cbox_X_reset_with(cbox_X* self, i_val* p); // create cbox with pointer p. Takes ownership of p. -int cbox_X_compare(const cbox_X* x, const cbox_X* y); // compares pointer addresses if 'i_opt c_no_compare' +int cbox_X_cmp(const cbox_X* x, const cbox_X* y); // compares pointer addresses if 'i_opt c_no_cmp' // is defined. Otherwise uses 'i_cmp' or default compare. ``` ## Types and constants @@ -66,14 +66,14 @@ int cbox_X_compare(const cbox_X* x, const cbox_X* y); // compares pointe #include <stdio.h> #include <string.h> -void int_del(int* x) { - printf("del: %d\n", *x); +void int_drop(int* x) { + printf("drop: %d\n", *x); } -// When 'i_del' is defined, you are also forced to define a clone function with -// 'i_valfrom', as it is normally required when i_del destroys resources. +// When 'i_drop' is defined, you are also forced to define a clone function with +// 'i_from', as it is normally required when i_drop destroys resources. // -// If cloning is not needed, define 'i_opt c_no_clone' instead of 'i_valfrom' +// If cloning is not needed, define 'i_opt c_no_clone' instead of 'i_from' // both for the cbox type and the container of cbox elements. It will also // disable emplace container functions. // @@ -81,22 +81,22 @@ void int_del(int* x) { // define cloning internally. #define i_val int -#define i_del int_del // optional func, just to display elements destroyed -#define i_valfrom c_default_clone -#include <stc/cbox.h> // cbox_int +#define i_drop int_drop // optional func, just to display elements destroyed +#define i_from c_default_clone +#include <stc/cbox.h> // cbox_int -#define i_key_ref cbox_int // note: use i_key_ref 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_key_bind cbox_int // note: use i_key_bind 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_ref cbox_int // note: use i_val_ref 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>>) +#define i_val_bind cbox_int // note: use i_val_bind 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>>) int main() { - c_auto (cvec_int, vec) // declare and init vec, call del at scope exit - c_auto (csset_int, set) // declare and init set, call del at scope exit + c_auto (cvec_int, vec) // declare and init vec, call drop at scope exit + c_auto (csset_int, set) // declare and init set, call drop at scope exit { c_apply(cvec_int, push_back, &vec, { cbox_int_new(2021), @@ -130,13 +130,13 @@ int main() Output: ``` vec: 2021 2012 2022 2015 -del: 2015 -del: 2022 +drop: 2015 +drop: 2022 vec: 2021 2012 set: 2015 2021 Done -del: 2021 -del: 2015 -del: 2021 -del: 2012 +drop: 2021 +drop: 2015 +drop: 2021 +drop: 2012 ``` diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 740df9a4..cc021001 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -13,7 +13,7 @@ macros, as one must always make sure to unwind temporary allocated resources bef | Usage | Description | |:---------------------------------------|:---------------------------------------------------| -| `c_auto (Type, var...)` | `c_autovar (Type var=Type_init(), Type_del(&var))` | +| `c_auto (Type, var...)` | `c_autovar (Type var=Type_init(), Type_drop(&var))` | | `c_autovar (Type var=init, end...)` | Declare `var`. Defer `end...` to end of block | | `c_autoscope (init, end...)` | Execute `init`. Defer `end...` to end of block | | `c_autodefer (end...)` | Defer `end...` to end of block | @@ -22,7 +22,7 @@ macros, as one must always make sure to unwind temporary allocated resources bef For multiple variables, use either multiple **c_autovar** in sequence, or declare variable outside scope and use **c_autoscope**. Also, **c_auto** support up to 3 variables. ```c -c_autovar (cstr s = cstr_new("Hello"), cstr_del(&s)) +c_autovar (cstr s = cstr_new("Hello"), cstr_drop(&s)) { cstr_append(&s, " world"); printf("%s\n", s.str); @@ -46,7 +46,7 @@ c_autoscope (mydata_init(&data), mydata_destroy(&data)) } cstr s1 = cstr_new("Hello"), s2 = cstr_new("world"); -c_autodefer (cstr_del(&s1), cstr_del(&s2)) +c_autodefer (cstr_drop(&s1), cstr_drop(&s2)) { printf("%s %s\n", s1.str, s2.str); } @@ -65,7 +65,7 @@ cvec_str readFile(const char* name) cvec_str vec = cvec_str_init(); // returned c_autovar (FILE* fp = fopen(name, "r"), fclose(fp)) - c_autovar (cstr line = cstr_null, cstr_del(&line)) + c_autovar (cstr line = cstr_null, cstr_drop(&line)) while (cstr_getline(&line, fp)) cvec_str_emplace_back(&vec, line.str); return vec; @@ -73,7 +73,7 @@ cvec_str readFile(const char* name) int main() { - c_autovar (cvec_str x = readFile(__FILE__), cvec_str_del(&x)) + c_autovar (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) c_foreach (i, cvec_str, x) printf("%s\n", i.ref->str); } @@ -140,14 +140,14 @@ int arr[] = {1, 2, 3}; c_apply_n(cvec_i, push_back, &vec, arr, c_arraylen(arr)); ``` -### c_new, c_alloc, c_alloc_n, c_del, c_make +### c_new, c_alloc, c_alloc_n, c_drop, c_make | Usage | Meaning | |:-------------------------------|:----------------------------------------| | `c_new (type, value)` | Move value to a new object on the heap | | `c_alloc (type)` | `(type *) c_malloc(sizeof(type))` | | `c_alloc_n (type, N)` | `(type *) c_malloc((N)*sizeof(type))` | -| `c_del (ctype, &c1, ..., &cN)` | `ctype_del(&c1); ... ctype_del(&cN)` | +| `c_drop (ctype, &c1, ..., &cN)` | `ctype_drop(&c1); ... ctype_drop(&cN)` | | `c_make(type){value...}` | `(type){value...}` // c++ compatability | ```c @@ -159,17 +159,17 @@ int* array = c_alloc_n (int, 100); c_free(array); cstr a = cstr_new("Hello"), b = cstr_new("World"); -c_del(cstr, &a, &b); +c_drop(cstr, &a, &b); ``` ### General predefined template parameter functions ``` -int c_default_compare(const Type*, const Type*); +int c_default_cmp(const Type*, const Type*); Type c_default_clone(Type val); // simple copy Type c_default_toraw(const Type* val); // dereference val -void c_default_del(Type* val); // does nothing +void c_default_drop(Type* val); // does nothing -int c_rawstr_compare(const char* const* a, const char* const* b); +int c_rawstr_cmp(const char* const* a, const char* const* b); bool c_rawstr_equalto(const char* const* a, const char* const* b); ``` diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 554b4c7b..1985c2ab 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -10,7 +10,7 @@ See the c++ class [std::deque](https://en.cppreference.com/w/cpp/container/deque ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -31,7 +31,7 @@ void cdeq_X_copy(cdeq_X* self, cdeq_X other); bool cdeq_X_reserve(cdeq_X* self, size_t cap); void cdeq_X_shrink_to_fit(cdeq_X* self); void cdeq_X_swap(cdeq_X* a, cdeq_X* b); -void cdeq_X_del(cdeq_X* self); // destructor +void cdeq_X_drop(cdeq_X* self); // destructor bool cdeq_X_empty(cdeq_X deq); size_t cdeq_X_size(cdeq_X deq); @@ -119,7 +119,7 @@ int main() { c_foreach (i, cdeq_i, q) printf(" %d", *i.ref); puts(""); - cdeq_i_del(&q); + cdeq_i_drop(&q); } ``` Output: diff --git a/docs/clist_api.md b/docs/clist_api.md index b45108a7..0817737b 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -24,10 +24,10 @@ See the c++ class [std::list](https://en.cppreference.com/w/cpp/container/list) ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val -#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_from // convertion func i_valraw => i_val - defaults to plain copy #define i_tag // defaults to i_val #include <stc/clist.h> ``` @@ -42,7 +42,7 @@ clist_X clist_X_clone(clist_X list); void clist_X_clear(clist_X* self); void clist_X_copy(clist_X* self, clist_X other); -void clist_X_del(clist_X* self); // destructor +void clist_X_drop(clist_X* self); // destructor bool clist_X_empty(clist_X list); size_t clist_X_count(clist_X list); // size() in O(n) time @@ -125,7 +125,7 @@ int main() { c_foreach (i, clist_d, list) printf(" %g", *i.ref); - clist_d_del(&list); + clist_d_drop(&list); } ``` Output: @@ -161,7 +161,7 @@ int main () c_foreach (x, clist_i, L) printf(" %d", *x.ref); puts(""); - clist_i_del(&L); + clist_i_drop(&L); } ``` Output: diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 0fec365c..e2cb668f 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -21,13 +21,13 @@ See the c++ class [std::unordered_map](https://en.cppreference.com/w/cpp/contain #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_keyraw*: REQUIRED IF i_keyraw is non-integral type #define i_equ // equality comparison two i_keyraw*: ALTERNATIVE to i_cmp -#define i_keydel // destroy key func - defaults to empty destruct +#define i_keydrop // destroy key func - defaults to empty destruct #define i_keyraw // convertion "raw" type - defaults to i_key -#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy +#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy #define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy -#define i_valdel // destroy value func - defaults to empty destruct +#define i_valdrop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val -#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy #define i_tag // defaults to i_key #include <stc/cmap.h> @@ -47,7 +47,7 @@ void cmap_X_max_load_factor(cmap_X* self, float max_load); bool cmap_X_reserve(cmap_X* self, size_t size); void cmap_X_shrink_to_fit(cmap_X* self); void cmap_X_swap(cmap_X* a, cmap_X* b); -void cmap_X_del(cmap_X* self); // destructor +void cmap_X_drop(cmap_X* self); // destructor size_t cmap_X_size(cmap_X map); size_t cmap_X_capacity(cmap_X map); // buckets * max_load_factor @@ -207,15 +207,15 @@ typedef struct { int x, y, z; } Vec3i; int main() { // Define map with defered destruct - c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_del(&vecs)) + c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) { cmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1); cmap_vi_insert(&vecs, (Vec3i){ 0, 100, 0}, 2); cmap_vi_insert(&vecs, (Vec3i){ 0, 0, 100}, 3); cmap_vi_insert(&vecs, (Vec3i){100, 100, 100}, 4); - c_foreach (i, cmap_vi, vecs) - printf("{ %3d, %3d, %3d }: %d\n", i.ref->first.x, i.ref->first.y, i.ref->first.z, i.ref->second); + c_forpair (vec, num, cmap_vi, vecs) + printf("{ %3d, %3d, %3d }: %d\n", _.vec.x, _.vec.y, _.vec.z, _.num); } } ``` @@ -240,15 +240,15 @@ typedef struct { int x, y, z; } Vec3i; int main() { - c_autovar (cmap_iv vecs = cmap_iv_init(), cmap_iv_del(&vecs)) + c_auto (cmap_iv, vecs) // shorthand for c_autovar with _init(), _drop(). { cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0}); cmap_iv_insert(&vecs, 3, (Vec3i){ 0, 0, 100}); cmap_iv_insert(&vecs, 4, (Vec3i){100, 100, 100}); - c_foreach (i, cmap_iv, vecs) - printf("%d: { %3d, %3d, %3d }\n", i.ref->first, i.ref->second.x, i.ref->second.y, i.ref->second.z); + c_forpair (num, vec, cmap_iv, vecs) + printf("%d: { %3d, %3d, %3d }\n", _.num_, _.vec.x, _.vec.y, _.vec.z); } } ``` @@ -270,45 +270,56 @@ typedef struct { cstr country; } Viking; -static bool Viking_equalto(const Viking* a, const Viking* b) { +#define Viking_init() ((Viking){cstr_null, cstr_null}) + +static inline bool RViking_equalto(const Viking* a, const Viking* b) { return cstr_equals_s(a->name, b->name) && cstr_equals_s(a->country, b->country); } -static uint32_t Viking_hash(const Viking* a, int ignored) { +static inline uint32_t RViking_hash(const Viking* a, int ignored) { return c_strhash(a->name.str) ^ (c_strhash(a->country.str) >> 15); } -static void Viking_del(Viking* v) { - c_del(cstr, &v->name, &v->country); +static inline Viking Viking_clone(Viking v) { + v.name = cstr_clone(v.name); + v.country = cstr_clone(v.country); +} + +void inline Viking_drop(Viking* vk) { + cstr_drop(&vk->name); + cstr_drop(&vk->country); } -#define i_key Viking +#define i_type Vikings +#define i_key_bind Viking #define i_val int -#define i_equ Viking_equalto -#define i_hash Viking_hash -#define i_del Viking_del -#define i_tag vk +// i_key_bind auto-binds: +// #define i_equ RViking_equalto +// #define i_hash RViking_hash +// #define i_keyfrom Viking_clone +// #define i_drop Viking_drop #include <stc/cmap.h> int main() { // Use a HashMap to store the vikings' health points. - cmap_vk vikings = cmap_vk_init(); - - cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25); - cmap_vk_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24); - cmap_vk_insert(&vikings, (Viking){cstr_new("Harald"), cstr_new("Iceland")}, 12); - cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Denmark")}, 21); - - Viking lookup = (Viking){cstr_new("Einar"), cstr_new("Norway")}; - printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, lookup)); - Viking_del(&lookup); - - // Print the status of the vikings. - c_foreach (i, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", i.ref->first.name.str, i.ref->first.country.str, i.ref->second); + c_auto (Vikings, vikings) // uses Vikings_init(), Vikings_drop() + { + Vikings_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25); + Vikings_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24); + Vikings_insert(&vikings, (Viking){cstr_new("Harald"), cstr_new("Iceland")}, 12); + Vikings_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Denmark")}, 21); + + c_auto (Viking, lookup) { + lookup = (Viking){cstr_new("Einar"), cstr_new("Norway")}; + printf("Lookup: Einar of Norway has %d hp\n\n", *Vikings_at(&vikings, lookup)); + } + + // Print the status of the vikings. + c_forpair (viking, hp, Vikings, vikings) { + printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.hp); + } } - cmap_vk_del(&vikings); } ``` Output: @@ -326,65 +337,65 @@ to add "raw" type entries (otherwise compile error): ```c #include <stc/cstr.h> -typedef struct { +typedef struct Viking { cstr name; cstr country; } Viking; -static void Viking_del(Viking* v) { - c_del(cstr, &v->name, &v->country); +static inline void Viking_drop(Viking* v) { + c_drop(cstr, &v->name, &v->country); } -// Define a "raw" type that does not need allocations. -// Define equals, hash, fromraw, toraw functions: +// Define Viking raw struct with hash, equalto, and convertion functions between Viking and RViking structs: -typedef struct { +typedef struct RViking { const char* name; const char* country; } RViking; -static bool RViking_equalto(const RViking* r1, const RViking* r2) - { return !strcmp(r1->name, r2->name) && !strcmp(r1->country, r2->country); } - -static uint32_t RViking_hash(const RViking* r, int ignored) - { return c_strhash(r->name) ^ (c_strhash(r->country) >> 15); } - -static Viking Viking_fromR(RViking r) - { return (Viking){cstr_from(r.name), cstr_from(r.country)}; } +static inline uint64_t RViking_hash(const RViking* raw, size_t ignore) { + uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15); + return hash; +} +static inline bool RViking_equalto(const RViking* rx, const RViking* ry) { + return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; +} -static RViking Viking_toR(const Viking* v) - { return (RViking){v->name.str, v->country.str}; } +static inline Viking Viking_from(RViking raw) { + return (Viking){cstr_from(raw.name), cstr_from(raw.country)}; +} +static inline RViking Viking_toraw(const Viking* vk) { + return (RViking){vk->name.str, vk->country.str}; +} -#define i_key Viking -#define i_val int -#define i_keydel Viking_del -#define i_keyraw RViking -#define i_equ RViking_equalto -#define i_hash RViking_hash -#define i_keyfrom Viking_fromR -#define i_keyto Viking_toR -#define i_tag vk +// With this in place, we define the Viking => int hash map type: +#define i_type Vikings +#define i_key_bind Viking +#define i_val int +#define i_keyraw RViking +// i_key_bind macro will make these functions auto-bind: +// #define i_hash RViking_hash +// #define i_equ RViking_equalto +// #define i_keyfrom Viking_from // uses _from because i_keyraw is defined +// #define i_keyto Viking_toraw +// #define i_keydrop Viking_drop #include <stc/cmap.h> int main() { - c_auto (cmap_vk, vikings) // RAII - { - // Insert works as before, takes a constructed Viking object - cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25); - cmap_vk_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24); - - // Emplace is simpler to use now - takes rawkey argument - cmap_vk_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); - cmap_vk_emplace(&vikings, (RViking){"Einar", "Denmark"}, 21); + c_auto (Vikings, vikings) { + c_apply_pair(Vikings, emplace, &vikings, { + {{"Einar", "Norway"}, 20}, + {{"Olaf", "Denmark"}, 24}, + {{"Harald", "Iceland"}, 12}, + }); + Vikings_emplace_or_assign(&vikings, (RViking){"Bjorn", "Sweden"}, 10); - // Lookup also uses rawkey args, no need construct/destruct key: - printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, (RViking){"Einar", "Norway"})); + Vikings_value *einar = Vikings_find(&vikings, (RViking){"Einar", "Norway"}).ref; + if (einar) einar->second += 3; // add 3 hp points to Einar - // Print the status of the vikings. - c_foreach (i, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", i.ref->first.name.str, - i.ref->first.country.str, i.ref->second); + c_forpair (viking, health, Vikings, vikings) { + printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.health); } } } diff --git a/docs/cpque_api.md b/docs/cpque_api.md index 5c0c9ec4..e891b7d2 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -12,7 +12,7 @@ See the c++ class [std::priority_queue](https://en.cppreference.com/w/cpp/contai ```c #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_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valfrom // convertion func i_val => i_val - defaults to plain copy #define i_tag // defaults to i_val #include <stc/cpque.h> @@ -29,7 +29,7 @@ void cpque_X_clear(cpque_X* self); bool cpque_X_reserve(cpque_X* self, size_t n); void cpque_X_shrink_to_fit(cpque_X* self); void cpque_X_copy(cpque_X* self, cpque_X other); -void cpque_X_del(cpque_X* self); // destructor +void cpque_X_drop(cpque_X* self); // destructor size_t cpque_X_size(cpque_X pq); bool cpque_X_empty(cpque_X pq); @@ -59,7 +59,7 @@ cpque_X_value cpque_X_value_clone(cpque_X_value val); #include <stdio.h> #define i_val int64_t -#define i_cmp -c_default_compare // min-heap +#define i_cmp -c_default_cmp // min-heap #define i_tag i #include <stc/cpque.h> @@ -69,7 +69,7 @@ int main() stc64_t rng = stc64_init(1234); stc64_uniform_t dist = stc64_uniform_init(0, N * 10); - // Declare heap, with defered del() + // Declare heap, with defered drop() c_auto (cpque_i, heap) { // Push ten million random numbers to priority queue, plus some negative ones. diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md index 469b7c99..9fd2c4e0 100644 --- a/docs/cqueue_api.md +++ b/docs/cqueue_api.md @@ -9,7 +9,7 @@ See the c++ class [std::queue](https://en.cppreference.com/w/cpp/container/queue ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -27,7 +27,7 @@ cqueue_X cqueue_X_clone(cqueue_X q); void cqueue_X_clear(cqueue_X* self); void cqueue_X_copy(cqueue_X* self, cqueue_X other); -void cqueue_X_del(cqueue_X* self); // destructor +void cqueue_X_drop(cqueue_X* self); // destructor size_t cqueue_X_size(cqueue_X q); bool cqueue_X_empty(cqueue_X q); @@ -76,7 +76,7 @@ int main() { c_foreach (i, cqueue_i, Q) printf(" %d", *i.ref); - cqueue_i_del(&Q); + cqueue_i_drop(&Q); } ``` Output: diff --git a/docs/crandom_api.md b/docs/crandom_api.md index 3dd829aa..b099eeaf 100644 --- a/docs/crandom_api.md +++ b/docs/crandom_api.md @@ -108,8 +108,8 @@ int main() } } // Cleanup - cstr_del(&bar); - csmap_i_del(&mhist); + cstr_drop(&bar); + csmap_i_drop(&mhist); } ``` Output: diff --git a/docs/cset_api.md b/docs/cset_api.md index 4883664d..b70f5fb9 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -11,10 +11,10 @@ A **cset** is an associative container that contains a set of unique objects of #define i_hash // hash func: REQUIRED IF i_keyraw is a non-pod type
#define i_cmp // three-way compare two i_keyraw*: REQUIRED IF i_keyraw is a non-integral type
#define i_equ // equality comparison two i_keyraw*: ALTERNATIVE to i_cmp
-#define i_del // destroy key func - defaults to empty destruct
+#define i_drop // destroy key func - defaults to empty destruct
#define i_keyraw // convertion "raw" type - defaults to i_key
-#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
-#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy
+#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
+#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy
#define i_tag // defaults to i_key
#include <stc/cset.h>
```
@@ -33,7 +33,7 @@ void cset_X_max_load_factor(cset_X* self, float max_load); bool cset_X_reserve(cset_X* self, size_t size);
void cset_X_shrink_to_fit(cset_X* self);
void cset_X_swap(cset_X* a, cset_X* b);
-void cset_X_del(cset_X* self); // destructor
+void cset_X_drop(cset_X* self); // destructor
size_t cset_X_size(cset_X set); // num. of allocated buckets
size_t cset_X_capacity(cset_X set); // buckets * max_load_factor
diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 646f8c99..88d58cd4 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -18,11 +18,11 @@ See the c++ class [std::map](https://en.cppreference.com/w/cpp/container/map) fo #define i_key // key: REQUIRED #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_keyraw* : REQUIRED IF i_keyraw is a non-integral type -#define i_keydel // destroy key func - defaults to empty destruct +#define i_keydrop // destroy key func - defaults to empty destruct #define i_keyraw // convertion "raw" type - defaults to i_key #define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy #define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy -#define i_valdel // destroy value func - defaults to empty destruct +#define i_valdrop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -40,12 +40,12 @@ csmap_X csmap_X_clone(csmap_x map); void csmap_X_clear(csmap_X* self); void csmap_X_copy(csmap_X* self, csmap_X other); void csmap_X_swap(csmap_X* a, csmap_X* b); -void csmap_X_del(csmap_X* self); // destructor +void csmap_X_drop(csmap_X* self); // destructor size_t csmap_X_size(csmap_X map); bool csmap_X_empty(csmap_X map); -const csmap_X_mapped* csmap_X_at(const csmap_X* self, i_keyraw rkey); // rkey must be in map. +csmap_X_mapped* csmap_X_at(const csmap_X* self, i_keyraw rkey); // rkey must be in map. const csmap_X_value* csmap_X_get(const csmap_X* self, i_keyraw rkey); // return NULL if not found csmap_X_value* csmap_X_get_mut(csmap_X* self, i_keyraw rkey); // mutable get bool csmap_X_contains(const csmap_X* self, i_keyraw rkey); @@ -144,7 +144,7 @@ int main() { uint32_t col = 0xcc7744ff; csmap_id idnames = csmap_id_init(); - c_autodefer (csmap_id_del(&idnames)) + c_autodefer (csmap_id_drop(&idnames)) { c_apply_pair(csmap_id, emplace, &idnames, { {100, "Red"}, @@ -174,7 +174,7 @@ Demonstrate csmap with plain-old-data key type Vec3i and int as mapped type: csm ```c typedef struct { int x, y, z; } Vec3i; -static int Vec3i_compare(const Vec3i* a, const Vec3i* b) { +static int Vec3i_cmp(const Vec3i* a, const Vec3i* b) { int c; if ((c = a->x - b->x) != 0) return c; if ((c = a->y - b->y) != 0) return c; @@ -183,7 +183,7 @@ static int Vec3i_compare(const Vec3i* a, const Vec3i* b) { #define i_key Vec3i #define i_val int -#define i_cmp Vec3i_compare // uses c_default_hash +#define i_cmp Vec3i_cmp // uses c_default_hash #define i_tag vi #include <stc/csmap.h> #include <stdio.h> @@ -224,7 +224,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { // equivalent to: c_auto (csmap_iv, vecs) - c_autovar (csmap_iv vecs = csmap_iv_init(), csmap_iv_del(&vecs)) + c_autovar (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) { csmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); csmap_iv_insert(&vecs, 2, (Vec3i){0, 100, 0}); diff --git a/docs/csptr_api.md b/docs/csptr_api.md index 640f5cf1..5cbe746f 100644 --- a/docs/csptr_api.md +++ b/docs/csptr_api.md @@ -1,19 +1,19 @@ -# STC [csptr](../include/stc/csptr.h): Shared Pointers +# STC [csptr](../include/stc/csptr.h): Atomic Reference Counted **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_del()*; +deallocated when the last remaining **csptr** owning the object is destroyed with *csptr_X_drop()*; -The object is destroyed using *csptr_X_del()*. A **csptr** may also own no objects, in which -case it is called empty. The *csptr_X_compare()*, *csptr_X_del()* methods are defined based on -the `i_cmp` and `i_valdel` macros specified. Use *csptr_X_clone(p)* when sharing ownership of +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 pointed-to object. 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. +**csptr** uses thread-safe atomic reference counting, through the *csptr_X_clone()* and *csptr_X_drop()* methods. -When declaring a container with shared pointers, define `i_val_ref` as the csptr type, see example. +When declaring a container with shared pointers, define `i_val_bind` as the csptr 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 @@ -26,7 +26,7 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory ```c #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_del // destroy value func - defaults to empty destruct +#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> @@ -35,34 +35,34 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory ## Methods ```c -csptr_X csptr_X_init(); // empty shared pointer -csptr_X csptr_X_new(i_val val); // create new heap allocated object. Take ownership of val. -csptr_X csptr_X_from(i_rawval raw); // like csptr_X_new(), but construct owned value from raw. -csptr_X csptr_X_with(i_val* p); // create a csptr from raw pointer. Takes ownership of p. +csptr_X csptr_X_init(); // empty shared pointer +csptr_X csptr_X_new(i_val val); // create new heap allocated object. Take ownership of val. +csptr_X csptr_X_from(i_valraw raw); // like csptr_X_new(), but construct owned value from raw. +csptr_X csptr_X_with(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) +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_del(csptr_X* self); // destruct (decrease use count, free at 0) +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_new(csptr_X* self, i_val val); // assign new csptr with value. Takes ownership of val. -void csptr_X_reset_from(csptr_X* self, i_rawval raw); // make and assign new csptr from raw value. +void csptr_X_reset_from(csptr_X* self, i_valraw raw); // make and assign new csptr from raw value. void csptr_X_reset_with(csptr_X* self, i_val* p); // create csptr with pointer p. Takes ownership of p. -int csptr_X_compare(const csptr_X* x, const csptr_X* y); // compares pointer addresses if 'i_opt c_no_compare' - // is defined. Otherwise uses 'i_cmp' or default compare. +int csptr_X_cmp(const csptr_X* x, const csptr_X* y); // compares pointer addresses if 'i_opt c_no_cmp' + // is defined. Otherwise uses 'i_cmp' or default compare. ``` ## 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 | +| 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 | ## Example @@ -73,24 +73,24 @@ int csptr_X_compare(const csptr_X* x, const csptr_X* y); // compares poi #define i_type Map #define i_key_str // strings #define i_val int -#define i_keydel(p) (printf("del name: %s\n", (p)->str), cstr_del(p)) +#define i_keydrop(p) (printf("drop name: %s\n", (p)->str), cstr_drop(p)) #include <stc/csmap.h> #define i_type Arc // (atomic) ref. counted type #define i_val Map #define i_from Map_clone -#define i_del(p) (printf("del Arc:\n"), Map_del(p)) +#define i_drop(p) (printf("drop Arc:\n"), Map_drop(p)) // no comparison of Maps needed (or available), and // no need for atomic ref. count in single thread: -#define i_opt c_no_compare|c_no_atomic +#define i_opt c_no_cmp|c_no_atomic #include <stc/csptr.h> #define i_type Stack -#define i_val_ref Arc // define i_val_ref for csptr / cbox value, not i_val +#define i_val_bind Arc // define i_val_bind for csptr / cbox value, not i_val #include <stc/cstack.h> #define i_type List -#define i_val_ref Arc // as above +#define i_val_bind Arc // as above #include <stc/clist.h> int main() @@ -155,22 +155,22 @@ LIST Joanna:1992 Joey:1990 Mary:1995 Brad:1999 Jack:1980 Rosanna:2001 SHARED:2021 Brad:1999 CLONED:2021 Jack:1980 Rosanna:2001 -del Arc: -del name: Rick -del name: Tracy -del name: Steve -del Arc: -del name: CLONED -del name: Brad -del name: Rosanna -del name: Jack -del Arc: -del name: Brad -del name: SHARED -del name: Rosanna -del name: Jack -del Arc: -del name: Joanna -del name: Mary -del name: Joey +drop Arc: +drop name: Rick +drop name: Tracy +drop name: Steve +drop Arc: +drop name: CLONED +drop name: Brad +drop name: Rosanna +drop name: Jack +drop Arc: +drop name: Brad +drop name: SHARED +drop name: Rosanna +drop name: Jack +drop Arc: +drop name: Joanna +drop name: Mary +drop name: Joey ``` diff --git a/docs/csset_api.md b/docs/csset_api.md index 501473a6..c5cd0f88 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -10,10 +10,10 @@ See the c++ class [std::set](https://en.cppreference.com/w/cpp/container/set) fo ```c
#define i_key // key: REQUIRED
#define i_cmp // three-way compare two i_keyraw* : REQUIRED IF i_keyraw is a non-integral type
-#define i_del // destroy key func - defaults to empty destruct
+#define i_drop // destroy key func - defaults to empty destruct
#define i_keyraw // convertion "raw" type - defaults to i_key
-#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
-#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy
+#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
+#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy
#define i_tag // defaults to i_key
#include <stc/csset.h>
```
@@ -28,7 +28,7 @@ csset_X csset_X_clone(csset_x set); void csset_X_clear(csset_X* self);
void csset_X_copy(csset_X* self, csset_X other);
void csset_X_swap(csset_X* a, csset_X* b);
-void csset_X_del(csset_X* self); // destructor
+void csset_X_drop(csset_X* self); // destructor
size_t csset_X_size(csset_X set);
bool csset_X_empty(csset_X set);
@@ -59,8 +59,8 @@ csset_X_value csset_X_value_clone(csset_X_value val); | Type name | Type definition | Used to represent... |
|:-------------------|:--------------------------------------------------|:----------------------------|
| `csset_X` | `struct { ... }` | The csset type |
-| `csset_X_rawkey` | `i_rawkey` | The raw key type |
-| `csset_X_rawvalue` | `i_rawkey` | The raw key type |
+| `csset_X_rawkey` | `i_keyraw` | The raw key type |
+| `csset_X_rawvalue` | `i_keyraw` | The raw key type |
| `csset_X_key` | `i_key` | The key type |
| `csset_X_value` | `i_key ` | The value: key is immutable |
| `csset_X_result` | `struct { csset_X_value* ref; bool inserted; }` | Result of insert/emplace |
diff --git a/docs/cstack_api.md b/docs/cstack_api.md index e71b213f..b6992dc0 100644 --- a/docs/cstack_api.md +++ b/docs/cstack_api.md @@ -10,7 +10,7 @@ See the c++ class [std::stack](https://en.cppreference.com/w/cpp/container/stack ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -31,7 +31,7 @@ void cstack_X_clear(cstack_X* self); bool cstack_X_reserve(cstack_X* self, size_t n); void cstack_X_shrink_to_fit(cstack_X* self); void cstack_X_copy(cstack_X* self, cstack_X other); -void cstack_X_del(cstack_X* self); // destructor +void cstack_X_drop(cstack_X* self); // destructor size_t cstack_X_size(cstack_X st); size_t cstack_X_capacity(cstack_X st); @@ -81,7 +81,7 @@ int main() { printf("top: %d\n", *cstack_i_top(&S)); - cstack_i_del(&S); + cstack_i_drop(&S); } ``` Output: diff --git a/docs/cstr_api.md b/docs/cstr_api.md index e54b3a4c..463a723c 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -26,7 +26,7 @@ cstr cstr_clone(cstr s); cstr* cstr_take(cstr* self, cstr s); // take the constructed or moved string cstr cstr_move(cstr* self); // move string to caller, leave empty string -void cstr_del(cstr *self); // destructor +void cstr_drop(cstr *self); // destructor const char* cstr_str(const cstr* self); // self->str char* cstr_data(cstr* self); // self->str @@ -85,13 +85,14 @@ Note that all methods with arguments `(..., const char* str, size_t n)`, `n` mus #### Helper methods: ```c -int cstr_compare(const cstr *s1, const cstr *s2); +int cstr_cmp(const cstr *s1, const cstr *s2); bool cstr_equalto(const cstr *s1, const cstr *s2); bool cstr_hash(const cstr *s, ...); -int c_rawstr_compare(const char** x, const char** y); -bool c_rawstr_equalto(const char** x, const char** y); -uint64_t c_rawstr_hash(const char* const* x, ...); +typedef const char* c_rawstr; +int c_rawstr_cmp(const c_rawstr* x, const c_rawstr* y); +bool c_rawstr_equalto(const c_rawstr* x, const c_rawstr* y); +uint64_t c_rawstr_hash(const c_rawstr* x, size_t dummy); uint64_t c_strhash(const char* str); char* c_strnstrn(const char* str, const char* needle, size_t slen, size_t nlen); @@ -141,7 +142,7 @@ int main() { cstr full_path = cstr_from_fmt("%s/%s.%s", "directory", "filename", "ext"); printf("%s\n", full_path.str); - c_del(cstr, &s0, &s1, &full_path); + c_drop(cstr, &s0, &s1, &full_path); } ``` Output: diff --git a/docs/csview_api.md b/docs/csview_api.md index 7daa67ee..609c5d10 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -77,7 +77,7 @@ bool cstr_ends_with_v(cstr s, csview sub); ``` #### Helper methods ```c -int csview_compare(const csview* x, const csview* y); +int csview_cmp(const csview* x, const csview* y); bool csview_equalto(const csview* x, const csview* y); uint64_t csview_hash(const csview* x, size_t dummy); ``` @@ -118,7 +118,7 @@ int main () cstr s3 = cstr_from_v(cstr_substr(s1, 0, 6)); // "Apples" printf("%s %s\n", s2, s3.str); - c_del(cstr, &str1, &s1, &s2, &s3); + c_drop(cstr, &str1, &s1, &s2, &s3); } ``` Output: @@ -166,7 +166,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_del(&v)) + c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_drop(&v)) c_foreach (i, cvec_str, v) printf("\"%s\"\n", i.ref->str); } diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 00c0498c..b9d4d2d5 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -14,7 +14,7 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect ```c #define i_val // value: REQUIRED #define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type -#define i_del // destroy value func - defaults to empty destruct +#define i_drop // destroy value func - defaults to empty destruct #define i_valraw // convertion "raw" type - defaults to i_val #define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy #define i_valto // convertion func i_val* => i_valraw - defaults to plain copy @@ -23,7 +23,7 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect ``` `X` should be replaced by the value of `i_tag` in all of the following documentation. -`i_del` may be defined instead of `i_valdel` (or `i_keydel`) for all non-map containers. +`i_drop` may be defined instead of `i_valdrop` (or `i_keydrop`) for all non-map containers. ## Methods @@ -39,7 +39,7 @@ bool cvec_X_reserve(cvec_X* self, size_t cap); bool cvec_X_resize(cvec_X* self, size_t size, i_val null); void cvec_X_shrink_to_fit(cvec_X* self); void cvec_X_swap(cvec_X* a, cvec_X* b); -void cvec_X_del(cvec_X* self); // destructor +void cvec_X_drop(cvec_X* self); // destructor bool cvec_X_empty(cvec_X vec); size_t cvec_X_size(cvec_X vec); @@ -47,7 +47,7 @@ size_t cvec_X_capacity(cvec_X vec); const cvec_X_value* cvec_X_at(const cvec_X* self, size_t idx); const cvec_X_value* cvec_X_get(const cvec_X* self, i_valraw raw); // return NULL if not found -cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // get mutable value +cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // get mutable value cvec_X_iter cvec_X_find(const cvec_X* self, i_valraw raw); cvec_X_iter cvec_X_find_in(cvec_X_iter i1, cvec_X_iter i2, i_valraw raw); cvec_X_iter cvec_X_bsearch(const cvec_X* self, i_valraw raw); @@ -152,13 +152,13 @@ int main() { cstr tmp = cstr_from_fmt("%d elements so far", cvec_str_size(names)); // emplace_back() will not compile if adding a new cstr type. Use push_back(): - cvec_str_push_back(&names, tmp); // tmp is moved to names, do not del() it. + cvec_str_push_back(&names, tmp); // tmp is moved to names, do not drop() it. printf("%s\n", names.data[1].str); // Access the second element c_foreach (i, cvec_str, names) printf("item: %s\n", i.ref->str); - cvec_str_del(&names); + cvec_str_drop(&names); } ``` Output: @@ -179,12 +179,12 @@ typedef struct { int id; } User; -int User_compare(const User* a, const User* b) { +int User_cmp(const User* a, const User* b) { int c = strcmp(a->name.str, b->name.str); return c != 0 ? c : a->id - b->id; } -void User_del(User* self) { - cstr_del(&self->name); +void User_drop(User* self) { + cstr_drop(&self->name); } User User_clone(User user) { user.name = cstr_clone(user.name); @@ -194,9 +194,9 @@ User User_clone(User user) { // Declare a memory managed, clonable vector of users. // Note that cvec_u_emplace_back() will clone input: #define i_val User -#define i_cmp User_compare -#define i_del User_del -#define i_valfrom User_clone +#define i_cmp User_cmp +#define i_drop User_drop +#define i_from User_clone #define i_tag u #include <stc/cvec.h> @@ -209,6 +209,6 @@ int main(void) { c_foreach (i, cvec_u, vec2) printf("%s: %d\n", i.ref->name.str, i.ref->id); - c_del(cvec_u, &vec, &vec2); // cleanup + c_drop(cvec_u, &vec, &vec2); // cleanup } ``` diff --git a/examples/advanced.c b/examples/advanced.c deleted file mode 100644 index 60276b09..00000000 --- a/examples/advanced.c +++ /dev/null @@ -1,68 +0,0 @@ -#include <stdio.h> -#include <stc/cstr.h> - -typedef struct Viking { - cstr name; - cstr country; -} Viking; - -void viking_del(Viking* vk) { - cstr_del(&vk->name); - cstr_del(&vk->country); -} - -// Define Viking raw struct with hash, equals, and convertion functions between Viking and VikingRaw structs: - -typedef struct VikingRaw { - const char* name; - const char* country; -} VikingRaw; - -uint64_t vikingraw_hash(const VikingRaw* raw, size_t ignore) { - uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15); - return hash; -} -static inline bool vikingraw_equalto(const VikingRaw* rx, const VikingRaw* ry) { - return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; -} - -static inline Viking viking_fromRaw(VikingRaw raw) { // note: parameter is by value - return c_make(Viking){cstr_from(raw.name), cstr_from(raw.country)}; -} -static inline VikingRaw viking_toRaw(const Viking* vk) { - return c_make(VikingRaw){vk->name.str, vk->country.str}; -} - -// With this in place, we define the Viking => int hash map type: -#define i_tag vk -#define i_key Viking -#define i_val int -#define i_equ vikingraw_equalto -#define i_hash vikingraw_hash -#define i_keyraw VikingRaw -#define i_keyfrom viking_fromRaw -#define i_keyto viking_toRaw -#define i_keydel viking_del -#include <stc/cmap.h> - -int main() -{ - c_auto (cmap_vk, vikings) { - c_apply_pair(cmap_vk, emplace, &vikings, { - {{"Einar", "Norway"}, 20}, - {{"Olaf", "Denmark"}, 24}, - {{"Harald", "Iceland"}, 12}, - }); - VikingRaw bjorn = {"Bjorn", "Sweden"}; - cmap_vk_emplace_or_assign(&vikings, bjorn, 10); - - VikingRaw einar = {"Einar", "Norway"}; - cmap_vk_value *e = cmap_vk_find(&vikings, einar).ref; - e->second += 3; // add 3 hp points to Einar - cmap_vk_emplace(&vikings, einar, 0).ref->second += 5; // add 5 more to Einar - - c_foreach (k, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", k.ref->first.name.str, k.ref->first.country.str, k.ref->second); - } - } -}
\ No newline at end of file diff --git a/examples/astar.c b/examples/astar.c index 88c602ef..ee002b79 100644 --- a/examples/astar.c +++ b/examples/astar.c @@ -24,9 +24,9 @@ point_init(int x, int y, int width) }
int
-point_compare_priority(const point* a, const point* b)
+point_cmp_priority(const point* a, const point* b)
{
- return c_default_compare(&a->priorty, &b->priorty);
+ return c_default_cmp(&a->priorty, &b->priorty);
}
int
@@ -49,7 +49,7 @@ point_index(const point* p) }
int
-point_key_compare(const point* a, const point* b)
+point_key_cmp(const point* a, const point* b)
{
int i = point_index(a);
int j = point_index(b);
@@ -57,22 +57,22 @@ point_key_compare(const point* a, const point* b) }
#define i_val point
-#define i_cmp point_compare_priority
+#define i_cmp point_cmp_priority
#include <stc/cpque.h>
#define i_val point
-#define i_opt c_no_compare
+#define i_opt c_no_cmp
#include <stc/cdeq.h>
#define i_key point
#define i_val int
-#define i_cmp point_key_compare
+#define i_cmp point_key_cmp
#define i_tag pcost
#include <stc/csmap.h>
#define i_key point
#define i_val point
-#define i_cmp point_key_compare
+#define i_cmp point_key_cmp
#define i_tag pstep
#include <stc/csmap.h>
@@ -155,10 +155,10 @@ main(void) "# # # # # # # # # #\n"
"# @ # ##### ##### ##### ######### ##### # ######### # #\n"
"# # # # # # #\n"
- "#########################################################################\n"), cstr_del(&maze))
+ "#########################################################################\n"), cstr_drop(&maze))
{
int width = cstr_find(maze, "\n") + 1;
- c_autovar (cdeq_point path = astar(&maze, width), cdeq_point_del(&path))
+ c_autovar (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path))
{
c_foreach (it, cdeq_point, path) maze.str[point_index(it.ref)] = 'x';
printf("%s", maze.str);
diff --git a/examples/bits.c b/examples/bits.c index fbdee3e8..ac59bd32 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -3,13 +3,13 @@ int main()
{
- c_autovar (cbits set = cbits_with_size(23, true), cbits_del(&set)) {
+ c_autovar (cbits set = cbits_with_size(23, true), cbits_drop(&set)) {
printf("count %zu, %zu\n", cbits_count(set), set.size);
cbits s1 = cbits_new("1110100110111");
char buf[256];
cbits_to_str(s1, buf, 0, -1);
printf("buf: %s: %zu\n", buf, cbits_count(s1));
- cbits_del(&s1);
+ cbits_drop(&s1);
cbits_reset(&set, 9);
cbits_resize(&set, 43, false);
@@ -36,7 +36,7 @@ int main() printf("%d", cbits_test(set, i));
puts("");
- c_autovar (cbits s2 = cbits_clone(set), cbits_del(&s2)) {
+ c_autovar (cbits s2 = cbits_clone(set), cbits_drop(&s2)) {
cbits_flip_all(&s2);
cbits_set(&s2, 16);
cbits_set(&s2, 17);
diff --git a/examples/box.c b/examples/box.c index c7763bb8..d400799b 100644 --- a/examples/box.c +++ b/examples/box.c @@ -3,7 +3,7 @@ typedef struct { cstr name, last; } Person;
-Person Person_from(const char* name, const char* last) {
+Person Person_new(const char* name, const char* last) {
return (Person){.name = cstr_from(name), .last = cstr_from(last)};
}
@@ -17,44 +17,43 @@ Person Person_clone(Person p) { p.last = cstr_clone(p.last);
return p;
}
-void Person_del(Person* p) {
- printf("del: %s %s\n", p->name.str, p->last.str);
- c_del(cstr, &p->name, &p->last);
+
+void Person_drop(Person* p) {
+ printf("drop: %s %s\n", p->name.str, p->last.str);
+ c_drop(cstr, &p->name, &p->last);
}
-#define i_val Person
-#define i_cmp Person_cmp
-#define i_from Person_clone
-#define i_del Person_del
-#define i_tag prs
+#define i_type PPtr
+#define i_val_bind Person // binds Person_cmp, ...
#include <stc/cbox.h>
-#define i_val_ref cbox_prs
-#define i_tag prs
+#define i_type Persons
+#define i_val_bind PPtr // binds PPtr_cmp, ...
#include <stc/cvec.h>
int main()
{
- c_auto (cvec_prs, vec)
- c_auto (cbox_prs, p, q)
+ c_auto (Persons, vec)
+ c_auto (PPtr, p, q)
{
- p = cbox_prs_new(Person_from("Dave", "Cooper"));
+ p = PPtr_new(Person_new("Dave", "Cooper"));
- q = cbox_prs_clone(p);
+ q = PPtr_clone(p);
cstr_assign(&q.get->name, "Dale");
printf("%s %s.\n", p.get->name.str, p.get->last.str);
printf("%s %s.\n", q.get->name.str, q.get->last.str);
- cvec_prs_push_back(&vec, cbox_prs_new(Person_from("Laura", "Palmer")));
- cvec_prs_push_back(&vec, cbox_prs_new(Person_from("Shelly", "Johnson")));
+ Persons_push_back(&vec, PPtr_new(Person_new("Laura", "Palmer")));
+ Persons_push_back(&vec, PPtr_new(Person_new("Shelly", "Johnson")));
- c_foreach (i, cvec_prs, vec)
+ c_foreach (i, Persons, vec)
printf("%s: %s\n", i.ref->get->name.str, i.ref->get->last.str);
- c_autovar (Person per = Person_from("Laura", "Palmer"), Person_del(&per)) {
- const cbox_prs *v = cvec_prs_get(&vec, (cbox_prs){&per});
+ // Look-up Shelly!
+ c_autovar (Person s = Person_new("Shelly", "Johnson"), Person_drop(&s)) {
+ const PPtr *v = Persons_get(&vec, (PPtr){&s});
if (v) printf("found: %s: %s\n", v->get->name.str, v->get->last.str);
}
}
diff --git a/examples/box2.c b/examples/box2.c index 48266963..5549dade 100644 --- a/examples/box2.c +++ b/examples/box2.c @@ -18,14 +18,17 @@ struct { } typedef Rectangle;
#define i_val Point
+#define i_opt c_no_cmp
#include <stc/cbox.h> // cbox_Point
#define i_val Rectangle
+#define i_opt c_no_cmp
#include <stc/cbox.h> // cbox_Rectangle
// Box in box:
-#define i_val_ref cbox_Point // NB: adviced to use i_val_ref when value is a cbox or csptr!
- // it will auto-set i_del, i_from, i_cmp for you.
+#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_opt c_no_cmp
#define i_tag BoxPoint
#include <stc/cbox.h> // cbox_BoxPoint
diff --git a/examples/complex.c b/examples/complex.c index b6aef5a8..17a10fad 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -1,35 +1,30 @@ #include <stc/cstr.h>
-void check_del(float* v) {printf("destroy %g\n", *v);}
+void check_drop(float* v) {printf("destroy %g\n", *v);}
+#define i_type FloatStack
#define i_val float
-#define i_valdel check_del
-#define i_opt c_no_clone
-#define i_tag f
+#define i_drop check_drop
+#define i_from c_default_clone
#include <stc/cstack.h>
-#define i_val cstack_f
-#define i_opt c_no_clone|c_no_compare
-#define i_valdel cstack_f_del
-#define i_tag arr
+#define i_type StackList
+#define i_val_bind FloatStack
+#define i_opt c_no_cmp
#include <stc/clist.h>
+#define i_type ListMap
#define i_key int
-#define i_val clist_arr
-#define i_valdel clist_arr_del
-#define i_opt c_no_clone
-#define i_tag lst
+#define i_val_bind StackList
#include <stc/cmap.h>
+#define i_type MapMap
#define i_key_str
-#define i_val cmap_lst
-#define i_valdel cmap_lst_del
-#define i_opt c_no_clone
-#define i_tag map
+#define i_val_bind ListMap
#include <stc/cmap.h>
// c++:
-// using cstack_f = std::stack<float>;
+// using FloatStack = std::stack<float>;
// using map_lst = std::unordered_map<int, std::forward_list<array2f>>;
// using map_map = std::unordered_map<std::string, map_lst>;
@@ -38,29 +33,29 @@ int main() { int x = 1, y = 3, tableKey = 42;
const char* strKey = "first";
- c_auto (cmap_map, myMap)
+ c_auto (MapMap, mmap)
{
- cstack_f stk = cstack_f_with_capacity(xdim * ydim);
- memset(stk.data, 0, xdim*ydim*sizeof *stk.data);
- stk.size = stk.capacity;
+ FloatStack stack = FloatStack_with_capacity(xdim * ydim);
+ memset(stack.data, 0, xdim*ydim*sizeof *stack.data);
+ stack.size = stack.capacity;
// Put in some data in stack array
- stk.data[x] = 3.1415927f;
- printf("stk size: %zu\n", cstack_f_size(stk));
+ stack.data[x] = 3.1415927f;
+ printf("stack size: %zu\n", FloatStack_size(stack));
- clist_arr tableList = clist_arr_init();
- clist_arr_push_back(&tableList, stk);
+ StackList list = StackList_init();
+ StackList_push_back(&list, stack);
- cmap_lst listMap = cmap_lst_init();
- cmap_lst_insert(&listMap, tableKey, tableList);
- cmap_map_insert(&myMap, cstr_from(strKey), listMap);
+ ListMap lmap = ListMap_init();
+ ListMap_insert(&lmap, tableKey, list);
+ MapMap_insert(&mmap, cstr_from(strKey), lmap);
// Access the data entry
- const cmap_lst* mapL = cmap_map_at(&myMap, strKey);
- const clist_arr* lstA = cmap_lst_at(mapL, tableKey);
- const cstack_f* arr = clist_arr_back(lstA);
- printf("value (%d) is: %f\n", x, *cstack_f_at(arr, x));
+ const ListMap* lmap_p = MapMap_at(&mmap, strKey);
+ const StackList* list_p = ListMap_at(lmap_p, tableKey);
+ const FloatStack* stack_p = StackList_back(list_p);
+ printf("value (%d) is: %f\n", x, *FloatStack_at(stack_p, x));
- stk.data[x] = 1.41421356f; // change the value in array
+ stack.data[x] = 1.41421356f; // change the value in array
}
}
diff --git a/examples/cpque.c b/examples/cpque.c index b3ee4adf..0b8a610c 100644 --- a/examples/cpque.c +++ b/examples/cpque.c @@ -13,7 +13,7 @@ static int (*icmp_fn)(const int* x, const int* y); #define imix_less(left, right) ((*(left) ^ 1) < (*(right) ^ 1)) static int imax_cmp(const int* x, const int* y) { return *x - *y; } static int imin_cmp(const int* x, const int* y) { return *y - *x; } -static int imix_cmp(const int* x, const int* y) { return c_less_compare(imix_less, x, y); } +static int imix_cmp(const int* x, const int* y) { return c_less_cmp(imix_less, x, y); } void print_queue(ipque q) { ipque copy = ipque_clone(q); @@ -22,13 +22,13 @@ void print_queue(ipque q) { ipque_pop(©); } puts(""); - ipque_del(©); + ipque_drop(©); } int main() { const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_arraylen(data); - c_auto (ipque, q, q2, q3) // init() and defered del() + c_auto (ipque, q, q2, q3) // init() and defered drop() { icmp_fn = imax_cmp; c_forrange (i, n) diff --git a/examples/csmap_find.c b/examples/csmap_find.c index 78b6bbf5..3ca7ff87 100644 --- a/examples/csmap_find.c +++ b/examples/csmap_find.c @@ -8,7 +8,7 @@ #include <stc/csmap.h> #define i_val csmap_istr_rawvalue -#define i_opt c_no_compare +#define i_opt c_no_cmp #define i_tag istr #include <stc/cvec.h> diff --git a/examples/csmap_insert.c b/examples/csmap_insert.c index 920cf02d..c3690c83 100644 --- a/examples/csmap_insert.c +++ b/examples/csmap_insert.c @@ -15,7 +15,7 @@ #include <stc/csmap.h>
#define i_val csmap_ii_rawvalue
-#define i_opt c_no_compare
+#define i_opt c_no_cmp
#define i_tag ii
#include <stc/cvec.h>
diff --git a/examples/cstr_match.c b/examples/cstr_match.c index 041a2d84..dc1423d7 100644 --- a/examples/cstr_match.c +++ b/examples/cstr_match.c @@ -3,7 +3,7 @@ int main()
{
- c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_del(&ss)) {
+ c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) {
size_t pos = cstr_find_n(ss, "brown", 0, 5);
printf("%zu [%s]\n", pos, pos == cstr_npos ? "<NULL>" : &ss.str[pos]);
printf("equals: %d\n", cstr_equals(ss, "The quick brown fox jumps over the lazy dog.JPG"));
diff --git a/examples/demos.c b/examples/demos.c index 70aa722d..32e5dde0 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -3,7 +3,7 @@ void stringdemo1()
{
printf("\nSTRINGDEMO1\n");
- c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_del(&cs))
+ c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs))
{
printf("%s.\n", cs.str);
@@ -35,7 +35,7 @@ void stringdemo1() void vectordemo1()
{
printf("\nVECTORDEMO1\n");
- c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_del(&bignums))
+ c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums))
{
cvec_ix_reserve(&bignums, 100);
for (size_t i = 10; i <= 100; i += 10)
@@ -118,7 +118,7 @@ void setdemo1() c_foreach (i, cset_i, nums)
printf("set: %d\n", *i.ref);
- cset_i_del(&nums);
+ cset_i_drop(&nums);
}
#define i_key int
@@ -133,7 +133,7 @@ void mapdemo1() cmap_ii_emplace(&nums, 8, 64);
cmap_ii_emplace(&nums, 11, 121);
printf("val 8: %d\n", *cmap_ii_at(&nums, 8));
- cmap_ii_del(&nums);
+ cmap_ii_drop(&nums);
}
#define i_key_str
@@ -181,7 +181,7 @@ void mapdemo3() printf("size %zu\n", cmap_str_size(table));
c_foreach (i, cmap_str, table)
printf("entry: %s: %s\n", i.ref->first.str, i.ref->second.str);
- cmap_str_del(&table); // frees key and value cstrs, and hash table.
+ cmap_str_drop(&table); // frees key and value cstrs, and hash table.
}
#define i_val float
@@ -192,7 +192,7 @@ void arraydemo1() {
printf("\nARRAYDEMO1\n");
c_autovar (carr3_f arr3 = carr3_f_with_values(30, 20, 10, 0.0f),
- carr3_f_del(&arr3))
+ carr3_f_drop(&arr3))
{
arr3.data[5][4][3] = 10.2f;
float **arr2 = arr3.data[5];
diff --git a/examples/ex_gauss1.c b/examples/ex_gauss1.c index c96562b6..6725393f 100644 --- a/examples/ex_gauss1.c +++ b/examples/ex_gauss1.c @@ -13,7 +13,7 @@ // Declare int vector with map entries that can be sorted by map keys.
struct {int first; size_t second;} typedef mapval;
static int compare(mapval *a, mapval *b) {
- return c_default_compare(&a->first, &b->first);
+ return c_default_cmp(&a->first, &b->first);
}
#define i_val mapval
diff --git a/examples/inits.c b/examples/inits.c index 386be86e..a1733caf 100644 --- a/examples/inits.c +++ b/examples/inits.c @@ -12,19 +12,19 @@ #include <stc/cmap.h>
typedef struct {int x, y;} ipair_t;
-inline static int ipair_compare(const ipair_t* a, const ipair_t* b) {
- int c = c_default_compare(&a->x, &b->x);
- return c ? c : c_default_compare(&a->y, &b->y);
+inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) {
+ int c = c_default_cmp(&a->x, &b->x);
+ return c ? c : c_default_cmp(&a->y, &b->y);
}
#define i_val ipair_t
-#define i_cmp ipair_compare
+#define i_cmp ipair_cmp
#define i_tag ip
#include <stc/cvec.h>
#define i_val ipair_t
-#define i_cmp ipair_compare
+#define i_cmp ipair_cmp
#define i_tag ip
#include <stc/clist.h>
diff --git a/examples/mapmap.c b/examples/mapmap.c index e22a4f7b..61b55493 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -1,47 +1,67 @@ // unordered_map<string, unordered_map<string, string>>:
+#define i_type People
#define i_key_str
#define i_val_str
-#define i_tag sect
-#include <stc/csmap.h> // csmap_sect
+#define i_keydrop(p) (printf("kdrop: %s\n", (p)->str), cstr_drop(p))
+#include <stc/csmap.h>
+#define i_type Departments
#define i_key_str
-#define i_val csmap_sect
-#define i_valdel csmap_sect_del
-#define i_valfrom csmap_sect_clone
-#define i_tag conf
-#include <stc/csmap.h> // csmap_conf
+#define i_val_bind People
+#include <stc/csmap.h>
-void add(csmap_conf* map, const char* section, const char* entry, const char* value)
+#define i_type Stack
+#define i_val_bind People_value
+#define i_opt c_no_cmp
+//#define i_from People_value_clone
+//#define i_drop People_value_drop
+#include <stc/cstack.h>
+
+void add(Departments* deps, const char* name, const char* email, const char* dep)
{
- csmap_sect *smap = &csmap_conf_insert(map, cstr_from(section), csmap_sect_init()).ref->second;
- csmap_sect_emplace_or_assign(smap, entry, value);
+ People *people = &Departments_insert(deps, cstr_from(dep), People_init()).ref->second;
+ People_emplace_or_assign(people, name, email);
}
-bool contains(csmap_conf* map, const char* section, const char* entry)
+Stack contains(Departments* map, const char* name)
{
- const csmap_conf_value *val = csmap_conf_get(map, section);
- return val && csmap_sect_get(&val->second, entry);
+ Stack stk = Stack_init();
+ const People_value* v;
+ c_foreach (i, Departments, *map)
+ if ((v = People_get(&i.ref->second, name))) {
+ Stack_push(&stk, People_value_clone(*v));
+ }
+ return stk;
}
int main(void)
{
- c_auto (csmap_conf, map)
+ c_auto (Departments, map)
{
- add(&map, "user", "name", "Joe");
- add(&map, "user", "groups", "proj1,proj3");
- add(&map, "group", "proj1", "Energy");
- add(&map, "group", "proj2", "Windy");
- add(&map, "group", "proj3", "Oil");
- add(&map, "admin", "employees", "2302");
- add(&map, "group", "proj2", "Wind"); // Update
-
- printf("contains: %d\n", contains(&map, "group", "employees"));
- printf("contains: %d\n", contains(&map, "admin", "name"));
- printf("contains: %d\n", contains(&map, "admin", "employees"));
-
- c_foreach (i, csmap_conf, map)
- c_foreach (j, csmap_sect, i.ref->second)
- printf("%s: %s - %s\n", i.ref->first.str, j.ref->first.str, j.ref->second.str);
+ add(&map, "Anna Kendro", "[email protected]", "Support");
+ add(&map, "Terry Dane", "[email protected]", "Development");
+ add(&map, "Kik Winston", "[email protected]", "Finance");
+ add(&map, "Nancy Drew", "[email protected]", "Development");
+ add(&map, "Nick Denton", "[email protected]", "Finance");
+ add(&map, "Stan Whiteword", "[email protected]", "Marketing");
+ add(&map, "Serena Bath", "[email protected]", "Support");
+ add(&map, "Patrick Dust", "[email protected]", "Finance");
+ add(&map, "Red Winger", "[email protected]", "Marketing");
+ add(&map, "Nick Denton", "[email protected]", "Support");
+ add(&map, "Colin Turth", "[email protected]", "Support");
+ add(&map, "Dennis Kay", "[email protected]", "Marketing");
+ add(&map, "Anne Dickens", "[email protected]", "Development");
+
+ c_foreach (i, Departments, map)
+ c_forpair (name, email, People, i.ref->second)
+ printf("%s: %s - %s\n", i.ref->first.str, _.name.str, _.email.str);
+ puts("");
+
+ c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Nick Denton")));
+ c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Patrick Dust")));
+ c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Dennis Kay")));
+ c_auto (Stack, s) printf("found: %zu\n", Stack_size(s = contains(&map, "Serena Bath")));
+ puts("Done");
}
}
\ No newline at end of file diff --git a/examples/mmap.c b/examples/mmap.c index 26b271d1..ea08017b 100644 --- a/examples/mmap.c +++ b/examples/mmap.c @@ -1,36 +1,34 @@ // This implements the multimap c++ example found at:
// https://en.cppreference.com/w/cpp/container/multimap/insert
-// Map of int => clist_str. Note the negation of c_default_compare
+// Map of int => clist_str. Note the negation of c_default_cmp
#define i_val_str
#include <stc/clist.h>
+#define i_type Multimap
#define i_key int
-#define i_val clist_str
-#define i_cmp -c_default_compare
-#define i_valdel clist_str_del
-#define i_valfrom clist_str_clone
-#define i_tag mult
+#define i_val_bind clist_str
+#define i_cmp -c_default_cmp
#include <stc/csmap.h>
-void print(const csmap_mult mmap)
+void print(const Multimap mmap)
{
- c_foreach (e, csmap_mult, mmap) {
+ c_foreach (e, Multimap, mmap) {
c_foreach (s, clist_str, e.ref->second)
printf("{%d,%s} ", e.ref->first, s.ref->str);
}
puts("");
}
-void insert(csmap_mult* mmap, int key, const char* str)
+void insert(Multimap* mmap, int key, const char* str)
{
- clist_str *list = &csmap_mult_insert(mmap, key, clist_str_init()).ref->second;
+ clist_str *list = &Multimap_insert(mmap, key, clist_str_init()).ref->second;
clist_str_emplace_back(list, str);
}
int main()
{
- c_auto (csmap_mult, mmap)
+ c_auto (Multimap, mmap)
{
// list-initialize
struct {int i; const char* s;} vals[] = {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}};
@@ -53,12 +51,12 @@ int main() print(mmap);
// erase all entries with key 5
- csmap_mult_erase(&mmap, 5);
+ Multimap_erase(&mmap, 5);
print(mmap);
// find and erase a specific entry
clist_str_iter pos;
- c_foreach (e, csmap_mult, mmap)
+ c_foreach (e, Multimap, mmap)
if ((pos = clist_str_find(&e.ref->second, "bar")).ref != clist_str_end(&e.ref->second).ref) {
clist_str_erase_at(&e.ref->second, pos);
break;
diff --git a/examples/multimap.c b/examples/multimap.c index 543b8b22..424ae606 100644 --- a/examples/multimap.c +++ b/examples/multimap.c @@ -35,7 +35,7 @@ struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = typedef struct { int year; cstr city, date; } OlympicLocation;
-int OlympicLocation_compare(OlympicLocation* a, OlympicLocation* b) {
+int OlympicLocation_cmp(OlympicLocation* a, OlympicLocation* b) {
return a->year - b->year;
}
@@ -44,14 +44,14 @@ OlympicLocation OlympicLocation_clone(OlympicLocation loc) { loc.date = cstr_clone(loc.date);
return loc;
}
-void OlympicLocation_del(OlympicLocation* self) {
- c_del(cstr, &self->city, &self->date);
+void OlympicLocation_drop(OlympicLocation* self) {
+ c_drop(cstr, &self->city, &self->date);
}
// Create a clist<OlympicLocation>, can be sorted by year.
#define i_val OlympicLocation
-#define i_cmp OlympicLocation_compare
-#define i_del OlympicLocation_del
+#define i_cmp OlympicLocation_cmp
+#define i_drop OlympicLocation_drop
#define i_from OlympicLocation_clone
#define i_tag OL
#include <stc/clist.h>
@@ -59,7 +59,7 @@ void OlympicLocation_del(OlympicLocation* self) { // Create a csmap<cstr, clist_OL> where key is country name
#define i_key_str
#define i_val clist_OL
-#define i_valdel clist_OL_del
+#define i_valdrop clist_OL_drop
#define i_valfrom clist_OL_clone
#define i_tag OL
#include <stc/csmap.h>
diff --git a/examples/new_arr.c b/examples/new_arr.c index dc597e4a..a593536e 100644 --- a/examples/new_arr.c +++ b/examples/new_arr.c @@ -15,7 +15,7 @@ int main() int w = 7, h = 5, d = 3; c_autovar (carr2_int volume = carr2_int_init(w, h), - carr2_int_del(&volume)) + carr2_int_drop(&volume)) { int *dat = carr2_int_data(&volume); for (size_t i = 0; i < carr2_int_size(volume); ++i) @@ -32,7 +32,7 @@ int main() } c_autovar (carr3_int volume = carr3_int_init(w, h, d), - carr3_int_del(&volume)) + carr3_int_drop(&volume)) { int *dat = carr3_int_data(&volume); for (size_t i = 0; i < carr3_int_size(volume); ++i) @@ -50,7 +50,7 @@ int main() } c_autovar (carr2_str text2d = carr2_str_with_values(h, d, cstr_init()), - carr2_str_del(&text2d)) + carr2_str_drop(&text2d)) { cstr_assign(&text2d.data[2][1], "hello"); cstr_assign(&text2d.data[4][0], "world"); diff --git a/examples/new_deq.c b/examples/new_deq.c index cc3ff76b..57224869 100644 --- a/examples/new_deq.c +++ b/examples/new_deq.c @@ -16,13 +16,13 @@ struct MyStruct { #include <stc/cdeq.h>
struct Point { int x, y; } typedef Point;
-int point_compare(const Point* a, const Point* b) {
- int c = c_default_compare(&a->x, &b->x);
- return c ? c : c_default_compare(&a->y, &b->y);
+int point_cmp(const Point* a, const Point* b) {
+ int c = a->x - b->x;
+ return c ? c : a->y - b->y;
}
#define i_val Point
-#define i_cmp point_compare
+#define i_cmp point_cmp
#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cdeq.h>
diff --git a/examples/new_list.c b/examples/new_list.c index e07030b5..0867c7a6 100644 --- a/examples/new_list.c +++ b/examples/new_list.c @@ -15,13 +15,13 @@ struct MyStruct { #include <stc/clist.h> struct Point { int x, y; } typedef Point; -int point_compare(const Point* a, const Point* b) { - int c = c_default_compare(&a->x, &b->x); - return c ? c : c_default_compare(&a->y, &b->y); +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; } #define i_val Point -#define i_cmp point_compare +#define i_cmp point_cmp #define i_opt c_is_fwd #define i_tag pnt #include <stc/clist.h> diff --git a/examples/new_map.c b/examples/new_map.c index 8975cd77..953ca793 100644 --- a/examples/new_map.c +++ b/examples/new_map.c @@ -16,15 +16,15 @@ struct MyStruct { // Point => int map
struct Point { int x, y; } typedef Point;
-int point_compare(const Point* a, const Point* b) {
- int c = c_default_compare(&a->x, &b->x);
- return c ? c : c_default_compare(&a->y, &b->y);
+int point_cmp(const Point* a, const Point* b) {
+ int c = a->x - b->x;
+ return c ? c : a->y - b->y;
}
// Point => int map
#define i_key Point
#define i_val int
-#define i_cmp point_compare
+#define i_cmp point_cmp
#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cmap.h>
diff --git a/examples/new_pque.c b/examples/new_pque.c index 5048ea77..1485e630 100644 --- a/examples/new_pque.c +++ b/examples/new_pque.c @@ -16,8 +16,8 @@ struct MyStruct { struct Point { int x, y; } typedef Point;
int Point_cmp(const Point* a, const Point* b) {
- int c = c_default_compare(&a->x, &b->x);
- return c ? c : c_default_compare(&a->y, &b->y);
+ int c = a->x - b->x;
+ return c ? c : a->y - b->y;
}
#define i_val Point
diff --git a/examples/new_queue.c b/examples/new_queue.c index 3ad571bb..9219a1b4 100644 --- a/examples/new_queue.c +++ b/examples/new_queue.c @@ -6,12 +6,12 @@ forward_cqueue(cqueue_pnt, struct Point);
struct Point { int x, y; } typedef Point;
-int point_compare(const Point* a, const Point* b) {
- int c = c_default_compare(&a->x, &b->x);
- return c ? c : c_default_compare(&a->y, &b->y);
+int point_cmp(const Point* a, const Point* b) {
+ int c = c_default_cmp(&a->x, &b->x);
+ return c ? c : c_default_cmp(&a->y, &b->y);
}
#define i_val Point
-#define i_cmp point_compare
+#define i_cmp point_cmp
#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cqueue.h>
diff --git a/examples/new_smap.c b/examples/new_smap.c index 7f0730db..2cb35b99 100644 --- a/examples/new_smap.c +++ b/examples/new_smap.c @@ -15,14 +15,14 @@ struct MyStruct { // Point => int map
struct Point { int x, y; } typedef Point;
-int point_compare(const Point* a, const Point* b) {
- int c = c_default_compare(&a->x, &b->x);
- return c ? c : c_default_compare(&a->y, &b->y);
+int point_cmp(const Point* a, const Point* b) {
+ int c = a->x - b->x;
+ return c ? c : a->y - b->y;
}
#define i_key Point
#define i_val int
-#define i_cmp point_compare
+#define i_cmp point_cmp
#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/csmap.h>
diff --git a/examples/new_sptr.c b/examples/new_sptr.c index 4a715160..d1eed636 100644 --- a/examples/new_sptr.c +++ b/examples/new_sptr.c @@ -2,33 +2,33 @@ struct Person { cstr name, last; } typedef Person;
-Person Person_from(const char* name, const char* last) {
+Person Person_new(const char* name, const char* last) {
return (Person){.name = cstr_from(name), .last = cstr_from(last)};
}
-void Person_del(Person* p) {
- printf("del: %s %s\n", p->name.str, p->last.str);
- c_del(cstr, &p->name, &p->last);
+void Person_drop(Person* p) {
+ printf("drop: %s %s\n", p->name.str, p->last.str);
+ c_drop(cstr, &p->name, &p->last);
}
#define i_val Person
-#define i_del Person_del
-#define i_opt c_no_compare
+#define i_drop Person_drop
+#define i_opt c_no_cmp
#define i_tag person
#include <stc/csptr.h>
// ...
#define i_val int
-#define i_del(x) printf("del: %d\n", *(x))
+#define i_drop(x) printf("drop: %d\n", *(x))
#include <stc/csptr.h>
-#define i_val_ref csptr_int
+#define i_val_bind csptr_int
#define i_tag iptr
#include <stc/cstack.h>
int main(void) {
- c_autovar (csptr_person p = csptr_person_new(Person_from("John", "Smiths")), csptr_person_del(&p))
- c_autovar (csptr_person q = csptr_person_clone(p), csptr_person_del(&q)) // share the pointer
+ c_autovar (csptr_person p = csptr_person_new(Person_new("John", "Smiths")), csptr_person_drop(&p))
+ c_autovar (csptr_person q = csptr_person_clone(p), csptr_person_drop(&q)) // share the pointer
{
printf("%s %s. uses: %lu\n", q.get->name.str, q.get->last.str, *q.use_count);
}
diff --git a/examples/new_vec.c b/examples/new_vec.c index 62804125..c5570942 100644 --- a/examples/new_vec.c +++ b/examples/new_vec.c @@ -15,13 +15,13 @@ struct MyStruct { #include <stc/cvec.h>
struct Point { int x, y; } typedef Point;
-int point_compare(const Point* a, const Point* b) {
- int c = c_default_compare(&a->x, &b->x);
- return c ? c : c_default_compare(&a->y, &b->y);
+int point_cmp(const Point* a, const Point* b) {
+ int c = c_default_cmp(&a->x, &b->x);
+ return c ? c : c_default_cmp(&a->y, &b->y);
}
#define i_val Point
-#define i_cmp point_compare
+#define i_cmp point_cmp
#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cvec.h>
@@ -37,11 +37,11 @@ int main() {
cvec_i32 vec = cvec_i32_init();
cvec_i32_push_back(&vec, 123);
- cvec_i32_del(&vec);
+ cvec_i32_drop(&vec);
cvec_float fvec = cvec_float_init();
cvec_float_push_back(&fvec, 123.3);
- cvec_float_del(&fvec);
+ cvec_float_drop(&fvec);
cvec_pnt pvec = cvec_pnt_init();
cvec_pnt_push_back(&pvec, (Point){42, 14});
@@ -51,9 +51,9 @@ int main() c_foreach (i, cvec_pnt, pvec)
printf(" (%d %d)", i.ref->x, i.ref->y);
puts("");
- cvec_pnt_del(&pvec);
+ cvec_pnt_drop(&pvec);
cvec_str svec = cvec_str_init();
cvec_str_emplace_back(&svec, "Hello, friend");
- cvec_str_del(&svec);
+ cvec_str_drop(&svec);
}
\ No newline at end of file diff --git a/examples/prime.c b/examples/prime.c index f858831a..0e2ede56 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -27,7 +27,7 @@ int main(void) printf("computing prime numbers up to %zu\n", n);
clock_t t1 = clock();
- c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_del(&primes)) {
+ c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) {
puts("done");
size_t np = cbits_count(primes);
clock_t t2 = clock();
diff --git a/examples/priority.c b/examples/priority.c index 1068cb91..5164d85d 100644 --- a/examples/priority.c +++ b/examples/priority.c @@ -4,7 +4,7 @@ #include <stc/crandom.h>
#define i_val int64_t
-#define i_cmp -c_default_compare // min-heap (increasing values)
+#define i_cmp -c_default_cmp // min-heap (increasing values)
#define i_tag i
#include <stc/cpque.h>
diff --git a/examples/queue.c b/examples/queue.c index 4acaa4d6..ffd0a1e7 100644 --- a/examples/queue.c +++ b/examples/queue.c @@ -2,7 +2,7 @@ #include <stdio.h>
#define i_val int
-#define i_del(x) printf("drop %d\n", *(x))
+#define i_drop(x) printf("drop %d\n", *(x))
#define i_from c_default_clone
#define i_tag i
#include <stc/cqueue.h>
diff --git a/examples/rawptr_elements.c b/examples/rawptr_elements.c index c5416822..463a7f35 100644 --- a/examples/rawptr_elements.c +++ b/examples/rawptr_elements.c @@ -6,7 +6,7 @@ struct { double x, y; } typedef Point; // Set of Point pointers: define all template parameters "in-line"
// Note it may be simpler to use a cbox for this.
#define i_key Point*
-#define i_keydel(x) c_free(*(x))
+#define i_keydrop(x) c_free(*(x))
#define i_keyfrom(x) c_new(Point, *(x))
#define i_hash(x, n) c_default_hash(*(x), sizeof *(x))
#define i_equ(x, y) c_memcmp_equalto(*(x), *(y))
@@ -18,7 +18,7 @@ typedef int64_t inttype; #define i_key_str
#define i_valraw inttype
#define i_val inttype*
-#define i_valdel(x) c_free(*(x))
+#define i_valdrop(x) c_free(*(x))
#define i_valfrom(raw) c_new(inttype, raw)
#define i_valto(x) **(x)
#include <stc/cmap.h>
diff --git a/examples/read.c b/examples/read.c index 4e670a10..5313cb65 100644 --- a/examples/read.c +++ b/examples/read.c @@ -6,16 +6,16 @@ cvec_str read_file(const char* name) {
cvec_str vec = cvec_str_init();
c_autovar (FILE* f = fopen(name, "r"), fclose(f))
- c_autovar (cstr line = cstr_init(), cstr_del(&line))
- while (cstr_getline(&line, f))
- cvec_str_emplace_back(&vec, line.str);
+ c_autovar (cstr line = cstr_init(), cstr_drop(&line))
+ while (cstr_getline(&line, f))
+ cvec_str_emplace_back(&vec, line.str);
return vec;
}
int main()
{
int n = 0;
- c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_del(&vec))
+ c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec))
c_foreach (i, cvec_str, vec)
printf("%5d: %s\n", ++n, i.ref->str);
diff --git a/examples/replace.c b/examples/replace.c index ebb40cc5..0349d9f4 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -13,7 +13,7 @@ int main () // Ustring positions: 0123456789*123456789*12345
cstr s = cstr_from(base); // "this is a test string."
cstr m = cstr_clone(s);
- c_autodefer (cstr_del(&s), cstr_del(&m)) {
+ c_autodefer (cstr_drop(&s), cstr_drop(&m)) {
cstr_append(&m, m.str);
cstr_append(&m, m.str);
printf("%s\n", m.str);
diff --git a/examples/splitstr.c b/examples/splitstr.c index 8bea911a..789b2c59 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -36,7 +36,7 @@ int main() cstr string = cstr_new("Split,this,,string,now,");
cvec_str vec = string_split(cstr_sv(string), c_sv(","));
- c_autodefer (cvec_str_del(&vec), cstr_del(&string))
+ c_autodefer (cvec_str_drop(&vec), cstr_drop(&string))
c_foreach (i, cvec_str, vec)
printf("\t\"%s\"\n", i.ref->str);
}
\ No newline at end of file diff --git a/examples/sptr_demo.c b/examples/sptr_demo.c index c3da5287..a6b33de6 100644 --- a/examples/sptr_demo.c +++ b/examples/sptr_demo.c @@ -1,8 +1,8 @@ #include <stdio.h>
#include <string.h>
-void int_del(int* x) {
- printf("del: %d\n", *x);
+void int_drop(int* x) {
+ printf("drop: %d\n", *x);
}
// csptr implements its own clone method using reference counting,
@@ -10,19 +10,19 @@ void int_del(int* x) { #define i_type iref // set type name to be defined (instead of 'csptr_int')
#define i_val int
-#define i_del int_del // optional, just to display the elements destroyed
+#define i_drop int_drop // optional, just to display the elements destroyed
#include <stc/csptr.h> // iref
-#define i_key_ref iref // note: use i_key_ref instead of i_key for csptr/cbox elements
+#define i_key_bind iref // note: use i_key_bind instead of i_key for csptr/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_bind iref // note: as above.
#include <stc/cvec.h> // cvec_iref (like: std::vector<std::shared_ptr<int>>)
int main()
{
- c_auto (cvec_iref, vec) // declare and init vec, call cvec_iref_del() at scope exit
- c_auto (csset_iref, set) // declare and init set, call csset_iref_del() at scope exit
+ c_auto (cvec_iref, vec) // declare and init vec, call cvec_iref_drop() at scope exit
+ c_auto (csset_iref, set) // declare and init set, call csset_iref_drop() at scope exit
{
const int years[] = {2021, 2012, 2022, 2015};
c_forrange (i, c_arraylen(years))
@@ -47,7 +47,7 @@ int main() printf("\nset:");
c_foreach (i, csset_iref, set) printf(" %d", *i.ref->get);
- c_autovar (iref p = iref_clone(vec.data[0]), iref_del(&p)) {
+ c_autovar (iref p = iref_clone(vec.data[0]), iref_drop(&p)) {
printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count);
}
diff --git a/examples/sptr_erase.c b/examples/sptr_erase.c index 4707abb1..d08b9072 100644 --- a/examples/sptr_erase.c +++ b/examples/sptr_erase.c @@ -1,50 +1,51 @@ #include <stdio.h>
-void show_del(int* x) { printf("del: %d\n", *x); }
+void show_drop(int* x) { printf("drop: %d\n", *x); }
+#define i_type Arc
#define i_val int
-#define i_del show_del // this "destroy" func shows which elements are destroyed
+#define i_drop show_drop // this "destroy" func shows which elements are destroyed
// csptr/cbox will use pointer address comparison of i_val if no i_cmp func is specified,
-// or 'i_opt c_no_compare' is defined, otherwise i_cmp is used to compare object values.
+// or 'i_opt c_no_cmp' is defined, otherwise i_cmp is used to compare object values.
// See the different results by commenting out the next line.
-#define i_cmp(x, y) (*(x) - *(y))
-#include <stc/csptr.h> // csptr_int: shared pointer to int
+//#define i_cmp(x, y) (*(x) - *(y))
+#include <stc/csptr.h> // Arc: shared pointer to int
-#define i_val_ref csptr_int
-#define i_tag intp
-#include <stc/cvec.h> // cvec_intp: cvec<csptr_int>
+#define i_type Vec
+#define i_val_bind Arc
+#include <stc/cvec.h> // Vec: cvec<Arc>
int main()
{
- c_auto (cvec_intp, vec)
+ c_auto (Vec, vec)
{
const int v[] = {2012, 1990, 2012, 2019, 2015};
c_forrange (i, c_arraylen(v))
- cvec_intp_push_back(&vec, csptr_int_new(v[i]));
+ Vec_push_back(&vec, Arc_new(v[i]));
// clone the second 2012 and push it back.
// note: cloning make sure that vec.data[2] has ref count 2.
- cvec_intp_emplace_back(&vec, vec.data[2]);
+ Vec_emplace_back(&vec, vec.data[2]);
printf("vec before erase :");
- c_foreach (i, cvec_intp, vec)
+ c_foreach (i, Vec, vec)
printf(" %d", *i.ref->get);
puts("");
// erase vec.data[2]; or first matching value depending on compare.
- cvec_intp_iter it;
- it = cvec_intp_find(&vec, vec.data[2]);
- if (it.ref != cvec_intp_end(&vec).ref)
- cvec_intp_erase_at(&vec, it);
+ Vec_iter it;
+ it = Vec_find(&vec, vec.data[2]);
+ if (it.ref != Vec_end(&vec).ref)
+ Vec_erase_at(&vec, it);
int year = 2015;
- it = cvec_intp_find(&vec, (csptr_int){&year}); // Ok as tmp only.
- if (it.ref != cvec_intp_end(&vec).ref)
- cvec_intp_erase_at(&vec, it);
+ it = Vec_find(&vec, (Arc){&year}); // Ok as tmp only.
+ if (it.ref != Vec_end(&vec).ref)
+ Vec_erase_at(&vec, it);
printf("vec after erase :");
- c_foreach (i, cvec_intp, vec)
+ c_foreach (i, Vec, vec)
printf(" %d", *i.ref->get);
puts("\nDone");
diff --git a/examples/sptr_music.c b/examples/sptr_music.c index fcb7a43f..04ec28cc 100644 --- a/examples/sptr_music.c +++ b/examples/sptr_music.c @@ -9,20 +9,21 @@ struct Song cstr title;
} typedef Song;
-Song Song_from(const char* artist, const char* title)
+Song Song_new(const char* artist, const char* title)
{ return (Song){cstr_from(artist), cstr_from(title)}; }
-void Song_del(Song* s) {
- printf("del: %s\n", s->title.str);
- c_del(cstr, &s->artist, &s->title);
+void Song_drop(Song* s) {
+ printf("drop: %s\n", s->title.str);
+ c_drop(cstr, &s->artist, &s->title);
}
#define i_val Song
-#define i_del Song_del
+#define i_drop Song_drop
+#define i_opt c_no_cmp
#define i_tag song
#include <stc/csptr.h> // define csptr_song
-#define i_val_ref csptr_song
+#define i_val_bind csptr_song
#define i_tag song
#include <stc/cvec.h>
@@ -31,9 +32,9 @@ void example3() c_auto (cvec_song, v, v2)
{
c_apply(cvec_song, push_back, &v, {
- csptr_song_new(Song_from("Bob Dylan", "The Times They Are A Changing")),
- csptr_song_new(Song_from("Aretha Franklin", "Bridge Over Troubled Water")),
- csptr_song_new(Song_from("Thalia", "Entre El Mar y Una Estrella"))
+ csptr_song_new(Song_new("Bob Dylan", "The Times They Are A Changing")),
+ csptr_song_new(Song_new("Aretha Franklin", "Bridge Over Troubled Water")),
+ csptr_song_new(Song_new("Thalia", "Entre El Mar y Una Estrella"))
});
c_foreach (s, cvec_song, v)
@@ -41,8 +42,8 @@ void example3() cvec_song_emplace_back(&v2, *s.ref); // note: calls csptr_song_clone()
c_apply(cvec_song, push_back, &v2, {
- csptr_song_new(Song_from("Michael Jackson", "Billie Jean")),
- csptr_song_new(Song_from("Rihanna", "Stay")),
+ csptr_song_new(Song_new("Michael Jackson", "Billie Jean")),
+ csptr_song_new(Song_new("Rihanna", "Stay")),
});
c_foreach (s, cvec_song, v2)
diff --git a/examples/sptr_pthread.c b/examples/sptr_pthread.c index cfb845b6..501fdcef 100644 --- a/examples/sptr_pthread.c +++ b/examples/sptr_pthread.c @@ -11,11 +11,10 @@ struct Base int value;
} typedef Base;
-void Base_del(Base* b) { printf("Base::~Base()\n"); }
-
#define i_val Base
-#define i_del Base_del
+#define i_drop(x) printf("Base::~Base()\n")
#define i_tag base
+#define i_opt c_no_cmp
#include <stc/csptr.h>
void* thr(csptr_base* lp)
@@ -28,7 +27,7 @@ void* thr(csptr_base* lp) " p.get() = %p, p.use_count() = %ld\n", (void*)lp->get, *lp->use_count);
}
/* atomically decrease ref. */
- csptr_base_del(lp);
+ csptr_base_drop(lp);
return NULL;
}
diff --git a/examples/sptr_to_maps.c b/examples/sptr_to_maps.c index a66e5b31..69798563 100644 --- a/examples/sptr_to_maps.c +++ b/examples/sptr_to_maps.c @@ -3,22 +3,23 @@ #define i_type Map
#define i_key_str // strings
#define i_val int
-#define i_keydel(p) (printf("del name: %s\n", (p)->str), cstr_del(p))
+#define i_keydrop(p) (printf("drop name: %s\n", (p)->str), cstr_drop(p))
#include <stc/csmap.h>
#define i_type Arc // (atomic) ref. counted type
#define i_val Map
-#define i_del(p) (printf("del Arc:\n"), Map_del(p))
+#define i_drop(p) (printf("drop Arc:\n"), Map_drop(p))
// no need for atomic ref. count in single thread:
-#define i_opt c_no_atomic
+// no compare function available for csmap:
+#define i_opt c_no_atomic|c_no_cmp
#include <stc/csptr.h>
#define i_type Stack
-#define i_val_ref Arc // define i_val_ref for csptr/cbox value (not i_val)
+#define i_val_bind Arc // define i_val_bind for csptr/cbox value (not i_val)
#include <stc/cstack.h>
#define i_type List
-#define i_val_ref Arc // as above
+#define i_val_bind Arc // as above
#include <stc/clist.h>
int main()
diff --git a/examples/vikings.c b/examples/vikings.c new file mode 100644 index 00000000..87977538 --- /dev/null +++ b/examples/vikings.c @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <stc/cstr.h> + +typedef struct Viking { + cstr name; + cstr country; +} Viking; + +void Viking_drop(Viking* vk) { + cstr_drop(&vk->name); + cstr_drop(&vk->country); +} + +// Define Viking raw struct with hash, equals, and convertion functions between Viking and RViking structs: + +typedef struct RViking { + const char* name; + const char* country; +} RViking; + +uint64_t RViking_hash(const RViking* raw, size_t ignore) { + uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15); + return hash; +} +static inline bool RViking_equalto(const RViking* rx, const RViking* ry) { + return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; +} + +static inline Viking Viking_from(RViking raw) { // note: parameter is by value + return c_make(Viking){cstr_from(raw.name), cstr_from(raw.country)}; +} +static inline RViking Viking_toraw(const Viking* vk) { + return c_make(RViking){vk->name.str, vk->country.str}; +} + +// With this in place, we define the Viking => int hash map type: +#define i_type Vikings +#define i_key_bind Viking +#define i_val int +#define i_keyraw RViking +// i_key_bind auto-maps these functions: +// #define i_hash Viking_hash +// #define i_equ Viking_equalto +// #define i_keyfrom Viking_from // uses _from because i_keyraw is defined +// #define i_keyto Viking_toraw +// #define i_keydrop Viking_drop +#include <stc/cmap.h> + +int main() +{ + c_auto (Vikings, vikings) { + c_apply_pair(Vikings, emplace, &vikings, { + {{"Einar", "Norway"}, 20}, + {{"Olaf", "Denmark"}, 24}, + {{"Harald", "Iceland"}, 12}, + }); + RViking bjorn = {"Bjorn", "Sweden"}; + Vikings_emplace_or_assign(&vikings, bjorn, 10); + + RViking einar = {"Einar", "Norway"}; + Vikings_value *e = Vikings_find(&vikings, einar).ref; + e->second += 3; // add 3 hp points to Einar + Vikings_emplace(&vikings, einar, 0).ref->second += 5; // add 5 more to Einar + + c_forpair (viking, hp, Vikings, vikings) { + printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.hp); + } + } +}
\ No newline at end of file diff --git a/include/stc/alt/clist.h b/include/stc/alt/clist.h index 6695a26e..14abc7e4 100644 --- a/include/stc/alt/clist.h +++ b/include/stc/alt/clist.h @@ -49,7 +49,7 @@ puts("sorted");
c_foreach (i, clist_ix, list)
if (++n % 10000 == 0) printf("%8d: %10zd\n", n, i.ref->value);
- clist_ix_del(&list);
+ clist_ix_drop(&list);
}
*/
#include <stc/ccommon.h>
@@ -61,13 +61,13 @@ _c_clist_types(clist_VOID, int); STC_API size_t _clist_count(const clist_VOID* self);
#define _clist_node(_cx_self, vp) c_container_of(vp, _cx_node, value)
-#define _c_using_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw, defTypes) \
+#define _c_using_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw, defTypes) \
\
defTypes( _c_clist_types(_cx_self, i_val); ) \
typedef i_valraw _cx_rawvalue; \
\
STC_API _cx_self _cx_memb(_clone)(_cx_self lst); \
- STC_API void _cx_memb(_del)(_cx_self* self); \
+ STC_API void _cx_memb(_drop)(_cx_self* self); \
STC_API void _cx_memb(_push_back)(_cx_self* self, i_val value); \
STC_API void _cx_memb(_push_front)(_cx_self* self, i_val value); \
STC_API void _cx_memb(_emplace_items)(_cx_self *self, const _cx_rawvalue arr[], size_t n); \
@@ -89,7 +89,7 @@ STC_API size_t _clist_count(const clist_VOID* self); STC_INLINE size_t _cx_memb(_count)(_cx_self lst) { return _clist_count((const clist_VOID*) &lst); } \
STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); } \
STC_INLINE i_val _cx_memb(_value_clone)(i_val val) { return i_valfrom(i_valto(&val)); } \
- STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); } \
+ STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); } \
STC_INLINE void _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw) \
{ _cx_memb(_push_back)(self, i_valfrom(raw)); } \
STC_INLINE void _cx_memb(_emplace_front)(_cx_self* self, i_valraw raw) \
@@ -143,13 +143,13 @@ STC_API size_t _clist_count(const clist_VOID* self); while (n-- && it.ref) _cx_memb(_next)(&it); return it; \
} \
\
- _c_implement_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw) \
+ _c_implement_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw) \
struct stc_trailing_semicolon
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw) \
+#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw) \
\
STC_DEF _cx_self \
_cx_memb(_clone)(_cx_self lst) { \
@@ -160,7 +160,7 @@ STC_API size_t _clist_count(const clist_VOID* self); } \
\
STC_DEF void \
- _cx_memb(_del)(_cx_self* self) { \
+ _cx_memb(_drop)(_cx_self* self) { \
while (self->last) _cx_memb(_erase_after_)(self, self->last); \
} \
\
@@ -232,7 +232,7 @@ STC_API size_t _clist_count(const clist_VOID* self); node->next = next; \
if (del == next) self->last = node = NULL; \
else if (self->last == del) self->last = node, node = NULL; \
- i_valdel(&del->value); c_free(del); \
+ i_valdrop(&del->value); c_free(del); \
return node; \
} \
\
@@ -361,7 +361,7 @@ _clist_mergesort(clist_VOID_node *list, int (*cmp)(const void*, const void*)) { }
#else
-#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdel, i_valfrom, i_valto, i_valraw)
+#define _c_implement_clist(_cx_self, i_val, i_cmp, i_valdrop, i_valfrom, i_valto, i_valraw)
#endif
#endif
diff --git a/include/stc/alt/csmap.h b/include/stc/alt/csmap.h index 5b331efb..beccf559 100644 --- a/include/stc/alt/csmap.h +++ b/include/stc/alt/csmap.h @@ -30,7 +30,7 @@ using_csmap(mx, int, char); // Sorted map<int, char>
int main(void) {
- c_autovar (csmap_mx m = csmap_mx_init(), csmap_mx_del(&m))
+ c_autovar (csmap_mx m = csmap_mx_init(), csmap_mx_drop(&m))
{
csmap_mx_insert(&m, 5, 'a');
csmap_mx_insert(&m, 8, 'b');
@@ -91,8 +91,8 @@ int main(void) { \
STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.size == 0; } \
STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cx.size; } \
- STC_INLINE void _cx_memb(_del)(_cx_self* self) { _cx_memb(_del_r_)(self->root); } \
- STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); *self = _cx_memb(_init)(); } \
+ STC_INLINE void _cx_memb(_drop)(_cx_self* self) { _cx_memb(_del_r_)(self->root); } \
+ STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); } \
STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) {c_swap(_cx_self, *a, *b); } \
STC_INLINE _cx_self _cx_memb(_clone)(_cx_self cx) { return c_make(_cx_self){ _cx_memb(_clone_r_)(cx.root), cx.size}; } \
STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) \
@@ -103,9 +103,9 @@ int main(void) { {_cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } \
\
STC_INLINE void \
- _cx_memb(_value_del)(_cx_value* val) { \
- i_keydel(_i_keyref(val)); \
- _i_MAP_ONLY( i_valdel(&val->second); ) \
+ _cx_memb(_value_drop)(_cx_value* val) { \
+ i_keydrop(_i_keyref(val)); \
+ _i_MAP_ONLY( i_valdrop(&val->second); ) \
} \
\
STC_INLINE void \
@@ -134,7 +134,7 @@ int main(void) { _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { \
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); \
if (res.inserted) {*_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} \
- else {i_keydel(&key); _i_MAP_ONLY( i_valdel(&mapped); )} \
+ else {i_keydrop(&key); _i_MAP_ONLY( i_valdrop(&mapped); )} \
return res; \
} \
\
@@ -143,7 +143,7 @@ int main(void) { _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { \
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); \
if (res.inserted) res.ref->first = key; \
- else {i_keydel(&key); i_valdel(&res.ref->second); } \
+ else {i_keydrop(&key); i_valdrop(&res.ref->second); } \
res.ref->second = mapped; return res; \
} \
\
@@ -156,7 +156,7 @@ int main(void) { _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { \
_cx_result res = _cx_memb(_insert_entry_)(self, rkey); \
if (res.inserted) res.ref->first = i_keyfrom(rkey); \
- else i_valdel(&res.ref->second); \
+ else i_valdrop(&res.ref->second); \
res.ref->second = i_valfrom(rmapped); return res; \
} \
\
@@ -191,8 +191,8 @@ int main(void) { } \
\
_c_implement_aatree(_cx_self, C, i_key, i_val, i_cmp, \
- i_valdel, i_valfrom, i_valto, i_valraw, \
- i_keydel, i_keyfrom, i_keyto, i_keyraw) \
+ i_valdrop, i_valfrom, i_valto, i_valraw, \
+ i_keydrop, i_keyfrom, i_keyto, i_keyraw) \
struct stc_trailing_semicolon
/* -------------------------- IMPLEMENTATION ------------------------- */
@@ -204,8 +204,8 @@ _c_aatree_complete_types(csmap_SENTINEL, csmap_); static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_sentinel, 0};
#define _c_implement_aatree(_cx_self, C, i_key, i_val, i_cmp, \
- i_valdel, i_valfrom, i_valto, i_valraw, \
- i_keydel, i_keyfrom, i_keyto, i_keyraw) \
+ i_valdrop, i_valfrom, i_valto, i_valraw, \
+ i_keydrop, i_keyfrom, i_keyto, i_keyraw) \
STC_DEF _cx_self \
_cx_memb(_init)(void) { \
_cx_self cx = {(_cx_node *) &_aatree_sentinel, 0}; \
@@ -330,7 +330,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti if (c != 0) \
tn->link[c < 0] = _cx_memb(_erase_r_)(tn->link[c < 0], rkey, erased); \
else { \
- if (!*erased) { _cx_memb(_value_del)(&tn->value); *erased = 1; } \
+ if (!*erased) { _cx_memb(_value_drop)(&tn->value); *erased = 1; } \
if (tn->link[0]->level && tn->link[1]->level) { \
tx = tn->link[0]; \
while (tx->link[1]->level) \
@@ -395,7 +395,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti if (tn->level != 0) { \
_cx_memb(_del_r_)(tn->link[0]); \
_cx_memb(_del_r_)(tn->link[1]); \
- _cx_memb(_value_del)(&tn->value); \
+ _cx_memb(_value_drop)(&tn->value); \
c_free(tn); \
} \
}
diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index 76b3a800..bd135b7e 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -41,7 +41,7 @@ typedef union { /**************************** PRIVATE API **********************************/
-enum { SSO_CAP = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 };
+enum { SSO_CAP = sizeof(_cstr_rep_t) - 1 };
#define cstr_is_long(s) (bool)((s)->sso.cap_len & 128)
#define cstr_select_(s, memb) (cstr_is_long(s) ? cstr_l_##memb : cstr_s_##memb)
@@ -52,18 +52,18 @@ enum { SSO_CAP = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 }; #define cstr_s_end(s) ((s)->sso.data + cstr_s_size(s))
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8)
-#define cstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1))
-#define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1))
+ #define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8)
+ #define cstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1))
+ #define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1))
#else
-#define cstr_l_cap(s) (~(s)->lon.ncap)
-#define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~(cap))
+ #define cstr_l_cap(s) (~(s)->lon.ncap)
+ #define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~(cap))
#endif
#define cstr_l_size(s) ((s)->lon.size)
#define cstr_l_set_size(s, len) ((s)->lon.data[(s)->lon.size = (len)] = 0)
#define cstr_l_data(s) (s)->lon.data
#define cstr_l_end(s) ((s)->lon.data + cstr_l_size(s))
-#define cstr_l_del(s) free((s)->lon.data)
+#define cstr_l_drop(s) free((s)->lon.data)
STC_API char* cstr_init_(cstr* self, size_t len, size_t cap);
STC_API void cstr_internal_move_(cstr* self, size_t pos1, size_t pos2);
@@ -74,15 +74,16 @@ STC_INLINE void cstr_set_size_(cstr* self, size_t len) { STC_INLINE _cstr_rep_t cstr_rep_(cstr* self) {
return cstr_is_long(self)
- ? c_make(_cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)}
- : c_make(_cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)};
+ ? c_make(_cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)}
+ : c_make(_cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)};
}
/**************************** PUBLIC API **********************************/
#define cstr_new(literal) cstr_from_n(literal, sizeof((c_strlit){literal}) - 1)
#define cstr_npos (SIZE_MAX >> 1)
-#define cstr_null (cstr){.sso = {.cap_len = SSO_CAP}}
+#define cstr_null (c_make(cstr){.sso = {.cap_len = SSO_CAP}})
+#define cstr_toraw(self) cstr_str(self)
STC_API char* cstr_reserve(cstr* self, size_t cap);
STC_API void cstr_shrink_to_fit(cstr* self);
@@ -126,8 +127,8 @@ STC_INLINE cstr cstr_clone(cstr s) { return cstr_from_n(rep.data, rep.size);
}
-STC_INLINE void cstr_del(cstr* self) {
- if (cstr_is_long(self)) cstr_l_del(self);
+STC_INLINE void cstr_drop(cstr* self) {
+ if (cstr_is_long(self)) cstr_l_drop(self);
}
STC_INLINE void cstr_clear(cstr* self) {
@@ -170,7 +171,7 @@ STC_INLINE bool cstr_equalto(const cstr* s1, const cstr* s2) { return strcmp(cstr_str(s1), cstr_str(s2)) == 0;
}
-STC_INLINE int cstr_compare(const cstr* s1, const cstr* s2) {
+STC_INLINE int cstr_cmp(const cstr* s1, const cstr* s2) {
return strcmp(cstr_str(s1), cstr_str(s2));
}
diff --git a/include/stc/alt/sstr.h b/include/stc/alt/sstr.h deleted file mode 100644 index 2ea1033d..00000000 --- a/include/stc/alt/sstr.h +++ /dev/null @@ -1,406 +0,0 @@ -/* MIT License
- *
- * Copyright (c) 2021 Tyge Løvset, NORCE, www.norceresearch.no
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* A string type with short string optimization in C99 with optimal short string
- * utilization (23 characters with 24 bytes string representation).
- */
-#ifndef SSTR_INCLUDED
-#define SSTR_INCLUDED
-
-#include <stc/ccommon.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifndef sstr_size_t
-typedef size_t sstr_size_t;
-#endif
-typedef struct { char* data; sstr_size_t size, cap; } sstr_rep_t;
-typedef const char sstr_literal_t[];
-
-typedef union {
- struct { char* data; sstr_size_t size, ncap; } lon;
- struct { char data[sizeof(sstr_rep_t)]; } sso;
-} sstr;
-
-/**************************** PRIVATE API **********************************/
-
-enum { SSO_CAP = offsetof(sstr, lon.ncap) + sizeof((sstr){{0}}.lon.ncap) - 1 };
-#define sstr_is_long(s) (bool)((s)->sso.data[SSO_CAP] & 128)
-#define sstr_select_(s, memb) (sstr_is_long(s) ? sstr_l_##memb : sstr_s_##memb)
-
-#define sstr_s_cap(s) SSO_CAP
-#define sstr_s_size(s) ((sstr_size_t)(SSO_CAP - (s)->sso.data[SSO_CAP]))
-#define sstr_s_set_size(s, len) ((s)->sso.data[SSO_CAP] = SSO_CAP - (len), (s)->sso.data[len] = 0)
-#define sstr_s_data(s) (s)->sso.data
-#define sstr_s_end(s) ((s)->sso.data + sstr_s_size(s))
-
-#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8)
-#define sstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1))
-#define sstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1))
-#else
-#define sstr_l_cap(s) (~(s)->lon.ncap)
-#define sstr_l_set_cap(s, cap) ((s)->lon.ncap = ~(cap))
-#endif
-#define sstr_l_size(s) ((s)->lon.size)
-#define sstr_l_set_size(s, len) ((s)->lon.data[(s)->lon.size = (len)] = 0)
-#define sstr_l_data(s) (s)->lon.data
-#define sstr_l_end(s) ((s)->lon.data + sstr_l_size(s))
-#define sstr_l_del(s) free((s)->lon.data)
-
-STC_API char* sstr_init_(sstr* self, sstr_size_t len, sstr_size_t cap);
-STC_API void sstr_internal_move_(sstr* self, size_t pos1, size_t pos2);
-
-STC_INLINE void sstr_set_size_(sstr* self, sstr_size_t len) {
- sstr_select_(self, set_size(self, len));
-}
-
-STC_INLINE sstr_rep_t sstr_rep_(sstr* self) {
- return sstr_is_long(self)
- ? c_make(sstr_rep_t){self->lon.data, sstr_l_size(self), sstr_l_cap(self)}
- : c_make(sstr_rep_t){self->sso.data, sstr_s_size(self), sstr_s_cap(self)};
-}
-
-/**************************** PUBLIC API **********************************/
-
-#define sstr_lit(lit) sstr_from_n(lit, sizeof((sstr_literal_t){lit}) - 1)
-#define sstr_npos (~(sstr_size_t)0 >> 1)
-
-STC_API char* sstr_reserve(sstr* self, sstr_size_t cap);
-STC_API void sstr_shrink_to_fit(sstr* self);
-STC_API void sstr_resize(sstr* self, sstr_size_t size, char value);
-STC_API char* strnstrn(const char *s, const char *needle, size_t slen, size_t nlen);
-STC_API sstr_size_t sstr_find_n(sstr s, const char* needle, sstr_size_t pos, sstr_size_t nmax);
-STC_API void sstr_assign_n(sstr* self, const char* str, sstr_size_t n);
-STC_API void sstr_append_n(sstr* self, const char* str, sstr_size_t n);
-STC_API bool sstr_getdelim(sstr *self, int delim, FILE *fp);
-STC_API void sstr_erase_n(sstr* self, size_t pos, size_t n);
-
-
-STC_INLINE sstr sstr_init(void) {
- sstr s;
- sstr_s_set_size(&s, 0);
- return s;
-}
-
-STC_INLINE sstr sstr_from_n(const char* str, sstr_size_t n) {
- sstr s;
- memcpy(sstr_init_(&s, n, n), str, n);
- return s;
-}
-
-STC_INLINE sstr sstr_from(const char* str) {
- return sstr_from_n(str, strlen(str));
-}
-
-STC_INLINE sstr sstr_with_size(sstr_size_t size, char value) {
- sstr s;
- memset(sstr_init_(&s, size, size), value, size);
- return s;
-}
-
-STC_INLINE sstr sstr_with_capacity(sstr_size_t cap) {
- sstr s;
- sstr_init_(&s, 0, cap);
- return s;
-}
-
-STC_INLINE sstr sstr_clone(sstr s) {
- sstr_rep_t rep = sstr_rep_(&s);
- return sstr_from_n(rep.data, rep.size);
-}
-
-STC_INLINE void sstr_del(sstr* self) {
- if (sstr_is_long(self)) sstr_l_del(self);
-}
-
-STC_INLINE void sstr_clear(sstr* self) {
- sstr_set_size_(self, 0);
-}
-
-STC_INLINE char* sstr_data(sstr* self) {
- return sstr_select_(self, data(self));
-}
-
-STC_INLINE const char* sstr_str(const sstr* self) {
- return sstr_select_(self, data(self));
-}
-
-STC_INLINE bool sstr_empty(sstr s) {
- return sstr_select_(&s, size(&s)) == 0;
-}
-
-STC_INLINE sstr_size_t sstr_size(sstr s) {
- return sstr_select_(&s, size(&s));
-}
-
-STC_INLINE sstr_size_t sstr_length(sstr s) {
- return sstr_select_(&s, size(&s));
-}
-
-STC_INLINE sstr_size_t sstr_capacity(sstr s) {
- return sstr_select_(&s, cap(&s));
-}
-
-STC_INLINE bool sstr_equals(sstr s1, const char* str) {
- return strcmp(sstr_str(&s1), str) == 0;
-}
-
-STC_INLINE bool sstr_equals_s(sstr s1, sstr s2) {
- return strcmp(sstr_str(&s1), sstr_str(&s2)) == 0;
-}
-
-STC_INLINE bool sstr_equalto(const sstr* s1, const sstr* s2) {
- return strcmp(sstr_str(s1), sstr_str(s2)) == 0;
-}
-
-STC_INLINE int sstr_compare(const sstr* s1, const sstr* s2) {
- return strcmp(sstr_str(s1), sstr_str(s2));
-}
-
-STC_INLINE sstr_size_t sstr_find(sstr s, const char* needle) {
- const char *str = sstr_str(&s), *res = strstr(str, needle);
- return res ? res - str : sstr_npos;
-}
-
-STC_INLINE bool sstr_find_s(sstr s, sstr needle) {
- return sstr_find(s, sstr_str(&needle));
-}
-
-STC_INLINE bool sstr_contains(sstr s, const char* needle) {
- return strstr(sstr_str(&s), needle) != NULL;
-}
-
-STC_INLINE bool sstr_contains_s(sstr s, sstr needle) {
- return strstr(sstr_str(&s), sstr_str(&needle)) != NULL;
-}
-
-STC_INLINE bool sstr_starts_with(sstr s, const char* sub) {
- const char* str = sstr_str(&s);
- while (*sub && *str == *sub) ++str, ++sub;
- return *sub == 0;
-}
-
-STC_INLINE bool sstr_starts_with_s(sstr s, sstr sub) {
- return sstr_starts_with(s, sstr_str(&sub));
-}
-
-STC_INLINE bool sstr_ends_with(sstr s, const char* sub) {
- sstr_rep_t rep = sstr_rep_(&s); sstr_size_t n = strlen(sub);
- return n <= rep.size && memcmp(rep.data + rep.size - n, sub, n) == 0;
-}
-
-STC_INLINE bool sstr_ends_with_s(sstr s, sstr sub) {
- return sstr_ends_with(s, sstr_str(&sub));
-}
-
-STC_INLINE void sstr_assign(sstr* self, const char* str) {
- sstr_assign_n(self, str, strlen(str));
-}
-
-STC_INLINE void sstr_copy(sstr* self, sstr s) {
- sstr_rep_t rep = sstr_rep_(&s);
- sstr_assign_n(self, rep.data, rep.size);
-}
-
-STC_INLINE void sstr_append(sstr* self, const char* str) {
- sstr_append_n(self, str, strlen(str));
-}
-
-STC_INLINE void sstr_append_s(sstr* self, sstr s) {
- sstr_rep_t rep = sstr_rep_(&s);
- sstr_append_n(self, rep.data, rep.size);
-}
-
-STC_INLINE void sstr_replace_n(sstr* self, size_t pos, size_t len, const char* str, size_t n) {
- sstr_internal_move_(self, pos + len, pos + n);
- memcpy(&sstr_data(self)[pos], str, n);
-}
-
-STC_INLINE void sstr_replace(sstr* self, size_t pos, size_t len, const char* str) {
- sstr_replace_n(self, pos, len, str, strlen(str));
-}
-
-STC_INLINE void sstr_replace_s(sstr* self, size_t pos, size_t len, sstr s) {
- sstr_rep_t rep = sstr_rep_(&s);
- sstr_replace_n(self, pos, len, rep.data, rep.size);
-}
-
-STC_INLINE void sstr_insert_n(sstr* self, size_t pos, const char* str, size_t n) {
- sstr_replace_n(self, pos, 0, str, n);
-}
-
-STC_INLINE void sstr_insert(sstr* self, size_t pos, const char* str) {
- sstr_replace_n(self, pos, 0, str, strlen(str));
-}
-
-STC_INLINE void sstr_insert_s(sstr* self, size_t pos, sstr s) {
- sstr_rep_t rep = sstr_rep_(&s);
- sstr_replace_n(self, pos, 0, rep.data, rep.size);
-}
-
-STC_INLINE bool sstr_getline(sstr *self, FILE *fp) {
- return sstr_getdelim(self, '\n', fp);
-}
-
-/* -------------------------- IMPLEMENTATION ------------------------- */
-
-#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-
-STC_DEF void sstr_internal_move_(sstr* self, size_t pos1, size_t pos2) {
- if (pos1 == pos2)
- return;
- sstr_rep_t rep = sstr_rep_(self);
- sstr_size_t newlen = rep.size + pos2 - pos1;
- if (newlen > rep.cap)
- rep.data = sstr_reserve(self, (rep.size*3 >> 1) + pos2 - pos1);
- memmove(&rep.data[pos2], &rep.data[pos1], rep.size - pos1);
- sstr_set_size_(self, newlen);
-}
-
-STC_DEF char* sstr_init_(sstr* self, sstr_size_t len, sstr_size_t cap) {
- if (cap > SSO_CAP) {
- self->lon.data = (char *)malloc(cap + 1);
- sstr_l_set_size(self, len);
- sstr_l_set_cap(self, cap);
- return self->lon.data;
- }
- sstr_s_set_size(self, len);
- return self->sso.data;
-}
-
-STC_DEF void sstr_shrink_to_fit(sstr* self) {
- sstr_rep_t rep = sstr_rep_(self);
- if (rep.size == rep.cap)
- return;
- if (rep.size > SSO_CAP) {
- self->lon.data = (char *)realloc(self->lon.data, sstr_l_size(self) + 1);
- sstr_l_set_cap(self, sstr_l_size(self));
- } else if (rep.cap > SSO_CAP) {
- memcpy(self->sso.data, rep.data, rep.size + 1);
- sstr_s_set_size(self, rep.size);
- free(rep.data);
- }
-}
-
-STC_DEF char* sstr_reserve(sstr* self, sstr_size_t cap) {
- if (sstr_is_long(self)) {
- if (cap > sstr_l_cap(self)) {
- self->lon.data = (char *)realloc(self->lon.data, cap + 1);
- sstr_l_set_cap(self, cap);
- }
- return self->lon.data;
- }
- /* from short to long: */
- if (cap > sstr_s_cap(self)) {
- char* data = (char *)malloc(cap + 1);
- sstr_size_t len = sstr_s_size(self);
- memcpy(data, self->sso.data, len);
- self->lon.data = data;
- sstr_l_set_size(self, len);
- sstr_l_set_cap(self, cap);
- return data;
- }
- return self->sso.data;
-}
-
-STC_DEF void sstr_resize(sstr* self, sstr_size_t size, char value) {
- sstr_rep_t rep = sstr_rep_(self);
- if (size > rep.size) {
- if (size > rep.cap) rep.data = sstr_reserve(self, size);
- memset(rep.data + rep.size, value, size - rep.size);
- }
- sstr_set_size_(self, size);
-}
-
-STC_DEF char* strnstrn(const char *s, const char *needle, size_t slen, size_t nlen) {
- if (!nlen) return (char *)s;
- if (nlen > slen) return NULL;
- slen -= nlen;
- do {
- if (*s == *needle && !memcmp(s, needle, nlen)) return (char *)s;
- ++s;
- } while (slen--);
- return NULL;
-}
-
-STC_DEF sstr_size_t
-sstr_find_n(sstr s, const char* needle, sstr_size_t pos, sstr_size_t nmax) {
- sstr_rep_t rep = sstr_rep_(&s);
- sstr_size_t nlen = (sstr_size_t) strlen(needle);
- if (pos > rep.size) return sstr_npos;
- char* res = strnstrn(rep.data + pos, needle, rep.size, nmax < nlen ? nmax : nlen);
- return res ? res - rep.data : sstr_npos;
-}
-
-STC_DEF void sstr_assign_n(sstr* self, const char* str, sstr_size_t n) {
- sstr_rep_t rep = sstr_rep_(self);
- if (n > rep.cap) {
- rep.data = (char *)realloc(sstr_is_long(self) ? rep.data : NULL, n + 1);
- sstr_l_set_cap(self, n);
- }
- memmove(rep.data, str, n);
- sstr_set_size_(self, n);
-}
-
-STC_DEF void sstr_append_n(sstr* self, const char* str, sstr_size_t n) {
- sstr_rep_t rep = sstr_rep_(self);
- if (rep.size + n > rep.cap) {
- sstr_size_t off = (sstr_size_t)(str - rep.data); /* handle self append */
- rep.data = sstr_reserve(self, (rep.size*3 >> 1) + n);
- if (off <= rep.size) str = rep.data + off;
- }
- memcpy(rep.data + rep.size, str, n);
- sstr_set_size_(self, rep.size + n);
-}
-
-STC_DEF bool sstr_getdelim(sstr *self, int delim, FILE *fp) {
- int c = fgetc(fp);
- if (c == EOF)
- return false;
- sstr_size_t pos = 0;
- sstr_rep_t rep = sstr_rep_(self);
- for (;;) {
- if (c == delim || c == EOF) {
- sstr_set_size_(self, pos);
- return true;
- }
- if (pos == rep.cap) {
- sstr_set_size_(self, pos);
- rep.data = sstr_reserve(self, (rep.cap = (rep.cap*3 >> 1) + 16));
- }
- rep.data[pos++] = (char) c;
- c = fgetc(fp);
- }
-}
-
-STC_DEF void sstr_erase_n(sstr* self, size_t pos, size_t n) {
- sstr_rep_t rep = sstr_rep_(self);
- if (n > rep.size - pos) n = rep.size - pos;
- memmove(&rep.data[pos], &rep.data[pos + n], rep.size - (pos + n));
- sstr_set_size_(self, rep.size - n);
-}
-
-#endif
-#endif
\ No newline at end of file diff --git a/include/stc/carr2.h b/include/stc/carr2.h index d1feb90b..92964d4d 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -34,7 +34,7 @@ int main() { int w = 7, h = 5; - c_autovar (carr2_int image = carr2_int_init(w, h), carr2_int_del(&image)) + c_autovar (carr2_int image = carr2_int_init(w, h), carr2_int_drop(&image)) { int *dat = carr2_int_data(&image); for (int i = 0; i < carr2_int_size(image); ++i) @@ -63,7 +63,7 @@ _cx_deftypes(_c_carr2_types, _cx_self, i_val); STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, i_val value); STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, _cx_value* storage); STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); #if !c_option(c_no_clone) STC_API _cx_self _cx_memb(_clone)(_cx_self src); STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other); @@ -124,7 +124,7 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { STC_DEF void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } #endif @@ -135,10 +135,11 @@ STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) { return values; } -STC_DEF void _cx_memb(_del)(_cx_self* self) { +STC_DEF void _cx_memb(_drop)(_cx_self* self) { if (!self->data) return; - for (_cx_value* p = self->data[0], *e = p + _cx_memb(_size)(*self); p != e; ++p) - i_valdel(p); + for (_cx_value* p = self->data[0], *q = p + _cx_memb(_size)(*self); p != q; ) { + --q; i_valdrop(q); + } c_free(self->data[0]); /* values */ c_free(self->data); /* pointers */ } diff --git a/include/stc/carr3.h b/include/stc/carr3.h index 4a4a6484..31df5bdf 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -34,7 +34,7 @@ int main() { int w = 7, h = 5, d = 3; - c_autovar (carr3_int image = carr3_int_init(w, h, d), carr3_int_del(&image)) + c_autovar (carr3_int image = carr3_int_init(w, h, d), carr3_int_drop(&image)) { int *dat = carr3_int_data(&image); for (int i = 0; i < carr3_int_size(image); ++i) @@ -65,7 +65,7 @@ _cx_deftypes(_c_carr3_types, _cx_self, i_val); STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, size_t zdim, i_val value); STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); #if !c_option(c_no_clone) STC_API _cx_self _cx_memb(_clone)(_cx_self src); STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other); @@ -130,7 +130,7 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); } #endif @@ -141,10 +141,11 @@ STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) { return values; } -STC_DEF void _cx_memb(_del)(_cx_self* self) { +STC_DEF void _cx_memb(_drop)(_cx_self* self) { if (!self->data) return; - for (_cx_value* p = **self->data, *e = p + _cx_memb(_size)(*self); p != e; ++p) - i_valdel(p); + for (_cx_value* p = **self->data, *q = p + _cx_memb(_size)(*self); p != q; ) { + --q; i_valdrop(q); + } c_free(self->data[0][0]); /* data */ c_free(self->data); /* pointers */ } diff --git a/include/stc/cbits.h b/include/stc/cbits.h index b3a70edc..a6ee3948 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -30,7 +30,7 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbits.h"
int main() {
- c_autovar (cbits bset = cbits_with_size(23, true), cbits_del(&bset))
+ c_autovar (cbits bset = cbits_with_size(23, true), cbits_drop(&bset))
{
cbits_reset(&bset, 9);
cbits_resize(&bset, 43, false);
@@ -75,14 +75,14 @@ STC_API bool cbits_disjoint(cbits set, cbits other); STC_INLINE cbits cbits_init() { return c_make(cbits){NULL, 0}; }
STC_INLINE cbits cbits_from(const char* s) { return cbits_from_n(s, strlen(s)); }
STC_INLINE void cbits_clear(cbits* self) { self->size = 0; }
-STC_INLINE void cbits_del(cbits* self) { c_free(self->data64); }
+STC_INLINE void cbits_drop(cbits* self) { c_free(self->data64); }
STC_INLINE size_t cbits_size(cbits set) { return set.size; }
#define cbits_new(literal) \
cbits_from_n(literal, sizeof c_make(c_strlit){literal} - 1)
STC_INLINE cbits* cbits_take(cbits* self, cbits other) {
- if (self->data64 != other.data64) {cbits_del(self); *self = other;}
+ if (self->data64 != other.data64) {cbits_drop(self); *self = other;}
return self;
}
diff --git a/include/stc/cbox.h b/include/stc/cbox.h index 89bd272e..51bc81a4 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -26,7 +26,7 @@ typedef struct { cstr name, last; } Person;
-Person Person_from(const char* name, const char* last) {
+Person Person_new(const char* name, const char* last) {
return (Person){.name = cstr_from(name), .last = cstr_from(last)};
}
Person Person_clone(Person p) {
@@ -34,21 +34,21 @@ Person Person_clone(Person p) { p.last = cstr_clone(p.last);
return p;
}
-void Person_del(Person* p) {
- printf("del: %s %s\n", p->name.str, p->last.str);
- c_del(cstr, &p->name, &p->last);
+void Person_drop(Person* p) {
+ printf("drop: %s %s\n", p->name.str, p->last.str);
+ c_drop(cstr, &p->name, &p->last);
}
#define i_val Person
-#define i_valdel Person_del
+#define i_valdrop Person_drop
#define i_valfrom Person_clone
-#define i_opt c_no_compare // compare by .get addresses only
+#define i_opt c_no_cmp // compare by .get addresses only
#define i_tag prs
#include <stc/cbox.h>
int main() {
- c_autovar (cbox_prs p = cbox_prs_new(Person_from("John", "Smiths")), cbox_prs_del(&p))
- c_autovar (cbox_prs q = cbox_prs_clone(p), cbox_prs_del(&q))
+ c_autovar (cbox_prs p = cbox_prs_new(Person_new("John", "Smiths")), cbox_prs_drop(&p))
+ c_autovar (cbox_prs q = cbox_prs_clone(p), cbox_prs_drop(&q))
{
cstr_assign(&q.get->name, "Joe");
@@ -63,6 +63,7 @@ int main() { #include "ccommon.h"
#include "forward.h"
#include <stdlib.h>
+#include <string.h>
#define cbox_null {NULL}
#endif // CBOX_H_INCLUDED
@@ -71,6 +72,7 @@ int main() { #define _i_prefix cbox_
#endif
#include "template.h"
+typedef i_valraw _cx_rawvalue;
#if !c_option(c_is_fwd)
_cx_deftypes(_c_cbox_types, _cx_self, i_val);
@@ -90,8 +92,8 @@ _cx_memb(_new)(i_val val) { // destructor
STC_INLINE void
-_cx_memb(_del)(_cx_self* self) {
- if (self->get) { i_valdel(self->get); c_free(self->get); }
+_cx_memb(_drop)(_cx_self* self) {
+ if (self->get) { i_valdrop(self->get); c_free(self->get); }
}
STC_INLINE _cx_self
@@ -102,19 +104,19 @@ _cx_memb(_move)(_cx_self* self) { STC_INLINE void
_cx_memb(_reset)(_cx_self* self) {
- _cx_memb(_del)(self); self->get = NULL;
+ _cx_memb(_drop)(self); self->get = NULL;
}
// take ownership of *p
STC_INLINE void
_cx_memb(_reset_with)(_cx_self* self, _cx_value* p) {
- _cx_memb(_del)(self); self->get = p;
+ _cx_memb(_drop)(self); self->get = p;
}
// take ownership of val
STC_INLINE void
_cx_memb(_reset_new)(_cx_self* self, i_val val) {
- if (self->get) { i_valdel(self->get); *self->get = val; }
+ if (self->get) { i_valdrop(self->get); *self->get = val; }
else self->get = c_new(i_val, val);
}
@@ -123,11 +125,10 @@ _cx_memb(_reset_new)(_cx_self* self, i_val val) { _cx_memb(_from)(i_valraw raw) {
return c_make(_cx_self){c_new(i_val, i_valfrom(raw))};
}
-
- STC_INLINE void
- _cx_memb(_reset_from)(_cx_self* self, i_valraw raw) {
- _cx_memb(_reset_new)(self, i_valfrom(raw));
- }
+ STC_INLINE i_valraw
+ _cx_memb(_toraw)(const _cx_self* self) {
+ return i_valto(self->get);
+ }
STC_INLINE _cx_self
_cx_memb(_clone)(_cx_self other) {
@@ -145,30 +146,32 @@ _cx_memb(_reset_new)(_cx_self* self, i_val val) { STC_INLINE void
_cx_memb(_take)(_cx_self* self, _cx_self other) {
- if (other.get != self->get) _cx_memb(_del)(self);
+ if (other.get != self->get) _cx_memb(_drop)(self);
*self = other;
}
STC_INLINE uint64_t
_cx_memb(_hash)(const _cx_self* self, size_t n) {
- #if (c_option(c_no_compare) || defined _i_default_compare) && SIZE_MAX >> 32
+ #if c_option(c_no_cmp) && SIZE_MAX >> 32
return c_hash64(&self->get, 8);
- #elif (c_option(c_no_compare) || defined _i_default_compare)
+ #elif c_option(c_no_cmp)
return c_hash32(&self->get, 4);
#else
- i_valraw raw = i_valto(self->get);
- return i_hash(&raw, sizeof raw);
+ return i_hash(self->get, sizeof *self->get);
#endif
}
STC_INLINE int
-_cx_memb(_compare)(const _cx_self* x, const _cx_self* y) {
- #if (c_option(c_no_compare) || defined _i_default_compare)
- return (int)(x->get - y->get);
+_cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) {
+ #if c_option(c_no_cmp)
+ return c_default_cmp(&x->get, &y->get);
#else
- i_valraw rx = i_valto(x->get);
- i_valraw ry = i_valto(y->get);
- return i_cmp(&rx, &ry);
+ return i_cmp(x->get, y->get);
#endif
}
-#include "template.h"
\ No newline at end of file +
+STC_INLINE bool
+_cx_memb(_equalto)(const _cx_self* x, const _cx_self* y) {
+ return !_cx_memb(_cmp)(x, y);
+}
+#include "template.h"
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 2942873f..d3664077 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -93,33 +93,37 @@ #endif
typedef const char c_strlit[];
-#define c_delete(T, ptr) do { T *_c_p = ptr; T##_del(_c_p); c_free(_c_p); } while (0)
+#define c_delete(T, ptr) do { T *_c_p = ptr; T##_drop(_c_p); c_free(_c_p); } while (0)
#define c_swap(T, x, y) do { T _c_t = x; x = y; y = _c_t; } while (0)
#define c_arraylen(a) (sizeof (a)/sizeof (a)[0])
-#define c_less_compare(less, x, y) (less(y, x) - less(x, y))
+#define c_less_cmp(less, x, y) (less(y, x) - less(x, y))
#define c_default_less(x, y) (*(x) < *(y))
-#define c_default_compare(x, y) c_less_compare(c_default_less, x, y)
+#define c_default_cmp(x, y) c_less_cmp(c_default_less, x, y)
#define c_default_equalto(x, y) (*(x) == *(y))
#define c_memcmp_equalto(x, y) (memcmp(x, y, sizeof *(x)) == 0)
-#define c_rawstr_compare(x, y) strcmp(*(x), *(y))
-#define c_rawstr_equalto(x, y) (strcmp(*(x), *(y)) == 0)
-#define c_rawstr_hash(x, dummy) c_strhash(*(x))
-
#define c_default_clone(x) (x)
#define c_default_fromraw(x) (x) // [deprecated]
#define c_default_toraw(ptr) (*(ptr))
-#define c_default_del(ptr) ((void) (ptr))
+#define c_default_drop(ptr) ((void) (ptr))
#define c_option(flag) ((i_opt) & (flag))
#define c_is_fwd 1
#define c_no_atomic 2
#define c_no_clone 4
-#define c_no_compare 8
+#define c_no_cmp 8
/* Generic algorithms */
+typedef char* c_mutstr;
+typedef const char* c_rawstr;
+#define c_rawstr_cmp(x, y) strcmp(*(x), *(y))
+#define c_rawstr_equalto(x, y) (strcmp(*(x), *(y)) == 0)
+#define c_rawstr_hash(x, dummy) c_strhash(*(x))
+#define c_rawstr_clone(s) strcpy((char*)c_malloc(strlen(s) + 1), s)
+#define c_rawstr_drop(x) c_free((char *) &**(x))
+
#define _c_ROTL(x, k) (x << (k) | x >> (8*sizeof(x) - (k)))
STC_INLINE uint64_t c_strhash(const char *s) {
@@ -168,16 +172,16 @@ STC_INLINE uint64_t c_default_hash(const void* key, size_t len) { #define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__)
#define c_auto_2(C, a) \
- c_autovar(C a = C##_init(), C##_del(&a))
+ c_autovar(C a = C##_init(), C##_drop(&a))
#define c_auto_3(C, a, b) \
c_autovar(c_EXPAND(C a = C##_init(), b = C##_init()), \
- C##_del(&b), C##_del(&a))
+ C##_drop(&b), C##_drop(&a))
#define c_auto_4(C, a, b, c) \
c_autovar(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \
- C##_del(&c), C##_del(&b), C##_del(&a))
+ C##_drop(&c), C##_drop(&b), C##_drop(&a))
#define c_auto_5(C, a, b, c, d) \
c_autovar(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \
- C##_del(&d), C##_del(&c), C##_del(&b), C##_del(&a))
+ C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a))
#define c_autobuf(b, type, n) c_autobuf_N(b, type, n, 256)
#define c_autobuf_N(b, type, n, BYTES) \
@@ -203,10 +207,10 @@ STC_INLINE uint64_t c_default_hash(const void* key, size_t len) { C##_##method(_c_cx, *_c_i); \
} while (0)
-#define c_del(C, ...) do { \
+#define c_drop(C, ...) do { \
C* _c_arr[] = {__VA_ARGS__}; \
for (size_t _c_i = 0; _c_i < c_arraylen(_c_arr); ++_c_i) \
- C##_del(_c_arr[_c_i]); \
+ C##_drop(_c_arr[_c_i]); \
} while (0)
#if defined(__SIZEOF_INT128__)
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index f8cc1d52..050f9e67 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -42,7 +42,7 @@ typedef i_valraw _cx_rawvalue; STC_API _cx_self _cx_memb(_init)(void);
STC_API void _cx_memb(_clear)(_cx_self* self);
-STC_API void _cx_memb(_del)(_cx_self* self);
+STC_API void _cx_memb(_drop)(_cx_self* self);
STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value);
STC_API bool _cx_memb(_expand_right_half_)(_cx_self* self, size_t idx, size_t n);
#ifndef _i_queue
@@ -54,9 +54,9 @@ STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* po const _cx_rawvalue* p1, const _cx_rawvalue* p2);
#endif // !c_no_clone
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter p1, _cx_iter p2, i_valraw raw);
-STC_API int _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y);
+STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y);
#endif
STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_val value);
STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
@@ -72,7 +72,7 @@ STC_INLINE i_val _cx_memb(_value_clone)(i_val val) { return i_valfrom(i_valto(&val)); }
STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->data == other.data) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
}
#endif
STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return !cdeq_rep_(&cx)->size; }
@@ -83,7 +83,7 @@ STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfro STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); }
STC_INLINE void _cx_memb(_pop_front)(_cx_self* self)
- { i_valdel(self->data); ++self->data; --cdeq_rep_(self)->size; }
+ { i_valdrop(self->data); ++self->data; --cdeq_rep_(self)->size; }
STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self)
{ return self->data + cdeq_rep_(self)->size - 1; }
STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return self->data; }
@@ -106,7 +106,7 @@ _cx_memb(_with_capacity)(const size_t n) { STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) {
_cx_value* p = &self->data[--cdeq_rep_(self)->size];
- i_valdel(p);
+ i_valdrop(p);
}
STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, const size_t idx) {
@@ -175,7 +175,7 @@ _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, i_valraw raw) { }
#endif // !c_no_clone
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, i_valraw raw) {
@@ -201,9 +201,9 @@ _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, STC_INLINE void
_cx_memb(_sort)(_cx_self* self) {
- _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_compare));
+ _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_cmp));
}
-#endif // !c_no_compare
+#endif // !c_no_cmp
#endif // _i_queue
/* -------------------------- IMPLEMENTATION ------------------------- */
@@ -224,8 +224,9 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) {
struct cdeq_rep* rep = cdeq_rep_(self);
if (rep->cap) {
- for (_cx_value *p = self->data, *q = p + rep->size; p != q; ++p)
- i_valdel(p);
+ for (_cx_value *p = self->data, *q = p + rep->size; p != q; ) {
+ --q; i_valdrop(q);
+ }
rep->size = 0;
}
}
@@ -242,7 +243,7 @@ _cx_memb(_shrink_to_fit)(_cx_self *self) { }
STC_DEF void
-_cx_memb(_del)(_cx_self* self) {
+_cx_memb(_drop)(_cx_self* self) {
_cx_memb(_clear)(self);
if (cdeq_rep_(self)->cap)
c_free(cdeq_rep_(self));
@@ -357,7 +358,7 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { const size_t n = p2 - p1;
if (n > 0) {
_cx_value* p = p1, *end = self->data + cdeq_rep_(self)->size;
- for (; p != p2; ++p) i_valdel(p);
+ for (; p != p2; ++p) { i_valdrop(p); }
if (p1 == self->data) self->data += n;
else memmove(p1, p2, (end - p2) * sizeof(i_val));
cdeq_rep_(self)->size -= n;
@@ -385,7 +386,7 @@ _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, }
#endif // !c_option(c_no_clone)
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) {
@@ -397,12 +398,12 @@ _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) { }
STC_DEF int
-_cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y) {
+_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) {
i_valraw rx = i_valto(x);
i_valraw ry = i_valto(y);
return i_cmp(&rx, &ry);
}
-#endif // !c_no_compare
+#endif // !c_no_cmp
#endif // !_i_queue
#endif // IMPLEMENTATION
#include "template.h"
diff --git a/include/stc/clist.h b/include/stc/clist.h index 7cd2df50..c239fdd9 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -91,15 +91,16 @@ typedef i_valraw _cx_rawvalue; STC_API size_t _clist_count(const clist_VOID* self);
-STC_API void _cx_memb(_del)(_cx_self* self);
+STC_API void _cx_memb(_drop)(_cx_self* self);
STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value);
STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_val value);
STC_API _cx_iter _cx_memb(_insert)(_cx_self* self, _cx_iter it, i_val value);
STC_API _cx_iter _cx_memb(_erase_at)(_cx_self* self, _cx_iter it);
STC_API _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2);
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_API size_t _cx_memb(_remove)(_cx_self* self, i_valraw val);
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw val);
+STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y);
#endif
STC_API _cx_iter _cx_memb(_splice)(_cx_self* self, _cx_iter it, _cx_self* other);
STC_API _cx_self _cx_memb(_split_off)(_cx_self* self, _cx_iter it1, _cx_iter it2);
@@ -114,14 +115,13 @@ STC_INLINE _cx_value* _cx_memb(_emplace_front)(_cx_self* self, i_valraw raw) { return _cx_memb(_push_front)(self, i_valfrom(raw)); }
STC_INLINE _cx_iter _cx_memb(_emplace)(_cx_self* self, _cx_iter it, i_valraw raw)
{ return _cx_memb(_insert)(self, it, i_valfrom(raw)); }
-STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw)
- { return i_valfrom(raw); }
STC_INLINE i_val _cx_memb(_value_clone)(i_val val)
{ return i_valfrom(i_valto(&val)); }
+
STC_INLINE void
_cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->last == other.last) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
}
#endif
STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL}; }
@@ -129,8 +129,7 @@ STC_INLINE bool _cx_memb(_reserve)(_cx_self* self, size_t n) { return tr STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.last == NULL; }
STC_INLINE size_t _cx_memb(_count)(_cx_self cx)
{ return _clist_count((const clist_VOID*) &cx); }
-STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); }
-STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); }
+STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); }
STC_INLINE void _cx_memb(_pop_front)(_cx_self* self)
{ _cx_memb(_erase_after_)(self, self->last); }
STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return &self->last->next->value; }
@@ -166,7 +165,7 @@ _cx_memb(_splice_range)(_cx_self* self, _cx_iter it, return _cx_memb(_splice)(self, it, &tmp);
}
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, i_valraw val) {
return _cx_memb(_find_in)(_cx_memb(_begin)(self), _cx_memb(_end)(self), val);
@@ -197,7 +196,7 @@ _cx_memb(_clone)(_cx_self cx) { #endif
STC_DEF void
-_cx_memb(_del)(_cx_self* self) {
+_cx_memb(_drop)(_cx_self* self) {
while (self->last) _cx_memb(_erase_after_)(self, self->last);
}
@@ -250,7 +249,7 @@ _cx_memb(_erase_after_)(_cx_self* self, _cx_node* node) { node->next = next;
if (del == next) self->last = node = NULL;
else if (self->last == del) self->last = node, node = NULL;
- i_valdel(&del->value); c_free(del);
+ i_valdrop(&del->value); c_free(del);
return node;
}
@@ -280,7 +279,7 @@ _cx_memb(_split_off)(_cx_self* self, _cx_iter it1, _cx_iter it2) { return cx;
}
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw val) {
@@ -321,7 +320,14 @@ _cx_memb(_sort)(_cx_self* self) { if (self->last)
self->last = (_cx_node *) _clist_mergesort((clist_VOID_node *) self->last->next, _cx_memb(_sort_cmp_));
}
-#endif // !c_no_compare
+
+STC_DEF int
+_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) {
+ i_valraw rx = i_valto(x);
+ i_valraw ry = i_valto(y);
+ return i_cmp(&rx, &ry);
+}
+#endif // !c_no_cmp
#endif // TEMPLATE IMPLEMENTATION
@@ -336,7 +342,7 @@ _clist_count(const clist_VOID* self) { return n;
}
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
// Singly linked list Mergesort implementation by Simon Tatham. O(n*log n).
// https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
@@ -387,7 +393,7 @@ _clist_mergesort(clist_VOID_node *list, int (*cmp)(const clist_VOID_node*, const insize *= 2;
}
}
-#endif // !c_no_compare
+#endif // !c_no_cmp
#endif // NON-TEMPLATE IMPLEMENTATION
#include "template.h"
#define CLIST_H_INCLUDED
diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 3d1915d3..10e9c586 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -31,7 +31,7 @@ #include <stc/cmap.h>
int main(void) {
- c_autovar (cmap_ichar m = cmap_ichar_init(), cmap_ichar_del(&m))
+ c_autovar (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m))
{
cmap_ichar_emplace(&m, 5, 'a');
cmap_ichar_emplace(&m, 8, 'b');
@@ -91,7 +91,7 @@ STC_API _cx_self _cx_memb(_with_capacity)(size_t cap); #if !c_option(c_no_clone)
STC_API _cx_self _cx_memb(_clone)(_cx_self map);
#endif
-STC_API void _cx_memb(_del)(_cx_self* self);
+STC_API void _cx_memb(_drop)(_cx_self* self);
STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t capacity);
STC_API chash_bucket_t _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr);
@@ -121,7 +121,7 @@ STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) return _cx_memb(_insert_or_assign)(self, key, mapped);
}
- STC_INLINE const _cx_mapped*
+ STC_INLINE _cx_mapped*
_cx_memb(_at)(const _cx_self* self, i_keyraw rkey) {
chash_bucket_t b = _cx_memb(_bucket_)(self, &rkey);
assert(self->_hashx[b.idx]);
@@ -132,13 +132,14 @@ STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) #if !c_option(c_no_clone)
STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->table == other.table) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
}
-STC_INLINE void
-_cx_memb(_value_clone)(_cx_value* _dst, _cx_value* _val) {
- *_i_keyref(_dst) = i_keyfrom(i_keyto(_i_keyref(_val)));
- _i_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); )
+STC_INLINE _cx_value
+_cx_memb(_value_clone)(_cx_value _val) {
+ *_i_keyref(&_val) = i_keyfrom(i_keyto(_i_keyref(&_val)));
+ _i_MAP_ONLY( _val.second = i_valfrom(i_valto(&_val.second)); )
+ return _val;
}
STC_INLINE _cx_result
@@ -159,16 +160,16 @@ _cx_memb(_value_toraw)(_cx_value* val) { }
STC_INLINE void
-_cx_memb(_value_del)(_cx_value* _val) {
- i_keydel(_i_keyref(_val));
- _i_MAP_ONLY( i_valdel(&_val->second); )
+_cx_memb(_value_drop)(_cx_value* _val) {
+ i_keydrop(_i_keyref(_val));
+ _i_MAP_ONLY( i_valdrop(&_val->second); )
}
STC_INLINE _cx_result
_cx_memb(_insert)(_cx_self* self, i_key _key _i_MAP_ONLY(, i_val _mapped)) {
_cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key));
if (_res.inserted) { *_i_keyref(_res.ref) = _key; _i_MAP_ONLY( _res.ref->second = _mapped; )}
- else { i_keydel(&_key); _i_MAP_ONLY( i_valdel(&_mapped); )}
+ else { i_keydrop(&_key); _i_MAP_ONLY( i_valdrop(&_mapped); )}
return _res;
}
@@ -249,10 +250,10 @@ STC_INLINE void _cx_memb(_wipe_)(_cx_self* self) { if (self->size == 0) return;
_cx_value* e = self->table, *end = e + self->bucket_count;
uint8_t *hx = self->_hashx;
- for (; e != end; ++e) if (*hx++) _cx_memb(_value_del)(e);
+ for (; e != end; ++e) if (*hx++) _cx_memb(_value_drop)(e);
}
-STC_DEF void _cx_memb(_del)(_cx_self* self) {
+STC_DEF void _cx_memb(_drop)(_cx_self* self) {
_cx_memb(_wipe_)(self);
c_free(self->_hashx);
c_free((void *) self->table);
@@ -269,7 +270,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped) {
_cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key));
if (_res.inserted) _res.ref->first = _key;
- else { i_keydel(&_key); i_valdel(&_res.ref->second); }
+ else { i_keydrop(&_key); i_valdrop(&_res.ref->second); }
_res.ref->second = _mapped; return _res;
}
#if !c_option(c_no_clone)
@@ -277,7 +278,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) {
_cx_result _res = _cx_memb(_insert_entry_)(self, rkey);
if (_res.inserted) _res.ref->first = i_keyfrom(rkey);
- else i_valdel(&_res.ref->second);
+ else i_valdrop(&_res.ref->second);
_res.ref->second = i_valfrom(rmapped); return _res;
}
#endif
@@ -323,7 +324,7 @@ _cx_memb(_clone)(_cx_self m) { };
_cx_value *e = m.table, *end = e + m.bucket_count, *dst = clone.table;
for (uint8_t *hx = m._hashx; e != end; ++hx, ++e, ++dst)
- if (*hx) _cx_memb(_value_clone)(dst, e);
+ if (*hx) *dst = _cx_memb(_value_clone)(*e);
return clone;
}
#endif
@@ -363,7 +364,7 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { const _cx_size _cap = self->bucket_count;
_cx_value* _slot = self->table;
uint8_t* _hashx = self->_hashx;
- _cx_memb(_value_del)(&_slot[i]);
+ _cx_memb(_value_drop)(&_slot[i]);
for (;;) { /* delete without leaving tombstone */
if (++j == _cap) j = 0;
if (! _hashx[j])
diff --git a/include/stc/cpque.h b/include/stc/cpque.h index 49aa2406..87be1e73 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -55,7 +55,7 @@ STC_INLINE bool _cx_memb(_resize)(_cx_self* self, const size_t len, i_val null) {
if (!_cx_memb(_reserve)(self, len)) return false;
const size_t n = self->size;
- for (size_t i = len; i < n; ++i) i_valdel(&self->data[i]);
+ for (size_t i = len; i < n; ++i) { i_valdrop(&self->data[i]); }
for (size_t i = n; i < len; ++i) self->data[i] = null;
self->size = len;
return true;
@@ -71,10 +71,10 @@ STC_INLINE _cx_self _cx_memb(_with_capacity)(size_t cap) { STC_INLINE void _cx_memb(_clear)(_cx_self* self) {
size_t i = self->size; self->size = 0;
- while (i--) i_valdel(&self->data[i]);
+ while (i--) { i_valdrop(&self->data[i]); }
}
-STC_INLINE void _cx_memb(_del)(_cx_self* self)
+STC_INLINE void _cx_memb(_drop)(_cx_self* self)
{ _cx_memb(_clear)(self); c_free(self->data); }
STC_INLINE size_t _cx_memb(_size)(_cx_self q)
@@ -97,7 +97,7 @@ STC_API _cx_self _cx_memb(_clone)(_cx_self q); STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->data == other.data) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
}
STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_value val)
@@ -139,7 +139,7 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self q) { STC_DEF void
_cx_memb(_erase_at)(_cx_self* self, size_t idx) {
- i_valdel(&self->data[idx]);
+ i_valdrop(&self->data[idx]);
size_t n = --self->size;
self->data[idx] = self->data[n];
_cx_memb(_sift_down_)(self->data - 1, idx + 1, n);
diff --git a/include/stc/cset.h b/include/stc/cset.h index d74a8ccc..91e703da 100644 --- a/include/stc/cset.h +++ b/include/stc/cset.h @@ -35,7 +35,7 @@ int main(void) { c_foreach (i, cset_sx, s)
printf("set %d\n", *i.ref);
- cset_sx_del(&s);
+ cset_sx_drop(&s);
}
*/
diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 101e7399..6ba220ab 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -32,7 +32,7 @@ #include <stc/csmap.h>
int main(void) {
- c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_del(&m))
+ c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m))
{
csmap_sx_emplace(&m, "Testing one", 1.234);
csmap_sx_emplace(&m, "Testing two", 12.34);
@@ -97,7 +97,7 @@ STC_API _cx_self _cx_memb(_init)(void); #if !c_option(c_no_clone)
STC_API _cx_self _cx_memb(_clone)(_cx_self tree);
#endif
-STC_API void _cx_memb(_del)(_cx_self* self);
+STC_API void _cx_memb(_drop)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap);
STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out);
STC_API _cx_iter _cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey);
@@ -112,7 +112,7 @@ STC_API void _cx_memb(_next)(_cx_iter* it); STC_INLINE bool _cx_memb(_empty)(_cx_self tree) { return _csmap_rep(&tree)->size == 0; }
STC_INLINE size_t _cx_memb(_size)(_cx_self tree) { return _csmap_rep(&tree)->size; }
STC_INLINE size_t _cx_memb(_capacity)(_cx_self tree) { return _csmap_rep(&tree)->cap; }
-STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); *self = _cx_memb(_init)(); }
+STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); }
STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); }
STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey)
{ _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it) != NULL; }
@@ -134,10 +134,16 @@ _cx_memb(_value_toraw)(_cx_value* val) { _i_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} );
}
+STC_INLINE int
+_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) {
+ _cx_rawkey rx = i_keyto(_i_keyref(x)), ry = i_keyto(_i_keyref(y));
+ return i_cmp(&rx, &ry);
+}
+
STC_INLINE void
-_cx_memb(_value_del)(_cx_value* val) {
- i_keydel(_i_keyref(val));
- _i_MAP_ONLY( i_valdel(&val->second); )
+_cx_memb(_value_drop)(_cx_value* val) {
+ i_keydrop(_i_keyref(val));
+ _i_MAP_ONLY( i_valdrop(&val->second); )
}
#ifndef _i_isset
@@ -150,7 +156,7 @@ _cx_memb(_value_del)(_cx_value* val) { _cx_memb(_put)(_cx_self* self, i_key key, i_val mapped)
{ return _cx_memb(_insert_or_assign)(self, key, mapped); }
- STC_INLINE const _cx_mapped*
+ STC_INLINE _cx_mapped*
_cx_memb(_at)(const _cx_self* self, i_keyraw rkey)
{ _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; }
#endif
@@ -166,13 +172,14 @@ _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) { STC_INLINE void
_cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->nodes == other.nodes) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
}
-STC_INLINE void
-_cx_memb(_value_clone)(_cx_value* dst, _cx_value* val) {
- *_i_keyref(dst) = i_keyfrom(i_keyto(_i_keyref(val)));
- _i_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); )
+STC_INLINE _cx_value
+_cx_memb(_value_clone)(_cx_value _val) {
+ *_i_keyref(&_val) = i_keyfrom(i_keyto(_i_keyref(&_val)));
+ _i_MAP_ONLY( _val.second = i_valfrom(i_valto(&_val.second)); )
+ return _val;
}
STC_INLINE _cx_result
@@ -190,7 +197,7 @@ STC_INLINE _cx_result _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) {
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key));
if (res.inserted) { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )}
- else { i_keydel(&key); _i_MAP_ONLY( i_valdel(&mapped); )}
+ else { i_keydrop(&key); _i_MAP_ONLY( i_valdrop(&mapped); )}
return res;
}
@@ -279,7 +286,7 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) {
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key));
if (res.inserted) res.ref->first = key;
- else { i_keydel(&key); i_valdel(&res.ref->second); }
+ else { i_keydrop(&key); i_valdrop(&res.ref->second); }
res.ref->second = mapped; return res;
}
#if !c_option(c_no_clone)
@@ -287,7 +294,7 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) {
_cx_result res = _cx_memb(_insert_entry_)(self, rkey);
if (res.inserted) res.ref->first = i_keyfrom(rkey);
- else i_valdel(&res.ref->second);
+ else i_valdrop(&res.ref->second);
res.ref->second = i_valfrom(rmapped); return res;
}
#endif
@@ -404,7 +411,7 @@ _cx_memb(_erase_r_)(_cx_node *d, _cx_size tn, const _cx_rawkey* rkey, int *erase d[tn].link[c < 0] = _cx_memb(_erase_r_)(d, d[tn].link[c < 0], rkey, erased);
else {
if (!(*erased)++)
- _cx_memb(_value_del)(&d[tn].value);
+ _cx_memb(_value_drop)(&d[tn].value);
if (d[tn].link[0] && d[tn].link[1]) {
tx = d[tn].link[0];
while (d[tx].link[1])
@@ -470,7 +477,7 @@ STC_DEF _cx_size _cx_memb(_clone_r_)(_cx_self* self, _cx_node* src, _cx_size sn) {
if (sn == 0) return 0;
_cx_size tx, tn = _cx_memb(_node_new_)(self, src[sn].level);
- _cx_memb(_value_clone)(&self->nodes[tn].value, &src[sn].value);
+ self->nodes[tn].value = _cx_memb(_value_clone)(src[sn].value);
tx = _cx_memb(_clone_r_)(self, src, src[sn].link[0]); self->nodes[tn].link[0] = tx;
tx = _cx_memb(_clone_r_)(self, src, src[sn].link[1]); self->nodes[tn].link[1] = tx;
return tn;
@@ -491,12 +498,12 @@ _cx_memb(_del_r_)(_cx_node* d, _cx_size tn) { if (tn) {
_cx_memb(_del_r_)(d, d[tn].link[0]);
_cx_memb(_del_r_)(d, d[tn].link[1]);
- _cx_memb(_value_del)(&d[tn].value);
+ _cx_memb(_value_drop)(&d[tn].value);
}
}
STC_DEF void
-_cx_memb(_del)(_cx_self* self) {
+_cx_memb(_drop)(_cx_self* self) {
if (_csmap_rep(self)->root) {
_cx_memb(_del_r_)(self->nodes, (_cx_size) _csmap_rep(self)->root);
c_free(_csmap_rep(self));
diff --git a/include/stc/csptr.h b/include/stc/csptr.h index 4753ef12..b66cd4d7 100644 --- a/include/stc/csptr.h +++ b/include/stc/csptr.h @@ -26,25 +26,25 @@ typedef struct { cstr name, last; } Person;
-Person Person_from(const char* name, const char* last) {
+Person Person_new(const char* name, const char* last) {
return (Person){.name = cstr_from(name), .last = cstr_from(last)};
}
-void Person_del(Person* p) {
- printf("del: %s %s\n", p->name.str, p->last.str);
- c_del(cstr, &p->name, &p->last);
+void Person_drop(Person* p) {
+ printf("drop: %s %s\n", p->name.str, p->last.str);
+ c_drop(cstr, &p->name, &p->last);
}
#define i_tag person
#define i_val Person
-#define i_valdel Person_del
+#define i_valdrop Person_drop
#include <stc/csptr.h>
int main() {
- csptr_person p = csptr_person_new(Person_from("John", "Smiths"));
+ csptr_person p = csptr_person_new(Person_new("John", "Smiths"));
csptr_person q = csptr_person_clone(p); // share the pointer
printf("%s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count);
- c_del(csptr_person, &p, &q);
+ c_drop(csptr_person, &p, &q);
}
*/
@@ -76,6 +76,7 @@ int main() { #endif
#define _i_has_internal_clone
#include "template.h"
+typedef i_valraw _cx_rawvalue;
#if !c_option(c_no_atomic)
#define _i_atomic_inc(v) c_atomic_inc(v)
@@ -132,9 +133,9 @@ _cx_memb(_move)(_cx_self* self) { }
STC_INLINE void
-_cx_memb(_del)(_cx_self* self) {
+_cx_memb(_drop)(_cx_self* self) {
if (self->use_count && _i_atomic_dec_and_test(self->use_count)) {
- i_valdel(self->get);
+ i_valdrop(self->get);
if (self->get != &((_cx_csptr_rep *)self->use_count)->value)
c_free(self->get);
c_free(self->use_count);
@@ -143,19 +144,19 @@ _cx_memb(_del)(_cx_self* self) { STC_INLINE void
_cx_memb(_reset)(_cx_self* self) {
- _cx_memb(_del)(self);
+ _cx_memb(_drop)(self);
self->use_count = NULL, self->get = NULL;
}
STC_INLINE void
_cx_memb(_reset_with)(_cx_self* self, _cx_value* p) {
- _cx_memb(_del)(self);
+ _cx_memb(_drop)(self);
*self = _cx_memb(_with)(p);
}
STC_INLINE void
_cx_memb(_reset_new)(_cx_self* self, i_val val) {
- _cx_memb(_del)(self);
+ _cx_memb(_drop)(self);
*self = _cx_memb(_new)(val);
}
@@ -164,47 +165,48 @@ _cx_memb(_reset_new)(_cx_self* self, i_val val) { return _cx_memb(_new)(i_valfrom(raw));
}
- STC_INLINE void
- _cx_memb(_reset_from)(_cx_self* self, i_valraw raw) {
- _cx_memb(_del)(self);
- *self = _cx_memb(_new)(i_valfrom(raw));
+ STC_INLINE i_valraw
+ _cx_memb(_toraw)(const _cx_self* self) {
+ return i_valto(self->get);
}
#endif
STC_INLINE void
_cx_memb(_copy)(_cx_self* self, _cx_self ptr) {
if (ptr.use_count) _i_atomic_inc(ptr.use_count);
- _cx_memb(_del)(self); *self = ptr;
+ _cx_memb(_drop)(self); *self = ptr;
}
STC_INLINE void
_cx_memb(_take)(_cx_self* self, _cx_self ptr) {
- if (self->get != ptr.get) _cx_memb(_del)(self);
+ if (self->get != ptr.get) _cx_memb(_drop)(self);
*self = ptr;
}
STC_INLINE uint64_t
_cx_memb(_hash)(const _cx_self* self, size_t n) {
- #if (c_option(c_no_compare) || defined _i_default_compare) && SIZE_MAX >> 32
+ #if c_option(c_no_cmp) && SIZE_MAX >> 32
return c_hash64(&self->get, 8);
- #elif (c_option(c_no_compare) || defined _i_default_compare)
+ #elif c_option(c_no_cmp)
return c_hash32(&self->get, 4);
#else
- i_valraw raw = i_valto(self->get);
- return i_hash(&raw, sizeof raw);
+ return i_hash(self->get, sizeof *self->get);
#endif
}
STC_INLINE int
-_cx_memb(_compare)(const _cx_self* x, const _cx_self* y) {
- #if (c_option(c_no_compare) || defined _i_default_compare)
- return (int)(x->get - y->get);
+_cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) {
+ #if c_option(c_no_cmp)
+ return c_default_cmp(&x->get, &y->get);
#else
- i_valraw rx = i_valto(x->get);
- i_valraw ry = i_valto(y->get);
- return i_cmp(&rx, &ry);
+ return i_cmp(x->get, y->get);
#endif
}
+
+STC_INLINE bool
+_cx_memb(_equalto)(const _cx_self* x, const _cx_self* y) {
+ return !_cx_memb(_cmp)(x, y);
+}
#undef _i_atomic_inc
#undef _i_atomic_dec_and_test
-#include "template.h"
\ No newline at end of file +#include "template.h"
diff --git a/include/stc/csset.h b/include/stc/csset.h index e4558192..07cf4b17 100644 --- a/include/stc/csset.h +++ b/include/stc/csset.h @@ -38,7 +38,7 @@ int main(void) { c_foreach (k, csset_i, s)
printf("set %d\n", *k.ref);
- csset_i_del(&s);
+ csset_i_drop(&s);
}
*/
diff --git a/include/stc/cstack.h b/include/stc/cstack.h index c1170f79..d43afe29 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -54,11 +54,11 @@ STC_INLINE _cx_self _cx_memb(_with_size)(size_t size, i_val fill) { STC_INLINE void _cx_memb(_clear)(_cx_self* self) {
_cx_value *p = self->data + self->size;
- while (p-- != self->data) i_valdel(p);
+ while (p-- != self->data) { i_valdrop(p); }
self->size = 0;
}
-STC_INLINE void _cx_memb(_del)(_cx_self* self)
+STC_INLINE void _cx_memb(_drop)(_cx_self* self)
{ _cx_memb(_clear)(self); c_free(self->data); }
STC_INLINE size_t _cx_memb(_size)(_cx_self v)
@@ -74,7 +74,7 @@ STC_INLINE _cx_value* _cx_memb(_top)(const _cx_self* self) { return &self->data[self->size - 1]; }
STC_INLINE void _cx_memb(_pop)(_cx_self* self)
- { _cx_value* p = &self->data[--self->size]; i_valdel(p); }
+ { _cx_value* p = &self->data[--self->size]; i_valdrop(p); }
STC_INLINE bool _cx_memb(_reserve)(_cx_self* self, size_t n) {
if (n < self->size) return true;
@@ -107,7 +107,7 @@ STC_INLINE _cx_self _cx_memb(_clone)(_cx_self v) { STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->data == other.data) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
}
STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val)
diff --git a/include/stc/cstr.h b/include/stc/cstr.h index a46de3c3..730f4d16 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -68,6 +68,7 @@ STC_API int c_strncasecmp(const char* s1, const char* s2, size_t nma STC_INLINE cstr cstr_init() { return cstr_null; }
#define cstr_str(self) (self)->str
+#define cstr_toraw(self) (self)->str
#define cstr_new(literal) \
cstr_from_n(literal, sizeof c_make(c_strlit){literal} - 1)
STC_INLINE cstr cstr_from(const char* str)
@@ -77,7 +78,7 @@ STC_INLINE size_t cstr_size(cstr s) { return _cstr_rep(&s)->size; } STC_INLINE size_t cstr_length(cstr s) { return _cstr_rep(&s)->size; }
STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_rep(&s)->cap; }
STC_INLINE bool cstr_empty(cstr s) { return _cstr_rep(&s)->size == 0; }
-STC_INLINE void cstr_del(cstr* self)
+STC_INLINE void cstr_drop(cstr* self)
{ if (_cstr_rep(self)->cap) c_free(_cstr_rep(self)); }
STC_INLINE cstr cstr_clone(cstr s)
{ return cstr_from_n(s.str, _cstr_rep(&s)->size); }
@@ -166,7 +167,7 @@ cstr_ends_with(cstr s, const char* sub) { }
/* container adaptor functions: */
-#define cstr_compare(xp, yp) strcmp((xp)->str, (yp)->str)
+#define cstr_cmp(xp, yp) strcmp((xp)->str, (yp)->str)
#define cstr_equalto(xp, yp) (strcmp((xp)->str, (yp)->str) == 0)
#define cstr_hash(xp, dummy) c_strhash((xp)->str)
@@ -249,7 +250,7 @@ cstr_printf(cstr* self, const char* fmt, ...) { va_start(args, fmt);
int n = cstr_vfmt(&ret, fmt, args);
va_end(args);
- cstr_del(self);
+ cstr_drop(self);
*self = ret;
return n;
}
diff --git a/include/stc/csview.h b/include/stc/csview.h index 872b6e1e..ac120e15 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -114,9 +114,13 @@ STC_INLINE bool cstr_ends_with_v(cstr s, csview sub) /* ---- Container helper functions ---- */
-#define csview_compare(xp, yp) strcmp((xp)->str, (yp)->str)
+STC_INLINE int csview_cmp(const csview* x, const csview* y) {
+ const size_t m = x->size < y->size ? x->size : y->size;
+ const int c = memcmp(x->str, y->str, m);
+ return c ? c : x->size - y->size;
+ }
#define csview_hash(xp, dummy) c_strhash((xp)->str)
-#define csview_equalto(xp, yp) (strcmp((xp)->str, (yp)->str) == 0)
+#define csview_equalto(xp, yp) (csview_cmp(xp, yp) == 0)
/* -------------------------- IMPLEMENTATION ------------------------- */
diff --git a/include/stc/cvec.h b/include/stc/cvec.h index f64f7840..01143d25 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -46,15 +46,15 @@ struct MyStruct { int main() {
cvec_i32 vec = cvec_i32_init();
cvec_i32_push_back(&vec, 123);
- cvec_i32_del(&vec);
+ cvec_i32_drop(&vec);
cvec_float fvec = cvec_float_init();
cvec_float_push_back(&fvec, 123.3);
- cvec_float_del(&fvec);
+ cvec_float_drop(&fvec);
cvec_str svec = cvec_str_init();
cvec_str_emplace_back(&svec, "Hello, friend");
- cvec_str_del(&svec);
+ cvec_str_drop(&svec);
}
*/
@@ -79,7 +79,7 @@ struct cvec_rep { size_t size, cap; void* data[]; }; typedef i_valraw _cx_rawvalue;
STC_API _cx_self _cx_memb(_init)(void);
-STC_API void _cx_memb(_del)(_cx_self* self);
+STC_API void _cx_memb(_drop)(_cx_self* self);
STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap);
STC_API bool _cx_memb(_resize)(_cx_self* self, size_t size, i_val null);
@@ -87,8 +87,8 @@ STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value); STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
const _cx_value* p1, const _cx_value* p2);
-#if !c_option(c_no_compare)
-STC_API int _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y);
+#if !c_option(c_no_cmp)
+STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y);
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw raw);
STC_API _cx_iter _cx_memb(_bsearch_in)(_cx_iter it1, _cx_iter it2, i_valraw raw);
#endif
@@ -107,7 +107,7 @@ STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw) STC_INLINE void
_cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->data == other.data) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
}
STC_INLINE _cx_iter
_cx_memb(_emplace)(_cx_self* self, const size_t idx, i_valraw raw) {
@@ -136,7 +136,7 @@ STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return self->da STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self)
{ return self->data + cvec_rep_(self)->size - 1; }
STC_INLINE void _cx_memb(_pop_back)(_cx_self* self)
- { _cx_value* p = &self->data[--cvec_rep_(self)->size]; i_valdel(p); }
+ { _cx_value* p = &self->data[--cvec_rep_(self)->size]; i_valdrop(p); }
STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self)
{ return c_make(_cx_iter){self->data}; }
STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
@@ -197,7 +197,7 @@ _cx_memb(_at)(const _cx_self* self, const size_t idx) { return self->data + idx;
}
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, i_valraw raw) {
@@ -226,9 +226,9 @@ _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, }
STC_INLINE void
_cx_memb(_sort)(_cx_self* self) {
- _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_compare));
+ _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_cmp));
}
-#endif // !c_no_compare
+#endif // !c_no_cmp
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp)
@@ -246,14 +246,15 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) {
struct cvec_rep* rep = cvec_rep_(self);
if (rep->cap) {
- for (_cx_value *p = self->data, *q = p + rep->size; p != q; ++p)
- i_valdel(p);
+ for (_cx_value *p = self->data, *q = p + rep->size; p != q; ) {
+ --q; i_valdrop(q);
+ }
rep->size = 0;
}
}
STC_DEF void
-_cx_memb(_del)(_cx_self* self) {
+_cx_memb(_drop)(_cx_self* self) {
_cx_memb(_clear)(self);
if (cvec_rep_(self)->cap)
c_free(cvec_rep_(self));
@@ -263,7 +264,7 @@ STC_DEF bool _cx_memb(_reserve)(_cx_self* self, const size_t cap) {
struct cvec_rep* rep = cvec_rep_(self);
const size_t len = rep->size;
- if (cap > rep->cap || cap && cap == len) {
+ if (cap > rep->cap || (cap && cap == len)) {
rep = (struct cvec_rep*) c_realloc(rep->cap ? rep : NULL,
offsetof(struct cvec_rep, data) + cap*sizeof(i_val));
if (!rep) return false;
@@ -279,7 +280,7 @@ _cx_memb(_resize)(_cx_self* self, const size_t len, i_val null) { if (!_cx_memb(_reserve)(self, len)) return false;
struct cvec_rep *rep = cvec_rep_(self);
const size_t n = rep->size;
- for (size_t i = len; i < n; ++i) i_valdel(&self->data[i]);
+ for (size_t i = len; i < n; ++i) { i_valdrop(&self->data[i]); }
for (size_t i = n; i < len; ++i) self->data[i] = null;
if (rep->cap) rep->size = len;
return true;
@@ -320,7 +321,7 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { intptr_t len = p2 - p1;
if (len > 0) {
_cx_value* p = p1, *end = self->data + cvec_rep_(self)->size;
- for (; p != p2; ++p) i_valdel(p);
+ for (; p != p2; ++p) { i_valdrop(p); }
memmove(p1, p2, (end - p2) * sizeof(i_val));
cvec_rep_(self)->size -= len;
}
@@ -356,7 +357,7 @@ _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, }
#endif
-#if !c_option(c_no_compare)
+#if !c_option(c_no_cmp)
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) {
@@ -381,12 +382,12 @@ _cx_memb(_bsearch_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) { }
STC_DEF int
-_cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y) {
+_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) {
i_valraw rx = i_valto(x);
i_valraw ry = i_valto(y);
return i_cmp(&rx, &ry);
}
-#endif // !c_no_compare
+#endif // !c_no_cmp
#endif
#include "template.h"
#define CVEC_H_INCLUDED
diff --git a/include/stc/template.h b/include/stc/template.h index 85c4a940..61befb2b 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -40,19 +40,13 @@ #define _cx_size _cx_memb(_size_t)
#endif
-#if defined i_valraw && !(defined i_valto && defined i_valfrom)
- #error "if i_valraw or i_valto defined, i_valfrom must be defined"
-#endif
-#if defined i_keyraw && !(defined i_keyto && defined i_keyfrom)
- #error "if i_keyraw or i_keyto defined, i_keyfrom a must be defined"
-#endif
-#ifdef i_key_csptr // [deprecated]
- #define i_key_ref i_key_csptr
- #error "i_key_csptr no longer supported: use new name i_key_ref"
+#if defined i_key_csptr || defined i_key_ref // [deprecated]
+ #define i_key_bind i_key_csptr
+ #error "i_key_csptr/ref no longer supported: use new name i_key_bind"
#endif
-#ifdef i_val_csptr // [deprecated]
- #define i_val_ref i_val_csptr
- #error "i_val_csptr no longer supported: use new name i_val_ref"
+#if defined i_val_csptr || defined i_val_ref // [deprecated]
+ #define i_val_bind i_val_csptr
+ #error "i_val_sptr/ref no longer supported: use new name i_val_bind"
#endif
#ifdef i_cnt // [deprecated]
#define i_type i_cnt
@@ -69,46 +63,53 @@ #include "cstr.h"
#endif
-#if defined i_key_ref
- #define i_key i_key_ref
- #define i_keyfrom c_PASTE(i_key, _clone)
- #ifndef i_cmp
- #define i_cmp c_PASTE(i_key, _compare)
- #endif
- #ifndef i_hash
- #define i_hash c_PASTE(i_key, _hash)
- #endif
- #ifndef i_keydel
- #define i_keydel c_PASTE(i_key, _del)
- #endif
-
-#elif defined i_key_str
-
- #define i_key cstr
- #define i_keyfrom cstr_from
- #define i_keyto cstr_str
- #define i_keyraw const char*
+#ifdef i_key_str
+ #define i_key_bind cstr
+ #define i_keyraw c_rawstr
#ifndef i_tag
#define i_tag str
#endif
- #ifndef i_cmp
- #define i_cmp c_rawstr_compare
+#endif
+
+#ifdef i_key_bind
+ #define i_key i_key_bind
+ #ifndef i_keyraw
+ #ifndef i_keyfrom
+ #define i_keyfrom c_PASTE(i_key, _clone)
+ #endif
+ #else
+ #ifndef i_keyfrom
+ #define i_keyfrom c_PASTE(i_key, _from)
+ #endif
+ #ifndef i_keyto
+ #define i_keyto c_PASTE(i_key, _toraw)
+ #endif
+ #endif
+ #ifndef i_cmp
+ #define i_cmp c_PASTE(i_keyraw, _cmp)
+ #endif
+ #ifndef i_equ
+ #define i_equ c_PASTE(i_keyraw, _equalto)
#endif
#ifndef i_hash
- #define i_hash c_rawstr_hash
+ #define i_hash c_PASTE(i_keyraw, _hash)
#endif
- #if !defined i_keydel
- #define i_keydel cstr_del
+ #ifndef i_keydrop
+ #define i_keydrop c_PASTE(i_key, _drop)
#endif
#endif
-/* Resolve i_del and i_from here */
-#if defined i_del && defined i_isset
- #define i_keydel i_del
-#elif defined i_del && !defined i_key
- #define i_valdel i_del
-#elif defined i_del
- #error "i_del not supported for maps, define i_keydel / i_valdel instead."
+#if defined i_keyraw && !(defined i_keyto && defined i_keyfrom)
+ #error "if i_keyraw defined, i_keyfrom and i_keyto must be defined"
+#endif
+
+/* Resolve i_drop and i_from here */
+#if defined i_drop && defined i_isset
+ #define i_keydrop i_drop
+#elif defined i_drop && !defined i_key
+ #define i_valdrop i_drop
+#elif defined i_drop
+ #error "i_drop not supported for maps, define i_keydrop / i_valdrop instead."
#endif
#if defined i_from && defined i_isset
#define i_keyfrom i_from
@@ -118,33 +119,40 @@ #error "i_from not supported for maps, define i_keyfrom / i_valfrom instead."
#endif
-#if defined i_val_ref
- #define i_val i_val_ref
- #define i_valfrom c_PASTE(i_val, _clone)
- #if !defined i_cmp && !defined i_key
- #define i_cmp c_PASTE(i_val, _compare)
- #endif
- #if !defined i_valdel
- #define i_valdel c_PASTE(i_val, _del)
+#ifdef i_val_str
+ #define i_val_bind cstr
+ #define i_valraw c_rawstr
+ #if !defined i_tag && !defined i_key
+ #define i_tag str
#endif
+#endif
-#elif defined i_val_str
-
- #define i_val cstr
- #define i_valfrom cstr_from
- #define i_valto cstr_str
- #define i_valraw const char*
- #if !defined i_tag && !defined i_key
- #define i_tag str
+#ifdef i_val_bind
+ #define i_val i_val_bind
+ #ifndef i_valraw
+ #ifndef i_valfrom
+ #define i_valfrom c_PASTE(i_val, _clone)
+ #endif
+ #else
+ #ifndef i_valfrom
+ #define i_valfrom c_PASTE(i_val, _from)
+ #endif
+ #ifndef i_valto
+ #define i_valto c_PASTE(i_val, _toraw)
+ #endif
#endif
#if !defined i_cmp && !defined i_key
- #define i_cmp c_rawstr_compare
+ #define i_cmp c_PASTE(i_valraw, _cmp)
#endif
- #if !defined i_valdel
- #define i_valdel cstr_del
+ #ifndef i_valdrop
+ #define i_valdrop c_PASTE(i_val, _drop)
#endif
#endif
+#if defined i_valraw && !(defined i_valto && defined i_valfrom)
+ #error "if i_valraw defined, i_valfrom and i_valto must be defined"
+#endif
+
#ifdef i_key
#ifdef _i_isset
#define i_val i_key
@@ -152,8 +160,8 @@ #ifndef i_tag
#define i_tag i_key
#endif
- #if !defined _i_has_internal_clone && defined i_keydel && !defined i_keyfrom && !c_option(c_no_clone)
- #error "i_keydel defined but not i_keyfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'"
+ #if !defined _i_has_internal_clone && defined i_keydrop && !defined i_keyfrom && !c_option(c_no_clone)
+ #error "i_keydrop defined but not i_keyfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'"
#endif
#if !defined i_keyfrom
#define i_keyfrom c_default_clone
@@ -167,8 +175,8 @@ #elif !defined i_equ
#define i_equ c_default_equalto
#endif
- #ifndef i_keydel
- #define i_keydel c_default_del
+ #ifndef i_keydrop
+ #define i_keydrop c_default_drop
#endif
#elif defined _i_isset
#error "i_key define is missing."
@@ -177,8 +185,8 @@ #ifndef i_tag
#define i_tag i_val
#endif
-#if !defined _i_has_internal_clone && defined i_valdel && !defined i_valfrom && !c_option(c_no_clone)
- #error "i_valdel/i_del defined but not i_valfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'"
+#if !defined _i_has_internal_clone && defined i_valdrop && !defined i_valfrom && !c_option(c_no_clone)
+ #error "i_valdrop/i_drop defined but not i_valfrom (e.g. as c_default_clone), or no 'i_opt c_no_clone'"
#endif
#if !defined i_valfrom
#define i_valfrom c_default_clone
@@ -187,12 +195,11 @@ #define i_valraw i_val
#define i_valto c_default_toraw
#endif
-#ifndef i_valdel
- #define i_valdel c_default_del
+#ifndef i_valdrop
+ #define i_valdrop c_default_drop
#endif
#ifndef i_cmp
- #define _i_default_compare
- #define i_cmp c_default_compare
+ #define i_cmp c_default_cmp
#endif
#ifndef i_hash
#define i_hash c_default_hash
@@ -205,29 +212,28 @@ #undef i_imp
#undef i_opt
#undef i_cmp
-#undef i_del
+#undef i_drop
#undef i_equ
#undef i_hash
#undef i_from
#undef i_val
#undef i_val_str
-#undef i_val_ref
-#undef i_valdel
+#undef i_val_bind
+#undef i_valdrop
#undef i_valraw
#undef i_valfrom
#undef i_valto
#undef i_key
#undef i_key_str
-#undef i_key_ref
-#undef i_keydel
+#undef i_key_bind
+#undef i_keydrop
#undef i_keyraw
#undef i_keyfrom
#undef i_keyto
#undef _i_prefix
-#undef _i_default_compare
#undef _i_has_internal_clone
#undef _i_template
#endif
|
