summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-07-06 22:26:53 +0200
committerTyge Løvset <[email protected]>2022-07-06 22:26:53 +0200
commitb94170eefce899d0b236804681d77fe026956fd9 (patch)
tree9d1bad3bdfce085cc8ff8c567943ffd8750aa644
parent6e91820d7cf632ff30b936c554a0bdf83c9e64b2 (diff)
downloadSTC-modified-b94170eefce899d0b236804681d77fe026956fd9.tar.gz
STC-modified-b94170eefce899d0b236804681d77fe026956fd9.zip
Version 3.7. Make sure to check NEWS/Changes in README.md for a few code-breaking API changes.
-rw-r--r--README.md14
-rw-r--r--benchmarks/build_all.sh2
-rw-r--r--benchmarks/external/ankerl/robin_hood.h (renamed from benchmarks/external/robin_hood.h)0
-rw-r--r--benchmarks/external/tsl/robin_hash.h1
-rw-r--r--benchmarks/external/update.sh43
-rw-r--r--benchmarks/misc/rust_cmap.c6
-rw-r--r--benchmarks/misc/string_bench_STC.cpp16
-rw-r--r--benchmarks/picobench/picobench_cmap.cpp51
-rw-r--r--benchmarks/picobench/picobench_csmap.cpp10
-rw-r--r--benchmarks/plotbench/cdeq_benchmark.cpp6
-rw-r--r--benchmarks/plotbench/cmap_benchmark.cpp4
-rw-r--r--benchmarks/plotbench/csmap_benchmark.cpp4
-rw-r--r--benchmarks/plotbench/cvec_benchmark.cpp4
-rw-r--r--benchmarks/shootout_hashmaps.cpp78
-rw-r--r--docs/carc_api.md2
-rw-r--r--docs/carray_api.md8
-rw-r--r--docs/cbox_api.md2
-rw-r--r--docs/cdeq_api.md8
-rw-r--r--docs/clist_api.md2
-rw-r--r--docs/cmap_api.md10
-rw-r--r--docs/cpque_api.md6
-rw-r--r--docs/cqueue_api.md2
-rw-r--r--docs/cset_api.md10
-rw-r--r--docs/csmap_api.md7
-rw-r--r--docs/csset_api.md2
-rw-r--r--docs/cstack_api.md8
-rw-r--r--docs/cstr_api.md1
-rw-r--r--docs/cvec_api.md8
-rw-r--r--examples/astar.c2
-rw-r--r--examples/bits2.c2
-rw-r--r--examples/books.c2
-rw-r--r--examples/complex.c2
-rw-r--r--examples/convert.c2
-rw-r--r--examples/cpque.c2
-rw-r--r--examples/csmap_erase.c2
-rw-r--r--examples/csmap_find.c10
-rw-r--r--examples/demos.c8
-rw-r--r--examples/inits.c2
-rw-r--r--examples/new_arr.c4
-rw-r--r--examples/new_pque.c4
-rw-r--r--examples/new_queue.c4
-rw-r--r--examples/queue.c2
-rw-r--r--examples/stack.c1
-rw-r--r--include/stc/alt/csmap.h6
-rw-r--r--include/stc/carc.h2
-rw-r--r--include/stc/carr2.h18
-rw-r--r--include/stc/carr3.h20
-rw-r--r--include/stc/cbits.h26
-rw-r--r--include/stc/cbox.h6
-rw-r--r--include/stc/cdeq.h32
-rw-r--r--include/stc/clist.h11
-rw-r--r--include/stc/cmap.h26
-rw-r--r--include/stc/cpque.h23
-rw-r--r--include/stc/cqueue.h4
-rw-r--r--include/stc/csmap.h26
-rw-r--r--include/stc/cstack.h75
-rw-r--r--include/stc/cstr.h3
-rw-r--r--include/stc/cvec.h43
-rw-r--r--include/stc/forward.h8
-rw-r--r--include/stc/template.h1
60 files changed, 374 insertions, 320 deletions
diff --git a/README.md b/README.md
index ef896068..f74888d8 100644
--- a/README.md
+++ b/README.md
@@ -3,9 +3,9 @@
STC - Smart Template Containers for C
=====================================
-News: Version 3.6 released (April 2022)
+News: Version 3.7 released (July 2022)
---------------------------------------
-- See [Changes version 3.6](#changes-version-36)
+- [See changes version 3](#version-3). Note some code-breaking API changes!
Introduction
------------
@@ -457,6 +457,16 @@ Memory efficiency
# Version 3
+## Changes version 3.7
+- NB! Changed self argument from value to const pointer on containers (does not apply to **cstr**):
+ - `CNT_size(const CNT *self)`
+ - `CNT_capacity(const CNT *self)`
+ - `CNT_empty(const CNT *self)`
+- Now both **cstack** and **cbits** can be used with template `i_cap` parameter: `#define i_cap <NUM>`. They then use fixed sized arrays, and no heap allocated memory.
+- Renamed *cstr_rename_n()* => *cstr_rename_with_n()* as it could be confused with replacing n instances instead of n bytes.
+- Renamed macro *c_apply_arr()* => *c_apply_array()*
+- Fixed bug in `csmap.h`: begin() on empty map was not fully initialized.
+
## Changes version 3.6
- Swapped to new **cstr** (*short string optimized*, aka SSO). Note that `cstr_str(&s)` must be used, `s.str` is no longer usable.
- Removed *redundant* size argument to `i_hash` template parameter and `c_default_hash`. Please update your code.
diff --git a/benchmarks/build_all.sh b/benchmarks/build_all.sh
index 348a79dd..1093807c 100644
--- a/benchmarks/build_all.sh
+++ b/benchmarks/build_all.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-cc='g++ -std=c++17'
+cc='g++ -std=c++20'
#cc='clang'
#cc='clang -c -DSTC_HEADER'
#cc='cl -nologo'
diff --git a/benchmarks/external/robin_hood.h b/benchmarks/external/ankerl/robin_hood.h
index 0af031f5..0af031f5 100644
--- a/benchmarks/external/robin_hood.h
+++ b/benchmarks/external/ankerl/robin_hood.h
diff --git a/benchmarks/external/tsl/robin_hash.h b/benchmarks/external/tsl/robin_hash.h
index f9fb9e76..89c7c96f 100644
--- a/benchmarks/external/tsl/robin_hash.h
+++ b/benchmarks/external/tsl/robin_hash.h
@@ -1589,6 +1589,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
*/
bucket_entry* static_empty_bucket_ptr() noexcept {
static bucket_entry empty_bucket(true);
+ tsl_rh_assert(empty_bucket.empty());
return &empty_bucket;
}
diff --git a/benchmarks/external/update.sh b/benchmarks/external/update.sh
index c0169fab..00b587cb 100644
--- a/benchmarks/external/update.sh
+++ b/benchmarks/external/update.sh
@@ -1,35 +1,32 @@
tsl_h="https://raw.github.com/Tessil/hopscotch-map/master/include/tsl/"
tsl_r="https://raw.github.com/Tessil/robin-map/master/include/tsl/"
-tsl_s="https://raw.github.com/Tessil/sparse-map/master/include/tsl/"
-greg="https://raw.github.com/greg7mdp/sparsepp/master/sparsepp/"
-martinus="https://raw.github.com/martinus/robin-hood-hashing/master/src/include/"
+smap="https://raw.github.com/greg7mdp/sparsepp/master/sparsepp/"
+pmap="https://raw.github.com/greg7mdp/parallel-hashmap/"
+martinus_r="https://raw.github.com/martinus/robin-hood-hashing/master/src/include/"
+martinus_d="https://raw.github.com/martinus/unordered_dense/master/include/ankerl/"
skarupke="https://raw.github.com/skarupke/flat_hash_map/master/"
-mkdir -p tsl sparsepp skarupke
+mkdir -p ankerl skarupke sparsepp tsl
-wget $martinus"robin_hood.h" -O "robin_hood.h"
+wget $martinus_r"robin_hood.h" -O "ankerl/robin_hood.h"
+wget $martinus_d"unordered_dense.h" -O "ankerl/unordered_dense.h"
-wget $skarupke"bytell_hash_map.hpp" -O "skarupke/bytell_hash_map.hpp"
+#wget $skarupke"bytell_hash_map.hpp" -O "skarupke/bytell_hash_map.hpp"
wget $skarupke"flat_hash_map.hpp" -O "skarupke/flat_hash_map.hpp"
-wget $greg"spp.h" -O "sparsepp/spp.h"
-wget $greg"spp_config.h" -O "sparsepp/spp_config.h"
-wget $greg"spp_dlalloc.h" -O "sparsepp/spp_dlalloc.h"
-wget $greg"spp_memory.h" -O "sparsepp/spp_memory.h"
-wget $greg"spp_smartptr.h" -O "sparsepp/spp_smartptr.h"
-wget $greg"spp_stdint.h" -O "sparsepp/spp_stdint.h"
-wget $greg"spp_timer.h" -O "sparsepp/spp_timer.h"
-wget $greg"spp_traits.h" -O "sparsepp/spp_traits.h"
-wget $greg"spp_utils.h" -O "sparsepp/spp_utils.h"
-
-wget $tsl_h"hopscotch_growth_policy.h" -O "tsl/hopscotch_growth_policy.h"
-wget $tsl_h"hopscotch_hash.h" -O "tsl/hopscotch_hash.h"
-wget $tsl_h"hopscotch_map.h" -O "tsl/hopscotch_map.h"
+#wget $smap"spp.h" -O "sparsepp/spp.h"
+#wget $smap"spp_config.h" -O "sparsepp/spp_config.h"
+#wget $smap"spp_dlalloc.h" -O "sparsepp/spp_dlalloc.h"
+#wget $smap"spp_memory.h" -O "sparsepp/spp_memory.h"
+#wget $smap"spp_smartptr.h" -O "sparsepp/spp_smartptr.h"
+#wget $smap"spp_stdint.h" -O "sparsepp/spp_stdint.h"
+#wget $smap"spp_timer.h" -O "sparsepp/spp_timer.h"
+#wget $smap"spp_traits.h" -O "sparsepp/spp_traits.h"
+#wget $smap"spp_utils.h" -O "sparsepp/spp_utils.h"
+#wget $tsl_h"hopscotch_growth_policy.h" -O "tsl/hopscotch_growth_policy.h"
+#wget $tsl_h"hopscotch_hash.h" -O "tsl/hopscotch_hash.h"
+#wget $tsl_h"hopscotch_map.h" -O "tsl/hopscotch_map.h"
wget $tsl_r"robin_growth_policy.h" -O "tsl/robin_growth_policy.h"
wget $tsl_r"robin_hash.h" -O "tsl/robin_hash.h"
wget $tsl_r"robin_map.h" -O "tsl/robin_map.h"
-
-#wget $tsl_s"sparse_growth_policy.h" -O "tsl/sparse_growth_policy.h"
-#wget $tsl_s"sparse_hash.h" -O "tsl/sparse_hash.h"
-#wget $tsl_s"sparse_map.h" -O "tsl/sparse_map.h"
diff --git a/benchmarks/misc/rust_cmap.c b/benchmarks/misc/rust_cmap.c
index 1e763bde..933910cb 100644
--- a/benchmarks/misc/rust_cmap.c
+++ b/benchmarks/misc/rust_cmap.c
@@ -37,7 +37,7 @@ int main()
uint64_t key = romu_trio(rng) & mask;
cmap_u64_insert(&m, key, 0).ref->second += 1;
}
- printf("insert : %zums \tsize : %" PRIuMAX "\n", (clock() - now)/ms, cmap_u64_size(m));
+ printf("insert : %zums \tsize : %" PRIuMAX "\n", (clock() - now)/ms, cmap_u64_size(&m));
now = clock();
sum = 0;
@@ -55,7 +55,7 @@ int main()
uint64_t key = romu_trio(rng2) & mask;
cmap_u64_erase(&m, key);
}
- printf("remove : %zums \tsize : %" PRIuMAX "\n", (clock() - now)/ms, cmap_u64_size(m));
+ printf("remove : %zums \tsize : %" PRIuMAX "\n", (clock() - now)/ms, cmap_u64_size(&m));
printf("press a key:\n"); getchar();
}
-} \ No newline at end of file
+}
diff --git a/benchmarks/misc/string_bench_STC.cpp b/benchmarks/misc/string_bench_STC.cpp
index 2e05dae3..9fc861ea 100644
--- a/benchmarks/misc/string_bench_STC.cpp
+++ b/benchmarks/misc/string_bench_STC.cpp
@@ -68,10 +68,10 @@ private:
void initShortStringVec(cvec_str* vs, cvec_sv* vsv)
{
- cvec_str_clear(vs);
+ cvec_str_drop(vs);
cvec_sv_clear(vsv);
- cvec_str_copy(vs, read_file("names.txt"));
+ *vs = read_file("names.txt");
/*
cvec_str_emplace_back(vs, "Susan");
cvec_str_emplace_back(vs, "Jason");
@@ -103,16 +103,16 @@ void initShortStringVec(cvec_str* vs, cvec_sv* vsv)
cvec_sv_push_back(vsv, csview_from_s(i.ref));
num += cstr_size(*i.ref);
}
- std::cout << "num strings: " << cvec_sv_size(*vsv) << std::endl;
- std::cout << "avg str len: " << num / (float)cvec_sv_size(*vsv) << std::endl;
+ std::cout << "num strings: " << cvec_sv_size(vsv) << std::endl;
+ std::cout << "avg str len: " << num / (float)cvec_sv_size(vsv) << std::endl;
}
void initLongStringVec(cvec_str* vs, cvec_sv* vsv)
{
- cvec_str_clear(vs);
+ cvec_str_drop(vs);
cvec_sv_clear(vsv);
- cvec_str_copy(vs, read_file("names.txt"));
+ *vs = read_file("names.txt");
c_foreach (i, cvec_str, *vs) {
cstr_append_s(i.ref, *i.ref);
cstr_append_s(i.ref, *i.ref);
@@ -149,8 +149,8 @@ void initLongStringVec(cvec_str* vs, cvec_sv* vsv)
cvec_sv_push_back(vsv, csview_from_s(i.ref));
num += cstr_size(*i.ref);
}
- std::cout << "num strings: " << cvec_sv_size(*vsv) << std::endl;
- std::cout << "avg str len: " << num / (float)cvec_sv_size(*vsv) << std::endl;
+ std::cout << "num strings: " << cvec_sv_size(vsv) << std::endl;
+ std::cout << "avg str len: " << num / (float)cvec_sv_size(vsv) << std::endl;
}
void initMaps(const cvec_str* vs, csmap_str* mapTrans, csmap_ssv* mapSview,
diff --git a/benchmarks/picobench/picobench_cmap.cpp b/benchmarks/picobench/picobench_cmap.cpp
index 4a330019..f4551aa1 100644
--- a/benchmarks/picobench/picobench_cmap.cpp
+++ b/benchmarks/picobench/picobench_cmap.cpp
@@ -6,10 +6,9 @@
#include <string>
#include <unordered_map>
#include <stdexcept>
-#include "../external/robin_hood.h"
-#include "../external/skarupke/bytell_hash_map.hpp"
-#include "../external/tsl/hopscotch_map.h"
-#include "../external/parallel_hashmap/phmap.h"
+#include "../external/ankerl/unordered_dense.h"
+#include "../external/skarupke/flat_hash_map.hpp"
+#include "../external/tsl/robin_map.h"
#define PICOBENCH_IMPLEMENT_WITH_MAIN
#include "picobench.hpp"
@@ -18,20 +17,14 @@ enum {N1 = 4000000, S1 = 1, MaxLoadFactor100 = 80};
uint64_t seed = time(NULL);
template <class K, class V> using umap = std::unordered_map<K, V>;
-template <class K, class V> using bmap = ska::bytell_hash_map<K, V>;
template <class K, class V> using fmap = ska::flat_hash_map<K, V>;
-template <class K, class V> using hmap = tsl::hopscotch_map<K, V>;
-template <class K, class V> using pmap = phmap::flat_hash_map<K, V>;
-template <class K, class V> using rmap = robin_hood::unordered_flat_map<K, V,
- robin_hood::hash<K>, std::equal_to<K>, MaxLoadFactor100>;
+template <class K, class V> using tmap = tsl::robin_map<K, V>;
+template <class K, class V> using dmap = ankerl::unordered_dense::map<K, V>;
#define DEFMAP(map, ...) \
using u##map = umap __VA_ARGS__; \
- using b##map = bmap __VA_ARGS__; \
using f##map = fmap __VA_ARGS__; \
- using h##map = hmap __VA_ARGS__; \
- using p##map = pmap __VA_ARGS__; \
- using r##map = rmap __VA_ARGS__
-
+ using t##map = tmap __VA_ARGS__; \
+ using d##map = dmap __VA_ARGS__
DEFMAP(map_i, <int32_t, int32_t>);
DEFMAP(map_x, <uint64_t, uint64_t>);
@@ -90,7 +83,7 @@ static void ins_and_erase_cmap_i(picobench::state& s)
csrandom(seed);
c_forrange (s.iterations())
cmap_i_erase(&map, crandom());
- s.set_result(cmap_i_size(map));
+ s.set_result(cmap_i_size(&map));
cmap_i_drop(&map);
}
@@ -110,17 +103,15 @@ static void ins_and_erase_cmap_x(picobench::state& s)
csrandom(seed);
c_forrange (s.iterations())
cmap_x_erase(&map, crandom());
- s.set_result(cmap_x_size(map));
+ s.set_result(cmap_x_size(&map));
cmap_x_drop(&map);
}
#define P samples(S1).iterations({N1/4})
PICOBENCH(ins_and_erase_i<umap_x>).P;
-PICOBENCH(ins_and_erase_i<bmap_x>).P;
+PICOBENCH(ins_and_erase_i<dmap_x>).P;
PICOBENCH(ins_and_erase_i<fmap_x>).P;
-PICOBENCH(ins_and_erase_i<hmap_x>).P;
-PICOBENCH(ins_and_erase_i<pmap_x>).P;
-PICOBENCH(ins_and_erase_i<rmap_x>).P;
+PICOBENCH(ins_and_erase_i<tmap_x>).P;
PICOBENCH(ins_and_erase_cmap_x).P;
#undef P
@@ -158,11 +149,9 @@ static void ins_and_access_cmap_i(picobench::state& s)
#define P samples(S1).iterations({N1, N1, N1, N1}).args({18, 23, 25, 31})
PICOBENCH(ins_and_access_i<umap_i>).P;
-PICOBENCH(ins_and_access_i<bmap_i>).P;
+PICOBENCH(ins_and_access_i<dmap_i>).P;
PICOBENCH(ins_and_access_i<fmap_i>).P;
-PICOBENCH(ins_and_access_i<hmap_i>).P;
-PICOBENCH(ins_and_access_i<pmap_i>).P;
-PICOBENCH(ins_and_access_i<rmap_i>).P;
+PICOBENCH(ins_and_access_i<tmap_i>).P;
PICOBENCH(ins_and_access_cmap_i).P;
#undef P
@@ -213,18 +202,16 @@ static void ins_and_access_cmap_s(picobench::state& s)
randomize(buf, s.arg());
result += cmap_str_erase(&map, buf);
}
- s.set_result(result + cmap_str_size(map));
+ s.set_result(result + cmap_str_size(&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})
PICOBENCH(ins_and_access_s<umap_s>).P;
-PICOBENCH(ins_and_access_s<bmap_s>).P;
+PICOBENCH(ins_and_access_s<dmap_s>).P;
PICOBENCH(ins_and_access_s<fmap_s>).P;
-PICOBENCH(ins_and_access_s<hmap_s>).P;
-PICOBENCH(ins_and_access_s<pmap_s>).P;
-PICOBENCH(ins_and_access_s<rmap_s>).P;
+PICOBENCH(ins_and_access_s<tmap_s>).P;
PICOBENCH(ins_and_access_cmap_s).P;
#undef P
@@ -293,10 +280,8 @@ static void iterate_cmap_x(picobench::state& s)
#define P samples(S1).iterations({N1/20}).args({12})
PICOBENCH(iterate_x<umap_x>).P;
-PICOBENCH(iterate_x<bmap_x>).P;
+PICOBENCH(iterate_x<dmap_x>).P;
PICOBENCH(iterate_x<fmap_x>).P;
-PICOBENCH(iterate_x<hmap_x>).P;
-PICOBENCH(iterate_x<pmap_x>).P;
-PICOBENCH(iterate_x<rmap_x>).P;
+PICOBENCH(iterate_x<tmap_x>).P;
PICOBENCH(iterate_cmap_x).P;
#undef P
diff --git a/benchmarks/picobench/picobench_csmap.cpp b/benchmarks/picobench/picobench_csmap.cpp
index ea2174fa..312b38c5 100644
--- a/benchmarks/picobench/picobench_csmap.cpp
+++ b/benchmarks/picobench/picobench_csmap.cpp
@@ -53,7 +53,7 @@ static void ctor_and_ins_one_csmap_i(picobench::state& s)
c_forrange (n, s.iterations()) {
csmap_i map = csmap_i_init();
csmap_i_insert(&map, n, 0);
- result += csmap_i_size(map);
+ result += csmap_i_size(&map);
csmap_i_drop(&map);
}
s.set_result(result);
@@ -87,7 +87,7 @@ static void insert_csmap_i(picobench::state& s)
picobench::scope scope(s);
c_forrange (n, s.iterations())
csmap_i_insert(&map, crandom() & 0xfffffff, n);
- s.set_result(csmap_i_size(map));
+ s.set_result(csmap_i_size(&map));
csmap_i_drop(&map);
}
@@ -133,7 +133,7 @@ static void ins_and_erase_csmap_i(picobench::state& s)
picobench::scope scope(s);
c_forrange (i, s.iterations())
csmap_i_insert(&map, crandom() & mask, i);
- result = csmap_i_size(map);
+ result = csmap_i_size(&map);
csmap_i_clear(&map);
csrandom(seed);
@@ -184,7 +184,7 @@ static void ins_and_access_csmap_i(picobench::state& s)
const csmap_i_value* val = csmap_i_get(&map, crandom() & mask);
if (val) csmap_i_erase(&map, val->first);
}
- s.set_result(result + csmap_i_size(map));
+ s.set_result(result + csmap_i_size(&map));
csmap_i_drop(&map);
}
@@ -245,7 +245,7 @@ static void ins_and_access_csmap_s(picobench::state& s)
csmap_str_erase(&map, cstr_str(&it.ref->first));
}*/
}
- s.set_result(result + csmap_str_size(map));
+ s.set_result(result + csmap_str_size(&map));
cstr_drop(&str);
csmap_str_drop(&map);
}
diff --git a/benchmarks/plotbench/cdeq_benchmark.cpp b/benchmarks/plotbench/cdeq_benchmark.cpp
index d938450a..72884e78 100644
--- a/benchmarks/plotbench/cdeq_benchmark.cpp
+++ b/benchmarks/plotbench/cdeq_benchmark.cpp
@@ -77,11 +77,11 @@ Sample test_stc_deque() {
c_forrange (N/3) {cdeq_x_push_back(&con, crandom() & mask1); cdeq_x_pop_front(&con);}
c_forrange (N/3) cdeq_x_push_back(&con, crandom() & mask1);
s.test[INSERT].t2 = clock();
- s.test[INSERT].sum = cdeq_x_size(con);
+ s.test[INSERT].sum = cdeq_x_size(&con);
s.test[ERASE].t1 = clock();
- c_forrange (cdeq_x_size(con)/2) { cdeq_x_pop_front(&con); cdeq_x_pop_back(&con); }
+ 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);
+ s.test[ERASE].sum = cdeq_x_size(&con);
cdeq_x_drop(&con);
}{
csrandom(seed);
diff --git a/benchmarks/plotbench/cmap_benchmark.cpp b/benchmarks/plotbench/cmap_benchmark.cpp
index 781ad720..4304db52 100644
--- a/benchmarks/plotbench/cmap_benchmark.cpp
+++ b/benchmarks/plotbench/cmap_benchmark.cpp
@@ -76,12 +76,12 @@ Sample test_stc_unordered_map() {
c_forrange (i, N/2) cmap_x_insert(&con, crandom() & mask1, i);
c_forrange (i, N/2) cmap_x_insert(&con, i, i);
s.test[INSERT].t2 = clock();
- s.test[INSERT].sum = cmap_x_size(con);
+ s.test[INSERT].sum = cmap_x_size(&con);
csrandom(seed);
s.test[ERASE].t1 = clock();
c_forrange (N) cmap_x_erase(&con, crandom() & mask1);
s.test[ERASE].t2 = clock();
- s.test[ERASE].sum = cmap_x_size(con);
+ s.test[ERASE].sum = cmap_x_size(&con);
cmap_x_drop(&con);
}{
container con = cmap_x_init();
diff --git a/benchmarks/plotbench/csmap_benchmark.cpp b/benchmarks/plotbench/csmap_benchmark.cpp
index 3fb8a0a4..b319006f 100644
--- a/benchmarks/plotbench/csmap_benchmark.cpp
+++ b/benchmarks/plotbench/csmap_benchmark.cpp
@@ -77,12 +77,12 @@ Sample test_stc_map() {
c_forrange (i, N/2) csmap_x_insert(&con, crandom() & mask1, i);
c_forrange (i, N/2) csmap_x_insert(&con, i, i);
s.test[INSERT].t2 = clock();
- s.test[INSERT].sum = csmap_x_size(con);
+ s.test[INSERT].sum = csmap_x_size(&con);
csrandom(seed);
s.test[ERASE].t1 = clock();
c_forrange (N) csmap_x_erase(&con, crandom() & mask1);
s.test[ERASE].t2 = clock();
- s.test[ERASE].sum = csmap_x_size(con);
+ s.test[ERASE].sum = csmap_x_size(&con);
csmap_x_drop(&con);
}{
container con = csmap_x_init();
diff --git a/benchmarks/plotbench/cvec_benchmark.cpp b/benchmarks/plotbench/cvec_benchmark.cpp
index 9ba95f31..44dcee2f 100644
--- a/benchmarks/plotbench/cvec_benchmark.cpp
+++ b/benchmarks/plotbench/cvec_benchmark.cpp
@@ -73,11 +73,11 @@ Sample test_stc_vector() {
csrandom(seed);
c_forrange (N) cvec_x_push_back(&con, crandom() & mask1);
s.test[INSERT].t2 = clock();
- s.test[INSERT].sum = cvec_x_size(con);
+ s.test[INSERT].sum = cvec_x_size(&con);
s.test[ERASE].t1 = clock();
c_forrange (N) { cvec_x_pop_back(&con); }
s.test[ERASE].t2 = clock();
- s.test[ERASE].sum = cvec_x_size(con);
+ s.test[ERASE].sum = cvec_x_size(&con);
cvec_x_drop(&con);
}{
csrandom(seed);
diff --git a/benchmarks/shootout_hashmaps.cpp b/benchmarks/shootout_hashmaps.cpp
index 0cf29ab7..9f5315c0 100644
--- a/benchmarks/shootout_hashmaps.cpp
+++ b/benchmarks/shootout_hashmaps.cpp
@@ -5,47 +5,47 @@
#include <stc/cstr.h>
#include "external/khash.h"
-enum {max_load_factor = 77};
+#define MAX_LOAD_FACTOR 77
#ifdef __cplusplus
#include <limits>
#include <unordered_map>
-#include "external/robin_hood.h"
-#include "external/skarupke/bytell_hash_map.hpp"
-#include "external/parallel_hashmap/phmap.h"
-#include "external/tsl/hopscotch_map.h"
+#include "external/ankerl/robin_hood.h"
+#include "external/ankerl/unordered_dense.h"
+#include "external/skarupke/flat_hash_map.hpp"
+//#include "external/skarupke/bytell_hash_map.hpp"
+//#include "external/parallel_hashmap/phmap.h"
+//#include "external/tsl/hopscotch_map.h"
#include "external/tsl/robin_map.h"
template<typename C> inline void std_destroy(C& c) { C().swap(c); }
template <class K, class V> using robin_hood_flat_map = robin_hood::unordered_flat_map<
- K, V, robin_hood::hash<K>, std::equal_to<K>, max_load_factor>;
+ K, V, robin_hood::hash<K>, std::equal_to<K>, MAX_LOAD_FACTOR>;
#endif
+// khash template expansion
KHASH_MAP_INIT_INT64(ii, int64_t)
-// cmap and khash template expansion
+// cmap template expansion
#define i_key int64_t
#define i_val int64_t
#define i_tag ii
#include <stc/cmap.h>
-stc64_t rng;
-size_t seed;
-#define SEED(s) rng = stc64_new(seed)
+#define SEED(s) rng = stc64_new(s)
#define RAND(N) (stc64_rand(&rng) & (((uint64_t)1 << N) - 1))
-
#define CMAP_SETUP(X, Key, Value) cmap_##X map = cmap_##X##_init() \
- ; cmap_##X##_max_load_factor(&map, max_load_factor/100.0f)
+ ; cmap_##X##_max_load_factor(&map, MAX_LOAD_FACTOR/100.0f)
#define CMAP_PUT(X, key, val) cmap_##X##_insert_or_assign(&map, key, val).ref->second
#define CMAP_EMPLACE(X, key, val) cmap_##X##_insert(&map, key, val).ref->second
#define CMAP_ERASE(X, key) cmap_##X##_erase(&map, key)
#define CMAP_FIND(X, key) cmap_##X##_contains(&map, key)
#define CMAP_FOR(X, i) c_foreach (i, cmap_##X, map)
#define CMAP_ITEM(X, i) i.ref->second
-#define CMAP_SIZE(X) cmap_##X##_size(map)
-#define CMAP_BUCKETS(X) cmap_##X##_bucket_count(map)
+#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##_drop(&map)
@@ -61,7 +61,7 @@ size_t seed;
#define KMAP_CLEAR(X) kh_clear(X, map)
#define KMAP_DTOR(X) kh_destroy(X, map)
-#define UMAP_SETUP(X, Key, Value) std::unordered_map<Key, Value> map; map.max_load_factor(max_load_factor/100.0f)
+#define UMAP_SETUP(X, Key, Value) std::unordered_map<Key, Value> map; map.max_load_factor(MAX_LOAD_FACTOR/100.0f)
#define UMAP_PUT(X, key, val) (map[key] = val)
#define UMAP_EMPLACE(X, key, val) map.emplace(key, val).first->second
#define UMAP_FIND(X, key) int(map.find(key) != map.end())
@@ -73,7 +73,7 @@ size_t seed;
#define UMAP_CLEAR(X) map.clear()
#define UMAP_DTOR(X) std_destroy(map)
-#define FMAP_SETUP(X, Key, Value) ska::flat_hash_map<Key, Value> map; map.max_load_factor(max_load_factor/100.0f)
+#define FMAP_SETUP(X, Key, Value) ska::flat_hash_map<Key, Value> map; map.max_load_factor(MAX_LOAD_FACTOR/100.0f)
#define FMAP_PUT(X, key, val) UMAP_PUT(X, key, val)
#define FMAP_EMPLACE(X, key, val) UMAP_EMPLACE(X, key, val)
#define FMAP_FIND(X, key) UMAP_FIND(X, key)
@@ -85,7 +85,7 @@ size_t seed;
#define FMAP_CLEAR(X) UMAP_CLEAR(X)
#define FMAP_DTOR(X) UMAP_DTOR(X)
-#define HMAP_SETUP(X, Key, Value) tsl::hopscotch_map<Key, Value> map; map.max_load_factor(max_load_factor/100.0f)
+#define HMAP_SETUP(X, Key, Value) tsl::hopscotch_map<Key, Value> map; map.max_load_factor(MAX_LOAD_FACTOR/100.0f)
#define HMAP_PUT(X, key, val) UMAP_PUT(X, key, val)
#define HMAP_EMPLACE(X, key, val) map.emplace(key, val).first.value()
#define HMAP_FIND(X, key) UMAP_FIND(X, key)
@@ -97,7 +97,7 @@ size_t seed;
#define HMAP_CLEAR(X) UMAP_CLEAR(X)
#define HMAP_DTOR(X) UMAP_DTOR(X)
-#define TMAP_SETUP(X, Key, Value) tsl::robin_map<Key, Value> map; map.max_load_factor(max_load_factor/100.0f)
+#define TMAP_SETUP(X, Key, Value) tsl::robin_map<Key, Value> map; map.max_load_factor(MAX_LOAD_FACTOR/100.0f)
#define TMAP_PUT(X, key, val) UMAP_PUT(X, key, val)
#define TMAP_EMPLACE(X, key, val) map.emplace(key, val).first.value()
#define TMAP_FIND(X, key) UMAP_FIND(X, key)
@@ -122,7 +122,19 @@ size_t seed;
#define RMAP_CLEAR(X) UMAP_CLEAR(X)
#define RMAP_DTOR(X) UMAP_DTOR(X)
-#define PMAP_SETUP(X, Key, Value) phmap::flat_hash_map<Key, Value> map; map.max_load_factor(max_load_factor/100.0f)
+#define DMAP_SETUP(X, Key, Value) ankerl::unordered_dense::map<Key, Value> map; map.max_load_factor(MAX_LOAD_FACTOR/100.0f)
+#define DMAP_PUT(X, key, val) UMAP_PUT(X, key, val)
+#define DMAP_EMPLACE(X, key, val) UMAP_EMPLACE(X, key, val)
+#define DMAP_FIND(X, key) UMAP_FIND(X, key)
+#define DMAP_ERASE(X, key) UMAP_ERASE(X, key)
+#define DMAP_FOR(X, i) UMAP_FOR(X, i)
+#define DMAP_ITEM(X, i) UMAP_ITEM(X, i)
+#define DMAP_SIZE(X) UMAP_SIZE(X)
+#define DMAP_BUCKETS(X) UMAP_BUCKETS(X)
+#define DMAP_CLEAR(X) UMAP_CLEAR(X)
+#define DMAP_DTOR(X) UMAP_DTOR(X)
+
+#define PMAP_SETUP(X, Key, Value) phmap::flat_hash_map<Key, Value> map; map.max_load_factor(MAX_LOAD_FACTOR/100.0f)
#define PMAP_PUT(X, key, val) UMAP_PUT(X, key, val)
#define PMAP_EMPLACE(X, key, val) UMAP_EMPLACE(X, key, val)
#define PMAP_FIND(X, key) UMAP_FIND(X, key)
@@ -191,7 +203,7 @@ size_t seed;
SEED(seed); \
for (size_t i = 0; i < m; ++i) \
M##_PUT(X, RAND(keybits), i); \
- size_t x = 200000000/M##_SIZE(X); \
+ size_t x = 100000000/M##_SIZE(X); \
clock_t difference, before = clock(); \
for (size_t k=0; k < x; k++) M##_FOR (X, it) \
sum += M##_ITEM(X, it); \
@@ -211,7 +223,7 @@ size_t seed;
for (size_t i = 0; i < m; ++i) \
M##_PUT(X, RAND(keybits), i); \
before = clock(); \
- size_t x = m * 10000000/M##_SIZE(X); \
+ size_t x = m * 8000000/M##_SIZE(X); \
for (size_t i = 0; i < x; ++i) \
found += M##_FIND(X, RAND(keybits)); \
SEED(seed); \
@@ -226,16 +238,16 @@ size_t seed;
#ifdef __cplusplus
#define RUN_TEST(n) MAP_TEST##n(KMAP, ii, N##n) MAP_TEST##n(CMAP, ii, N##n) \
- MAP_TEST##n(PMAP, ii, N##n) MAP_TEST##n(FMAP, ii, N##n) \
- MAP_TEST##n(RMAP, ii, N##n) MAP_TEST##n(HMAP, ii, N##n) \
- MAP_TEST##n(TMAP, ii, N##n) MAP_TEST##n(UMAP, ii, N##n)
+ MAP_TEST##n(FMAP, ii, N##n) MAP_TEST##n(TMAP, ii, N##n) \
+ MAP_TEST##n(RMAP, ii, N##n) MAP_TEST##n(DMAP, ii, N##n) \
+ MAP_TEST##n(UMAP, ii, N##n)
#else
#define RUN_TEST(n) MAP_TEST##n(KMAP, ii, N##n) MAP_TEST##n(CMAP, ii, N##n)
#endif
enum {
- DEFAULT_N_MILL = 40,
- DEFAULT_KEYBITS = 25,
+ DEFAULT_N_MILL = 10,
+ DEFAULT_KEYBITS = 22,
};
int main(int argc, char* argv[])
@@ -244,16 +256,18 @@ int main(int argc, char* argv[])
unsigned keybits = argc >= 3 ? atoi(argv[2]) : DEFAULT_KEYBITS;
unsigned n = n_mill * 1000000;
unsigned N0 = n, N1 = n/2, N2 = n/2, N3 = n, N4 = n, N5 = n;
- seed = time(NULL); // 1636306010;
+ stc64_t rng;
+ size_t seed = time(NULL);
printf("\nUnordered hash map shootout\n");
- printf("CMAP = https://github.com/tylov/STC\n"
- "KMAP = https://github.com/attractivechaos/klib\n"
- "PMAP = https://github.com/greg7mdp/parallel-hashmap\n"
+ printf("KMAP = https://github.com/attractivechaos/klib\n"
+ "CMAP = https://github.com/tylov/STC (**)\n"
+ //"PMAP = https://github.com/greg7mdp/parallel-hashmap\n"
"FMAP = https://github.com/skarupke/flat_hash_map\n"
- "RMAP = https://github.com/martinus/robin-hood-hashing\n"
- "HMAP = https://github.com/Tessil/hopscotch-map\n"
"TMAP = https://github.com/Tessil/robin-map\n"
+ //"HMAP = https://github.com/Tessil/hopscotch-map\n"
+ "RMAP = https://github.com/martinus/robin-hood-hashing\n"
+ "DMAP = https://github.com/martinus/unordered_dense\n"
"UMAP = std::unordered_map\n\n");
printf("Usage %s [n-million=%d key-bits=%d]\n", argv[0], DEFAULT_N_MILL, DEFAULT_KEYBITS);
diff --git a/docs/carc_api.md b/docs/carc_api.md
index bdab2533..534e3da3 100644
--- a/docs/carc_api.md
+++ b/docs/carc_api.md
@@ -39,7 +39,7 @@ carc_X carc_X_from_ptr(i_val* p); // create a carc
carc_X carc_X_clone(carc_X other); // return other with increased use count
carc_X carc_X_move(carc_X* self); // transfer ownership to another carc.
void carc_X_take(carc_X* self, carc_X other); // take ownership of other.
-void carc_X_copy(carc_X* self, carc_X other); // copy shared (increase use count)
+void carc_X_assign(carc_X* self, carc_X other); // copy shared (increase use count)
void carc_X_drop(carc_X* self); // destruct (decrease use count, free at 0)
long carc_X_use_count(carc_X ptr);
diff --git a/docs/carray_api.md b/docs/carray_api.md
index fba152c6..579bf119 100644
--- a/docs/carray_api.md
+++ b/docs/carray_api.md
@@ -26,11 +26,11 @@ carr2_X carr2_X_with_size(size_t xdim, size_t ydim, i_val val);
carr2_X carr2_X_with_data(size_t xdim, size_t ydim, i_val* array);
carr2_X carr2_X_new_uninit(size_t xdim, size_t ydim);
carr2_X carr2_X_clone(carr2_X arr);
-void carr2_X_copy(carr2_X* self, carr2_X other);
+void carr2_X_copy(carr2_X* self, const carr2_X* other);
i_val* carr2_X_release(carr2_X* self); // release storage (not freed)
void carr2_X_drop(carr2_X* self);
-size_t carr2_X_size(carr2_X arr);
+size_t carr2_X_size(const carr2_X* self);
i_val* carr2_X_data(carr2_X* self); // access storage data
const i_val* carr2_X_at(const carr2_X* self, size_t x, size_t y);
size_t carr2_X_idx(const carr2_X* self, size_t x, size_t y);
@@ -47,11 +47,11 @@ carr3_X carr3_X_with_size(size_t xdim, size_t ydim, size_t zdim, i_v
carr3_X carr3_X_with_data(size_t xdim, size_t ydim, size_t zdim, i_val* array);
carr3_X carr3_X_new_uninit(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);
+void carr3_X_copy(carr3_X* self, const carr3_X* other);
i_val* carr3_X_release(carr3_X* self); // release storage (not freed)
void carr3_X_drop(carr3_X* self);
-size_t carr3_X_size(carr3_X arr);
+size_t carr3_X_size(const carr3_X* self);
i_val* carr3_X_data(carr3_X* self); // storage data
const i_val* carr3_X_at(const carr3_X* self, size_t x, size_t y, size_t z);
size_t carr3_X_idx(const carr3_X* self, size_t x, size_t y, size_t z);
diff --git a/docs/cbox_api.md b/docs/cbox_api.md
index 8709548a..4087ffa3 100644
--- a/docs/cbox_api.md
+++ b/docs/cbox_api.md
@@ -38,7 +38,7 @@ cbox_X cbox_X_from_ptr(i_val* p); // create a cbox f
cbox_X cbox_X_clone(cbox_X other); // return deep copied clone
cbox_X cbox_X_move(cbox_X* self); // transfer ownership to another cbox.
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_assign(cbox_X* self, cbox_X other); // deep copy to self
void cbox_X_drop(cbox_X* self); // destruct the contained object and free's it.
void cbox_X_reset(cbox_X* self);
diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md
index a1f1228f..1840468c 100644
--- a/docs/cdeq_api.md
+++ b/docs/cdeq_api.md
@@ -28,15 +28,15 @@ cdeq_X cdeq_X_with_capacity(size_t size);
cdeq_X cdeq_X_clone(cdeq_X deq);
void cdeq_X_clear(cdeq_X* self);
-void cdeq_X_copy(cdeq_X* self, cdeq_X other);
+void cdeq_X_copy(cdeq_X* self, const 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_drop(cdeq_X* self); // destructor
-bool cdeq_X_empty(cdeq_X deq);
-size_t cdeq_X_size(cdeq_X deq);
-size_t cdeq_X_capacity(cdeq_X deq);
+bool cdeq_X_empty(const cdeq_X* self);
+size_t cdeq_X_size(const cdeq_X* self);
+size_t cdeq_X_capacity(const cdeq_X* self);
const cdeq_X_value* cdeq_X_at(const cdeq_X* self, size_t idx);
const cdeq_X_value* cdeq_X_get(const cdeq_X* self, i_valraw raw); // return NULL if not found
diff --git a/docs/clist_api.md b/docs/clist_api.md
index 58970a19..9cd950bb 100644
--- a/docs/clist_api.md
+++ b/docs/clist_api.md
@@ -42,7 +42,7 @@ clist_X clist_X_init(void);
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_copy(clist_X* self, const clist_X* other);
void clist_X_drop(clist_X* self); // destructor
bool clist_X_empty(clist_X list);
diff --git a/docs/cmap_api.md b/docs/cmap_api.md
index 58d33534..5804112f 100644
--- a/docs/cmap_api.md
+++ b/docs/cmap_api.md
@@ -48,17 +48,17 @@ cmap_X cmap_X_with_capacity(size_t cap);
cmap_X cmap_X_clone(cmap_x map);
void cmap_X_clear(cmap_X* self);
-void cmap_X_copy(cmap_X* self, cmap_X other);
+void cmap_X_copy(cmap_X* self, const cmap_X* other);
void cmap_X_max_load_factor(cmap_X* self, float max_load); // default: 0.85
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_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
-bool cmap_X_empty(cmap_X map);
-size_t cmap_X_bucket_count(cmap_X map); // num. of allocated buckets
+size_t cmap_X_size(const cmap_X* self);
+size_t cmap_X_capacity(const cmap_X self); // buckets * max_load_factor
+bool cmap_X_empty(const cmap_X* self );
+size_t cmap_X_bucket_count(const cmap_X* self); // num. of allocated buckets
const cmap_X_mapped* cmap_X_at(const cmap_X* self, i_keyraw rkey); // rkey must be in map
cmap_X_mapped* cmap_X_at_mut(cmap_X* self, i_keyraw rkey); // mutable at
diff --git a/docs/cpque_api.md b/docs/cpque_api.md
index d9a381cc..12f5c3bc 100644
--- a/docs/cpque_api.md
+++ b/docs/cpque_api.md
@@ -32,11 +32,11 @@ cpque_X cpque_X_clone(cpque_X pq);
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_copy(cpque_X* self, const cpque_X* other);
void cpque_X_drop(cpque_X* self); // destructor
-size_t cpque_X_size(cpque_X pq);
-bool cpque_X_empty(cpque_X pq);
+size_t cpque_X_size(const cpque_X* self);
+bool cpque_X_empty(const cpque_X* self);
i_val* cpque_X_top(const cpque_X* self);
void cpque_X_make_heap(cpque_X* self); // heapify the vector.
diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md
index ffb75216..1f5469d6 100644
--- a/docs/cqueue_api.md
+++ b/docs/cqueue_api.md
@@ -27,7 +27,7 @@ cqueue_X cqueue_X_init(void);
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_copy(cqueue_X* self, const cqueue_X* other);
void cqueue_X_drop(cqueue_X* self); // destructor
size_t cqueue_X_size(cqueue_X q);
diff --git a/docs/cset_api.md b/docs/cset_api.md
index b325eaca..95a236b1 100644
--- a/docs/cset_api.md
+++ b/docs/cset_api.md
@@ -28,17 +28,17 @@ cset_X cset_X_with_capacity(size_t cap);
cset_X cset_X_clone(cset_x set);
void cset_X_clear(cset_X* self);
-void cset_X_copy(cset_X* self, cset_X other);
+void cset_X_copy(cset_X* self, const cset_X* other);
void cset_X_max_load_factor(cset_X* self, float max_load); // default: 0.85
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_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
-bool cset_X_empty(cset_X set);
-size_t cset_X_bucket_count(cset_X set);
+size_t cset_X_size(const cset_X* self); // num. of allocated buckets
+size_t cset_X_capacity(const cset_X* self); // buckets * max_load_factor
+bool cset_X_empty(const cset_X* self);
+size_t cset_X_bucket_count(const cset_X* self);
bool cset_X_contains(const cset_X* self, i_keyraw rkey);
const cset_X_value* cset_X_get(const cset_X* self, i_keyraw rkey); // return NULL if not found
diff --git a/docs/csmap_api.md b/docs/csmap_api.md
index a797e3cd..b3cf668b 100644
--- a/docs/csmap_api.md
+++ b/docs/csmap_api.md
@@ -47,12 +47,13 @@ void csmap_X_shrink_to_fit(csmap_X* self);
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_copy(csmap_X* self, const csmap_X* other);
void csmap_X_swap(csmap_X* a, csmap_X* b);
void csmap_X_drop(csmap_X* self); // destructor
-size_t csmap_X_size(csmap_X map);
-bool csmap_X_empty(csmap_X map);
+size_t csmap_X_size(const csmap_X self);
+bool csmap_X_empty(const csmap_X* self);
+bool csmap_X_capacity(const csmap_X* self);
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_mut(csmap_X* self, i_keyraw rkey); // mutable at
diff --git a/docs/csset_api.md b/docs/csset_api.md
index 5106a791..66ce8505 100644
--- a/docs/csset_api.md
+++ b/docs/csset_api.md
@@ -30,7 +30,7 @@ void csset_X_shrink_to_fit(csset_X* self);
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_copy(csset_X* self, const csset_X* other);
void csset_X_swap(csset_X* a, csset_X* b);
void csset_X_drop(csset_X* self); // destructor
diff --git a/docs/cstack_api.md b/docs/cstack_api.md
index a72153e1..f148df38 100644
--- a/docs/cstack_api.md
+++ b/docs/cstack_api.md
@@ -32,12 +32,12 @@ 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);
i_val* cstack_X_append_uninit(cstack_X* self, size_t n);
-void cstack_X_copy(cstack_X* self, cstack_X other);
+void cstack_X_copy(cstack_X* self, const cstack_X* other);
void cstack_X_drop(cstack_X* self); // destructor
-size_t cstack_X_size(cstack_X st);
-size_t cstack_X_capacity(cstack_X st);
-bool cstack_X_empty(cstack_X st);
+size_t cstack_X_size(const cstack_X* self);
+size_t cstack_X_capacity(const cstack_X* self);
+bool cstack_X_empty(const cstack_X* self);
i_val* cstack_X_top(const cstack_X* self);
const i_val* cstack_X_at(const cstack_X* self, size_t idx);
diff --git a/docs/cstr_api.md b/docs/cstr_api.md
index 071da20a..7afdcf77 100644
--- a/docs/cstr_api.md
+++ b/docs/cstr_api.md
@@ -49,7 +49,6 @@ void cstr_clear(cstr* self);
char* cstr_assign(cstr* self, const char* str);
char* cstr_assign_s(cstr* self, cstr s);
char* cstr_assign_n(cstr* self, const char* str, size_t len); // assign n first chars of str
-void cstr_copy(cstr* self, cstr s); // like cstr_assign_s()
int cstr_printf(cstr* self, const char* fmt, ...); // printf() formatting
char* cstr_append(cstr* self, const char* app);
diff --git a/docs/cvec_api.md b/docs/cvec_api.md
index e504954c..db2bd8ce 100644
--- a/docs/cvec_api.md
+++ b/docs/cvec_api.md
@@ -33,7 +33,7 @@ cvec_X cvec_X_with_capacity(size_t size);
cvec_X cvec_X_clone(cvec_X vec);
void cvec_X_clear(cvec_X* self);
-void cvec_X_copy(cvec_X* self, cvec_X other);
+void cvec_X_copy(cvec_X* self, const cvec_X* other);
bool cvec_X_reserve(cvec_X* self, size_t cap);
bool cvec_X_resize(cvec_X* self, size_t size, i_val null);
cvec_X_value* cvec_X_append_uninit(cvec_X* self, size_t n); // return start of uninit
@@ -41,9 +41,9 @@ void cvec_X_shrink_to_fit(cvec_X* self);
void cvec_X_swap(cvec_X* a, cvec_X* b);
void cvec_X_drop(cvec_X* self); // destructor
-bool cvec_X_empty(cvec_X vec);
-size_t cvec_X_size(cvec_X vec);
-size_t cvec_X_capacity(cvec_X vec);
+bool cvec_X_empty(const cvec_X* self);
+size_t cvec_X_size(const cvec_X* self);
+size_t cvec_X_capacity(const cvec_X* self);
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
diff --git a/examples/astar.c b/examples/astar.c
index 4b86df9e..7d90bf35 100644
--- a/examples/astar.c
+++ b/examples/astar.c
@@ -88,7 +88,7 @@ astar(cstr* maze, int width)
point goal = point_from(maze, "!", width);
csmap_pcost_insert(&costs, start, 0);
cpque_point_push(&front, start);
- while (!cpque_point_empty(front))
+ while (!cpque_point_empty(&front))
{
point current = *cpque_point_top(&front);
cpque_point_pop(&front);
diff --git a/examples/bits2.c b/examples/bits2.c
index bb3324e3..73c18351 100644
--- a/examples/bits2.c
+++ b/examples/bits2.c
@@ -2,7 +2,7 @@
// Example of static sized (stack allocated) bitsets
#define i_type Bits
-#define i_len 80 // enable fixed bitset on the stack
+#define i_cap 80 // enable fixed bitset on the stack
#include <stc/cbits.h>
int main()
diff --git a/examples/books.c b/examples/books.c
index b2015208..fb9e4564 100644
--- a/examples/books.c
+++ b/examples/books.c
@@ -33,7 +33,7 @@ int main()
// queried using references (&str).
if (cmap_str_contains(&book_reviews, "Les Misérables")) {
printf("We've got %" PRIuMAX " reviews, but Les Misérables ain't one.",
- cmap_str_size(book_reviews));
+ cmap_str_size(&book_reviews));
}
// oops, this review has a lot of spelling mistakes, let's delete it.
diff --git a/examples/complex.c b/examples/complex.c
index 79a34a6a..c15d3bc7 100644
--- a/examples/complex.c
+++ b/examples/complex.c
@@ -42,7 +42,7 @@ int main() {
// Put in some data in stack array
stack.data[x] = 3.1415927f;
- printf("stack size: %" PRIuMAX "\n", FloatStack_size(stack));
+ printf("stack size: %" PRIuMAX "\n", FloatStack_size(&stack));
StackList list = StackList_init();
StackList_push_back(&list, stack);
diff --git a/examples/convert.c b/examples/convert.c
index c1380c94..56cd1eca 100644
--- a/examples/convert.c
+++ b/examples/convert.c
@@ -36,7 +36,7 @@ int main()
cvec_str_emplace_back(&keys, cstr_str(&i.ref->first));
cvec_str_emplace_back(&values, cstr_str(&i.ref->second));
}
- c_forrange (i, cvec_str_size(keys))
+ c_forrange (i, cvec_str_size(&keys))
printf(" %s: %s\n", cstr_str(keys.data + i), cstr_str(values.data + i));
puts("\nCOPY VEC TO LIST:");
diff --git a/examples/cpque.c b/examples/cpque.c
index 2c08f796..00d2697e 100644
--- a/examples/cpque.c
+++ b/examples/cpque.c
@@ -13,7 +13,7 @@ static bool (*less_fn)(const int* x, const int* y);
void print_queue(ipque q) {
ipque copy = ipque_clone(q);
- while (!ipque_empty(copy)) {
+ while (!ipque_empty(&copy)) {
printf("%d ", *ipque_top(&copy));
ipque_pop(&copy);
}
diff --git a/examples/csmap_erase.c b/examples/csmap_erase.c
index 09d28d78..37d25f37 100644
--- a/examples/csmap_erase.c
+++ b/examples/csmap_erase.c
@@ -12,7 +12,7 @@ void printmap(mymap m)
{
c_foreach (elem, mymap, m)
printf(" [%d, %s]", elem.ref->first, cstr_str(&elem.ref->second));
- printf("\nsize() == %" PRIuMAX "\n\n", mymap_size(m));
+ printf("\nsize() == %" PRIuMAX "\n\n", mymap_size(&m));
}
int main()
diff --git a/examples/csmap_find.c b/examples/csmap_find.c
index c3047110..f74f7fb9 100644
--- a/examples/csmap_find.c
+++ b/examples/csmap_find.c
@@ -17,10 +17,10 @@ void print_elem(csmap_istr_raw p) {
}
#define using_print_collection(CX) \
- void print_collection_##CX(CX t) { \
+ void print_collection_##CX(const CX* t) { \
printf("%" PRIuMAX " elements: ", CX##_size(t)); \
\
- c_foreach (p, CX, t) { \
+ c_foreach (p, CX, *t) { \
print_elem(CX##_value_toraw(p.ref)); \
} \
puts(""); \
@@ -48,7 +48,7 @@ int main()
c_apply(v, csmap_istr_emplace(&m1, c_pair(v)), csmap_istr_raw,
{{40, "Zr"}, {45, "Rh"}});
puts("The starting map m1 is (key, value):");
- print_collection_csmap_istr(m1);
+ print_collection_csmap_istr(&m1);
typedef cvec_istr_value pair;
cvec_istr_push_back(&v, (pair){43, "Tc"});
@@ -59,13 +59,13 @@ int main()
cvec_istr_push_back(&v, (pair){44, "Ru"}); // attempt a duplicate
puts("Inserting the following vector data into m1:");
- print_collection_cvec_istr(v);
+ print_collection_cvec_istr(&v);
c_foreach (i, cvec_istr, cvec_istr_begin(&v), cvec_istr_end(&v))
csmap_istr_emplace(&m1, c_pair(i.ref));
puts("The modified map m1 is (key, value):");
- print_collection_csmap_istr(m1);
+ print_collection_csmap_istr(&m1);
puts("");
findit(m1, 45);
findit(m1, 6);
diff --git a/examples/demos.c b/examples/demos.c
index 7c5b9a4b..4cb50082 100644
--- a/examples/demos.c
+++ b/examples/demos.c
@@ -47,7 +47,7 @@ void vectordemo1()
cvec_ix_pop_back(&bignums); // erase the last
cvec_ix_erase_n(&bignums, 0, 1); // erase the first
- for (size_t i = 0; i < cvec_ix_size(bignums); ++i) {
+ for (size_t i = 0; i < cvec_ix_size(&bignums); ++i) {
printf("%" PRIuMAX ": %" PRIuMAX "\n", i, bignums.data[i]);
}
}
@@ -175,11 +175,11 @@ void mapdemo3()
cmap_str_iter it = cmap_str_find(&table, "Make");
c_foreach (i, cmap_str, table)
printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
- printf("size %" PRIuMAX ": remove: Make: %s\n", cmap_str_size(table), cstr_str(&it.ref->second));
+ printf("size %" PRIuMAX ": remove: Make: %s\n", cmap_str_size(&table), cstr_str(&it.ref->second));
//cmap_str_erase(&table, "Make");
cmap_str_erase_at(&table, it);
- printf("size %" PRIuMAX "\n", cmap_str_size(table));
+ printf("size %" PRIuMAX "\n", cmap_str_size(&table));
c_foreach (i, cmap_str, table)
printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
cmap_str_drop(&table); // frees key and value cstrs, and hash table.
@@ -200,7 +200,7 @@ void arraydemo1()
float *arr1 = arr3.data[5][4];
printf("arr3: %" PRIuMAX ": (%" PRIuMAX ", %" PRIuMAX ", %" PRIuMAX ") = %" PRIuMAX "\n", sizeof(arr3),
- arr3.xdim, arr3.ydim, arr3.zdim, carr3_f_size(arr3));
+ arr3.xdim, arr3.ydim, arr3.zdim, carr3_f_size(&arr3));
printf("%g\n", arr1[3]); // = 10.2
printf("%g\n", arr2[4][3]); // = 10.2
diff --git a/examples/inits.c b/examples/inits.c
index dc67075c..608dd146 100644
--- a/examples/inits.c
+++ b/examples/inits.c
@@ -44,7 +44,7 @@ int main(void)
c_apply_array(v, cpque_f_push(&floats, *v), const float, nums, c_arraylen(nums));
puts("\npop and show high priorites first:");
- while (! cpque_f_empty(floats)) {
+ while (! cpque_f_empty(&floats)) {
printf("%.1f ", *cpque_f_top(&floats));
cpque_f_pop(&floats);
}
diff --git a/examples/new_arr.c b/examples/new_arr.c
index 8ccc62fa..17a96062 100644
--- a/examples/new_arr.c
+++ b/examples/new_arr.c
@@ -17,7 +17,7 @@ int main()
carr2_int_drop(&volume))
{
int *dat = carr2_int_data(&volume);
- for (size_t i = 0; i < carr2_int_size(volume); ++i)
+ for (size_t i = 0; i < carr2_int_size(&volume); ++i)
dat[i] = i;
for (size_t x = 0; x < volume.xdim; ++x)
@@ -34,7 +34,7 @@ int main()
carr3_int_drop(&volume))
{
int *dat = carr3_int_data(&volume);
- for (size_t i = 0; i < carr3_int_size(volume); ++i)
+ for (size_t i = 0; i < carr3_int_size(&volume); ++i)
dat[i] = i;
for (size_t x = 0; x < volume.xdim; ++x)
diff --git a/examples/new_pque.c b/examples/new_pque.c
index 2e5cf9ca..1f968f4c 100644
--- a/examples/new_pque.c
+++ b/examples/new_pque.c
@@ -46,7 +46,7 @@ int main()
cpque_pnt_push(&pque, (Point){54, 74});
cpque_pnt_push(&pque, (Point){12, 62});
// print
- while (!cpque_pnt_empty(pque)) {
+ while (!cpque_pnt_empty(&pque)) {
cpque_pnt_value *v = cpque_pnt_top(&pque);
printf(" (%d,%d)", v->x, v->y);
cpque_pnt_pop(&pque);
@@ -58,7 +58,7 @@ int main()
cpque_int_push(&ique, 123);
cpque_int_push(&ique, 321);
// print
- for (size_t i=0; i<cpque_int_size(ique); ++i)
+ for (size_t i=0; i<cpque_int_size(&ique); ++i)
printf(" %d", ique.data[i]);
puts("");
}
diff --git a/examples/new_queue.c b/examples/new_queue.c
index f3051871..ea68c9b9 100644
--- a/examples/new_queue.c
+++ b/examples/new_queue.c
@@ -31,7 +31,7 @@ int main() {
cqueue_int_push(&Q, stc64_uniform(&rng, &dist));
// Push or pop on the queue ten million times
- printf("befor: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(Q), cqueue_int_capacity(Q));
+ printf("befor: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(&Q), cqueue_int_capacity(&Q));
for (int i=n; i>0; --i) {
int r = stc64_uniform(&rng, &dist);
if (r & 1)
@@ -39,6 +39,6 @@ int main() {
else
cqueue_int_pop(&Q);
}
- printf("after: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(Q), cqueue_int_capacity(Q));
+ printf("after: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(&Q), cqueue_int_capacity(&Q));
}
}
diff --git a/examples/queue.c b/examples/queue.c
index cfc8d988..cc6f8302 100644
--- a/examples/queue.c
+++ b/examples/queue.c
@@ -26,6 +26,6 @@ int main() {
else
--n, cqueue_i_pop(&queue);
}
- printf("%d, %" PRIuMAX "\n", n, cqueue_i_size(queue));
+ printf("%d, %" PRIuMAX "\n", n, cqueue_i_size(&queue));
}
}
diff --git a/examples/stack.c b/examples/stack.c
index ca809c97..1991e269 100644
--- a/examples/stack.c
+++ b/examples/stack.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#define i_tag i
+#define i_cap 100
#define i_val int
#include <stc/cstack.h>
diff --git a/include/stc/alt/csmap.h b/include/stc/alt/csmap.h
index 168cf480..60a1b72a 100644
--- a/include/stc/alt/csmap.h
+++ b/include/stc/alt/csmap.h
@@ -155,11 +155,11 @@ _cx_memb(_value_clone)(_cx_value _val) {
}
STC_INLINE void
-_cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->root == other.root)
+_cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->root == other->root)
return;
_cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(other);
+ *self = _cx_memb(_clone)(*other);
}
#endif // !_i_no_clone
diff --git a/include/stc/carc.h b/include/stc/carc.h
index 73ccc5bf..57f00899 100644
--- a/include/stc/carc.h
+++ b/include/stc/carc.h
@@ -155,7 +155,7 @@ STC_INLINE _cx_self _cx_memb(_clone)(_cx_self ptr) {
return ptr;
}
-STC_INLINE void _cx_memb(_copy)(_cx_self* self, _cx_self ptr) {
+STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self ptr) {
if (ptr.use_count)
_i_atomic_inc(ptr.use_count);
_cx_memb(_drop)(self);
diff --git a/include/stc/carr2.h b/include/stc/carr2.h
index dc35893a..66a98f58 100644
--- a/include/stc/carr2.h
+++ b/include/stc/carr2.h
@@ -38,7 +38,7 @@ int main() {
c_autovar (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image))
{
int *dat = carr2_int_data(&image);
- for (int i = 0; i < carr2_int_size(image); ++i)
+ for (int i = 0; i < carr2_int_size(&image); ++i)
dat[i] = i;
for (int x = 0; x < image.xdim; ++x)
@@ -67,14 +67,14 @@ STC_API _cx_value* _cx_memb(_release)(_cx_self* self);
STC_API void _cx_memb(_drop)(_cx_self* self);
#if !defined _i_no_clone
STC_API _cx_self _cx_memb(_clone)(_cx_self src);
-STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other);
+STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other);
#endif
STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim) {
return _cx_memb(_with_data)(xdim, ydim, c_alloc_n(_cx_value, xdim*ydim));
}
-STC_INLINE size_t _cx_memb(_size)(_cx_self arr)
- { return arr.xdim*arr.ydim; }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* self)
+ { return self->xdim*self->ydim; }
STC_INLINE _cx_value *_cx_memb(_data)(_cx_self* self)
{ return *self->data; }
@@ -118,14 +118,14 @@ STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null) {
STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) {
_cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim);
- for (_cx_value* p = _arr.data[0], *q = src.data[0], *e = p + _cx_memb(_size)(src); p != e; ++p, ++q)
+ for (_cx_value* p = _arr.data[0], *q = src.data[0], *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q)
*p = i_keyclone((*q));
return _arr;
}
-STC_DEF void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->data == other.data) return;
- _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
+STC_DEF void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->data == other->data) return;
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(*other);
}
#endif
@@ -138,7 +138,7 @@ STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) {
STC_DEF void _cx_memb(_drop)(_cx_self* self) {
if (!self->data) return;
- for (_cx_value* p = self->data[0], *q = p + _cx_memb(_size)(*self); p != q; ) {
+ for (_cx_value* p = self->data[0], *q = p + _cx_memb(_size)(self); p != q; ) {
--q; i_keydrop(q);
}
c_free(self->data[0]); /* values */
diff --git a/include/stc/carr3.h b/include/stc/carr3.h
index bbd3a065..8ff1670e 100644
--- a/include/stc/carr3.h
+++ b/include/stc/carr3.h
@@ -38,7 +38,7 @@ int main() {
c_autovar (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image))
{
int *dat = carr3_int_data(&image);
- for (int i = 0; i < carr3_int_size(image); ++i)
+ for (int i = 0; i < carr3_int_size(&image); ++i)
dat[i] = i;
for (int x = 0; x < image.xdim; ++x)
@@ -69,15 +69,15 @@ STC_API _cx_value* _cx_memb(_release)(_cx_self* self);
STC_API void _cx_memb(_drop)(_cx_self* self);
#if !defined _i_no_clone
STC_API _cx_self _cx_memb(_clone)(_cx_self src);
-STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other);
+STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other);
#endif
STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim, size_t zdim) {
return _cx_memb(_with_data)(xdim, ydim, zdim, c_alloc_n(_cx_value, xdim*ydim*zdim));
}
-STC_INLINE size_t _cx_memb(_size)(_cx_self arr)
- { return arr.xdim*arr.ydim*arr.zdim; }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* self)
+ { return self->xdim*self->ydim*self->zdim; }
STC_INLINE _cx_value* _cx_memb(_data)(_cx_self* self)
{ return **self->data; }
@@ -95,7 +95,7 @@ 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)
- { return c_make(_cx_iter){**self->data + _cx_memb(_size)(*self)}; }
+ { return c_make(_cx_iter){**self->data + _cx_memb(_size)(self)}; }
STC_INLINE void _cx_memb(_next)(_cx_iter* it)
{ ++it->ref; }
@@ -123,14 +123,14 @@ STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_k
STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) {
_cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim, src.zdim);
- for (_cx_value* p = **_arr.data, *q = **src.data, *e = p + _cx_memb(_size)(src); p != e; ++p, ++q)
+ for (_cx_value* p = **_arr.data, *q = **src.data, *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q)
*p = i_keyclone((*q));
return _arr;
}
-STC_DEF void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->data == other.data) return;
- _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
+STC_DEF void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->data == other->data) return;
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(*other);
}
#endif
@@ -143,7 +143,7 @@ STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) {
STC_DEF void _cx_memb(_drop)(_cx_self* self) {
if (!self->data) return;
- for (_cx_value* p = **self->data, *q = p + _cx_memb(_size)(*self); p != q; ) {
+ for (_cx_value* p = **self->data, *q = p + _cx_memb(_size)(self); p != q; ) {
--q; i_keydrop(q);
}
c_free(self->data[0][0]); /* data */
diff --git a/include/stc/cbits.h b/include/stc/cbits.h
index f7ce2368..dccd5fb3 100644
--- a/include/stc/cbits.h
+++ b/include/stc/cbits.h
@@ -82,7 +82,7 @@ STC_API char* _cbits_to_str(const uint64_t* set, const size_t sz,
#define _i_memb(name) c_paste(i_type, name)
-#if !defined i_len
+#if !defined i_cap
#define _i_assert(x) assert(x)
#define i_type cbits
@@ -90,6 +90,7 @@ STC_API char* _cbits_to_str(const uint64_t* set, const size_t sz,
struct { uint64_t *data64; size_t _size; } typedef i_type;
STC_INLINE cbits cbits_init(void) { return c_make(cbits){NULL}; }
+STC_INLINE void cbits_inits(cbits* self) { self->data64 = NULL; self->_size = 0; }
STC_INLINE void cbits_drop(cbits* self) { c_free(self->data64); }
STC_INLINE size_t cbits_size(const cbits* self) { return self->_size; }
STC_API void cbits_resize(cbits* self, size_t size, bool value);
@@ -131,18 +132,19 @@ STC_INLINE cbits cbits_with_pattern(const size_t size, const uint64_t pattern) {
return set;
}
-#else // i_len
+#else // i_cap
#define _i_assert(x) (void)0
#if !defined i_type
- #define i_type c_paste(cbits, i_len)
+ #define i_type c_paste(cbits, i_cap)
#endif
-struct { uint64_t data64[(i_len - 1)/64 + 1]; } typedef i_type;
+struct { uint64_t data64[(i_cap - 1)/64 + 1]; } typedef i_type;
STC_INLINE i_type _i_memb(_init)(void) { return c_make(i_type){0}; }
+STC_INLINE void _i_memb(_inits)(i_type* self) {}
STC_INLINE void _i_memb(_drop)(i_type* self) {}
-STC_INLINE size_t _i_memb(_size)(const i_type* self) { return i_len; }
+STC_INLINE size_t _i_memb(_size)(const i_type* self) { return i_cap; }
STC_INLINE i_type _i_memb(_move)(i_type* self) { return *self; }
STC_INLINE i_type* _i_memb(_take)(i_type* self, i_type other)
@@ -151,24 +153,24 @@ STC_INLINE i_type* _i_memb(_take)(i_type* self, i_type other)
STC_INLINE i_type _i_memb(_clone)(i_type other)
{ return other; }
-STC_INLINE i_type* _i_memb(_copy)(i_type* self, i_type other)
- { *self = other; return self; }
+STC_INLINE i_type* _i_memb(_copy)(i_type* self, const i_type* other)
+ { *self = *other; return self; }
STC_INLINE void _i_memb(_set_all)(i_type *self, const bool value);
STC_INLINE void _i_memb(_set_pattern)(i_type *self, const uint64_t pattern);
STC_INLINE i_type _i_memb(_with_size)(const size_t size, const bool value) {
- assert(size <= i_len);
+ assert(size <= i_cap);
i_type set; _i_memb(_set_all)(&set, value);
return set;
}
STC_INLINE i_type _i_memb(_with_pattern)(const size_t size, const uint64_t pattern) {
- assert(size <= i_len);
+ assert(size <= i_cap);
i_type set; _i_memb(_set_pattern)(&set, pattern);
return set;
}
-#endif // i_len
+#endif // i_cap
STC_INLINE void _i_memb(_set_all)(i_type *self, const bool value)
@@ -248,7 +250,7 @@ STC_INLINE bool _i_memb(_disjoint)(const i_type* self, const i_type* other) {
/* -------------------------- IMPLEMENTATION ------------------------- */
#if defined(i_implement) || defined(i_extern)
-#if !defined i_len
+#if !defined i_cap
STC_DEF cbits* cbits_copy(cbits* self, const cbits* other) {
if (self->data64 == other->data64)
return self;
@@ -318,7 +320,7 @@ STC_DEF bool _cbits_disjoint(const uint64_t* set, const uint64_t* other, const s
#define CBITS_H_INCLUDED
#undef _i_memb
#undef _i_assert
-#undef i_len
+#undef i_cap
#undef i_type
#undef i_opt
#undef i_header
diff --git a/include/stc/cbox.h b/include/stc/cbox.h
index f1e410b1..c3a9dd02 100644
--- a/include/stc/cbox.h
+++ b/include/stc/cbox.h
@@ -139,11 +139,11 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) {
return out;
}
- STC_INLINE void _cx_memb(_copy)(_cx_self* self, _cx_self other) {
- if (self->get == other.get)
+ STC_INLINE void _cx_memb(_assign)(_cx_self* self, const _cx_self ptr) {
+ if (self->get == ptr.get)
return;
_cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(other);
+ *self = _cx_memb(_clone)(ptr);
}
#endif // !_i_no_clone
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h
index 9c706e52..c5e08393 100644
--- a/include/stc/cdeq.h
+++ b/include/stc/cdeq.h
@@ -49,13 +49,13 @@ STC_API void _cx_memb(_drop)(_cx_self* self);
STC_API _cx_value* _cx_memb(_push)(_cx_self* self, i_key value);
STC_API void _cx_memb(_shrink_to_fit)(_cx_self *self);
#if !defined _i_queue
-#if !defined _i_no_clone
-STC_API _cx_value* _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2);
#if !defined _i_no_emplace
STC_API _cx_value* _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
const _cx_raw* p1, const _cx_raw* p2);
#endif // _i_no_emplace
+#if !defined _i_no_clone
+STC_API _cx_value* _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
#endif // !_i_no_clone
#if !c_option(c_no_cmp)
@@ -76,15 +76,16 @@ STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
#endif
STC_INLINE i_key _cx_memb(_value_clone)(i_key val)
{ return i_keyclone(val); }
-STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->data == other.data) return;
- _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
+STC_INLINE void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->data == other->data) return;
+ _cx_memb(_drop)(self);
+ *self = _cx_memb(_clone)(*other);
}
#endif // !_i_no_clone
-STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cdeq_rep_(&cx)->size; }
-STC_INLINE size_t _cx_memb(_capacity)(_cx_self cx) { return cdeq_rep_(&cx)->cap; }
-STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return !cdeq_rep_(&cx)->size; }
-STC_INLINE _cx_raw _cx_memb(_value_toraw)(_cx_value* pval) { return i_keyto(pval); }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* cx) { return cdeq_rep_(cx)->size; }
+STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* cx) { return cdeq_rep_(cx)->cap; }
+STC_INLINE bool _cx_memb(_empty)(const _cx_self* cx) { return !cdeq_rep_(cx)->size; }
+STC_INLINE _cx_raw _cx_memb(_value_toraw)(const _cx_value* pval) { return i_keyto(pval); }
STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); }
STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return self->data; }
STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self)
@@ -142,12 +143,13 @@ _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) {
return _cx_memb(_erase_range_p)(self, it1.ref, it2.ref);
}
-#if !defined _i_no_clone && !defined _i_no_emplace
+#if !defined _i_no_clone
STC_INLINE _cx_value*
_cx_memb(_emplace_range)(_cx_self* self, _cx_iter it, _cx_iter it1, _cx_iter it2) {
return _cx_memb(_clone_range_p)(self, it.ref, it1.ref, it2.ref);
}
-
+#endif // !_i_no_clone
+#if !defined _i_no_emplace
STC_INLINE _cx_value*
_cx_memb(_emplace_front)(_cx_self* self, _cx_raw raw) {
return _cx_memb(_push_front)(self, i_keyfrom(raw));
@@ -165,7 +167,7 @@ STC_INLINE _cx_value*
_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) {
return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
}
-#endif // !_i_no_clone && !_i_no_emplace
+#endif // !_i_no_emplace
#if !c_option(c_no_cmp)
@@ -225,7 +227,7 @@ _cx_memb(_clear)(_cx_self* self) {
STC_DEF void
_cx_memb(_shrink_to_fit)(_cx_self *self) {
- if (_cx_memb(_size)(*self) != _cx_memb(_capacity)(*self)) {
+ if (_cx_memb(_size)(self) != _cx_memb(_capacity)(self)) {
struct cdeq_rep* rep = cdeq_rep_(self);
const size_t sz = rep->size;
memmove(self->_base, self->data, sz*sizeof(i_key));
@@ -389,7 +391,6 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) {
return c_make(_cx_iter){p1};
}
-#if !defined _i_no_clone
#if !defined _i_no_emplace
STC_DEF _cx_value*
_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) {
@@ -401,6 +402,7 @@ _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, co
}
#endif // !_i_no_emplace
+#if !defined _i_no_clone
STC_DEF _cx_value*
_cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
const _cx_value* p1, const _cx_value* p2) {
diff --git a/include/stc/clist.h b/include/stc/clist.h
index 29bf56f3..0fbf01ae 100644
--- a/include/stc/clist.h
+++ b/include/stc/clist.h
@@ -116,10 +116,12 @@ STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
STC_INLINE i_key _cx_memb(_value_clone)(i_key val)
{ return i_keyclone(val); }
STC_INLINE void
-_cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->last == other.last) return;
- _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
+_cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->last == other->last) return;
+ _cx_memb(_drop)(self); *self = _cx_memb(_clone)(*other);
}
+#endif // !_i_no_clone
+
#if !defined _i_no_emplace
STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push_back)(self, i_keyfrom(raw)); }
@@ -130,11 +132,10 @@ STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_r
STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push_back)(self, i_keyfrom(raw)); }
#endif // !_i_no_emplace
-#endif // !_i_no_clone
STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL}; }
STC_INLINE bool _cx_memb(_reserve)(_cx_self* self, size_t n) { return true; }
-STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.last == NULL; }
+STC_INLINE bool _cx_memb(_empty)(const _cx_self* self) { return self->last == NULL; }
STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); }
STC_INLINE _cx_value* _cx_memb(_push)(_cx_self* self, i_key value)
{ return _cx_memb(_push_back)(self, value); }
diff --git a/include/stc/cmap.h b/include/stc/cmap.h
index 3cc08cde..cfff214b 100644
--- a/include/stc/cmap.h
+++ b/include/stc/cmap.h
@@ -102,18 +102,18 @@ STC_API void _cx_memb(_erase_entry)(_cx_self* self, _cx_value* val);
STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self)_cmap_inits; }
STC_INLINE void _cx_memb(_shrink_to_fit)(_cx_self* self) { _cx_memb(_reserve)(self, self->size); }
STC_INLINE void _cx_memb(_max_load_factor)(_cx_self* self, float ml) {self->max_load_factor = ml; }
-STC_INLINE bool _cx_memb(_empty)(_cx_self m) { return m.size == 0; }
-STC_INLINE size_t _cx_memb(_size)(_cx_self m) { return m.size; }
-STC_INLINE size_t _cx_memb(_bucket_count)(_cx_self map) { return map.bucket_count; }
-STC_INLINE size_t _cx_memb(_capacity)(_cx_self map)
- { return (size_t)(map.bucket_count*map.max_load_factor); }
+STC_INLINE bool _cx_memb(_empty)(const _cx_self* map) { return !map->size; }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* map) { return map->size; }
+STC_INLINE size_t _cx_memb(_bucket_count)(_cx_self* map) { return map->bucket_count; }
+STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* map)
+ { return (size_t)(map->bucket_count*map->max_load_factor); }
STC_INLINE void _cx_memb(_swap)(_cx_self *map1, _cx_self *map2) {c_swap(_cx_self, *map1, *map2); }
STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, _cx_rawkey rkey)
{ return self->size && self->_hashx[_cx_memb(_bucket_)(self, &rkey).idx]; }
#ifndef _i_isset
STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped);
- #if !defined _i_no_clone && !defined _i_no_emplace
+ #if !defined _i_no_emplace
STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, _cx_rawkey rkey, i_valraw rmapped);
#endif
@@ -129,11 +129,11 @@ STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, _cx_rawkey rke
#endif // !_i_isset
#if !defined _i_no_clone
-STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->table == other.table)
+STC_INLINE void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->table == other->table)
return;
_cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(other);
+ *self = _cx_memb(_clone)(*other);
}
STC_INLINE _cx_value
@@ -142,6 +142,7 @@ _cx_memb(_value_clone)(_cx_value _val) {
_i_MAP_ONLY( _val.second = i_valclone(_val.second); )
return _val;
}
+#endif // !_i_no_clone
#if !defined _i_no_emplace
STC_INLINE _cx_result
@@ -154,10 +155,9 @@ _cx_memb(_emplace)(_cx_self* self, _cx_rawkey rkey _i_MAP_ONLY(, i_valraw rmappe
return _res;
}
#endif // !_i_no_emplace
-#endif // !_i_no_clone
STC_INLINE _cx_raw
-_cx_memb(_value_toraw)(_cx_value* val) {
+_cx_memb(_value_toraw)(const _cx_value* val) {
return _i_SET_ONLY( i_keyto(val) )
_i_MAP_ONLY( c_make(_cx_raw){i_keyto((&val->first)), i_valto((&val->second))} );
}
@@ -299,7 +299,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) {
return _res;
}
- #if !defined _i_no_clone && !defined _i_no_emplace
+ #if !defined _i_no_emplace
STC_DEF _cx_result
_cx_memb(_emplace_or_assign)(_cx_self* self, _cx_rawkey rkey, i_valraw rmapped) {
_cx_result _res = _cx_memb(_insert_entry_)(self, rkey);
@@ -310,7 +310,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) {
_res.ref->second = i_valfrom(rmapped);
return _res;
}
- #endif // !_i_no_clone && !_i_no_emplace
+ #endif // !_i_no_emplace
#endif // !_i_isset
STC_DEF chash_bucket_t
diff --git a/include/stc/cpque.h b/include/stc/cpque.h
index 3a7cc0a1..bb7c207e 100644
--- a/include/stc/cpque.h
+++ b/include/stc/cpque.h
@@ -73,14 +73,14 @@ STC_INLINE void _cx_memb(_clear)(_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)
- { return q.size; }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* q)
+ { return q->size; }
-STC_INLINE bool _cx_memb(_empty)(_cx_self q)
- { return !q.size; }
+STC_INLINE bool _cx_memb(_empty)(const _cx_self* q)
+ { return !q->size; }
-STC_INLINE size_t _cx_memb(_capacity)(_cx_self q)
- { return q.capacity; }
+STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* q)
+ { return q->capacity; }
STC_INLINE _cx_value* _cx_memb(_top)(const _cx_self* self)
{ return &self->data[0]; }
@@ -91,18 +91,19 @@ STC_INLINE void _cx_memb(_pop)(_cx_self* self)
#if !defined _i_no_clone
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(_drop)(self); *self = _cx_memb(_clone)(other);
+STC_INLINE void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->data == other->data) return;
+ _cx_memb(_drop)(self);
+ *self = _cx_memb(_clone)(*other);
}
STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val)
{ return i_keyclone(val); }
+#endif // !_i_no_clone
#if !defined _i_no_emplace
STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
{ _cx_memb(_push)(self, i_keyfrom(raw)); }
#endif // !_i_no_emplace
-#endif // !_i_no_clone
/* -------------------------- IMPLEMENTATION ------------------------- */
#if defined(i_implement)
@@ -118,7 +119,7 @@ _cx_memb(_sift_down_)(_cx_value* arr, const size_t idx, const size_t n) {
STC_DEF void
_cx_memb(_make_heap)(_cx_self* self) {
- size_t n = _cx_memb(_size)(*self);
+ size_t n = self->size;
_cx_value *arr = self->data - 1;
for (size_t k = n >> 1; k != 0; --k)
_cx_memb(_sift_down_)(arr, k, n);
diff --git a/include/stc/cqueue.h b/include/stc/cqueue.h
index 00874f35..0c0df063 100644
--- a/include/stc/cqueue.h
+++ b/include/stc/cqueue.h
@@ -40,7 +40,7 @@ int main() {
cqueue_int_push(&Q, stc64_uniform(&rng, &dist));
// Push or pop on the queue ten million times
- printf("before: size, capacity: %d, %d\n", n, cqueue_int_size(Q), cqueue_int_capacity(Q));
+ printf("before: size, capacity: %d, %d\n", n, cqueue_int_size(&Q), cqueue_int_capacity(&Q));
for (int i=n; i>0; --i) {
int r = stc64_uniform(&rng, &dist);
if (r & 1)
@@ -48,7 +48,7 @@ int main() {
else
--n, cqueue_int_pop(&Q);
}
- printf("after: size, capacity: %d, %d\n", n, cqueue_int_size(Q), cqueue_int_capacity(Q));
+ printf("after: size, capacity: %d, %d\n", n, cqueue_int_size(&Q), cqueue_int_capacity(&Q));
}
}
*/
diff --git a/include/stc/csmap.h b/include/stc/csmap.h
index 5af28830..97f1fce1 100644
--- a/include/stc/csmap.h
+++ b/include/stc/csmap.h
@@ -97,11 +97,11 @@ typedef _i_SET_ONLY( i_keyraw )
_i_MAP_ONLY( struct { i_keyraw first; i_valraw second; } )
_cx_raw;
-#if !defined _i_no_clone
-STC_API _cx_self _cx_memb(_clone)(_cx_self tree);
#if !defined _i_no_emplace
STC_API _cx_result _cx_memb(_emplace)(_cx_self* self, _cx_rawkey rkey _i_MAP_ONLY(, i_valraw rmapped));
#endif // !_i_no_emplace
+#if !defined _i_no_clone
+STC_API _cx_self _cx_memb(_clone)(_cx_self tree);
#endif // !_i_no_clone
STC_API _cx_self _cx_memb(_init)(void);
STC_API _cx_result _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped));
@@ -117,9 +117,9 @@ 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);
STC_API void _cx_memb(_next)(_cx_iter* it);
-STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return _csmap_rep(&cx)->size == 0; }
-STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return _csmap_rep(&cx)->size; }
-STC_INLINE size_t _cx_memb(_capacity)(_cx_self cx) { return _csmap_rep(&cx)->cap; }
+STC_INLINE bool _cx_memb(_empty)(const _cx_self* cx) { return _csmap_rep(cx)->size == 0; }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* cx) { return _csmap_rep(cx)->size; }
+STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* cx) { return _csmap_rep(cx)->cap; }
STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); }
STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, _cx_rawkey rkey)
{ _cx_iter it; _cx_memb(_find_it)(self, rkey, &it); return it; }
@@ -142,7 +142,7 @@ _cx_memb(_clear)(_cx_self* self)
{ _cx_memb(_drop)(self); *self = _cx_memb(_init)(); }
STC_INLINE _cx_raw
-_cx_memb(_value_toraw)(_cx_value* val) {
+_cx_memb(_value_toraw)(const _cx_value* val) {
return _i_SET_ONLY( i_keyto(val) )
_i_MAP_ONLY( c_make(_cx_raw){i_keyto((&val->first)),
i_valto((&val->second))} );
@@ -169,11 +169,11 @@ _cx_memb(_value_clone)(_cx_value _val) {
}
STC_INLINE void
-_cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->nodes == other.nodes)
+_cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->nodes == other->nodes)
return;
_cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(other);
+ *self = _cx_memb(_clone)(*other);
}
STC_INLINE void
@@ -184,7 +184,7 @@ _cx_memb(_shrink_to_fit)(_cx_self *self) {
#endif // !_i_no_clone
#ifndef _i_isset
- #if !defined _i_no_clone && !defined _i_no_emplace
+ #if !defined _i_no_emplace
STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, _cx_rawkey rkey, i_valraw rmapped);
#endif
STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped);
@@ -275,7 +275,7 @@ static i_size
_cx_memb(_new_node_)(_cx_self* self, int level) {
i_size tn; struct csmap_rep *rep = _csmap_rep(self);
if (rep->disp) {
- tn = rep->disp;
+ tn = (i_size)rep->disp;
rep->disp = self->nodes[tn].link[1];
} else {
if (rep->head == rep->cap)
@@ -324,7 +324,7 @@ _cx_memb(_push)(_cx_self* self, _cx_value _val) {
return res;
}
- #if !defined _i_no_clone && !defined _i_no_emplace
+ #if !defined _i_no_emplace
STC_DEF _cx_result
_cx_memb(_emplace_or_assign)(_cx_self* self, _cx_rawkey rkey, i_valraw rmapped) {
_cx_result res = _cx_memb(_insert_entry_)(self, rkey);
@@ -337,7 +337,7 @@ _cx_memb(_push)(_cx_self* self, _cx_value _val) {
}
return res;
}
- #endif // !_i_no_clone && !_i_no_emplace
+ #endif // !_i_no_emplace
#endif // !_i_isset
STC_DEF _cx_value*
diff --git a/include/stc/cstack.h b/include/stc/cstack.h
index b9cff196..46d209ca 100644
--- a/include/stc/cstack.h
+++ b/include/stc/cstack.h
@@ -34,12 +34,29 @@
#include "template.h"
#if !c_option(c_is_fwd)
-_cx_deftypes(_c_cstack_types, _cx_self, i_key);
+#ifdef i_cap
+ #define _i_no_clone
+ _cx_deftypes(_c_cstack_fixed, _cx_self, i_key, i_cap);
+#else
+ _cx_deftypes(_c_cstack_types, _cx_self, i_key);
+#endif
#endif
typedef i_keyraw _cx_raw;
-STC_INLINE _cx_self _cx_memb(_init)(void)
- { return c_make(_cx_self){0, 0, 0}; }
+STC_INLINE _cx_self _cx_memb(_init)(void) {
+ _cx_self s; s.size = 0;
+#ifndef i_cap
+ s.capacity = 0; s.data = NULL;
+#endif
+ return s;
+}
+
+#ifdef i_cap
+STC_INLINE void _cx_memb(_inits)(_cx_self* self)
+ { self->size = 0; }
+#else
+STC_INLINE void _cx_memb(_inits)(_cx_self* self)
+ { self->size = 0; self->capacity = 0; self->data = NULL; }
STC_INLINE _cx_self _cx_memb(_with_capacity)(size_t cap) {
_cx_self out = {(_cx_value *) c_malloc(cap*sizeof(i_key)), 0, cap};
@@ -51,6 +68,7 @@ STC_INLINE _cx_self _cx_memb(_with_size)(size_t size, i_key null) {
while (size) out.data[--size] = null;
return out;
}
+#endif
STC_INLINE void _cx_memb(_clear)(_cx_self* self) {
_cx_value *p = self->data + self->size;
@@ -58,22 +76,33 @@ STC_INLINE void _cx_memb(_clear)(_cx_self* self) {
self->size = 0;
}
-STC_INLINE void _cx_memb(_drop)(_cx_self* self)
- { _cx_memb(_clear)(self); c_free(self->data); }
+STC_INLINE void _cx_memb(_drop)(_cx_self* self) {
+ _cx_memb(_clear)(self);
+#ifndef i_cap
+ c_free(self->data);
+#endif
+}
-STC_INLINE size_t _cx_memb(_size)(_cx_self v)
- { return v.size; }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* self)
+ { return self->size; }
-STC_INLINE bool _cx_memb(_empty)(_cx_self v)
- { return !v.size; }
+STC_INLINE bool _cx_memb(_empty)(const _cx_self* self)
+ { return !self->size; }
-STC_INLINE size_t _cx_memb(_capacity)(_cx_self v)
- { return v.capacity; }
+STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* self) {
+#ifndef i_cap
+ return self->capacity;
+#else
+ return i_cap;
+#endif
+}
STC_INLINE bool _cx_memb(_reserve)(_cx_self* self, size_t n) {
if (n < self->size) return true;
+#ifndef i_cap
_cx_value *t = (_cx_value *)c_realloc(self->data, n*sizeof *t);
if (t) { self->capacity = n, self->data = t; return true; }
+#endif
return false;
}
@@ -88,11 +117,11 @@ _cx_memb(_append_uninit)(_cx_self *self, size_t n) {
STC_INLINE void _cx_memb(_shrink_to_fit)(_cx_self* self)
{ _cx_memb(_reserve)(self, self->size); }
-STC_INLINE _cx_value* _cx_memb(_top)(const _cx_self* self)
+STC_INLINE const _cx_value* _cx_memb(_top)(const _cx_self* self)
{ return &self->data[self->size - 1]; }
STC_INLINE _cx_value* _cx_memb(_push)(_cx_self* self, _cx_value val) {
- if (self->size == self->capacity)
+ if (self->size == _cx_memb(_capacity)(self))
if (!_cx_memb(_reserve)(self, self->size*3/2 + 4))
return NULL;
_cx_value* vp = self->data + self->size++;
@@ -111,7 +140,6 @@ STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, size_t idx)
STC_INLINE _cx_value* _cx_memb(_at_mut)(_cx_self* self, size_t idx)
{ assert(idx < self->size); return self->data + idx; }
-#if !defined _i_no_clone
#if !defined _i_no_emplace
STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push)(self, i_keyfrom(raw)); }
@@ -119,31 +147,36 @@ STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push)(self, i_keyfrom(raw)); }
#endif // !_i_no_emplace
+#if !defined _i_no_clone
STC_INLINE _cx_self _cx_memb(_clone)(_cx_self v) {
- _cx_self out = {(_cx_value *) c_malloc(v.size*sizeof(_cx_value)), v.size, v.size};
+ _cx_self out = {(_cx_value *)c_malloc(v.size*sizeof(_cx_value)), v.size, v.size};
if (!out.data) out.capacity = 0;
else for (size_t i = 0; i < v.size; ++v.data)
out.data[i++] = i_keyclone((*v.data));
return out;
}
-STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->data == other.data) return;
- _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other);
+STC_INLINE void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
+ if (self->data == other->data) return;
+ _cx_memb(_drop)(self);
+ *self = _cx_memb(_clone)(*other);
}
STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val)
{ return i_keyclone(val); }
-STC_INLINE i_keyraw _cx_memb(_value_toraw)(_cx_value* val)
+STC_INLINE i_keyraw _cx_memb(_value_toraw)(const _cx_value* val)
{ return i_keyto(val); }
#endif // !_i_no_clone
STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self)
- { return c_make(_cx_iter){self->data}; }
+ { return c_make(_cx_iter){(_cx_value*)self->data}; }
+
STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
- { return c_make(_cx_iter){self->data + self->size}; }
+ { return c_make(_cx_iter){(_cx_value*)self->data + self->size}; }
+
STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; }
+
STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs)
{ it.ref += offs; return it; }
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index ed533064..441fe94a 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -300,9 +300,6 @@ STC_INLINE char* cstr_assign_s(cstr* self, cstr s) {
return cstr_assign_n(self, sv.str, sv.size);
}
-STC_INLINE void cstr_copy(cstr* self, cstr s)
- { cstr_assign_s(self, s); }
-
STC_INLINE char* cstr_append(cstr* self, const char* str)
{ return cstr_append_n(self, str, strlen(str)); }
diff --git a/include/stc/cvec.h b/include/stc/cvec.h
index 77462a30..19303125 100644
--- a/include/stc/cvec.h
+++ b/include/stc/cvec.h
@@ -93,17 +93,6 @@ STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, _cx_raw r
STC_API _cx_iter _cx_memb(_binary_search_in)(_cx_iter it1, _cx_iter it2, _cx_raw raw, _cx_iter* lower_bound);
#endif
-#if !defined _i_no_clone
-STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
-STC_API _cx_value* _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2);
-STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val)
- { return i_keyclone(val); }
-STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->data == other.data) return;
- _cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(other);
- }
#if !defined _i_no_emplace
STC_API _cx_value* _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
const _cx_raw* p1, const _cx_raw* p2);
@@ -119,17 +108,29 @@ STC_INLINE _cx_value*
_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) {
return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
}
+#endif // !_i_no_emplace
+
+#if !defined _i_no_clone
+STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
+STC_API _cx_value* _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
+STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val)
+ { return i_keyclone(val); }
+STC_INLINE void _cx_memb(_copy)(_cx_self* self, const _cx_self* other) {
+ if (self->data == other->data) return;
+ _cx_memb(_drop)(self);
+ *self = _cx_memb(_clone)(*other);
+ }
STC_INLINE _cx_value*
_cx_memb(_emplace_range)(_cx_self* self, _cx_iter it, _cx_iter it1, _cx_iter it2) {
return _cx_memb(_clone_range_p)(self, it.ref, it1.ref, it2.ref);
}
-#endif // !_i_no_emplace
#endif // !_i_no_clone
-STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cvec_rep_(&cx)->size; }
-STC_INLINE size_t _cx_memb(_capacity)(_cx_self cx) { return cvec_rep_(&cx)->cap; }
-STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return !cvec_rep_(&cx)->size; }
-STC_INLINE _cx_raw _cx_memb(_value_toraw)(_cx_value* val) { return i_keyto(val); }
+STC_INLINE size_t _cx_memb(_size)(const _cx_self* cx) { return cvec_rep_(cx)->size; }
+STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* cx) { return cvec_rep_(cx)->cap; }
+STC_INLINE bool _cx_memb(_empty)(const _cx_self* cx) { return !cvec_rep_(cx)->size; }
+STC_INLINE _cx_raw _cx_memb(_value_toraw)(const _cx_value* val) { return i_keyto(val); }
STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); }
STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return self->data; }
STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self)
@@ -146,7 +147,7 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; }
STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs)
{ it.ref += offs; return it; }
-STC_INLINE size_t _cx_memb(_index)(_cx_self cx, _cx_iter it) { return it.ref - cx.data; }
+STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it) { return it.ref - cx->data; }
STC_INLINE _cx_self
_cx_memb(_with_size)(const size_t size, i_key null) {
@@ -163,13 +164,13 @@ _cx_memb(_with_capacity)(const size_t cap) {
}
STC_INLINE void
-_cx_memb(_shrink_to_fit)(_cx_self *self) {
- _cx_memb(_reserve)(self, _cx_memb(_size)(*self));
+_cx_memb(_shrink_to_fit)(_cx_self* self) {
+ _cx_memb(_reserve)(self, _cx_memb(_size)(self));
}
STC_INLINE _cx_value*
-_cx_memb(_append_uninit)(_cx_self *self, const size_t n) {
- return _cx_memb(_insert_uninit_p)(self, self->data + _cx_memb(_size)(*self), n);
+_cx_memb(_append_uninit)(_cx_self* self, const size_t n) {
+ return _cx_memb(_insert_uninit_p)(self, self->data + _cx_memb(_size)(self), n);
}
STC_INLINE _cx_value*
diff --git a/include/stc/forward.h b/include/stc/forward.h
index 18c3d7b0..9c462b8e 100644
--- a/include/stc/forward.h
+++ b/include/stc/forward.h
@@ -192,6 +192,14 @@ typedef union {
size_t size, capacity; \
} SELF
+#define _c_cstack_fixed(SELF, VAL, CAP) \
+ typedef VAL SELF##_value; \
+ typedef struct { SELF##_value *ref; } SELF##_iter; \
+ typedef struct SELF { \
+ SELF##_value data[CAP]; \
+ size_t size; \
+ } SELF
+
#define _c_cpque_types(SELF, VAL) \
typedef VAL SELF##_value; \
typedef struct SELF { \
diff --git a/include/stc/template.h b/include/stc/template.h
index 217b29d3..93f5e4c2 100644
--- a/include/stc/template.h
+++ b/include/stc/template.h
@@ -259,6 +259,7 @@
#undef i_cmp
#undef i_eq
#undef i_hash
+#undef i_cap
#undef i_size
#undef i_val