diff options
| -rw-r--r-- | README.md | 37 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 48 | ||||
| -rw-r--r-- | include/stc/algo/csort.h | 36 | ||||
| -rw-r--r-- | include/stc/algo/filter.h | 6 | ||||
| -rw-r--r-- | include/stc/coption.h | 6 | ||||
| -rw-r--r-- | misc/benchmarks/build_all.sh | 4 | ||||
| -rw-r--r-- | misc/benchmarks/various/cbits_benchmark.cpp (renamed from misc/benchmarks/misc/cbits_benchmark.cpp) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/csort_bench.c | 61 | ||||
| -rw-r--r-- | misc/benchmarks/various/cspan_bench.c (renamed from misc/benchmarks/misc/cspan_bench.c) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/names.txt (renamed from misc/benchmarks/misc/names.txt) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/prng_bench.cpp (renamed from misc/benchmarks/misc/prng_bench.cpp) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/rust_cmap.c (renamed from misc/benchmarks/misc/rust_cmap.c) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/rust_hashmap.rs (renamed from misc/benchmarks/misc/rust_hashmap.rs) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/sso_bench.cpp (renamed from misc/benchmarks/misc/sso_bench.cpp) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/string_bench_STC.cpp (renamed from misc/benchmarks/misc/string_bench_STC.cpp) | 0 | ||||
| -rw-r--r-- | misc/benchmarks/various/string_bench_STD.cpp (renamed from misc/benchmarks/misc/string_bench_STD.cpp) | 0 | ||||
| -rw-r--r-- | misc/examples/prime.c | 9 | ||||
| -rw-r--r-- | misc/examples/sort.c | 64 |
18 files changed, 131 insertions, 140 deletions
@@ -5,12 +5,17 @@ STC - Smart Template Containers for C News: Version 4.1 Released (Feb 2023) ------------------------------------------------ -Major changes: +I am happy to finally announce a new release! Major changes: - A new exciting [**cspan**](docs/cspan_api.md) single/multi-dimensional array view (with numpy-like slicing). - Signed sizes and indices for all containers. See C++ Core Guidelines by Stroustrup/Sutter: [ES.100](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es100-dont-mix-signed-and-unsigned-arithmetic), [ES.102](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es102-use-signed-types-for-arithmetic), [ES.106](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es106-dont-try-to-avoid-negative-values-by-using-unsigned), and [ES.107](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es107-dont-use-unsigned-for-subscripts-prefer-gslindex). - Customizable allocator [per templated container type](https://github.com/tylov/STC/discussions/44#discussioncomment-4891925). -- Updates on cregex with several [new unicode character classes](docs/cregex_api.md#regex-cheatsheet). -- Uppercase flow-control macro names in ccommon.h [supported as alternatives](include/stc/priv/altnames.h). +- Updates on **cregex** with several [new unicode character classes](docs/cregex_api.md#regex-cheatsheet). +- Algorithms: + - [crange](docs/ccommon_api.md#crange) - similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html) integer range generator. + - [c_forfilter](docs/ccommon_api.md#c_forfilter) - ranges-like filtering. + - [csort](misc/benchmarks/various/csort_bench.c) - fast quicksort with custom inline comparison. +- Support for [uppercase flow-control](include/stc/priv/altnames.h) macro names in ccommon.h. +- Create single header container versions with python script. - Some API changes in cregex and cstr. - [Previous changes for version 4](#version-4). @@ -91,14 +96,14 @@ STC conventions - Container names are prefixed by `c`, e.g. `cvec`, `cstr`. - Public STC macros are prefixed by `c_`, e.g. `c_foreach`, `c_make`. - Template parameter macros are prefixed by `i_`, e.g. `i_val`, `i_type`. -- All containers can be initialized with `{0}`, i.e. no heap allocation used for empty init. -- Common types for container type Con: +- All containers can be initialized with `{0}`, i.e. no heap allocation used by default init. +- Common types for a container type Con: - Con - Con_value - Con_raw - Con_iter - Con_ssize -- Common function names for container type Con: +- Common function names for a container type Con: - Con_init() - Con_reserve(&con, capacity) - Con_drop(&con) @@ -116,8 +121,8 @@ STC conventions - Con_next(&iter) - Con_advance(iter, n) -Standout features of STC ------------------------- +Some standout features of STC +----------------------------- 1. ***Centralized analysis of template arguments***. Assigns good defaults to non-specified templates. You may specify a number of "standard" template arguments for each container, but as minimum only one is required (two for maps). In the latter case, STC assumes the elements are basic types. For more complex types, @@ -130,8 +135,10 @@ Finally, destruction of the lookup key (i.e. string literal) after usage is not is convenient in C. A great ergonomic feature is that the alternative lookup type can also be used for adding entries into containers through using the *emplace*-functions. E.g. `MyCStrVec_emplace_back(&vec, "Hello")`. 3. ***Standardized container iterators***. All container can be iterated the same way, and uses the -same element access syntax. E.g. `c_foreach (it, IntContainer, container) printf(" %d", *it.ref);` will work for -every type of container defined as `IntContainer` with `int` elements. Also the form `c_foreach (it, IntContainer, it1, it2)` +same element access syntax. E.g.: + - `c_foreach (it, IntContainer, container) printf(" %d", *it.ref);` will work for +every type of container defined as `IntContainer` with `int` elements. Also the form: + - `c_foreach (it, IntContainer, it1, it2)` may be used to iterate from `it1` up to `it2`. Usage @@ -172,12 +179,12 @@ int main() } ``` For user defined struct elements, `i_cmp` compare function should be defined, as the default `<` and `==` -only works for integral types. Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching. +only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching*. Similarily, if an element destructor `i_valdrop` is defined, `i_valclone` function is required. -Alternatively `#define i_opt c_no_clone` to disable container cloning. +*Alternatively `#define i_opt c_no_clone` to disable container cloning.* -In order to include two **cvec**'s with different element types, include <stc/cvec.h> twice, e.g.: +In order to include two **cvec**'s with different element types, include <stc/cvec.h> twice: ```c #define i_val struct One #define i_opt c_no_cmp @@ -326,7 +333,7 @@ As a special case, there may be non-templated functions in templated containers once and if needed. Currently, define `i_extern` before including **clist** for its sorting function, and before **cregex** or **utf8** to implement them (global `STC_EXTERN` can alternatively be defined). -It is possible to generate single headers by executing the python script in src/singleheader.py <header>. +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, @@ -386,7 +393,7 @@ Val: - `i_valfrom` - Convertion func *i_val* <- *i_valraw*. - `i_valto` - Convertion func *i_val*\* -> *i_valraw*. -Specials: +Specials (meta-template parameters): - `i_keyclass TYPE` - Auto-binds to standard named functions: *TYPE_clone()*, *TYPE_drop()*, *TYPE_cmp()*, *TYPE_eq()*, *TYPE_hash()*. If `i_keyraw` is defined, function *TYPE_toraw()* is bound to `i_keyto`, and *TYPE_from()* binds to `i_keyfrom`. Only functions required by the container type needs to be defined. E.g.: - *TYPE_hash()* and *TYPE_eq()* are only required by **cmap**, **cset** and smart pointers. - *TYPE_cmp()* is not used by **cstack** and **cmap/cset**, or if *#define i_opt c_no_cmp* is specified. diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index c25d76da..a2f0b99d 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -218,14 +218,14 @@ c_forrange (i, 30, 0, -5) printf(" %lld", i); // 30 25 20 15 10 5 ``` -### c_forwhile, c_forfilter +### c_forfilter Iterate containers with stop-criteria and chained range filtering. | Usage | Description | |:----------------------------------------------------|:---------------------------------------| -| `c_forwhile (it, ctype, start, pred)` | Iterate until pred is false | | `c_forfilter (it, ctype, container, filter)` | Filter out items in chain with && | | `c_forfilter (it, ctype, container, filter, pred)` | Filter and iterate until pred is false | +| `c_forwhile (it, ctype, start, pred)` | Iterate until pred is false | | Built-in filter | Description | |:----------------------------------|:-------------------------------------| @@ -233,12 +233,13 @@ Iterate containers with stop-criteria and chained range filtering. | `c_flt_take(it, numItems)` | Take numItems | | `c_flt_skipwhile(it, predicate)` | Skip items until predicate is false | | `c_flt_takewhile(it, predicate)` | Take items until predicate is false | +| `c_flt_last(it)` | Get count of last filter successes | +| `c_flt_lastwhile(it)` | Get value of last while-filter | -`it.index` holds the index of the source item, and `it.count` the current number of items taken. +`it.index` holds the index of the source item. ```c -#define i_type IVec -#define i_val int -#include <stc/cstack.h> +// Example: +#include <stc/algo/crange.h> #include <stc/algo/filter.h> #include <stdio.h> @@ -246,29 +247,28 @@ bool isPrime(int i) { for (int j=2; j*j <= i; ++j) if (i % j == 0) return false; return true; } -#define isOdd(i) ((i) & 1) +// Get 10 prime numbers after 1 million, but only every 25th of them. int main() { - c_auto (IVec, vec) { - c_forrange (i, 1000) IVec_push(&vec, 1000000 + i); - - c_forfilter (i, IVec, vec, - isOdd(*i.ref) - && c_flt_skip(i, 100) // built-in - && isPrime(*i.ref) - , c_flt_take(i, 10)) { // breaks loop on false. - printf(" %d", *i.ref); - } - puts(""); + crange R = crange_make(1000001, INT32_MAX, 2); + + c_forfilter (i, crange, R, + isPrime(*i.ref) + && (c_flt_skip(i, INT32_MAX) || + c_flt_last(i) % 25 == 0) + , c_flt_take(i, 10)) // breaks loop on false. + { + printf(" %d", *i.ref); } } -// Out: 1000211 1000213 1000231 1000249 1000253 1000273 1000289 1000291 1000303 1000313 +// Out: 1000303 1000639 1000999 1001311 1001593 1001981 1002299 1002583 1002887 1003241 ``` -Note that `c_flt_take()` is given as an optional argument, which makes the loop stop when it becomes false (for efficiency). Chaining it after `isPrime()` instead will give same result, but the full input is processed. +Note that `c_flt_take()` is given as an optional argument, which breaks the loop on false +(for efficiency). Without the comma, it will give same result, but the full input is processed first. ### c_make, c_new, c_delete -- **c_make**: Make a container from a literal initializer list. Example: +- **c_make**: Make any container from an initializer list. Example: ```c #define i_val_str // cstr value type #include <stc/cset.h> @@ -277,7 +277,9 @@ Note that `c_flt_take()` is given as an optional argument, which makes the loop #define i_val int #include <stc/cmap.h> ... -cset_str myset = c_make(cset_str, {"This", "is", "the", "story"}); // note: const char* values given! +// Initializes with const char*, internally converted to cstr! +cset_str myset = c_make(cset_str, {"This", "is", "the", "story"}); + int x = 7, y = 8; cmap_int mymap = c_make(cmap_int, { {1, 2}, {3, 4}, {5, 6}, {x, y} }); ``` @@ -293,7 +295,7 @@ c_delete(cstr, stringptr); ``` ### crange -- **crange** is a number sequence generator type, similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html). The **crange_value** type is `long long`. Below *start*, *stop*, and *step* are of type *crange_value*: +A number sequence generator type, similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html). The **crange_value** type is `long long`. Below *start*, *stop*, and *step* are of type *crange_value*: ```c crange& crange_obj(...) // create a compound literal crange object crange crange_make(stop); // will generate 0, 1, ..., stop-1 diff --git a/include/stc/algo/csort.h b/include/stc/algo/csort.h index c8c41257..c452064f 100644 --- a/include/stc/algo/csort.h +++ b/include/stc/algo/csort.h @@ -20,8 +20,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include <stc/priv/template.h> #include <stc/ccommon.h> +#include <stc/priv/template.h> /* Generic Quicksort in C, performs as fast as c++ std::sort(). template params: @@ -31,37 +31,21 @@ template params: // test: #include <stdio.h> -#include <time.h> -#include <stdlib.h> #define i_val int #include <stc/algo/csort.h> -#include <stc/crandom.h> -#ifdef __cplusplus -#include <algorithm> -#endif -void testsort(csort_int_value *a, size_t size, const char *desc) { - clock_t t = clock(); - csort_int(a, size); - t = clock() - t; +int main() { + int arr[] = {23, 321, 5434, 25, 245, 1, 654, 33, 543, 21}; + + csort_int(arr, c_arraylen(arr)); - printf("%s: %zu elements sorted in %.3fms\n", - desc, size, t*1000.0/CLOCKS_PER_SEC); + for (int i = 0; i < c_arraylen(arr); i++) + printf(" %d", arr[i]); + puts(""); } +*/ -int main() { - size_t i, size = 10000000; - csort_int_value *a = (csort_int_value*)malloc(sizeof(*a) * size); - if (a != NULL) { - for (i = 0; i < size; i++) - a[i] = crandom() & (1U << 28) - 1; - testsort(a, size, "random"); - for (i = 0; i < 20; i++) printf(" %d", a[i]); - puts(""); - free(a); - } -}*/ -typedef i_val c_PASTE(c_PASTE(csort_, i_tag), _value); +typedef i_val c_PASTE(c_CONCAT(csort_, i_tag), _value); static inline void c_PASTE(cisort_, i_tag)(i_val arr[], intptr_t lo, intptr_t hi) { for (intptr_t j = lo, i = lo + 1; i <= hi; j = i, ++i) { diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index b2b59fa6..8357cb4d 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -57,6 +57,8 @@ int main() #define c_flt_skip(i, n) (++(i).s1[(i).s1top++] > (n)) #define c_flt_skipwhile(i, pred) ((i).s2[(i).s2top++] |= !(pred)) #define c_flt_takewhile(i, pred) !c_flt_skipwhile(i, pred) +#define c_flt_last(i) (i).s1[(i).s1top-1] +#define c_flt_lastwhile(i) (i).s2[(i).s2top-1] #define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__) @@ -68,10 +70,10 @@ int main() #define c_forfilter_B(i, C, start, filter) \ for (struct {C##_iter it; C##_value *ref; \ - uint32_t s1[c_NFILTERS], index, count; \ + uint32_t s1[c_NFILTERS], index; \ bool s2[c_NFILTERS]; uint8_t s1top, s2top;} \ i = {.it=start, .ref=i.it.ref}; i.it.ref \ ; C##_next(&i.it), i.ref = i.it.ref, ++i.index, i.s1top=0, i.s2top=0) \ - if (!((filter) && ++i.count)) ; else + if (!(filter)) ; else #endif diff --git a/include/stc/coption.h b/include/stc/coption.h index 69d0796f..65dae444 100644 --- a/include/stc/coption.h +++ b/include/stc/coption.h @@ -107,7 +107,7 @@ static void coption_permute_(char *argv[], int j, int n) { */ static int coption_get(coption *opt, int argc, char *argv[], const char *shortopts, const coption_long *longopts) { - int optc = -1, i0, j, posixly_correct = (shortopts[0] == '+'); + int optc = -1, i0, j, posixly_correct = (shortopts && shortopts[0] == '+'); if (!posixly_correct) { while (opt->_i < argc && (argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0')) ++opt->_i, ++opt->_nargs; @@ -149,12 +149,12 @@ static int coption_get(coption *opt, int argc, char *argv[], } } } - } else { /* a short option */ + } else if (shortopts) { /* a short option */ const char *p; if (opt->_pos == 0) opt->_pos = 1; optc = opt->opt = argv[opt->_i][opt->_pos++]; opt->_optstr[1] = optc, opt->optstr = opt->_optstr; - p = strchr((char *) shortopts, optc); + p = strchr(shortopts, optc); if (p == 0) { optc = '?'; /* unknown option */ } else if (p[1] == ':') { diff --git a/misc/benchmarks/build_all.sh b/misc/benchmarks/build_all.sh index 869559ba..d055bd2e 100644 --- a/misc/benchmarks/build_all.sh +++ b/misc/benchmarks/build_all.sh @@ -15,12 +15,12 @@ if [ ! -z "$1" ] ; then cc=$@ fi if [ $run = 0 ] ; then - for i in *.cpp misc/*.c* picobench/*.cpp plotbench/*.cpp ; do + for i in *.cpp various/*.c* picobench/*.cpp plotbench/*.cpp ; do echo $cc -I../include $i -o $(basename -s .cpp $i).exe $cc -I../include $i -o $(basename -s .cpp $i).exe done else - for i in misc/*.c* picobench/*.cpp ; do + for i in various/*.c* picobench/*.cpp ; do echo $cc -O3 -I../include $i $cc -O3 -I../include $i if [ -f $(basename -s .c $i).exe ]; then ./$(basename -s .c $i).exe; fi diff --git a/misc/benchmarks/misc/cbits_benchmark.cpp b/misc/benchmarks/various/cbits_benchmark.cpp index dd709db1..dd709db1 100644 --- a/misc/benchmarks/misc/cbits_benchmark.cpp +++ b/misc/benchmarks/various/cbits_benchmark.cpp diff --git a/misc/benchmarks/various/csort_bench.c b/misc/benchmarks/various/csort_bench.c new file mode 100644 index 00000000..97885eb8 --- /dev/null +++ b/misc/benchmarks/various/csort_bench.c @@ -0,0 +1,61 @@ +// Generic Quicksort in C, performs as fast as c++ std::sort(). +#include <stdio.h> +#include <time.h> +#include <stdlib.h> +#ifdef __cplusplus + #include <algorithm> +#endif +#define i_val int +#include <stc/algo/csort.h> + +#define ROTL(d,bits) ((d<<(bits)) | (d>>(8*sizeof(d)-(bits)))) +uint64_t random(uint64_t s[3]) { + uint64_t xp = s[0], yp = s[1], zp = s[2]; + s[0] = 15241094284759029579u * zp; + s[1] = yp - xp; s[1] = ROTL(s[1], 12); + s[2] = zp - yp; s[2] = ROTL(s[2], 44); + return xp; +} + +void testsort(int *a, int size, const char *desc) { + clock_t t = clock(); +#ifdef __cplusplus + { printf("std::sort: "); std::sort(a, a + size); } +#else + { printf("stc_sort: "); csort_int(a, size); } +#endif + t = clock() - t; + + printf("time: %.1fms, n: %d, %s\n", + (double)t*1000.0/CLOCKS_PER_SEC, size, desc); +} + + +int main(int argc, char *argv[]) { + size_t i, size = argc > 1 ? strtoull(argv[1], NULL, 0) : 10000000; + uint64_t s[3] = {123456789, 3456789123, 789123456}; + + int32_t *a = (int32_t*)malloc(sizeof(*a) * size); + if (!a) return -1; + + for (i = 0; i < size; i++) + a[i] = random(s) & (1U << 30) - 1; + testsort(a, size, "random"); + for (i = 0; i < 20; i++) + printf(" %d", (int)a[i]); + puts(""); + for (i = 0; i < size; i++) + a[i] = i; + testsort(a, size, "sorted"); + for (i = 0; i < size; i++) + a[i] = size - i; + testsort(a, size, "reverse sorted"); + for (i = 0; i < size; i++) + a[i] = 126735; + testsort(a, size, "constant"); + for (i = 0; i < size; i++) + a[i] = i + 1; + a[size - 1] = 0; + testsort(a, size, "rotated"); + free(a); +} diff --git a/misc/benchmarks/misc/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index 589df13a..589df13a 100644 --- a/misc/benchmarks/misc/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c diff --git a/misc/benchmarks/misc/names.txt b/misc/benchmarks/various/names.txt index 561acbbf..561acbbf 100644 --- a/misc/benchmarks/misc/names.txt +++ b/misc/benchmarks/various/names.txt diff --git a/misc/benchmarks/misc/prng_bench.cpp b/misc/benchmarks/various/prng_bench.cpp index 6f4e0e47..6f4e0e47 100644 --- a/misc/benchmarks/misc/prng_bench.cpp +++ b/misc/benchmarks/various/prng_bench.cpp diff --git a/misc/benchmarks/misc/rust_cmap.c b/misc/benchmarks/various/rust_cmap.c index 83b7dd19..83b7dd19 100644 --- a/misc/benchmarks/misc/rust_cmap.c +++ b/misc/benchmarks/various/rust_cmap.c diff --git a/misc/benchmarks/misc/rust_hashmap.rs b/misc/benchmarks/various/rust_hashmap.rs index 5394a7c3..5394a7c3 100644 --- a/misc/benchmarks/misc/rust_hashmap.rs +++ b/misc/benchmarks/various/rust_hashmap.rs diff --git a/misc/benchmarks/misc/sso_bench.cpp b/misc/benchmarks/various/sso_bench.cpp index 0fffef7a..0fffef7a 100644 --- a/misc/benchmarks/misc/sso_bench.cpp +++ b/misc/benchmarks/various/sso_bench.cpp diff --git a/misc/benchmarks/misc/string_bench_STC.cpp b/misc/benchmarks/various/string_bench_STC.cpp index ae8e4c38..ae8e4c38 100644 --- a/misc/benchmarks/misc/string_bench_STC.cpp +++ b/misc/benchmarks/various/string_bench_STC.cpp diff --git a/misc/benchmarks/misc/string_bench_STD.cpp b/misc/benchmarks/various/string_bench_STD.cpp index 8bb87937..8bb87937 100644 --- a/misc/benchmarks/misc/string_bench_STD.cpp +++ b/misc/benchmarks/various/string_bench_STD.cpp diff --git a/misc/examples/prime.c b/misc/examples/prime.c index 4a3b8498..1a272e78 100644 --- a/misc/examples/prime.c +++ b/misc/examples/prime.c @@ -27,20 +27,19 @@ cbits sieveOfEratosthenes(intptr_t n) int main(void) { intptr_t n = 1000000000; - printf("computing prime numbers up to %" c_ZI "\n", n); + printf("Computing prime numbers up to %" c_ZI "\n", n); clock_t t1 = clock(); c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { - puts("done"); intptr_t np = cbits_count(&primes); clock_t t2 = clock(); - printf("number of primes: %" c_ZI ", time: %f\n", np, (float)(t2 - t1) / (float)CLOCKS_PER_SEC); + printf("Number of primes: %" c_ZI ", time: %f\n\n", np, (float)(t2 - t1) / (float)CLOCKS_PER_SEC); puts("Show all the primes in the range [2, 1000):"); printf("2"); c_forrange (i, 3, 1000, 2) if (cbits_test(&primes, i>>1)) printf(" %lld", i); - puts(""); + puts("\n"); puts("Show the last 50 primes using a temporary crange generator:"); crange R = crange_make(n - 1, 0, -2); @@ -48,7 +47,7 @@ int main(void) , cbits_test(&primes, *i.ref>>1) , c_flt_take(i, 50)) { printf("%lld ", *i.ref); - if (i.count % 10 == 0) puts(""); + if (c_flt_last(i) % 10 == 0) puts(""); } } } diff --git a/misc/examples/sort.c b/misc/examples/sort.c deleted file mode 100644 index 65077143..00000000 --- a/misc/examples/sort.c +++ /dev/null @@ -1,64 +0,0 @@ -#include <time.h> -#include <stdlib.h> -#include <stdio.h> -#include <stc/crandom.h> - -#ifdef __cplusplus - #include <algorithm> - typedef long long csort_elm_value; -#else - #define i_tag elm - #define i_val long long - #include <stc/algo/csort.h> -#endif -#define fmt_Elem "%lld" - - -int testsort(csort_elm_value *a, long size, const char *desc) { - clock_t t = clock(); -#ifdef __cplusplus - printf("std::sort: "); - std::sort(a, a + size); -#else - printf("csort: "); - csort_elm(a, size); -#endif - t = clock() - t; - - printf("%s: %d elements sorted in %.2f ms\n", - desc, (int)size, (float)t*1000.0f/CLOCKS_PER_SEC); - return 0; -} - -int main(int argc, char *argv[]) { - long i, size = argc > 1 ? strtol(argv[1], NULL, 0) : 10000000; - csort_elm_value *a = (csort_elm_value*)c_malloc(c_sizeof(*a) * size); - if (a == NULL) return -1; - - for (i = 0; i < size; i++) - a[i] = crandom() & ((1U << 28) - 1); - - testsort(a, size, "random"); - for (i = 0; i < 20; i++) - printf(" " fmt_Elem, a[i]); - puts(""); - for (i = 1; i < size; i++) - if (a[i - 1] > a[i]) return -1; - - testsort(a, size, "sorted"); - - for (i = 0; i < size; i++) a[i] = size - i; - testsort(a, size, "reverse sorted"); - - for (i = 0; i < size; i++) a[i] = 126735; - testsort(a, size, "constant"); - - for (i = 0; i < size; i++) a[i] = i + 1; - a[size - 1] = 0; - testsort(a, size, "rotated"); - - for (i = 0; i < size; i++) a[i] = i % (size / 8); - testsort(a, size, "repeated"); - - free(a); -} |
