From eb85069b669e754836b9d4587ba03d3af1a5e975 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sun, 26 Mar 2023 00:27:45 +0100 Subject: development branch for 4.2 Removed uses of c_auto and c_with in documentation examples and code examples. Still using c_defer a few places. Renamed c11/fmt.h to c11/print.h. Some additions in ccommon.h, e.g. c_const_cast(T, x). Improved docs. --- misc/examples/new_queue.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'misc/examples/new_queue.c') diff --git a/misc/examples/new_queue.c b/misc/examples/new_queue.c index 7fae90d2..f7887ffb 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/new_queue.c @@ -25,22 +25,23 @@ int main() { stc64_t rng = stc64_new((uint64_t)time(NULL)); stc64_uniform_t dist = stc64_uniform_new(0, n); - c_auto (IQ, Q) - { - // Push 50'000'000 random numbers onto the queue. - c_forrange (n) - IQ_push(&Q, (int)stc64_uniform(&rng, &dist)); - - // Push or pop on the queue 50 million times - printf("befor: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); - - c_forrange (n) { - int r = (int)stc64_uniform(&rng, &dist); - if (r & 3) - IQ_push(&Q, r); - else - IQ_pop(&Q); - } - printf("after: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); + IQ Q = {0}; + + // Push 50'000'000 random numbers onto the queue. + c_forrange (n) + IQ_push(&Q, (int)stc64_uniform(&rng, &dist)); + + // Push or pop on the queue 50 million times + printf("befor: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); + + c_forrange (n) { + int r = (int)stc64_uniform(&rng, &dist); + if (r & 3) + IQ_push(&Q, r); + else + IQ_pop(&Q); } + + printf("after: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); + IQ_drop(&Q); } -- cgit v1.2.3 From a0a290645828c88597efce80f6b0f5a958cefa89 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 30 Mar 2023 17:59:08 +0200 Subject: Added crand.h - Alternative API to crandom.h, which will be deprecated. --- README.md | 6 +-- docs/cpque_api.md | 8 +-- docs/crandom_api.md | 45 ++++++++--------- include/stc/clist.h | 4 +- include/stc/cqueue.h | 10 ++-- misc/benchmarks/picobench/picobench_cmap.cpp | 68 ++++++++++++------------- misc/benchmarks/picobench/picobench_csmap.cpp | 72 +++++++++++++-------------- misc/benchmarks/plotbench/cdeq_benchmark.cpp | 30 +++++------ misc/benchmarks/plotbench/clist_benchmark.cpp | 26 +++++----- misc/benchmarks/plotbench/cmap_benchmark.cpp | 34 ++++++------- misc/benchmarks/plotbench/cpque_benchmark.cpp | 32 ++++++------ misc/benchmarks/plotbench/csmap_benchmark.cpp | 34 ++++++------- misc/benchmarks/plotbench/cvec_benchmark.cpp | 22 ++++---- misc/benchmarks/shootout_hashmaps.cpp | 8 +-- misc/benchmarks/various/cbits_benchmark.cpp | 14 +++--- misc/benchmarks/various/prng_bench.cpp | 6 +-- misc/benchmarks/various/sso_bench.cpp | 14 +++--- misc/examples/birthday.c | 10 ++-- misc/examples/gauss2.c | 10 ++-- misc/examples/list.c | 7 ++- misc/examples/new_queue.c | 10 ++-- misc/examples/priority.c | 10 ++-- misc/examples/queue.c | 12 ++--- misc/examples/random.c | 16 +++--- 24 files changed, 249 insertions(+), 259 deletions(-) (limited to 'misc/examples/new_queue.c') diff --git a/README.md b/README.md index 75a5357e..b5f9ceb7 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Others ------ - [***ccommon*** - Generic safe macros and algorithms](docs/ccommon_api.md) - [***cregex*** - Regular expressions (extended from Rob Pike's regexp9)](docs/cregex_api.md) -- [***crandom*** - A novel very fast *PRNG* named **stc64**](docs/crandom_api.md) +- [***crand*** - A novel very fast *PRNG* named **stc64**](docs/crandom_api.md) - [***coption*** - getopt() alike command line args parser](docs/coption_api.md) Highlights @@ -343,7 +343,7 @@ once and if needed. Currently, define `i_extern` before including **clist** for It is possible to generate single headers by executing the python script `src/singleheader.py header-file > single`. Conveniently, `src\libstc.c` implements non-templated functions as shared symbols for **cstr**, **csview**, -**cbits** and **crandom**. When building in shared mode (-DSTC_HEADER), you may include this file in your project, +**cbits** and **crand**. When building in shared mode (-DSTC_HEADER), you may include this file in your project, or define your own as descibed above. ```c // stc_libs.c @@ -592,7 +592,7 @@ STC is generally very memory efficient. Type sizes: - Allows for `i_key*` template parameters instead of `i_val*` for all containers, not only for **cset** and **csset**. - Optimized *c_default_hash()*. Therefore *c_hash32()* and *c_hash64()* are removed (same speed). - Added *.._push()* and *.._emplace()* function to all containers to allow for more generic coding. -- Renamed global PRNGs *stc64_random()* and *stc64_srandom()* to *crandom()* and *csrandom()*. +- Renamed global PRNGs *stc64_random()* and *stc64_srandom()* to *crand()* and *csrand()*. - Added some examples and benchmarks for SSO and heterogenous lookup comparison with c++20 (string_bench_*.cpp). ## Brief summary of changes from version 2.x to 3.0 diff --git a/docs/cpque_api.md b/docs/cpque_api.md index 1396dc1f..962ee162 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -60,7 +60,7 @@ i_val cpque_X_value_clone(i_val value); ## Example ```c -#include +#include #include #define i_val int64_t @@ -71,15 +71,15 @@ i_val cpque_X_value_clone(i_val value); int main() { intptr_t N = 10000000; - stc64_t rng = stc64_new(1234); - stc64_uniform_t dist = stc64_uniform_new(0, N * 10); + crand_t rng = crand_init(1234); + crand_unif_t dist = crand_unif_init(0, N * 10); // Define heap cpque_i heap = {0}; // Push ten million random numbers to priority queue. c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + cpque_i_push(&heap, crand_unif(&rng, &dist)); // Add some negative ones. int nums[] = {-231, -32, -873, -4, -343}; diff --git a/docs/crandom_api.md b/docs/crandom_api.md index e69cc539..7281b2d7 100644 --- a/docs/crandom_api.md +++ b/docs/crandom_api.md @@ -1,4 +1,4 @@ -# STC [crandom](../include/stc/crandom.h): Pseudo Random Number Generator +# STC [crand](../include/stc/crand.h): Pseudo Random Number Generator ![Random](pics/random.jpg) This features a *64-bit PRNG* named **stc64**, and can generate bounded uniform and normal @@ -33,45 +33,40 @@ xoshiro and pcg (Vigna/O'Neill) PRNGs: https://www.pcg-random.org/posts/on-vigna ## Header file -All crandom definitions and prototypes are available by including a single header file. +All crand definitions and prototypes are available by including a single header file. ```c -#include +#include ``` ## Methods ```c -void csrandom(uint64_t seed); // seed global stc64 prng -uint64_t crandom(void); // global stc64_rand(rng) -double crandomf(void); // global stc64_randf(rng) +void csrand(uint64_t seed); // seed global stc64 prng +uint64_t crand(void); // global crand_u64(rng) +double crandf(void); // global crand_f64(rng) -stc64_t stc64_new(uint64_t seed); // stc64_init(s) is deprecated -stc64_t stc64_with_seq(uint64_t seed, uint64_t seq); // with unique stream +crand_t crand_init(uint64_t seed); // stc64_init(s) is deprecated +uint64_t crand_u64(crand_t* rng); // range [0, 2^64 - 1] +double crand_f64(crand_t* rng); // range [0.0, 1.0) -uint64_t stc64_rand(stc64_t* rng); // range [0, 2^64 - 1] -double stc64_randf(stc64_t* rng); // range [0.0, 1.0) +crand_unif_t crand_unif_init(int64_t low, int64_t high); // uniform-distribution +int64_t crand_unif(crand_t* rng, crand_unif_t* dist); // range [low, high] -stc64_uniform_t stc64_uniform_new(int64_t low, int64_t high); // uniform-distribution -int64_t stc64_uniform(stc64_t* rng, stc64_uniform_t* dist); // range [low, high] -stc64_uniformf_t stc64_uniformf_new(double lowf, double highf); -double stc64_uniformf(stc64_t* rng, stc64_uniformf_t* dist); // range [lowf, highf) - -stc64_normalf_t stc64_normalf_new(double mean, double stddev); // normal-distribution -double stc64_normalf(stc64_t* rng, stc64_normalf_t* dist); +crand_norm_t crand_norm_init(double mean, double stddev); // normal-distribution +double crand_norm(crand_t* rng, crand_norm_t* dist); ``` ## Types | Name | Type definition | Used to represent... | |:-------------------|:------------------------------------------|:-----------------------------| -| `stc64_t` | `struct {uint64_t state[4];}` | The PRNG engine type | -| `stc64_uniform_t` | `struct {int64_t lower; uint64_t range;}` | Integer uniform distribution | -| `stc64_uniformf_t` | `struct {double lower, range;}` | Real number uniform distr. | -| `stc64_normalf_t` | `struct {double mean, stddev;}` | Normal distribution type | +| `crand_t` | `struct {uint64_t state[4];}` | The PRNG engine type | +| `crand_unif_t` | `struct {int64_t lower; uint64_t range;}` | Integer uniform distribution | +| `crand_norm_t` | `struct {double mean, stddev;}` | Normal distribution type | ## Example ```c #include -#include +#include #include // Declare int -> int sorted map. Uses typetag 'i' for ints. @@ -89,13 +84,13 @@ int main() // Setup random engine with normal distribution. uint64_t seed = time(NULL); - stc64_t rng = stc64_new(seed); - stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); + crand_t rng = crand_init(seed); + crand_norm_t dist = crand_norm_init(Mean, StdDev); // Create histogram map csmap_i mhist = csmap_i_init(); c_forrange (N) { - int index = (int) round( stc64_normalf(&rng, &dist) ); + int index = (int)round(crand_norm(&rng, &dist)); csmap_i_emplace(&mhist, index, 0).ref->second += 1; } diff --git a/include/stc/clist.h b/include/stc/clist.h index eb72b888..fa26fd65 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -26,7 +26,7 @@ it also support both push_back() and push_front(), unlike std::forward_list: #include - #include + #include #define i_key int64_t #define i_tag ix @@ -38,7 +38,7 @@ { int n; for (int i = 0; i < 1000000; ++i) // one million - clist_ix_push_back(&list, crandom() >> 32); + clist_ix_push_back(&list, crand() >> 32); n = 0; c_foreach (i, clist_ix, list) if (++n % 10000 == 0) printf("%8d: %10zu\n", n, *i.ref); diff --git a/include/stc/cqueue.h b/include/stc/cqueue.h index 67909f8e..1934305a 100644 --- a/include/stc/cqueue.h +++ b/include/stc/cqueue.h @@ -22,7 +22,7 @@ */ // STC queue /* -#include +#include #include #define i_key int @@ -30,19 +30,19 @@ int main() { int n = 10000000; - stc64_t rng = stc64_new(1234); - stc64_uniform_t dist = stc64_uniform_new(0, n); + crand_t rng = crand_init(1234); + crand_unif_t dist = crand_unif_init(0, n); c_auto (cqueue_int, Q) { // Push ten million random numbers onto the queue. for (int i=0; i0; --i) { - int r = stc64_uniform(&rng, &dist); + int r = crand_unif(&rng, &dist); if (r & 1) ++n, cqueue_int_push(&Q, r); else diff --git a/misc/benchmarks/picobench/picobench_cmap.cpp b/misc/benchmarks/picobench/picobench_cmap.cpp index 3ffba5b9..bccbe70c 100644 --- a/misc/benchmarks/picobench/picobench_cmap.cpp +++ b/misc/benchmarks/picobench/picobench_cmap.cpp @@ -1,5 +1,5 @@ #define i_static -#include +#include #define i_static #include #include @@ -54,36 +54,36 @@ static void ins_and_erase_i(picobench::state& s) { MapInt map; map.max_load_factor((int)MaxLoadFactor100 / 100.0); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (s.iterations()) - map[crandom()]; + map[crand()]; map.clear(); - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) - map[crandom()]; - csrandom(seed); + map[crand()]; + csrand(seed); c_forrange (s.iterations()) - map.erase(crandom()); + map.erase(crand()); s.set_result(map.size()); } /* static void ins_and_erase_cmap_i(picobench::state& s) { cmap_i map = cmap_i_init(); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (s.iterations()) - cmap_i_insert(&map, crandom(), 0); + cmap_i_insert(&map, crand(), 0); cmap_i_clear(&map); - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) - cmap_i_insert(&map, crandom(), 0); - csrandom(seed); + cmap_i_insert(&map, crand(), 0); + csrand(seed); c_forrange (s.iterations()) - cmap_i_erase(&map, crandom()); + cmap_i_erase(&map, crand()); s.set_result(cmap_i_size(&map)); cmap_i_drop(&map); } @@ -91,18 +91,18 @@ static void ins_and_erase_cmap_i(picobench::state& s) static void ins_and_erase_cmap_x(picobench::state& s) { cmap_x map = cmap_x_init(); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (s.iterations()) - cmap_x_insert(&map, crandom(), 0); + cmap_x_insert(&map, crand(), 0); cmap_x_clear(&map); - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) - cmap_x_insert(&map, crandom(), 0); - csrandom(seed); + cmap_x_insert(&map, crand(), 0); + csrand(seed); c_forrange (s.iterations()) - cmap_x_erase(&map, crandom()); + cmap_x_erase(&map, crand()); s.set_result(cmap_x_size(&map)); cmap_x_drop(&map); } @@ -124,11 +124,11 @@ static void ins_and_access_i(picobench::state& s) size_t result = 0; MapInt map; map.max_load_factor((int)MaxLoadFactor100 / 100.0); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (N1) - result += ++map[crandom() & mask]; + result += ++map[crand() & mask]; s.set_result(result); } @@ -137,11 +137,11 @@ static void ins_and_access_cmap_i(picobench::state& s) uint64_t mask = (1ull << s.arg()) - 1; size_t result = 0; cmap_i map = cmap_i_init(); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (N1) - result += ++cmap_i_insert(&map, crandom() & mask, 0).ref->second; + result += ++cmap_i_insert(&map, crand() & mask, 0).ref->second; s.set_result(result); cmap_i_drop(&map); } @@ -158,7 +158,7 @@ PICOBENCH_SUITE("Map3"); static void randomize(char* str, size_t len) { for (size_t k=0; k < len; ++k) { - union {uint64_t i; char c[8];} r = {.i = crandom()}; + union {uint64_t i; char c[8];} r = {.i = crand()}; for (unsigned i=0; i<8 && ksecond; } // reset rng back to inital state - csrandom(seed); + csrand(seed); // measure erase then iterate whole map c_forrange (n, s.iterations()) { - cmap_x_erase(&map, crandom()); + cmap_x_erase(&map, crand()); if (!(n & K)) c_foreach (i, cmap_x, map) result += i.ref->second; } diff --git a/misc/benchmarks/picobench/picobench_csmap.cpp b/misc/benchmarks/picobench/picobench_csmap.cpp index 5caab6cc..a6a97b14 100644 --- a/misc/benchmarks/picobench/picobench_csmap.cpp +++ b/misc/benchmarks/picobench/picobench_csmap.cpp @@ -1,6 +1,6 @@ #include #define i_static -#include +#include #define i_static #include #include @@ -71,20 +71,20 @@ template static void insert_i(picobench::state& s) { MapInt map; - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (n, s.iterations()) - map.emplace(crandom() & 0xfffffff, n); + map.emplace(crand() & 0xfffffff, n); s.set_result(map.size()); } static void insert_csmap_i(picobench::state& s) { csmap_i map = csmap_i_init(); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (n, s.iterations()) - csmap_i_insert(&map, crandom() & 0xfffffff, n); + csmap_i_insert(&map, crand() & 0xfffffff, n); s.set_result(csmap_i_size(&map)); csmap_i_drop(&map); } @@ -103,21 +103,21 @@ static void ins_and_erase_i(picobench::state& s) size_t result = 0; uint64_t mask = (1ull << s.arg()) - 1; MapInt map; - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (i, s.iterations()) - map.emplace(crandom() & mask, i); + map.emplace(crand() & mask, i); result = map.size(); map.clear(); - csrandom(seed); + csrand(seed); c_forrange (i, s.iterations()) - map[crandom() & mask] = i; + map[crand() & mask] = i; - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) - map.erase(crandom() & mask); + map.erase(crand() & mask); s.set_result(result); } @@ -126,21 +126,21 @@ static void ins_and_erase_csmap_i(picobench::state& s) size_t result = 0; uint64_t mask = (1ull << s.arg()) - 1; csmap_i map = csmap_i_init(); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (i, s.iterations()) - csmap_i_insert(&map, crandom() & mask, i); + csmap_i_insert(&map, crand() & mask, i); result = csmap_i_size(&map); csmap_i_clear(&map); - csrandom(seed); + csrand(seed); c_forrange (i, s.iterations()) - csmap_i_insert_or_assign(&map, crandom() & mask, i); + csmap_i_insert_or_assign(&map, crand() & mask, i); - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) - csmap_i_erase(&map, crandom() & mask); + csmap_i_erase(&map, crand() & mask); s.set_result(result); csmap_i_drop(&map); } @@ -158,12 +158,12 @@ static void ins_and_access_i(picobench::state& s) uint64_t mask = (1ull << s.arg()) - 1; size_t result = 0; MapInt map; - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (s.iterations()) { - result += ++map[crandom() & mask]; - auto it = map.find(crandom() & mask); + result += ++map[crand() & mask]; + auto it = map.find(crand() & mask); if (it != map.end()) map.erase(it->first); } s.set_result(result + map.size()); @@ -174,12 +174,12 @@ static void ins_and_access_csmap_i(picobench::state& s) uint64_t mask = (1ull << s.arg()) - 1; size_t result = 0; csmap_i map = csmap_i_init(); - csrandom(seed); + csrand(seed); picobench::scope scope(s); c_forrange (s.iterations()) { - result += ++csmap_i_insert(&map, crandom() & mask, 0).ref->second; - const csmap_i_value* val = csmap_i_get(&map, crandom() & mask); + result += ++csmap_i_insert(&map, crand() & mask, 0).ref->second; + const csmap_i_value* val = csmap_i_get(&map, crand() & mask); if (val) csmap_i_erase(&map, val->first); } s.set_result(result + csmap_i_size(&map)); @@ -194,7 +194,7 @@ PICOBENCH(ins_and_access_csmap_i).P; PICOBENCH_SUITE("Map4"); static void randomize(char* str, int len) { - union {uint64_t i; char c[8];} r = {.i = crandom()}; + union {uint64_t i; char c[8];} r = {.i = crand()}; for (int i = len - 7, j = 0; i < len; ++j, ++i) str[i] = (r.c[j] & 63) + 48; } @@ -207,12 +207,12 @@ static void ins_and_access_s(picobench::state& s) MapStr map; picobench::scope scope(s); - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) { randomize(&str[0], str.size()); map.emplace(str, str); } - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) { randomize(&str[0], str.size()); result += map.erase(str); @@ -228,12 +228,12 @@ static void ins_and_access_csmap_s(picobench::state& s) csmap_str map = csmap_str_init(); picobench::scope scope(s); - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) { randomize(buf, s.arg()); csmap_str_emplace(&map, buf, buf); } - csrandom(seed); + csrand(seed); c_forrange (s.iterations()) { randomize(buf, s.arg()); result += csmap_str_erase(&map, buf); @@ -262,22 +262,22 @@ static void iterate_x(picobench::state& s) uint64_t K = (1ull << s.arg()) - 1; picobench::scope scope(s); - csrandom(seed); + csrand(seed); size_t result = 0; // measure insert then iterate whole map c_forrange (n, s.iterations()) { - map[crandom()] = n; + map[crand()] = n; if (!(n & K)) for (auto const& keyVal : map) result += keyVal.second; } // reset rng back to inital state - csrandom(seed); + csrand(seed); // measure erase then iterate whole map c_forrange (n, s.iterations()) { - map.erase(crandom()); + map.erase(crand()); if (!(n & K)) for (auto const& keyVal : map) result += keyVal.second; } @@ -290,22 +290,22 @@ static void iterate_csmap_x(picobench::state& s) uint64_t K = (1ull << s.arg()) - 1; picobench::scope scope(s); - csrandom(seed); + csrand(seed); size_t result = 0; // measure insert then iterate whole map c_forrange (n, s.iterations()) { - csmap_x_insert_or_assign(&map, crandom(), n); + csmap_x_insert_or_assign(&map, crand(), n); if (!(n & K)) c_foreach (i, csmap_x, map) result += i.ref->second; } // reset rng back to inital state - csrandom(seed); + csrand(seed); // measure erase then iterate whole map c_forrange (n, s.iterations()) { - csmap_x_erase(&map, crandom()); + csmap_x_erase(&map, crand()); if (!(n & K)) c_foreach (i, csmap_x, map) result += i.ref->second; } diff --git a/misc/benchmarks/plotbench/cdeq_benchmark.cpp b/misc/benchmarks/plotbench/cdeq_benchmark.cpp index 1259cc07..a8399ea8 100644 --- a/misc/benchmarks/plotbench/cdeq_benchmark.cpp +++ b/misc/benchmarks/plotbench/cdeq_benchmark.cpp @@ -1,7 +1,7 @@ #include #include #define i_static -#include +#include #ifdef __cplusplus #include @@ -28,10 +28,10 @@ Sample test_std_deque() { { s.test[INSERT].t1 = clock(); container con; - csrandom(seed); - c_forrange (N/3) con.push_front(crandom() & mask1); - c_forrange (N/3) {con.push_back(crandom() & mask1); con.pop_front();} - c_forrange (N/3) con.push_back(crandom() & mask1); + csrand(seed); + c_forrange (N/3) con.push_front(crand() & mask1); + c_forrange (N/3) {con.push_back(crand() & mask1); con.pop_front();} + c_forrange (N/3) con.push_back(crand() & mask1); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = con.size(); s.test[ERASE].t1 = clock(); @@ -40,13 +40,13 @@ Sample test_std_deque() { s.test[ERASE].sum = con.size(); }{ container con; - csrandom(seed); - c_forrange (N) con.push_back(crandom() & mask2); + csrand(seed); + c_forrange (N) con.push_back(crand() & mask2); s.test[FIND].t1 = clock(); size_t sum = 0; // Iteration - not inherent find - skipping //container::iterator it; - //c_forrange (S) if ((it = std::find(con.begin(), con.end(), crandom() & mask2)) != con.end()) sum += *it; + //c_forrange (S) if ((it = std::find(con.begin(), con.end(), crand() & mask2)) != con.end()) sum += *it; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); @@ -72,10 +72,10 @@ Sample test_stc_deque() { s.test[INSERT].t1 = clock(); container con = cdeq_x_init(); //cdeq_x_reserve(&con, N); - csrandom(seed); - c_forrange (N/3) cdeq_x_push_front(&con, crandom() & mask1); - 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); + csrand(seed); + c_forrange (N/3) cdeq_x_push_front(&con, crand() & mask1); + c_forrange (N/3) {cdeq_x_push_back(&con, crand() & mask1); cdeq_x_pop_front(&con);} + c_forrange (N/3) cdeq_x_push_back(&con, crand() & mask1); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = cdeq_x_size(&con); s.test[ERASE].t1 = clock(); @@ -84,13 +84,13 @@ Sample test_stc_deque() { s.test[ERASE].sum = cdeq_x_size(&con); cdeq_x_drop(&con); }{ - csrandom(seed); + csrand(seed); container con = cdeq_x_init(); - c_forrange (N) cdeq_x_push_back(&con, crandom() & mask2); + c_forrange (N) cdeq_x_push_back(&con, crand() & mask2); s.test[FIND].t1 = clock(); size_t sum = 0; //cdeq_x_iter it, end = cdeq_x_end(&con); - //c_forrange (S) if ((it = cdeq_x_find(&con, crandom() & mask2)).ref != end.ref) sum += *it.ref; + //c_forrange (S) if ((it = cdeq_x_find(&con, crand() & mask2)).ref != end.ref) sum += *it.ref; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); diff --git a/misc/benchmarks/plotbench/clist_benchmark.cpp b/misc/benchmarks/plotbench/clist_benchmark.cpp index 04c8e8cd..46bd2793 100644 --- a/misc/benchmarks/plotbench/clist_benchmark.cpp +++ b/misc/benchmarks/plotbench/clist_benchmark.cpp @@ -1,7 +1,7 @@ #include #include #define i_static -#include +#include #ifdef __cplusplus #include @@ -28,9 +28,9 @@ Sample test_std_forward_list() { { s.test[INSERT].t1 = clock(); container con; - csrandom(seed); - c_forrange (N/2) con.push_front(crandom() & mask1); - c_forrange (N/2) con.push_front(crandom() & mask1); + csrand(seed); + c_forrange (N/2) con.push_front(crand() & mask1); + c_forrange (N/2) con.push_front(crand() & mask1); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = 0; s.test[ERASE].t1 = clock(); @@ -39,13 +39,13 @@ Sample test_std_forward_list() { s.test[ERASE].sum = 0; }{ container con; - csrandom(seed); - c_forrange (N) con.push_front(crandom() & mask2); + csrand(seed); + c_forrange (N) con.push_front(crand() & mask2); s.test[FIND].t1 = clock(); size_t sum = 0; container::iterator it; // Iteration - not inherent find - skipping - //c_forrange (S) if ((it = std::find(con.begin(), con.end(), crandom() & mask2)) != con.end()) sum += *it; + //c_forrange (S) if ((it = std::find(con.begin(), con.end(), crand() & mask2)) != con.end()) sum += *it; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); @@ -70,9 +70,9 @@ Sample test_stc_forward_list() { { s.test[INSERT].t1 = clock(); container con = clist_x_init(); - csrandom(seed); - c_forrange (N/2) clist_x_push_front(&con, crandom() & mask1); - c_forrange (N/2) clist_x_push_back(&con, crandom() & mask1); + csrand(seed); + c_forrange (N/2) clist_x_push_front(&con, crand() & mask1); + c_forrange (N/2) clist_x_push_back(&con, crand() & mask1); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = 0; s.test[ERASE].t1 = clock(); @@ -81,13 +81,13 @@ Sample test_stc_forward_list() { s.test[ERASE].sum = 0; clist_x_drop(&con); }{ - csrandom(seed); + csrand(seed); container con = clist_x_init(); - c_forrange (N) clist_x_push_front(&con, crandom() & mask2); + c_forrange (N) clist_x_push_front(&con, crand() & mask2); s.test[FIND].t1 = clock(); size_t sum = 0; //clist_x_iter it, end = clist_x_end(&con); - //c_forrange (S) if ((it = clist_x_find(&con, crandom() & mask2)).ref != end.ref) sum += *it.ref; + //c_forrange (S) if ((it = clist_x_find(&con, crand() & mask2)).ref != end.ref) sum += *it.ref; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); diff --git a/misc/benchmarks/plotbench/cmap_benchmark.cpp b/misc/benchmarks/plotbench/cmap_benchmark.cpp index 7a8f29d2..0582d162 100644 --- a/misc/benchmarks/plotbench/cmap_benchmark.cpp +++ b/misc/benchmarks/plotbench/cmap_benchmark.cpp @@ -1,7 +1,7 @@ #include #include #define i_static -#include +#include #ifdef __cplusplus #include @@ -26,28 +26,28 @@ Sample test_std_unordered_map() { typedef std::unordered_map container; Sample s = {"std,unordered_map"}; { - csrandom(seed); + csrand(seed); s.test[INSERT].t1 = clock(); container con; - c_forrange (i, N/2) con.emplace(crandom() & mask1, i); + c_forrange (i, N/2) con.emplace(crand() & mask1, i); c_forrange (i, N/2) con.emplace(i, i); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = con.size(); - csrandom(seed); + csrand(seed); s.test[ERASE].t1 = clock(); - c_forrange (N) con.erase(crandom() & mask1); + c_forrange (N) con.erase(crand() & mask1); s.test[ERASE].t2 = clock(); s.test[ERASE].sum = con.size(); }{ container con; - csrandom(seed); - c_forrange (i, N/2) con.emplace(crandom() & mask1, i); + csrand(seed); + c_forrange (i, N/2) con.emplace(crand() & mask1, i); c_forrange (i, N/2) con.emplace(i, i); - csrandom(seed); + csrand(seed); s.test[FIND].t1 = clock(); size_t sum = 0; container::iterator it; - c_forrange (N) if ((it = con.find(crandom() & mask1)) != con.end()) sum += it->second; + c_forrange (N) if ((it = con.find(crand() & mask1)) != con.end()) sum += it->second; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); @@ -70,30 +70,30 @@ Sample test_stc_unordered_map() { typedef cmap_x container; Sample s = {"STC,unordered_map"}; { - csrandom(seed); + csrand(seed); s.test[INSERT].t1 = clock(); container con = cmap_x_init(); - c_forrange (i, N/2) cmap_x_insert(&con, crandom() & mask1, i); + c_forrange (i, N/2) cmap_x_insert(&con, crand() & 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); - csrandom(seed); + csrand(seed); s.test[ERASE].t1 = clock(); - c_forrange (N) cmap_x_erase(&con, crandom() & mask1); + c_forrange (N) cmap_x_erase(&con, crand() & mask1); s.test[ERASE].t2 = clock(); s.test[ERASE].sum = cmap_x_size(&con); cmap_x_drop(&con); }{ container con = cmap_x_init(); - csrandom(seed); - c_forrange (i, N/2) cmap_x_insert(&con, crandom() & mask1, i); + csrand(seed); + c_forrange (i, N/2) cmap_x_insert(&con, crand() & mask1, i); c_forrange (i, N/2) cmap_x_insert(&con, i, i); - csrandom(seed); + csrand(seed); s.test[FIND].t1 = clock(); size_t sum = 0; const cmap_x_value* val; c_forrange (N) - if ((val = cmap_x_get(&con, crandom() & mask1))) + if ((val = cmap_x_get(&con, crand() & mask1))) sum += val->second; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; diff --git a/misc/benchmarks/plotbench/cpque_benchmark.cpp b/misc/benchmarks/plotbench/cpque_benchmark.cpp index a729c09f..da092b7f 100644 --- a/misc/benchmarks/plotbench/cpque_benchmark.cpp +++ b/misc/benchmarks/plotbench/cpque_benchmark.cpp @@ -1,7 +1,7 @@ #include #include #define i_static -#include +#include #define i_val float #define i_cmp -c_default_cmp @@ -11,19 +11,17 @@ #include static const uint32_t seed = 1234; +static const int N = 10000000; void std_test() { - stc64_t rng; - int N = 10000000; - std::priority_queue, std::greater> pq; - rng = stc64_new(seed); + csrand(seed); clock_t start = clock(); c_forrange (i, N) - pq.push((float) stc64_randf(&rng)*100000); + pq.push((float) crandf()*100000.0); - printf("Built priority queue: %f secs\n", (clock() - start) / (float) CLOCKS_PER_SEC); + printf("Built priority queue: %f secs\n", (float)(clock() - start)/(float)CLOCKS_PER_SEC); printf("%g ", pq.top()); start = clock(); @@ -31,32 +29,30 @@ void std_test() pq.pop(); } - printf("\npopped PQ: %f secs\n\n", (clock() - start) / (float) CLOCKS_PER_SEC); + printf("\npopped PQ: %f secs\n\n", (float)(clock() - start)/(float)CLOCKS_PER_SEC); } void stc_test() { - stc64_t rng; - int N = 10000000, M = 10; + int N = 10000000; c_auto (cpque_f, pq) { - rng = stc64_new(seed); + csrand(seed); clock_t start = clock(); - c_forrange (i, N) - cpque_f_push(&pq, (float) stc64_randf(&rng)*100000); + c_forrange (i, N) { + cpque_f_push(&pq, (float) crandf()*100000); + } - printf("Built priority queue: %f secs\n", (clock() - start) / (float) CLOCKS_PER_SEC); + printf("Built priority queue: %f secs\n", (float)(clock() - start)/(float)CLOCKS_PER_SEC); printf("%g ", *cpque_f_top(&pq)); - c_forrange (i, M) { + start = clock(); + c_forrange (i, N) { cpque_f_pop(&pq); } - start = clock(); - c_forrange (i, M, N) - cpque_f_pop(&pq); printf("\npopped PQ: %f secs\n", (clock() - start) / (float) CLOCKS_PER_SEC); } } diff --git a/misc/benchmarks/plotbench/csmap_benchmark.cpp b/misc/benchmarks/plotbench/csmap_benchmark.cpp index 46bd695c..da3fc9cc 100644 --- a/misc/benchmarks/plotbench/csmap_benchmark.cpp +++ b/misc/benchmarks/plotbench/csmap_benchmark.cpp @@ -1,7 +1,7 @@ #include #include #define i_static -#include +#include #ifdef __cplusplus #include @@ -26,28 +26,28 @@ Sample test_std_map() { typedef std::map container; Sample s = {"std,map"}; { - csrandom(seed); + csrand(seed); s.test[INSERT].t1 = clock(); container con; - c_forrange (i, N/2) con.emplace(crandom() & mask1, i); + c_forrange (i, N/2) con.emplace(crand() & mask1, i); c_forrange (i, N/2) con.emplace(i, i); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = con.size(); - csrandom(seed); + csrand(seed); s.test[ERASE].t1 = clock(); - c_forrange (N) con.erase(crandom() & mask1); + c_forrange (N) con.erase(crand() & mask1); s.test[ERASE].t2 = clock(); s.test[ERASE].sum = con.size(); }{ container con; - csrandom(seed); - c_forrange (i, N/2) con.emplace(crandom() & mask1, i); + csrand(seed); + c_forrange (i, N/2) con.emplace(crand() & mask1, i); c_forrange (i, N/2) con.emplace(i, i); - csrandom(seed); + csrand(seed); s.test[FIND].t1 = clock(); size_t sum = 0; container::iterator it; - c_forrange (N) if ((it = con.find(crandom() & mask1)) != con.end()) sum += it->second; + c_forrange (N) if ((it = con.find(crand() & mask1)) != con.end()) sum += it->second; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); @@ -71,30 +71,30 @@ Sample test_stc_map() { typedef csmap_x container; Sample s = {"STC,map"}; { - csrandom(seed); + csrand(seed); s.test[INSERT].t1 = clock(); container con = csmap_x_init(); - c_forrange (i, N/2) csmap_x_insert(&con, crandom() & mask1, i); + c_forrange (i, N/2) csmap_x_insert(&con, crand() & 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); - csrandom(seed); + csrand(seed); s.test[ERASE].t1 = clock(); - c_forrange (N) csmap_x_erase(&con, crandom() & mask1); + c_forrange (N) csmap_x_erase(&con, crand() & mask1); s.test[ERASE].t2 = clock(); s.test[ERASE].sum = csmap_x_size(&con); csmap_x_drop(&con); }{ container con = csmap_x_init(); - csrandom(seed); - c_forrange (i, N/2) csmap_x_insert(&con, crandom() & mask1, i); + csrand(seed); + c_forrange (i, N/2) csmap_x_insert(&con, crand() & mask1, i); c_forrange (i, N/2) csmap_x_insert(&con, i, i); - csrandom(seed); + csrand(seed); s.test[FIND].t1 = clock(); size_t sum = 0; const csmap_x_value* val; c_forrange (N) - if ((val = csmap_x_get(&con, crandom() & mask1))) + if ((val = csmap_x_get(&con, crand() & mask1))) sum += val->second; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; diff --git a/misc/benchmarks/plotbench/cvec_benchmark.cpp b/misc/benchmarks/plotbench/cvec_benchmark.cpp index fe7e09fb..b605f4e6 100644 --- a/misc/benchmarks/plotbench/cvec_benchmark.cpp +++ b/misc/benchmarks/plotbench/cvec_benchmark.cpp @@ -1,7 +1,7 @@ #include #include #define i_static -#include +#include #ifdef __cplusplus #include @@ -28,8 +28,8 @@ Sample test_std_vector() { { s.test[INSERT].t1 = clock(); container con; - csrandom(seed); - c_forrange (N) con.push_back(crandom() & mask1); + csrand(seed); + c_forrange (N) con.push_back(crand() & mask1); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = con.size(); s.test[ERASE].t1 = clock(); @@ -38,13 +38,13 @@ Sample test_std_vector() { s.test[ERASE].sum = con.size(); }{ container con; - csrandom(seed); - c_forrange (N) con.push_back(crandom() & mask2); + csrand(seed); + c_forrange (N) con.push_back(crand() & mask2); s.test[FIND].t1 = clock(); size_t sum = 0; //container::iterator it; // Iteration - not inherent find - skipping - //c_forrange (S) if ((it = std::find(con.begin(), con.end(), crandom() & mask2)) != con.end()) sum += *it; + //c_forrange (S) if ((it = std::find(con.begin(), con.end(), crand() & mask2)) != con.end()) sum += *it; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); @@ -70,8 +70,8 @@ Sample test_stc_vector() { { s.test[INSERT].t1 = clock(); container con = cvec_x_init(); - csrandom(seed); - c_forrange (N) cvec_x_push_back(&con, crandom() & mask1); + csrand(seed); + c_forrange (N) cvec_x_push_back(&con, crand() & mask1); s.test[INSERT].t2 = clock(); s.test[INSERT].sum = cvec_x_size(&con); s.test[ERASE].t1 = clock(); @@ -80,13 +80,13 @@ Sample test_stc_vector() { s.test[ERASE].sum = cvec_x_size(&con); cvec_x_drop(&con); }{ - csrandom(seed); + csrand(seed); container con = cvec_x_init(); - c_forrange (N) cvec_x_push_back(&con, crandom() & mask2); + c_forrange (N) cvec_x_push_back(&con, crand() & mask2); s.test[FIND].t1 = clock(); size_t sum = 0; //cvec_x_iter it, end = cvec_x_end(&con); - //c_forrange (S) if ((it = cvec_x_find(&con, crandom() & mask2)).ref != end.ref) sum += *it.ref; + //c_forrange (S) if ((it = cvec_x_find(&con, crand() & mask2)).ref != end.ref) sum += *it.ref; s.test[FIND].t2 = clock(); s.test[FIND].sum = sum; s.test[ITER].t1 = clock(); diff --git a/misc/benchmarks/shootout_hashmaps.cpp b/misc/benchmarks/shootout_hashmaps.cpp index 947a35b4..bae9a42b 100644 --- a/misc/benchmarks/shootout_hashmaps.cpp +++ b/misc/benchmarks/shootout_hashmaps.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #define MAX_LOAD_FACTOR 85 @@ -40,8 +40,8 @@ KHASH_MAP_INIT_INT64(ii, IValue) #define i_max_load_factor MAX_LOAD_FACTOR / 100.0f #include -#define SEED(s) rng = stc64_new(s) -#define RAND(N) (stc64_rand(&rng) & (((uint64_t)1 << N) - 1)) +#define SEED(s) rng = crand_init(s) +#define RAND(N) (crand_u64(&rng) & (((uint64_t)1 << N) - 1)) #define CMAP_SETUP(X, Key, Value) cmap_##X map = cmap_##X##_init() #define CMAP_PUT(X, key, val) cmap_##X##_insert_or_assign(&map, key, val).ref->second @@ -314,7 +314,7 @@ int main(int argc, char* argv[]) unsigned keybits = argc >= 3 ? atoi(argv[2]) : DEFAULT_KEYBITS; unsigned n = n_mill * 1000000; unsigned N1 = n, N2 = n, N3 = n, N4 = n, N5 = n; - stc64_t rng; + crand_t rng; size_t seed = 123456; // time(NULL); printf("\nUnordered hash map shootout\n"); diff --git a/misc/benchmarks/various/cbits_benchmark.cpp b/misc/benchmarks/various/cbits_benchmark.cpp index dd709db1..1764f556 100644 --- a/misc/benchmarks/various/cbits_benchmark.cpp +++ b/misc/benchmarks/various/cbits_benchmark.cpp @@ -5,7 +5,7 @@ enum{ N=1<<22 }; // 4.2 mill. #define i_static -#include +#include #define i_type cbits #define i_len N #include @@ -39,12 +39,12 @@ int main(int argc, char **argv) one_sec_delay(); total = 0; - csrandom(seed); + csrand(seed); current_time = get_time_in_ms(); c_forrange (40 * N) { - uint64_t r = crandom(); + uint64_t r = crand(); bools[r & (N-1)] = r & 1<<29; } @@ -66,13 +66,13 @@ int main(int argc, char **argv) one_sec_delay(); total = 0; - csrandom(seed); + csrand(seed); current_time = get_time_in_ms(); bitset bits; c_forrange (40 * N) { - uint64_t r = crandom(); + uint64_t r = crand(); bits[r & (N-1)] = r & 1<<29; } @@ -92,13 +92,13 @@ int main(int argc, char **argv) one_sec_delay(); total = 0; - csrandom(seed); + csrand(seed); current_time = get_time_in_ms(); cbits bits2 = cbits_with_size(N, false); c_forrange (40 * N) { - uint64_t r = crandom(); + uint64_t r = crand(); cbits_set_value(&bits2, r & (N-1), r & 1<<29); } diff --git a/misc/benchmarks/various/prng_bench.cpp b/misc/benchmarks/various/prng_bench.cpp index be07f799..234e3805 100644 --- a/misc/benchmarks/various/prng_bench.cpp +++ b/misc/benchmarks/various/prng_bench.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include static inline uint64_t rotl64(const uint64_t x, const int k) { return (x << k) | (x >> (64 - k)); } @@ -124,7 +124,7 @@ int main(void) { enum {N = 500000000}; uint16_t* recipient = new uint16_t[N]; - static stc64_t rng; + static crand_t rng; init_state(rng.state, 12345123); std::mt19937 mt(12345123); @@ -187,7 +187,7 @@ int main(void) beg = clock(); for (size_t i = 0; i < N; i++) - recipient[i] = stc64_rand(&rng); + recipient[i] = crand_u64(&rng); end = clock(); cout << "stc64:\t\t" << (float(end - beg) / CLOCKS_PER_SEC) diff --git a/misc/benchmarks/various/sso_bench.cpp b/misc/benchmarks/various/sso_bench.cpp index 0fffef7a..993ff1bb 100644 --- a/misc/benchmarks/various/sso_bench.cpp +++ b/misc/benchmarks/various/sso_bench.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #define i_type StcVec @@ -30,7 +30,7 @@ static inline std::string randomString_STD(int strsize) { char* p = &s[0]; union { uint64_t u8; uint8_t b[8]; } r; for (int i = 0; i < strsize; ++i) { - if ((i & 7) == 0) r.u8 = crandom() & 0x3f3f3f3f3f3f3f3f; + if ((i & 7) == 0) r.u8 = crand() & 0x3f3f3f3f3f3f3f3f; p[i] = CHARS[r.b[i & 7]]; } return s; @@ -41,7 +41,7 @@ static inline cstr randomString_STC(int strsize) { char* p = cstr_data(&s); union { uint64_t u8; uint8_t b[8]; } r; for (int i = 0; i < strsize; ++i) { - if ((i & 7) == 0) r.u8 = crandom() & 0x3f3f3f3f3f3f3f3f; + if ((i & 7) == 0) r.u8 = crand() & 0x3f3f3f3f3f3f3f3f; p[i] = CHARS[r.b[i & 7]]; } return s; @@ -85,7 +85,7 @@ int main() { // VECTOR WITH STRINGS - csrandom(seed); + csrand(seed); sum = 0, n = 0; std::cerr << "\nstrsize\tmsecs\tstd::vector, size=" << BENCHMARK_SIZE << "\n"; for (int strsize = 1; strsize <= MAX_STRING_SIZE; strsize += 2) { @@ -95,7 +95,7 @@ int main() { } std::cout << "Avg:\t" << sum/n << '\n'; - csrandom(seed); + csrand(seed); sum = 0, n = 0; std::cerr << "\nstrsize\tmsecs\tcvec, size=" << BENCHMARK_SIZE << "\n"; for (int strsize = 1; strsize <= MAX_STRING_SIZE; strsize += 2) { @@ -108,7 +108,7 @@ int main() { // SORTED SET WITH STRINGS - csrandom(seed); + csrand(seed); sum = 0, n = 0; std::cerr << "\nstrsize\tmsecs\tstd::set, size=" << BENCHMARK_SIZE/16 << "\n"; for (int strsize = 1; strsize <= MAX_STRING_SIZE; strsize += 2) { @@ -118,7 +118,7 @@ int main() { } std::cout << "Avg:\t" << sum/n << '\n'; - csrandom(seed); + csrand(seed); sum = 0, n = 0; std::cerr << "\nstrsize\tmsecs\tcsset, size=" << BENCHMARK_SIZE/16 << "\n"; for (int strsize = 1; strsize <= MAX_STRING_SIZE; strsize += 2) { diff --git a/misc/examples/birthday.c b/misc/examples/birthday.c index 2b52cc48..c301128a 100644 --- a/misc/examples/birthday.c +++ b/misc/examples/birthday.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #define i_tag ic #define i_key uint64_t @@ -17,11 +17,11 @@ static void test_repeats(void) const static uint64_t mask = (1ull << BITS) - 1; printf("birthday paradox: value range: 2^%d, testing repeats of 2^%d values\n", BITS, BITS_TEST); - stc64_t rng = stc64_new(seed); + crand_t rng = crand_init(seed); cmap_ic m = cmap_ic_with_capacity(N); c_forrange (i, N) { - uint64_t k = stc64_rand(&rng) & mask; + uint64_t k = crand_u64(&rng) & mask; int v = cmap_ic_insert(&m, k, 0).ref->second += 1; if (v > 1) printf("repeated value %" PRIu64 " (%d) at 2^%d\n", k, v, (int)log2((double)i)); @@ -38,12 +38,12 @@ void test_distribution(void) { enum {BITS = 26}; printf("distribution test: 2^%d values\n", BITS); - stc64_t rng = stc64_new(seed); + crand_t rng = crand_init(seed); const size_t N = 1ull << BITS ; cmap_x map = {0}; c_forrange (N) { - uint64_t k = stc64_rand(&rng); + uint64_t k = crand_u64(&rng); cmap_x_insert(&map, k & 0xf, 0).ref->second += 1; } diff --git a/misc/examples/gauss2.c b/misc/examples/gauss2.c index 7fede5aa..df709d03 100644 --- a/misc/examples/gauss2.c +++ b/misc/examples/gauss2.c @@ -1,7 +1,7 @@ #include #include -#include +#include #include // Declare int -> int sorted map. @@ -13,21 +13,21 @@ int main() { enum {N = 5000000}; uint64_t seed = (uint64_t)time(NULL); - stc64_t rng = stc64_new(seed); - const double Mean = round(stc64_randf(&rng)*98.f - 49.f), StdDev = stc64_randf(&rng)*10.f + 1.f, Scale = 74.f; + crand_t rng = crand_init(seed); + const double Mean = round(crand_f64(&rng)*98.f - 49.f), StdDev = crand_f64(&rng)*10.f + 1.f, Scale = 74.f; printf("Demo of gaussian / normal distribution of %d random samples\n", N); printf("Mean %f, StdDev %f\n", Mean, StdDev); // Setup random engine with normal distribution. - stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); + crand_norm_t dist = crand_norm_init(Mean, StdDev); // Create and init histogram map with defered destruct csmap_int hist = {0}; cstr bar = {0}; c_forrange (N) { - int index = (int)round( stc64_normalf(&rng, &dist) ); + int index = (int)round(crand_norm(&rng, &dist)); csmap_int_insert(&hist, index, 0).ref->second += 1; } diff --git a/misc/examples/list.c b/misc/examples/list.c index 9f0b2504..eb81067d 100644 --- a/misc/examples/list.c +++ b/misc/examples/list.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #define i_type DList #define i_val double @@ -11,11 +11,10 @@ int main() { const int n = 3000000; DList list = {0}; - stc64_t rng = stc64_new(1234567); - stc64_uniformf_t dist = stc64_uniformf_new(100.0f, n); + crand_t rng = crand_init(1234567); int m = 0; c_forrange (n) - DList_push_back(&list, stc64_uniformf(&rng, &dist)), ++m; + DList_push_back(&list, crand_f64(&rng)*n + 100), ++m; double sum = 0.0; printf("sumarize %d:\n", m); diff --git a/misc/examples/new_queue.c b/misc/examples/new_queue.c index f7887ffb..044e44cb 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/new_queue.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -22,20 +22,20 @@ int point_cmp(const Point* a, const Point* b) { int main() { int n = 50000000; - stc64_t rng = stc64_new((uint64_t)time(NULL)); - stc64_uniform_t dist = stc64_uniform_new(0, n); + crand_t rng = crand_init((uint64_t)time(NULL)); + crand_unif_t dist = crand_unif_init(0, n); IQ Q = {0}; // Push 50'000'000 random numbers onto the queue. c_forrange (n) - IQ_push(&Q, (int)stc64_uniform(&rng, &dist)); + IQ_push(&Q, (int)crand_unif(&rng, &dist)); // Push or pop on the queue 50 million times printf("befor: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); c_forrange (n) { - int r = (int)stc64_uniform(&rng, &dist); + int r = (int)crand_unif(&rng, &dist); if (r & 3) IQ_push(&Q, r); else diff --git a/misc/examples/priority.c b/misc/examples/priority.c index d3d0283e..95dd3183 100644 --- a/misc/examples/priority.c +++ b/misc/examples/priority.c @@ -1,7 +1,7 @@ #include #include -#include +#include #define i_val int64_t #define i_cmp -c_default_cmp // min-heap (increasing values) @@ -10,22 +10,22 @@ int main() { intptr_t N = 10000000; - stc64_t rng = stc64_new((uint64_t)time(NULL)); - stc64_uniform_t dist = stc64_uniform_new(0, N * 10); + crand_t rng = crand_init((uint64_t)time(NULL)); + crand_unif_t dist = crand_unif_init(0, N * 10); cpque_i heap = {0}; // Push ten million random numbers to priority queue printf("Push %" c_ZI " numbers\n", N); c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + cpque_i_push(&heap, crand_unif(&rng, &dist)); // push some negative numbers too. c_forlist (i, int, {-231, -32, -873, -4, -343}) cpque_i_push(&heap, *i.ref); c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + cpque_i_push(&heap, crand_unif(&rng, &dist)); puts("Extract the hundred smallest."); c_forrange (100) { diff --git a/misc/examples/queue.c b/misc/examples/queue.c index 0f387d52..83c18d09 100644 --- a/misc/examples/queue.c +++ b/misc/examples/queue.c @@ -1,4 +1,4 @@ -#include +#include #include #define i_val int @@ -7,20 +7,20 @@ int main() { int n = 100000000; - stc64_uniform_t dist; - stc64_t rng = stc64_new(1234); - dist = stc64_uniform_new(0, n); + crand_unif_t dist; + crand_t rng = crand_init(1234); + dist = crand_unif_init(0, n); cqueue_i queue = {0}; // Push ten million random numbers onto the queue. c_forrange (n) - cqueue_i_push(&queue, (int)stc64_uniform(&rng, &dist)); + cqueue_i_push(&queue, (int)crand_unif(&rng, &dist)); // Push or pop on the queue ten million times printf("%d\n", n); c_forrange (n) { // forrange uses initial n only. - int r = (int)stc64_uniform(&rng, &dist); + int r = (int)crand_unif(&rng, &dist); if (r & 1) ++n, cqueue_i_push(&queue, r); else diff --git a/misc/examples/random.c b/misc/examples/random.c index e27279a0..ea9c483e 100644 --- a/misc/examples/random.c +++ b/misc/examples/random.c @@ -1,12 +1,12 @@ #include #include -#include +#include int main() { const size_t N = 1000000000; const uint64_t seed = (uint64_t)time(NULL), range = 1000000; - stc64_t rng = stc64_new(seed); + crand_t rng = crand_init(seed); int64_t sum; clock_t diff, before; @@ -15,28 +15,28 @@ int main() sum = 0; before = clock(); c_forrange (N) { - sum += (uint32_t)stc64_rand(&rng); + sum += (uint32_t)crand_u64(&rng); } diff = clock() - before; printf("full range\t\t: %f secs, %" c_ZI ", avg: %f\n", (float)diff / CLOCKS_PER_SEC, N, (float)sum / (float)N); - stc64_uniform_t dist1 = stc64_uniform_new(0, range); - rng = stc64_new(seed); + crand_unif_t dist1 = crand_unif_init(0, range); + rng = crand_init(seed); sum = 0; before = clock(); c_forrange (N) { - sum += stc64_uniform(&rng, &dist1); // unbiased + sum += crand_unif(&rng, &dist1); // unbiased } diff = clock() - before; printf("unbiased 0-%" PRIu64 "\t: %f secs, %" c_ZI ", avg: %f\n", range, (float)diff/CLOCKS_PER_SEC, N, (float)sum / (float)N); sum = 0; - rng = stc64_new(seed); + rng = crand_init(seed); before = clock(); c_forrange (N) { - sum += (int64_t)(stc64_rand(&rng) % (range + 1)); // biased + sum += (int64_t)(crand_u64(&rng) % (range + 1)); // biased } diff = clock() - before; printf("biased 0-%" PRIu64 " \t: %f secs, %" c_ZI ", avg: %f\n", -- cgit v1.2.3 From 5693ae9ae0d1a18627ba540e0240da010b282296 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Fri, 31 Mar 2023 22:08:07 +0200 Subject: Added stc/extend.h: A generalized way to type-safely extend a container with new members which can be accessed from the template parameters. See examples/functor.c --- README.md | 2 +- include/stc/carc.h | 18 ++++++------- include/stc/cbox.h | 18 ++++++------- include/stc/cdeq.h | 10 +++---- include/stc/clist.h | 6 ++--- include/stc/cmap.h | 10 +++---- include/stc/cpque.h | 2 +- include/stc/csmap.h | 2 +- include/stc/cstack.h | 2 +- include/stc/cvec.h | 12 ++++----- include/stc/extend.h | 65 +++++++++++++++++++++++++++++++++++++++++++++ include/stc/priv/template.h | 4 +++ misc/examples/functor.c | 47 +++++++++++++------------------- misc/examples/new_list.c | 4 +-- misc/examples/new_map.c | 2 +- misc/examples/new_queue.c | 2 +- misc/examples/new_smap.c | 2 +- misc/examples/new_vec.c | 4 +-- 18 files changed, 135 insertions(+), 77 deletions(-) create mode 100644 include/stc/extend.h (limited to 'misc/examples/new_queue.c') diff --git a/README.md b/README.md index b5f9ceb7..3f985b7a 100644 --- a/README.md +++ b/README.md @@ -518,7 +518,7 @@ typedef struct Dataset { ... // Implementation -#define i_opt c_is_forward // flag that the container was forward declared. +#define i_is_forward // flag that the container was forward declared. #define i_val struct Point #define i_tag pnt #include diff --git a/include/stc/carc.h b/include/stc/carc.h index 02bbaf52..5d38d2e7 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -90,7 +90,7 @@ typedef i_keyraw _cx_raw; #define _i_atomic_inc(v) (void)(++*(v)) #define _i_atomic_dec_and_test(v) !(--*(v)) #endif -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_carc_types, _cx_self, i_key); #endif struct _cx_memb(_rep_) { catomic_long counter; i_key value; }; @@ -177,8 +177,8 @@ STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self ptr) { STC_INLINE int _cx_memb(_raw_cmp)(const _cx_raw* rx, const _cx_raw* ry) { return i_cmp(rx, ry); } -STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) { - _cx_raw rx = i_keyto(x->get), ry = i_keyto(y->get); +STC_INLINE int _cx_memb(_cmp)(const _cx_self* self, const _cx_self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); return i_cmp((&rx), (&ry)); } #endif @@ -187,24 +187,24 @@ STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) { STC_INLINE bool _cx_memb(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) { return i_eq(rx, ry); } -STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y) { - _cx_raw rx = i_keyto(x->get), ry = i_keyto(y->get); +STC_INLINE bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); return i_eq((&rx), (&ry)); } #elif !defined i_no_cmp STC_INLINE bool _cx_memb(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) { return i_cmp(rx, ry) == 0; } -STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y) - { return _cx_memb(_cmp)(x, y) == 0; } +STC_INLINE bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other) + { return _cx_memb(_cmp)(self, other) == 0; } #endif #ifndef i_no_hash STC_INLINE uint64_t _cx_memb(_raw_hash)(const _cx_raw* rx) { return i_hash(rx); } -STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* x) - { _cx_raw rx = i_keyto(x->get); return i_hash((&rx)); } +STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* self) + { _cx_raw rx = i_keyto(self->get); return i_hash((&rx)); } #endif #undef _i_eq diff --git a/include/stc/cbox.h b/include/stc/cbox.h index 641fcbfc..6cc86c6f 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -76,7 +76,7 @@ int main() { #include "priv/template.h" typedef i_keyraw _cx_raw; -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_cbox_types, _cx_self, i_key); #endif @@ -163,8 +163,8 @@ STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self* moved) { STC_INLINE int _cx_memb(_raw_cmp)(const _cx_raw* rx, const _cx_raw* ry) { return i_cmp(rx, ry); } -STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) { - _cx_raw rx = i_keyto(x->get), ry = i_keyto(y->get); +STC_INLINE int _cx_memb(_cmp)(const _cx_self* self, const _cx_self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); return i_cmp((&rx), (&ry)); } #endif @@ -173,24 +173,24 @@ STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) { STC_INLINE bool _cx_memb(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) { return i_eq(rx, ry); } -STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y) { - _cx_raw rx = i_keyto(x->get), ry = i_keyto(y->get); +STC_INLINE bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other) { + _cx_raw rx = i_keyto(self->get), ry = i_keyto(other->get); return i_eq((&rx), (&ry)); } #elif !defined i_no_cmp STC_INLINE bool _cx_memb(_raw_eq)(const _cx_raw* rx, const _cx_raw* ry) { return i_cmp(rx, ry) == 0; } -STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y) - { return _cx_memb(_cmp)(x, y) == 0; } +STC_INLINE bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other) + { return _cx_memb(_cmp)(self, other) == 0; } #endif #ifndef i_no_hash STC_INLINE uint64_t _cx_memb(_raw_hash)(const _cx_raw* rx) { return i_hash(rx); } -STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* x) - { _cx_raw rx = i_keyto(x->get); return i_hash((&rx)); } +STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* self) + { _cx_raw rx = i_keyto(self->get); return i_hash((&rx)); } #endif #undef _i_eq diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 09c0a7f8..a032722b 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -36,7 +36,7 @@ #endif #include "priv/template.h" -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_cdeq_types, _cx_self, i_key); #endif typedef i_keyraw _cx_raw; @@ -196,10 +196,10 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_raw raw) { return (_cx_value *) _cx_memb(_get)(self, raw); } STC_INLINE bool -_cx_memb(_eq)(const _cx_self* x, const _cx_self* y) { - if (x->_len != y->_len) return false; - for (intptr_t i = 0; i < x->_len; ++i) { - const _cx_raw _rx = i_keyto(x->data+i), _ry = i_keyto(y->data+i); +_cx_memb(_eq)(const _cx_self* self, const _cx_self* other) { + if (self->_len != other->_len) return false; + for (intptr_t i = 0; i < self->_len; ++i) { + const _cx_raw _rx = i_keyto(self->data+i), _ry = i_keyto(other->data+i); if (!(i_eq((&_rx), (&_ry)))) return false; } return true; diff --git a/include/stc/clist.h b/include/stc/clist.h index fa26fd65..ca02ae3c 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -82,7 +82,7 @@ #endif #include "priv/template.h" -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_clist_types, _cx_self, i_key); #endif _cx_deftypes(_c_clist_complete_types, _cx_self, dummy); @@ -204,8 +204,8 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_raw val) { return _cx_memb(_find_in)(_cx_memb(_begin)(self), _cx_memb(_end)(self), val).ref; } -STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y) { - _cx_iter i = _cx_memb(_begin)(x), j = _cx_memb(_begin)(y); +STC_INLINE bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other) { + _cx_iter i = _cx_memb(_begin)(self), j = _cx_memb(_begin)(other); for (; i.ref && j.ref; _cx_memb(_next)(&i), _cx_memb(_next)(&j)) { const _cx_raw _rx = i_keyto(i.ref), _ry = i_keyto(j.ref); if (!(i_eq((&_rx), (&_ry)))) return false; diff --git a/include/stc/cmap.h b/include/stc/cmap.h index c840523f..437a5982 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -82,7 +82,7 @@ typedef struct { int64_t idx; uint8_t hx; } chash_bucket_t; #define _i_size i_ssize #endif #include "priv/template.h" -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, i_ssize, _i_MAP_ONLY, _i_SET_ONLY); #endif @@ -277,11 +277,11 @@ _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { } STC_INLINE bool -_cx_memb(_eq)(const _cx_self* m1, const _cx_self* m2) { - if (_cx_memb(_size)(m1) != _cx_memb(_size)(m2)) return false; - for (_cx_iter i = _cx_memb(_begin)(m1); i.ref; _cx_memb(_next)(&i)) { +_cx_memb(_eq)(const _cx_self* self, const _cx_self* other) { + if (_cx_memb(_size)(self) != _cx_memb(_size)(other)) return false; + for (_cx_iter i = _cx_memb(_begin)(self); i.ref; _cx_memb(_next)(&i)) { const _cx_rawkey _raw = i_keyto(_i_keyref(i.ref)); - if (!_cx_memb(_contains)(m2, _raw)) return false; + if (!_cx_memb(_contains)(other, _raw)) return false; } return true; } diff --git a/include/stc/cpque.h b/include/stc/cpque.h index 00eaa49e..f3ca7081 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -32,7 +32,7 @@ #endif #include "priv/template.h" -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_cpque_types, _cx_self, i_key); #endif typedef i_keyraw _cx_raw; diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 50593ba3..d0a877c4 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -80,7 +80,7 @@ int main(void) { #define _i_size i_ssize #endif #include "priv/template.h" -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, i_ssize, _i_MAP_ONLY, _i_SET_ONLY); #endif diff --git a/include/stc/cstack.h b/include/stc/cstack.h index f0c930e5..0f855dc9 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -33,7 +33,7 @@ #endif #include "priv/template.h" -#if !c_option(c_is_forward) +#ifndef i_is_forward #ifdef i_capacity #define i_no_clone _cx_deftypes(_c_cstack_fixed, _cx_self, i_key, i_capacity); diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 8f35e5fc..4fe5ddab 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -39,7 +39,7 @@ struct MyStruct { #include #define i_key int -#define i_opt c_is_forward // forward declared +#define i_is_forward // forward declared #define i_tag i32 #include @@ -73,7 +73,7 @@ int main() { #endif #include "priv/template.h" -#if !c_option(c_is_forward) +#ifndef i_is_forward _cx_deftypes(_c_cvec_types, _cx_self, i_key); #endif typedef i_keyraw _cx_raw; @@ -234,10 +234,10 @@ _cx_memb(_get_mut)(const _cx_self* self, _cx_raw raw) { return (_cx_value*) _cx_memb(_get)(self, raw); } STC_INLINE bool -_cx_memb(_eq)(const _cx_self* x, const _cx_self* y) { - if (x->_len != y->_len) return false; - for (intptr_t i = 0; i < x->_len; ++i) { - const _cx_raw _rx = i_keyto(x->data+i), _ry = i_keyto(y->data+i); +_cx_memb(_eq)(const _cx_self* self, const _cx_self* other) { + if (self->_len != other->_len) return false; + for (intptr_t i = 0; i < self->_len; ++i) { + const _cx_raw _rx = i_keyto(self->data+i), _ry = i_keyto(other->data+i); if (!(i_eq((&_rx), (&_ry)))) return false; } return true; diff --git a/include/stc/extend.h b/include/stc/extend.h new file mode 100644 index 00000000..a3efe02d --- /dev/null +++ b/include/stc/extend.h @@ -0,0 +1,65 @@ +/* MIT License + * + * Copyright (c) 2023 Tyge Løvset + * + * 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. + */ +#include +#include + +#ifdef i_key_str + #define _i_key cstr +#elif defined i_keyclass + #define _i_key i_keyclass +#elif defined i_keyboxed + #define _i_key i_keyboxed +#elif defined i_key + #define _i_key i_key +#endif + +#ifdef i_val_str + #define _i_val cstr +#elif defined i_valclass + #define _i_val i_valclass +#elif defined i_valboxed + #define _i_val i_valboxed +#elif defined i_val + #define _i_val i_val +#endif + +#ifdef _i_key + c_PASTE(forward_, i_con)(i_type, _i_key, _i_val); +#else + c_PASTE(forward_, i_con)(i_type, _i_val); +#endif + +typedef struct { + i_ext; + i_type get; +} c_PASTE(i_type, Ext); + +#define c_getcon(cptr) c_container_of(cptr, _cx_memb(Ext), get) + +#define i_is_forward +#define _i_inc +#include _i_inc +#undef _i_inc +#undef _i_key +#undef _i_val +#undef i_con \ No newline at end of file diff --git a/include/stc/priv/template.h b/include/stc/priv/template.h index e352f488..d9e38dba 100644 --- a/include/stc/priv/template.h +++ b/include/stc/priv/template.h @@ -96,6 +96,9 @@ #endif #endif +#if c_option(c_is_forward) + #define i_is_forward +#endif #if c_option(c_no_cmp) #define i_no_cmp #endif @@ -341,6 +344,7 @@ #undef i_no_hash #undef i_no_clone #undef i_no_emplace +#undef i_is_forward #undef _i_prefix #undef _i_expandby diff --git a/misc/examples/functor.c b/misc/examples/functor.c index f8074c3a..45158cd1 100644 --- a/misc/examples/functor.c +++ b/misc/examples/functor.c @@ -6,35 +6,24 @@ // i_hash/i_eq: has self for cmap and cset types only #include -#include -#include -#include -#include -// predeclare -forward_cpque(ipque, int); - -struct { - ipque Q; - bool (*less)(const int*, const int*); -} typedef IPQueue; - - -#define i_type ipque +#define i_type IPQue #define i_val int -#define i_opt c_is_forward // needed to avoid re-type-define container type -#define i_less(x, y) c_container_of(self, IPQueue, Q)->less(x, y) -#include +#define i_ext bool (*less)(const int*, const int*) +#define i_less(x, y) c_getcon(self)->less(x, y) +#define i_con cpque +#include -void print_queue(const char* name, IPQueue q) { +void print_queue(const char* name, IPQueExt q) { // NB: make a clone because there is no way to traverse // priority_queue's content without erasing the queue. - IPQueue copy = {ipque_clone(q.Q), q.less}; + IPQueExt copy = {q.less, IPQue_clone(q.get)}; - for (printf("%s: \t", name); !ipque_empty(©.Q); ipque_pop(©.Q)) - printf("%d ", *ipque_top(©.Q)); + for (printf("%s: \t", name); !IPQue_empty(©.get); IPQue_pop(©.get)) + printf("%d ", *IPQue_top(©.get)); puts(""); - ipque_drop(©.Q); + + IPQue_drop(©.get); } static bool int_less(const int* x, const int* y) { return *x < *y; } @@ -49,21 +38,21 @@ int main() printf("%d ", data[i]); puts(""); - IPQueue q1 = {ipque_init(), int_less}; // Max priority queue - IPQueue minq1 = {ipque_init(), int_greater}; // Min priority queue - IPQueue q5 = {ipque_init(), int_lambda}; // Using lambda to compare elements. + IPQueExt q1 = {int_less}; // Max priority queue + IPQueExt minq1 = {int_greater}; // Min priority queue + IPQueExt q5 = {int_lambda}; // Using lambda to compare elements. c_forrange (i, n) - ipque_push(&q1.Q, data[i]); + IPQue_push(&q1.get, data[i]); print_queue("q1", q1); c_forrange (i, n) - ipque_push(&minq1.Q, data[i]); + IPQue_push(&minq1.get, data[i]); print_queue("minq1", minq1); c_forrange (i, n) - ipque_push(&q5.Q, data[i]); + IPQue_push(&q5.get, data[i]); print_queue("q5", q5); - c_drop(ipque, &q1.Q, &minq1.Q, &q5.Q); + c_drop(IPQue, &q1.get, &minq1.get, &q5.get); } diff --git a/misc/examples/new_list.c b/misc/examples/new_list.c index eae4b8f5..8b291d34 100644 --- a/misc/examples/new_list.c +++ b/misc/examples/new_list.c @@ -11,7 +11,7 @@ typedef struct { #define i_val int #define i_tag i32 -#define i_opt c_is_forward +#define i_is_forward #include typedef struct Point { int x, y; } Point; @@ -22,7 +22,7 @@ int point_cmp(const Point* a, const Point* b) { #define i_val Point #define i_cmp point_cmp -#define i_opt c_is_forward +#define i_is_forward #define i_tag pnt #include diff --git a/misc/examples/new_map.c b/misc/examples/new_map.c index 4b02c46a..3a4f934d 100644 --- a/misc/examples/new_map.c +++ b/misc/examples/new_map.c @@ -26,7 +26,7 @@ int point_cmp(const Point* a, const Point* b) { #define i_val int #define i_cmp point_cmp #define i_hash c_default_hash -#define i_opt c_is_forward +#define i_is_forward #define i_tag pnt #include diff --git a/misc/examples/new_queue.c b/misc/examples/new_queue.c index 044e44cb..916f4dbc 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/new_queue.c @@ -12,7 +12,7 @@ int point_cmp(const Point* a, const Point* b) { } #define i_val Point #define i_cmp point_cmp -#define i_opt c_is_forward +#define i_is_forward #define i_tag pnt #include diff --git a/misc/examples/new_smap.c b/misc/examples/new_smap.c index d85d5c75..d8245b8b 100644 --- a/misc/examples/new_smap.c +++ b/misc/examples/new_smap.c @@ -20,7 +20,7 @@ int point_cmp(const Point* a, const Point* b) { #define i_key Point #define i_val int #define i_cmp point_cmp -#define i_opt c_is_forward +#define i_is_forward #include // cstr => cstr map diff --git a/misc/examples/new_vec.c b/misc/examples/new_vec.c index 988b78d9..df443b7f 100644 --- a/misc/examples/new_vec.c +++ b/misc/examples/new_vec.c @@ -10,7 +10,7 @@ struct MyStruct { } typedef MyStruct; #define i_val int -#define i_opt c_is_forward +#define i_is_forward #define i_tag i32 #include @@ -18,7 +18,7 @@ typedef struct Point { int x, y; } Point; #define i_val Point #define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) -#define i_opt c_is_forward +#define i_is_forward #define i_tag pnt #include -- cgit v1.2.3