From d623c6c85071b9af5d607bb5d9aceceaea05220a Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 23 Dec 2022 23:55:10 +0100 Subject: Experimental uppercase macros. --- misc/examples/arc_containers.c | 12 +++++------ misc/examples/arc_demo.c | 16 +++++++------- misc/examples/arcvec_erase.c | 10 ++++----- misc/examples/astar.c | 14 ++++++------ misc/examples/birthday.c | 12 +++++------ misc/examples/bits.c | 16 +++++++------- misc/examples/bits2.c | 6 +++--- misc/examples/books.c | 6 +++--- misc/examples/box.c | 10 ++++----- misc/examples/box2.c | 6 +++--- misc/examples/city.c | 16 +++++++------- misc/examples/complex.c | 2 +- misc/examples/convert.c | 20 ++++++++--------- misc/examples/cpque.c | 18 ++++++++-------- misc/examples/csmap_erase.c | 12 +++++------ misc/examples/csmap_find.c | 10 ++++----- misc/examples/csmap_insert.c | 22 +++++++++---------- misc/examples/csset_erase.c | 12 +++++------ misc/examples/cstr_match.c | 2 +- misc/examples/demos.c | 28 ++++++++++++------------ misc/examples/forfilter.c | 48 ++++++++++++++++++++--------------------- misc/examples/forloops.c | 44 ++++++++++++++++++------------------- misc/examples/gauss1.c | 20 ++++++++--------- misc/examples/gauss2.c | 8 +++---- misc/examples/hashmap.c | 4 ++-- misc/examples/inits.c | 26 +++++++++++----------- misc/examples/intrusive.c | 24 ++++++++++----------- misc/examples/list.c | 18 ++++++++-------- misc/examples/list_erase.c | 8 +++---- misc/examples/list_splice.c | 8 +++---- misc/examples/lower_bound.c | 8 +++---- misc/examples/mapmap.c | 8 +++---- misc/examples/mmap.c | 12 +++++------ misc/examples/multimap.c | 12 +++++------ misc/examples/music_arc.c | 30 +++++++++++++------------- misc/examples/new_arr.c | 12 +++++------ misc/examples/new_deq.c | 10 ++++----- misc/examples/new_list.c | 16 +++++++------- misc/examples/new_map.c | 18 ++++++++-------- misc/examples/new_pque.c | 8 +++---- misc/examples/new_queue.c | 6 +++--- misc/examples/new_smap.c | 16 +++++++------- misc/examples/new_sptr.c | 8 +++---- misc/examples/new_vec.c | 10 ++++----- misc/examples/person_arc.c | 12 +++++------ misc/examples/phonebook.c | 12 +++++------ misc/examples/prime.c | 8 +++---- misc/examples/priority.c | 10 ++++----- misc/examples/queue.c | 6 +++--- misc/examples/random.c | 6 +++--- misc/examples/rawptr_elements.c | 18 ++++++++-------- misc/examples/read.c | 8 +++---- misc/examples/regex1.c | 4 ++-- misc/examples/regex2.c | 8 +++---- misc/examples/regex_match.c | 10 ++++----- misc/examples/regex_replace.c | 6 +++--- misc/examples/replace.c | 2 +- misc/examples/shape.c | 18 ++++++++-------- misc/examples/sidebyside.cpp | 6 +++--- misc/examples/sorted_map.c | 12 +++++------ misc/examples/splitstr.c | 10 ++++----- misc/examples/sso_map.c | 4 ++-- misc/examples/sso_substr.c | 2 +- misc/examples/stack.c | 10 ++++----- misc/examples/sview_split.c | 2 +- misc/examples/unordered_set.c | 4 ++-- misc/examples/utf8replace_c.c | 4 ++-- misc/examples/vikings.c | 4 ++-- misc/examples/words.c | 10 ++++----- 69 files changed, 414 insertions(+), 414 deletions(-) (limited to 'misc/examples') diff --git a/misc/examples/arc_containers.c b/misc/examples/arc_containers.c index b577f2c8..026f9eb5 100644 --- a/misc/examples/arc_containers.c +++ b/misc/examples/arc_containers.c @@ -27,8 +27,8 @@ int main() { - c_auto (Stack, stack) - c_auto (List, list) + c_AUTO (Stack, stack) + c_AUTO (List, list) { // POPULATE stack with shared pointers to Maps: Map *map; @@ -64,14 +64,14 @@ int main() puts("STACKS"); - c_foreach (i, Stack, stack) { - c_forpair (name, year, Map, *i.ref->get) + c_FOREACH (i, Stack, stack) { + c_FORPAIR (name, year, Map, *i.ref->get) printf(" %s:%d", cstr_str(_.name), *_.year); puts(""); } puts("LIST"); - c_foreach (i, List, list) { - c_forpair (name, year, Map, *i.ref->get) + c_FOREACH (i, List, list) { + c_FORPAIR (name, year, Map, *i.ref->get) printf(" %s:%d", cstr_str(_.name), *_.year); puts(""); } diff --git a/misc/examples/arc_demo.c b/misc/examples/arc_demo.c index 087f90ac..f1cf3fda 100644 --- a/misc/examples/arc_demo.c +++ b/misc/examples/arc_demo.c @@ -21,19 +21,19 @@ void int_drop(int* x) { int main() { - c_auto (cvec_Arc, vec) // declare and init vec, call cvec_Arc_drop() at scope exit - c_auto (csset_Arc, set) // declare and init set, call csset_Arc_drop() at scope exit + c_AUTO (cvec_Arc, vec) // declare and init vec, call cvec_Arc_drop() at scope exit + c_AUTO (csset_Arc, set) // declare and init set, call csset_Arc_drop() at scope exit { const int years[] = {2021, 2012, 2022, 2015}; - c_forrange (i, c_arraylen(years)) + c_FORRANGE (i, c_ARRAYLEN(years)) cvec_Arc_push(&vec, Arc_from(years[i])); printf("vec:"); - c_foreach (i, cvec_Arc, vec) printf(" %d", *i.ref->get); + c_FOREACH (i, cvec_Arc, vec) printf(" %d", *i.ref->get); puts(""); // add odd numbers from vec to set - c_foreach (i, cvec_Arc, vec) + c_FOREACH (i, cvec_Arc, vec) if (*i.ref->get & 1) csset_Arc_insert(&set, Arc_clone(*i.ref)); // copy shared pointer => increments counter. @@ -42,12 +42,12 @@ int main() cvec_Arc_pop_back(&vec); printf("vec:"); - c_foreach (i, cvec_Arc, vec) printf(" %d", *i.ref->get); + c_FOREACH (i, cvec_Arc, vec) printf(" %d", *i.ref->get); printf("\nset:"); - c_foreach (i, csset_Arc, set) printf(" %d", *i.ref->get); + c_FOREACH (i, csset_Arc, set) printf(" %d", *i.ref->get); - c_with (Arc p = Arc_clone(vec.data[0]), Arc_drop(&p)) { + c_WITH (Arc p = Arc_clone(vec.data[0]), Arc_drop(&p)) { printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); } diff --git a/misc/examples/arcvec_erase.c b/misc/examples/arcvec_erase.c index c70d59d9..eb54084a 100644 --- a/misc/examples/arcvec_erase.c +++ b/misc/examples/arcvec_erase.c @@ -15,9 +15,9 @@ void show_drop(int* x) { printf("drop: %d\n", *x); } int main() { - c_auto (Vec, vec) + c_AUTO (Vec, vec) { - c_forlist (i, int, {2012, 1990, 2012, 2019, 2015}) + c_FORLIST (i, int, {2012, 1990, 2012, 2019, 2015}) Vec_emplace(&vec, *i.ref); // clone the second 2012 and push it back. @@ -25,7 +25,7 @@ int main() Vec_push(&vec, Arc_clone(vec.data[2])); printf("vec before erase :"); - c_foreach (i, Vec, vec) + c_FOREACH (i, Vec, vec) printf(" %d", *i.ref->get); printf("\nerase vec.data[2]; or first matching value depending on compare.\n"); @@ -40,12 +40,12 @@ int main() Vec_erase_at(&vec, it); printf("vec after erase :"); - c_foreach (i, Vec, vec) + c_FOREACH (i, Vec, vec) printf(" %d", *i.ref->get); Vec_sort(&vec); printf("\nvec after sort :"); - c_foreach (i, Vec, vec) + c_FOREACH (i, Vec, vec) printf(" %d", *i.ref->get); puts("\nDone"); diff --git a/misc/examples/astar.c b/misc/examples/astar.c index d4a821f9..e308eb78 100644 --- a/misc/examples/astar.c +++ b/misc/examples/astar.c @@ -80,9 +80,9 @@ astar(cstr* maze, int width) { cdeq_point path = cdeq_point_init(); - c_auto (cpque_point, front) - c_auto (csmap_pstep, from) - c_auto (csmap_pcost, costs) + c_AUTO (cpque_point, front) + c_AUTO (csmap_pstep, from) + c_AUTO (csmap_pcost, costs) { point start = point_from(maze, "@", width); point goal = point_from(maze, "!", width); @@ -99,7 +99,7 @@ astar(cstr* maze, int width) { -1, 0, 0, width }, /* ~ ~ ~ ~ ~ ~ ~ */ { 1, 0, 0, width }, { -1, -1, 0, width }, { 0, -1, 0, width }, { 1, -1, 0, width }, }; - for (size_t i = 0; i < c_arraylen(deltas); i++) + for (size_t i = 0; i < c_ARRAYLEN(deltas); i++) { point delta = deltas[i]; point next = point_init(current.x + delta.x, current.y + delta.y, width); @@ -131,7 +131,7 @@ astar(cstr* maze, int width) int main(void) { - c_with (cstr maze = cstr_lit( + c_WITH (cstr maze = cstr_lit( "#########################################################################\n" "# # # # # # #\n" "# # ######### # ##### ######### ##### ##### ##### # ! #\n" @@ -157,9 +157,9 @@ main(void) "#########################################################################\n"), cstr_drop(&maze)) { int width = cstr_find(&maze, "\n") + 1; - c_with (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) + c_WITH (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) { - c_foreach (it, cdeq_point, path) cstr_data(&maze)[point_index(it.ref)] = 'x'; + c_FOREACH (it, cdeq_point, path) cstr_data(&maze)[point_index(it.ref)] = 'x'; printf("%s", cstr_str(&maze)); } } diff --git a/misc/examples/birthday.c b/misc/examples/birthday.c index 48b8ceaa..be7f0457 100644 --- a/misc/examples/birthday.c +++ b/misc/examples/birthday.c @@ -18,10 +18,10 @@ static void test_repeats(void) printf("birthday paradox: value range: 2^%d, testing repeats of 2^%d values\n", BITS, BITS_TEST); stc64_t rng = stc64_new(seed); - c_auto (cmap_ic, m) + c_AUTO (cmap_ic, m) { cmap_ic_reserve(&m, N); - c_forrange (i, N) { + c_FORRANGE (i, N) { uint64_t k = stc64_rand(&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", @@ -42,17 +42,17 @@ void test_distribution(void) stc64_t rng = stc64_new(seed); const size_t N = 1ull << BITS ; - c_auto (cmap_x, map) { - c_forrange (N) { + c_AUTO (cmap_x, map) { + c_FORRANGE (N) { uint64_t k = stc64_rand(&rng); cmap_x_insert(&map, k & 0xf, 0).ref->second += 1; } uint64_t sum = 0; - c_foreach (i, cmap_x, map) sum += i.ref->second; + c_FOREACH (i, cmap_x, map) sum += i.ref->second; sum /= map.size; - c_foreach (i, cmap_x, map) { + c_FOREACH (i, cmap_x, map) { printf("%4" PRIu32 ": %" PRIu64 " - %" PRIu64 ": %11.8f\n", i.ref->first, i.ref->second, sum, (1 - (double)i.ref->second / sum)); diff --git a/misc/examples/bits.c b/misc/examples/bits.c index 82fd65ec..c50eac6e 100644 --- a/misc/examples/bits.c +++ b/misc/examples/bits.c @@ -3,7 +3,7 @@ int main() { - c_with (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { + c_WITH (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { printf("count %" c_ZU ", %" c_ZU "\n", cbits_count(&set), cbits_size(&set)); cbits s1 = cbits_from("1110100110111"); char buf[256]; @@ -16,7 +16,7 @@ int main() printf(" str: %s\n", cbits_to_str(&set, buf, 0, 255)); printf("%4" c_ZU ": ", cbits_size(&set)); - c_forrange (i, cbits_size(&set)) + c_FORRANGE (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts(""); @@ -26,34 +26,34 @@ int main() cbits_resize(&set, 102, true); cbits_set_value(&set, 99, false); printf("%4" c_ZU ": ", cbits_size(&set)); - c_forrange (i, cbits_size(&set)) + c_FORRANGE (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts("\nIterate:"); printf("%4" c_ZU ": ", cbits_size(&set)); - c_forrange (i, cbits_size(&set)) + c_FORRANGE (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts(""); - c_with (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { + c_WITH (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { cbits_flip_all(&s2); cbits_set(&s2, 16); cbits_set(&s2, 17); cbits_set(&s2, 18); printf(" new: "); - c_forrange (i, cbits_size(&s2)) + c_FORRANGE (i, cbits_size(&s2)) printf("%d", cbits_test(&s2, i)); puts(""); printf(" xor: "); cbits_xor(&set, &s2); - c_forrange (i, cbits_size(&set)) + c_FORRANGE (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts(""); cbits_set_all(&set, false); printf("%4" c_ZU ": ", cbits_size(&set)); - c_forrange (i, cbits_size(&set)) + c_FORRANGE (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); puts(""); } diff --git a/misc/examples/bits2.c b/misc/examples/bits2.c index 59e0b337..502e7268 100644 --- a/misc/examples/bits2.c +++ b/misc/examples/bits2.c @@ -23,19 +23,19 @@ int main() Bits_reset(&s2, 66); Bits_reset(&s2, 67); printf(" s2: "); - c_forrange (i, Bits_size(&s2)) + c_FORRANGE (i, Bits_size(&s2)) printf("%d", Bits_test(&s2, i)); puts(""); printf("xor: "); Bits_xor(&s1, &s2); - c_forrange (i, Bits_size(&s1)) + c_FORRANGE (i, Bits_size(&s1)) printf("%d", Bits_test(&s1, i)); puts(""); printf("all: "); Bits_set_pattern(&s1, 0x3333333333333333); - c_forrange (i, Bits_size(&s1)) + c_FORRANGE (i, Bits_size(&s1)) printf("%d", Bits_test(&s1, i)); puts(""); } diff --git a/misc/examples/books.c b/misc/examples/books.c index b6067d81..96c7ff6e 100644 --- a/misc/examples/books.c +++ b/misc/examples/books.c @@ -8,7 +8,7 @@ // would be `HashMap` in this example). int main() { - c_auto (cmap_str, book_reviews) + c_AUTO (cmap_str, book_reviews) { // Review some books. cmap_str_emplace(&book_reviews, @@ -41,7 +41,7 @@ int main() // Look up the values associated with some keys. const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland"}; - c_forrange (i, c_arraylen(to_find)) { + c_FORRANGE (i, c_ARRAYLEN(to_find)) { const cmap_str_value* b = cmap_str_get(&book_reviews, to_find[i]); if (b) printf("%s: %s\n", cstr_str(&b->first), cstr_str(&b->second)); @@ -53,7 +53,7 @@ int main() printf("Review for Jane: %s\n", cstr_str(cmap_str_at(&book_reviews, "Pride and Prejudice"))); // Iterate over everything. - c_forpair (book, review, cmap_str, book_reviews) { + c_FORPAIR (book, review, cmap_str, book_reviews) { printf("%s: \"%s\"\n", cstr_str(_.book), cstr_str(_.review)); } } diff --git a/misc/examples/box.c b/misc/examples/box.c index da13501f..446a7603 100644 --- a/misc/examples/box.c +++ b/misc/examples/box.c @@ -24,7 +24,7 @@ Person Person_clone(Person p) { void Person_drop(Person* p) { printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); - c_drop(cstr, &p->name, &p->last); + c_DROP(cstr, &p->name, &p->last); } #define i_type PBox @@ -37,8 +37,8 @@ void Person_drop(Person* p) { int main() { - c_auto (Persons, vec) - c_auto (PBox, p, q) + c_AUTO (Persons, vec) + c_AUTO (PBox, p, q) { p = PBox_from(Person_make("Laura", "Palmer")); q = PBox_clone(p); @@ -54,12 +54,12 @@ int main() Persons_push(&vec, PBox_clone(p)); Persons_push(&vec, PBox_clone(q)); - c_foreach (i, Persons, vec) + c_FOREACH (i, Persons, vec) printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); puts(""); // Look-up Audrey! Create a temporary Person for lookup. - c_with (Person a = Person_make("Audrey", "Home"), Person_drop(&a)) { + c_WITH (Person a = Person_make("Audrey", "Home"), Person_drop(&a)) { const PBox *v = Persons_get(&vec, a); // lookup if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); } diff --git a/misc/examples/box2.c b/misc/examples/box2.c index b9628eeb..6281f800 100644 --- a/misc/examples/box2.c +++ b/misc/examples/box2.c @@ -51,9 +51,9 @@ int main(void) { }; // Declare auto-deleted box objects - c_auto (cbox_Rectangle, boxed_rectangle) - c_auto (cbox_Point, boxed_point) - c_auto (cbox_BoxPoint, box_in_a_box, boxbox2) + c_AUTO (cbox_Rectangle, boxed_rectangle) + c_AUTO (cbox_Point, boxed_point) + c_AUTO (cbox_BoxPoint, box_in_a_box, boxbox2) { // Heap allocated rectangle boxed_rectangle = cbox_Rectangle_make((Rectangle){ diff --git a/misc/examples/city.c b/misc/examples/city.c index 8557c6cf..7f355bdf 100644 --- a/misc/examples/city.c +++ b/misc/examples/city.c @@ -44,16 +44,16 @@ City City_clone(City c) { void City_drop(City* c) { printf("drop %s\n", cstr_str(&c->name)); - c_drop(cstr, &c->name, &c->country); + c_DROP(cstr, &c->name, &c->country); } int main(void) { - c_auto (Cities, cities, copy) - c_auto (CityMap, map) + c_AUTO (Cities, cities, copy) + c_AUTO (CityMap, map) { - c_forlist (i, City, { + c_FORLIST (i, City, { {cstr_lit("New York"), cstr_lit("US"), 4.3f, 23.2f, 9000000}, {cstr_lit("Paris"), cstr_lit("France"), 4.3f, 23.2f, 9000000}, {cstr_lit("Berlin"), cstr_lit("Germany"), 4.3f, 23.2f, 9000000}, @@ -63,7 +63,7 @@ int main(void) Cities_sort(&cities); printf("Vec:\n"); - c_foreach (c, Cities, cities) + c_FOREACH (c, Cities, cities) printf("city:%s, %d, use:%ld\n", cstr_str(&c.ref->get->name), c.ref->get->population, CityArc_use_count(c.ref)); @@ -71,19 +71,19 @@ int main(void) copy = Cities_clone(cities); // share each element! int k = 0, id[] = {8, 4, 3, 9, 2, 5}; - c_foreach (i, Cities, cities) + c_FOREACH (i, Cities, cities) CityMap_insert(&map, id[k++], CityArc_clone(*i.ref)); Cities_pop(&cities); Cities_pop(&cities); printf("Vec:\n"); - c_foreach (c, Cities, cities) + c_FOREACH (c, Cities, cities) printf("city:%s, %d, use:%ld\n", cstr_str(&c.ref->get->name), c.ref->get->population, CityArc_use_count(c.ref)); printf("\nMap:\n"); - c_forpair (id, city, CityMap, map) + c_FORPAIR (id, city, CityMap, map) printf("id:%d, city:%s, %d, use:%ld\n", *_.id, cstr_str(&_.city->get->name), _.city->get->population, CityArc_use_count(_.city)); puts(""); diff --git a/misc/examples/complex.c b/misc/examples/complex.c index dd2f951a..6fed1d4d 100644 --- a/misc/examples/complex.c +++ b/misc/examples/complex.c @@ -31,7 +31,7 @@ int main() { - c_auto (MapMap, mmap) + c_AUTO (MapMap, mmap) { FloatStack stack = FloatStack_with_size(10, 0); diff --git a/misc/examples/convert.c b/misc/examples/convert.c index 18be3c81..f2324268 100644 --- a/misc/examples/convert.c +++ b/misc/examples/convert.c @@ -13,38 +13,38 @@ int main() { - c_auto (cmap_str, map, mclone) - c_auto (cvec_str, keys, values) - c_auto (clist_str, list) + c_AUTO (cmap_str, map, mclone) + c_AUTO (cvec_str, keys, values) + c_AUTO (clist_str, list) { - c_forlist (i, cmap_str_raw, { + c_FORLIST (i, cmap_str_raw, { {"green", "#00ff00"}, {"blue", "#0000ff"}, {"yellow", "#ffff00"}, }) cmap_str_emplace(&map, c_PAIR(i.ref)); puts("MAP:"); - c_foreach (i, cmap_str, map) + c_FOREACH (i, cmap_str, map) printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); puts("\nCLONE MAP:"); mclone = cmap_str_clone(map); - c_foreach (i, cmap_str, mclone) + c_FOREACH (i, cmap_str, mclone) printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); puts("\nCOPY MAP TO VECS:"); - c_foreach (i, cmap_str, mclone) { + c_FOREACH (i, cmap_str, mclone) { 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:"); - c_foreach (i, cvec_str, keys) + c_FOREACH (i, cvec_str, keys) clist_str_emplace_back(&list, cstr_str(i.ref)); - c_foreach (i, clist_str, list) + c_FOREACH (i, clist_str, list) printf(" %s\n", cstr_str(i.ref)); } } diff --git a/misc/examples/cpque.c b/misc/examples/cpque.c index 7254b0f7..47080038 100644 --- a/misc/examples/cpque.c +++ b/misc/examples/cpque.c @@ -24,12 +24,12 @@ struct { #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_functor(self, x, y) c_container_of(self, IPQueue, Q)->less(x, y) // <== This. +#define i_less_functor(self, x, y) c_CONTAINER_OF(self, IPQueue, Q)->less(x, y) // <== This. #include #define print(name, q, n) do { \ printf("%s: \t", name); \ - c_forrange (i, n) printf("%d ", q[i]); \ + c_FORRANGE (i, n) printf("%d ", q[i]); \ puts(""); \ } while(0) @@ -50,22 +50,22 @@ static bool int_lambda(const int* x, const int* y) { return (*x ^ 1) < (*y ^ 1); int main() { - const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_arraylen(data); + const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_ARRAYLEN(data); print("data", data, n); - c_autodrop (IPQueue, q1, {ipque_init(), int_less}) // Max priority queue - c_autodrop (IPQueue, minq1, {ipque_init(), int_greater}) // Min priority queue - c_autodrop (IPQueue, q5, {ipque_init(), int_lambda}) // Using lambda to compare elements. + c_AUTODROP (IPQueue, q1, {ipque_init(), int_less}) // Max priority queue + c_AUTODROP (IPQueue, minq1, {ipque_init(), int_greater}) // Min priority queue + c_AUTODROP (IPQueue, q5, {ipque_init(), int_lambda}) // Using lambda to compare elements. { - c_forrange (i, n) + c_FORRANGE (i, n) ipque_push(&q1.Q, data[i]); print_queue("q1", q1); - c_forrange (i, n) + c_FORRANGE (i, n) ipque_push(&minq1.Q, data[i]); print_queue("minq1", minq1); - c_forrange (i, n) + c_FORRANGE (i, n) ipque_push(&q5.Q, data[i]); print_queue("q5", q5); } diff --git a/misc/examples/csmap_erase.c b/misc/examples/csmap_erase.c index 48d8ceef..bef00a17 100644 --- a/misc/examples/csmap_erase.c +++ b/misc/examples/csmap_erase.c @@ -10,14 +10,14 @@ void printmap(mymap m) { - c_foreach (elem, mymap, m) + c_FOREACH (elem, mymap, m) printf(" [%d, %s]", elem.ref->first, cstr_str(&elem.ref->second)); printf("\nsize() == %" c_ZU "\n\n", mymap_size(&m)); } int main() { - c_auto (mymap, m1) + c_AUTO (mymap, m1) { // Fill in some data to test with, one at a time mymap_insert(&m1, 1, cstr_lit("A")); @@ -34,10 +34,10 @@ int main() printmap(m1); } - c_auto (mymap, m2) + c_AUTO (mymap, m2) { // Fill in some data to test with, one at a time - c_forlist (i, mymap_raw, { + c_FORLIST (i, mymap_raw, { {10, "Bob"}, {11, "Rob"}, {12, "Robert"}, @@ -51,7 +51,7 @@ int main() mymap_iter it2 = mymap_find(&m2, mymap_back(&m2)->first); puts("to remove:"); - c_foreach (i, mymap, it1, it2) + c_FOREACH (i, mymap, it1, it2) printf(" [%d, %s]", i.ref->first, cstr_str(&i.ref->second)); puts(""); // The 2nd member function removes elements @@ -61,7 +61,7 @@ int main() printmap(m2); } - c_auto (mymap, m3) + c_AUTO (mymap, m3) { // Fill in some data to test with, one at a time, using emplace mymap_emplace(&m3, 1, "red"); diff --git a/misc/examples/csmap_find.c b/misc/examples/csmap_find.c index 3c507476..a61a47be 100644 --- a/misc/examples/csmap_find.c +++ b/misc/examples/csmap_find.c @@ -20,7 +20,7 @@ void print_elem(csmap_istr_raw p) { void print_collection_##CX(const CX* t) { \ printf("%" c_ZU " elements: ", CX##_size(t)); \ \ - c_foreach (p, CX, *t) { \ + c_FOREACH (p, CX, *t) { \ print_elem(CX##_value_toraw(p.ref)); \ } \ puts(""); \ @@ -42,10 +42,10 @@ void findit(csmap_istr c, csmap_istr_key val) int main() { - c_auto (csmap_istr, m1) - c_auto (cvec_istr, v) + c_AUTO (csmap_istr, m1) + c_AUTO (cvec_istr, v) { - c_forlist (i, csmap_istr_raw, {{40, "Zr"}, {45, "Rh"}}) + c_FORLIST (i, csmap_istr_raw, {{40, "Zr"}, {45, "Rh"}}) csmap_istr_emplace(&m1, c_PAIR(i.ref)); puts("The starting map m1 is (key, value):"); @@ -62,7 +62,7 @@ int main() puts("Inserting the following vector data into m1:"); print_collection_cvec_istr(&v); - c_foreach (i, cvec_istr, cvec_istr_begin(&v), cvec_istr_end(&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):"); diff --git a/misc/examples/csmap_insert.c b/misc/examples/csmap_insert.c index 8f777fc6..b1b0a5be 100644 --- a/misc/examples/csmap_insert.c +++ b/misc/examples/csmap_insert.c @@ -19,13 +19,13 @@ #include void print_ii(csmap_ii map) { - c_foreach (e, csmap_ii, map) + c_FOREACH (e, csmap_ii, map) printf("(%d, %d) ", e.ref->first, e.ref->second); puts(""); } void print_istr(csmap_istr map) { - c_foreach (e, csmap_istr, map) + c_FOREACH (e, csmap_istr, map) printf("(%d, %s) ", e.ref->first, cstr_str(&e.ref->second)); puts(""); } @@ -33,7 +33,7 @@ void print_istr(csmap_istr map) { int main() { // insert single values - c_auto (csmap_ii, m1) { + c_AUTO (csmap_ii, m1) { csmap_ii_insert(&m1, 1, 10); csmap_ii_insert(&m1, 2, 20); @@ -60,8 +60,8 @@ int main() } // The templatized version inserting a jumbled range - c_auto (csmap_ii, m2) - c_auto (cvec_ii, v) { + c_AUTO (csmap_ii, m2) + c_AUTO (cvec_ii, v) { typedef cvec_ii_value ipair; cvec_ii_push(&v, (ipair){43, 294}); cvec_ii_push(&v, (ipair){41, 262}); @@ -70,21 +70,21 @@ int main() cvec_ii_push(&v, (ipair){44, 311}); puts("Inserting the following vector data into m2:"); - c_foreach (e, cvec_ii, v) + c_FOREACH (e, cvec_ii, v) printf("(%d, %d) ", e.ref->first, e.ref->second); puts(""); - c_foreach (e, cvec_ii, v) + c_FOREACH (e, cvec_ii, v) csmap_ii_insert_or_assign(&m2, e.ref->first, e.ref->second); puts("The modified key and mapped values of m2 are:"); - c_foreach (e, csmap_ii, m2) + c_FOREACH (e, csmap_ii, m2) printf("(%d, %d) ", e.ref->first, e.ref->second); puts("\n"); } // The templatized versions move-constructing elements - c_auto (csmap_istr, m3) { + c_AUTO (csmap_istr, m3) { csmap_istr_value ip1 = {475, cstr_lit("blue")}, ip2 = {510, cstr_lit("green")}; // single element @@ -99,9 +99,9 @@ int main() puts(""); } - c_auto (csmap_ii, m4) { + c_AUTO (csmap_ii, m4) { // Insert the elements from an initializer_list - c_forlist (i, csmap_ii_raw, {{ 4, 44 }, { 2, 22 }, { 3, 33 }, + c_FORLIST (i, csmap_ii_raw, {{ 4, 44 }, { 2, 22 }, { 3, 33 }, { 1, 11 }, { 5, 55 }}) csmap_ii_insert(&m4, c_PAIR(i.ref)); diff --git a/misc/examples/csset_erase.c b/misc/examples/csset_erase.c index 33eb2163..c281c626 100644 --- a/misc/examples/csset_erase.c +++ b/misc/examples/csset_erase.c @@ -5,12 +5,12 @@ int main() { - c_auto (csset_int, set) + c_AUTO (csset_int, set) { - c_forlist (i, int, {30, 20, 80, 40, 60, 90, 10, 70, 50}) + c_FORLIST (i, int, {30, 20, 80, 40, 60, 90, 10, 70, 50}) csset_int_insert(&set, *i.ref); - c_foreach (k, csset_int, set) + c_FOREACH (k, csset_int, set) printf(" %d", *k.ref); puts(""); @@ -19,7 +19,7 @@ int main() printf("Show values >= %d:\n", val); it = csset_int_lower_bound(&set, val); - c_foreach (k, csset_int, it, csset_int_end(&set)) + c_FOREACH (k, csset_int, it, csset_int_end(&set)) printf(" %d", *k.ref); puts(""); @@ -27,7 +27,7 @@ int main() while (it.ref != csset_int_end(&set).ref) it = csset_int_erase_at(&set, it); - c_foreach (k, csset_int, set) + c_FOREACH (k, csset_int, set) printf(" %d", *k.ref); puts(""); @@ -36,7 +36,7 @@ int main() it = csset_int_lower_bound(&set, val); csset_int_erase_range(&set, csset_int_begin(&set), it); - c_foreach (k, csset_int, set) + c_FOREACH (k, csset_int, set) printf(" %d", *k.ref); puts(""); } diff --git a/misc/examples/cstr_match.c b/misc/examples/cstr_match.c index 286ba505..116e5dd4 100644 --- a/misc/examples/cstr_match.c +++ b/misc/examples/cstr_match.c @@ -4,7 +4,7 @@ int main() { - c_with (cstr ss = cstr_lit("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { + c_WITH (cstr ss = cstr_lit("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { size_t pos = cstr_find_at(&ss, 0, "brown"); printf("%" c_ZU " [%s]\n", pos, pos == c_NPOS ? "" : cstr_str(&ss) + pos); printf("equals: %d\n", cstr_equals(&ss, "The quick brown fox jumps over the lazy dog.JPG")); diff --git a/misc/examples/demos.c b/misc/examples/demos.c index fc3771cb..b077aa73 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -3,7 +3,7 @@ void stringdemo1() { printf("\nSTRINGDEMO1\n"); - c_with (cstr cs = cstr_lit("one-nine-three-seven-five"), cstr_drop(&cs)) + c_WITH (cstr cs = cstr_lit("one-nine-three-seven-five"), cstr_drop(&cs)) { printf("%s.\n", cstr_str(&cs)); @@ -35,7 +35,7 @@ void stringdemo1() void vectordemo1() { printf("\nVECTORDEMO1\n"); - c_with (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) + c_WITH (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) { cvec_ix_reserve(&bignums, 100); for (size_t i = 10; i <= 100; i += 10) @@ -59,7 +59,7 @@ void vectordemo1() void vectordemo2() { printf("\nVECTORDEMO2\n"); - c_auto (cvec_str, names) { + c_AUTO (cvec_str, names) { cvec_str_emplace_back(&names, "Mary"); cvec_str_emplace_back(&names, "Joe"); cvec_str_emplace_back(&names, "Chris"); @@ -67,7 +67,7 @@ void vectordemo2() printf("names[1]: %s\n", cstr_str(&names.data[1])); cvec_str_sort(&names); // Sort the array - c_foreach (i, cvec_str, names) + c_FOREACH (i, cvec_str, names) printf("sorted: %s\n", cstr_str(i.ref)); } } @@ -80,7 +80,7 @@ void vectordemo2() void listdemo1() { printf("\nLISTDEMO1\n"); - c_auto (clist_ix, nums, nums2) + c_AUTO (clist_ix, nums, nums2) { for (int i = 0; i < 10; ++i) clist_ix_push_back(&nums, i); @@ -89,7 +89,7 @@ void listdemo1() /* splice nums2 to front of nums */ clist_ix_splice(&nums, clist_ix_begin(&nums), &nums2); - c_foreach (i, clist_ix, nums) + c_FOREACH (i, clist_ix, nums) printf("spliced: %d\n", *i.ref); puts(""); @@ -101,7 +101,7 @@ void listdemo1() clist_ix_push_back(&nums, -99); clist_ix_sort(&nums); - c_foreach (i, clist_ix, nums) + c_FOREACH (i, clist_ix, nums) printf("sorted: %d\n", *i.ref); } } @@ -117,7 +117,7 @@ void setdemo1() cset_i_insert(&nums, 8); cset_i_insert(&nums, 11); - c_foreach (i, cset_i, nums) + c_FOREACH (i, cset_i, nums) printf("set: %d\n", *i.ref); cset_i_drop(&nums); } @@ -145,7 +145,7 @@ void mapdemo1() void mapdemo2() { printf("\nMAPDEMO2\n"); - c_auto (cmap_si, nums) + c_AUTO (cmap_si, nums) { cmap_si_emplace_or_assign(&nums, "Hello", 64); cmap_si_emplace_or_assign(&nums, "Groovy", 121); @@ -156,7 +156,7 @@ void mapdemo2() printf("long: %s: %d\n", cstr_str(&i.ref->first), i.ref->second); // or rather use the short form: - c_foreach (i, cmap_si, nums) + c_FOREACH (i, cmap_si, nums) printf("short: %s: %d\n", cstr_str(&i.ref->first), i.ref->second); } } @@ -173,14 +173,14 @@ void mapdemo3() cmap_str_emplace(&table, "Make", "my"); cmap_str_emplace(&table, "Sunny", "day"); cmap_str_iter it = cmap_str_find(&table, "Make"); - c_foreach (i, cmap_str, table) + c_FOREACH (i, cmap_str, table) printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); printf("size %" c_ZU ": 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 %" c_ZU "\n", cmap_str_size(&table)); - c_foreach (i, cmap_str, 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. } @@ -192,7 +192,7 @@ void mapdemo3() void arraydemo1() { printf("\nARRAYDEMO1\n"); - c_with (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), + c_WITH (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 10.2f; @@ -207,7 +207,7 @@ void arraydemo1() printf("%g\n", arr3.data[5][4][3]); // = 10.2 float x = 0.0; - c_foreach (i, carr3_f, arr3) + c_FOREACH (i, carr3_f, arr3) *i.ref = ++x; printf("%g\n", arr3.data[29][19][9]); // = 6000 } diff --git a/misc/examples/forfilter.c b/misc/examples/forfilter.c index ba4dce7f..32154904 100644 --- a/misc/examples/forfilter.c +++ b/misc/examples/forfilter.c @@ -20,23 +20,23 @@ void demo1(void) { - c_auto (IVec, vec) { - c_forlist (i, int, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, 10, 11, 12, 13, 14, 15, 80, 16, 17}) + c_AUTO (IVec, vec) { + c_FORLIST (i, int, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, 10, 11, 12, 13, 14, 15, 80, 16, 17}) IVec_push(&vec, *i.ref); puts("demo1:"); - c_forfilter (i, IVec, vec, flt_skipValue(i, 80)) + c_FORFILTER (i, IVec, vec, flt_skipValue(i, 80)) printf(" %d", *i.ref); puts(""); int res, sum = 0; - c_forfilter (i, IVec, vec - , c_flt_skipwhile(i, *i.ref != 80) - && c_flt_skip(i, 1) - && c_flt_skipwhile(i, *i.ref != 80) + c_FORFILTER (i, IVec, vec + , c_FLT_SKIPWHILE(i, *i.ref != 80) + && c_FLT_SKIP(i, 1) + && c_FLT_SKIPWHILE(i, *i.ref != 80) && flt_isEven(i) && flt_skipValue(i, 80) - , c_flt_take(i, 5) // short-circuit + , c_FLT_TAKE(i, 5) // short-circuit ){ sum += res = flt_square(i); printf(" %d", res); @@ -60,15 +60,15 @@ fn main() { void demo2(void) { - c_auto (IVec, vector) { + c_AUTO (IVec, vector) { puts("demo2:"); - c_forfilter (x, crange, crange_literal(INT64_MAX) - , c_flt_skipwhile(x, *x.ref != 11) + c_FORFILTER (x, crange, crange_literal(INT64_MAX) + , c_FLT_SKIPWHILE(x, *x.ref != 11) && *x.ref % 2 != 0 - , c_flt_take(x, 5)) + , c_FLT_TAKE(x, 5)) IVec_push(&vector, *x.ref * *x.ref); - c_foreach (x, IVec, vector) printf(" %d", *x.ref); + c_FOREACH (x, IVec, vector) printf(" %d", *x.ref); puts(""); } } @@ -88,17 +88,17 @@ fn main() { */ void demo3(void) { - c_auto (SVec, words, words_containing_i) { + c_AUTO (SVec, words, words_containing_i) { const char* sentence = "This is a sentence in C99."; - c_fortoken (w, sentence, " ") + c_FORTOKEN (w, sentence, " ") SVec_push(&words, *w.ref); - c_forfilter (w, SVec, words, + c_FORFILTER (w, SVec, words, csview_contains(*w.ref, "i")) SVec_push(&words_containing_i, *w.ref); puts("demo3:"); - c_foreach (w, SVec, words_containing_i) + c_FOREACH (w, SVec, words_containing_i) printf(" %.*s", c_ARGSV(*w.ref)); puts(""); } @@ -107,8 +107,8 @@ void demo3(void) void demo4(void) { csview s = c_SV("ab123cReAghNGnΩoEp"); // Ω = multi-byte - c_auto (cstr, out) { - c_forfilter (i, csview, s, utf8_isupper(utf8_peek(i.ref))) { + c_AUTO (cstr, out) { + c_FORFILTER (i, csview, s, utf8_isupper(utf8_peek(i.ref))) { char chr[4]; utf8_encode(chr, utf8_tolower(utf8_peek(i.ref))); cstr_push(&out, chr); @@ -124,12 +124,12 @@ void demo5(void) #define flt_mid_decade(i) ((*i.ref % 10) != 0) puts("demo5:"); crange r1 = crange_make(1963, INT32_MAX); - c_forfilter (i, crange, r1 - , c_flt_skip(i,15) - && c_flt_skipwhile(i, flt_mid_decade(i)) - && c_flt_skip(i,30) + c_FORFILTER (i, crange, r1 + , c_FLT_SKIP(i,15) + && c_FLT_SKIPWHILE(i, flt_mid_decade(i)) + && c_FLT_SKIP(i,30) && flt_even(i) - , c_flt_take(i,10)) + , c_FLT_TAKE(i,10)) printf(" %lld", *i.ref); puts(""); } diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c index 2654f095..95a955a3 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/forloops.c @@ -13,67 +13,67 @@ int main() { - puts("c_forrange:"); - c_forrange (30) printf(" xx"); + puts("c_FORRANGE:"); + c_FORRANGE (30) printf(" xx"); puts(""); - c_forrange (i, 30) printf(" %lld", i); + c_FORRANGE (i, 30) printf(" %lld", i); puts(""); - c_forrange (i, 30, 60) printf(" %lld", i); + c_FORRANGE (i, 30, 60) printf(" %lld", i); puts(""); - c_forrange (i, 30, 90, 2) printf(" %lld", i); + c_FORRANGE (i, 30, 90, 2) printf(" %lld", i); puts("\n\nc_forlist:"); - c_forlist (i, int, {12, 23, 453, 65, 676}) + c_FORLIST (i, int, {12, 23, 453, 65, 676}) printf(" %d", *i.ref); puts(""); - c_forlist (i, const char*, {"12", "23", "453", "65", "676"}) + c_FORLIST (i, const char*, {"12", "23", "453", "65", "676"}) printf(" %s", *i.ref); puts(""); - c_forlist (i, const char*, {"12", "23", "453", "65", "676"}) + c_FORLIST (i, const char*, {"12", "23", "453", "65", "676"}) printf(" %s", i.data[i.size - 1 - i.index]); - c_auto (IVec, vec) - c_auto (IMap, map) + c_AUTO (IVec, vec) + c_AUTO (IMap, map) { - c_forlist (i, int, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199}) + c_FORLIST (i, int, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199}) IVec_push(&vec, *i.ref); - c_forlist (i, IMap_value, {{12, 23}, {453, 65}, {676, 123}, {34, 67}}) + c_FORLIST (i, IMap_value, {{12, 23}, {453, 65}, {676, 123}, {34, 67}}) IMap_push(&map, *i.ref); puts("\n\nc_foreach:"); - c_foreach (i, IVec, vec) + c_FOREACH (i, IVec, vec) printf(" %d", *i.ref); puts(""); - c_foreach (i, IMap, map) + c_FOREACH (i, IMap, map) printf(" (%d %d)", i.ref->first, i.ref->second); puts("\n\nc_forpair:"); - c_forpair (key, val, IMap, map) + c_FORPAIR (key, val, IMap, map) printf(" (%d %d)", *_.key, *_.val); puts("\n\nc_forwhile:"); - c_forwhile (i, IVec, IVec_begin(&vec), i.index < 3) + c_FORWHILE (i, IVec, IVec_begin(&vec), i.index < 3) printf(" %d", *i.ref); #define isOdd(i) (*i.ref & 1) puts("\n\nc_forfilter:"); - c_forfilter (i, IVec, vec - , c_flt_skipwhile(i, *i.ref != 65) - && c_flt_takewhile(i, *i.ref != 280) - && c_flt_skipwhile(i, isOdd(i)) + c_FORFILTER (i, IVec, vec + , c_FLT_SKIPWHILE(i, *i.ref != 65) + && c_FLT_TAKEWHILE(i, *i.ref != 280) + && c_FLT_SKIPWHILE(i, isOdd(i)) && isOdd(i) - && c_flt_skip(i, 2) - , c_flt_take(i, 1)) + && c_FLT_SKIP(i, 2) + , c_FLT_TAKE(i, 1)) printf(" %d", *i.ref); puts(""); // 189 diff --git a/misc/examples/gauss1.c b/misc/examples/gauss1.c index 675ff338..519a7895 100644 --- a/misc/examples/gauss1.c +++ b/misc/examples/gauss1.c @@ -29,27 +29,27 @@ int main() stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); // Create and init histogram vec and map with defered destructors: - c_auto (cvec_ii, histvec) - c_auto (cmap_ii, histmap) + c_AUTO (cvec_ii, histvec) + c_AUTO (cmap_ii, histmap) { - c_forrange (N) { - int index = (int) round( stc64_normalf(&rng, &dist) ); + c_FORRANGE (N) { + int index = (int)round( stc64_normalf(&rng, &dist) ); cmap_ii_insert(&histmap, index, 0).ref->second += 1; } // Transfer map to vec and sort it by map keys. - c_foreach (i, cmap_ii, histmap) + c_FOREACH (i, cmap_ii, histmap) cvec_ii_push(&histvec, (cmap_ii_value){i.ref->first, i.ref->second}); cvec_ii_sort(&histvec); // Print the gaussian bar chart - c_auto (cstr, bar) - c_foreach (i, cvec_ii, histvec) { - size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); + c_FOREACH (i, cvec_ii, histvec) { + int n = (int)(i.ref->second * StdDev * Scale * 2.5 / N); if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", i.ref->first, cstr_str(&bar)); + printf("%4d ", i.ref->first); + c_FORRANGE (n) printf("*"); + puts(""); } } } diff --git a/misc/examples/gauss2.c b/misc/examples/gauss2.c index 2e07c5a5..c2ed2e00 100644 --- a/misc/examples/gauss2.c +++ b/misc/examples/gauss2.c @@ -23,16 +23,16 @@ int main() stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); // Create and init histogram map with defered destruct - c_auto (csmap_int, mhist) + c_AUTO (csmap_int, mhist) { - c_forrange (N) { + c_FORRANGE (N) { int index = (int) round( stc64_normalf(&rng, &dist) ); csmap_int_insert(&mhist, index, 0).ref->second += 1; } // Print the gaussian bar chart - c_auto (cstr, bar) - c_forpair (index, count, csmap_int, mhist) { + c_AUTO (cstr, bar) + c_FORPAIR (index, count, csmap_int, mhist) { size_t n = (size_t) (*_.count * StdDev * Scale * 2.5 / (float)N); if (n > 0) { cstr_resize(&bar, n, '*'); diff --git a/misc/examples/hashmap.c b/misc/examples/hashmap.c index f59ed824..bc4f2566 100644 --- a/misc/examples/hashmap.c +++ b/misc/examples/hashmap.c @@ -17,7 +17,7 @@ const char* call(const char* number) { } int main(void) { - c_auto (cmap_str, contacts) + c_AUTO (cmap_str, contacts) { cmap_str_emplace(&contacts, "Daniel", "798-1364"); cmap_str_emplace(&contacts, "Ashley", "645-7689"); @@ -40,7 +40,7 @@ int main(void) { cmap_str_erase(&contacts, "Ashley"); puts(""); - c_forpair (contact, number, cmap_str, contacts) { + c_FORPAIR (contact, number, cmap_str, contacts) { printf("Calling %s: %s\n", cstr_str(_.contact), call(cstr_str(_.number))); } puts(""); diff --git a/misc/examples/inits.c b/misc/examples/inits.c index 021a3e0a..459a0ec1 100644 --- a/misc/examples/inits.c +++ b/misc/examples/inits.c @@ -36,11 +36,11 @@ int main(void) { // CVEC FLOAT / PRIORITY QUEUE - c_auto (cpque_f, floats) { + c_AUTO (cpque_f, floats) { const float nums[] = {4.0f, 2.0f, 5.0f, 3.0f, 1.0f}; // PRIORITY QUEUE - c_forrange (i, c_arraylen(nums)) + c_FORRANGE (i, c_ARRAYLEN(nums)) cpque_f_push(&floats, nums[i]); puts("\npop and show high priorites first:"); @@ -54,20 +54,20 @@ int main(void) // CMAP ID int year = 2020; - c_auto (cmap_id, idnames) { + c_AUTO (cmap_id, idnames) { cmap_id_emplace(&idnames, 100, "Hello"); cmap_id_insert(&idnames, 110, cstr_lit("World")); cmap_id_insert(&idnames, 120, cstr_from_fmt("Howdy, -%d-", year)); - c_foreach (i, cmap_id, idnames) + c_FOREACH (i, cmap_id, idnames) printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second)); puts(""); } // CMAP CNT - c_auto (cmap_cnt, countries) { - c_forlist (i, cmap_cnt_raw, { + c_AUTO (cmap_cnt, countries) { + c_FORLIST (i, cmap_cnt_raw, { {"Norway", 100}, {"Denmark", 50}, {"Iceland", 10}, @@ -83,33 +83,33 @@ int main(void) cmap_cnt_emplace(&countries, "Norway", 0).ref->second += 20; cmap_cnt_emplace(&countries, "Finland", 0).ref->second += 20; - c_forpair (country, health, cmap_cnt, countries) + c_FORPAIR (country, health, cmap_cnt, countries) printf("%s: %d\n", cstr_str(_.country), *_.health); puts(""); } // CVEC PAIR - c_auto (cvec_ip, pairs1) { - c_forlist (i, ipair_t, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}) + c_AUTO (cvec_ip, pairs1) { + c_FORLIST (i, ipair_t, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}) cvec_ip_push_back(&pairs1, *i.ref); cvec_ip_sort(&pairs1); - c_foreach (i, cvec_ip, pairs1) + c_FOREACH (i, cvec_ip, pairs1) printf("(%d %d) ", i.ref->x, i.ref->y); puts(""); } // CLIST PAIR - c_auto (clist_ip, pairs2) { - c_forlist (i, ipair_t, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}) + c_AUTO (clist_ip, pairs2) { + c_FORLIST (i, ipair_t, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}) clist_ip_push_back(&pairs2, *i.ref); clist_ip_sort(&pairs2); - c_foreach (i, clist_ip, pairs2) + c_FOREACH (i, clist_ip, pairs2) printf("(%d %d) ", i.ref->x, i.ref->y); puts(""); } diff --git a/misc/examples/intrusive.c b/misc/examples/intrusive.c index acf4416d..4135317e 100644 --- a/misc/examples/intrusive.c +++ b/misc/examples/intrusive.c @@ -1,4 +1,4 @@ -// Example of intrusive list by using the node API and typesafe c_container_of(). +// Example of intrusive list by using the node API and typesafe c_CONTAINER_OF(). #include @@ -14,39 +14,39 @@ int main() { - c_auto (List2, list2) + c_AUTO (List2, list2) { List1 list1 = List1_init(); // should not be destroyed, list2 will destroy shared nodes. - c_forlist (i, int, {6, 9, 3, 1, 7, 4, 5, 2, 8}) + c_FORLIST (i, int, {6, 9, 3, 1, 7, 4, 5, 2, 8}) List2_push_back(&list2, (List1_node){NULL, *i.ref}); - c_foreach (i, List2, list2) - List1_push_node_back(&list1, c_container_of(&i.ref->value, List1_node, value)); + c_FOREACH (i, List2, list2) + List1_push_node_back(&list1, c_CONTAINER_OF(&i.ref->value, List1_node, value)); printf("list1:"); - c_foreach (i, List1, list1) printf(" %d", *i.ref); + c_FOREACH (i, List1, list1) printf(" %d", *i.ref); printf("\nlist2:"); - c_foreach (i, List2, list2) printf(" %d", i.ref->value); + c_FOREACH (i, List2, list2) printf(" %d", i.ref->value); printf("\nsort list1"); List1_sort(&list1); printf("\nlist1:"); - c_foreach (i, List1, list1) printf(" %d", *i.ref); + c_FOREACH (i, List1, list1) printf(" %d", *i.ref); printf("\nlist2:"); - c_foreach (i, List2, list2) printf(" %d", i.ref->value); + c_FOREACH (i, List2, list2) printf(" %d", i.ref->value); printf("\nremove 5 from both lists in O(1) time"); List1_iter it1 = List1_find(&list1, 5); if (it1.ref) { List1_unlink_node_after(&list1, it1.prev); - free(List2_unlink_node_after(&list2, c_container_of(it1.prev, List2_node, value))); + free(List2_unlink_node_after(&list2, c_CONTAINER_OF(it1.prev, List2_node, value))); } printf("\nlist1:"); - c_foreach (i, List1, list1) printf(" %d", *i.ref); + c_FOREACH (i, List1, list1) printf(" %d", *i.ref); printf("\nlist2:"); - c_foreach (i, List2, list2) printf(" %d", i.ref->value); + c_FOREACH (i, List2, list2) printf(" %d", i.ref->value); puts(""); } } diff --git a/misc/examples/list.c b/misc/examples/list.c index a538d93c..4aacfe38 100644 --- a/misc/examples/list.c +++ b/misc/examples/list.c @@ -12,37 +12,37 @@ int main() { const int n = 2000000; - c_auto (clist_fx, list) + c_AUTO (clist_fx, list) { stc64_t rng = stc64_new(1234); stc64_uniformf_t dist = stc64_uniformf_new(100.0f, n); int m = 0; - c_forrange (n) + c_FORRANGE (n) clist_fx_push_back(&list, stc64_uniformf(&rng, &dist)), ++m; double sum = 0.0; printf("sumarize %d:\n", m); - c_foreach (i, clist_fx, list) + c_FOREACH (i, clist_fx, list) sum += *i.ref; printf("sum %f\n\n", sum); - c_forwhile (i, clist_fx, clist_fx_begin(&list), i.index < 10) + c_FORWHILE (i, clist_fx, clist_fx_begin(&list), i.index < 10) printf("%8d: %10f\n", (int)i.index, *i.ref); puts("sort"); clist_fx_sort(&list); // mergesort O(n*log n) puts("sorted"); - c_forwhile (i, clist_fx, clist_fx_begin(&list), i.index < 10) + c_FORWHILE (i, clist_fx, clist_fx_begin(&list), i.index < 10) printf("%8d: %10f\n", (int)i.index, *i.ref); puts(""); clist_fx_clear(&list); - c_forlist (i, int, {10, 20, 30, 40, 30, 50}) + c_FORLIST (i, int, {10, 20, 30, 40, 30, 50}) clist_fx_push_back(&list, *i.ref); const double* v = clist_fx_get(&list, 30); printf("found: %f\n", *v); - c_foreach (i, clist_fx, list) printf(" %g", *i.ref); + c_FOREACH (i, clist_fx, list) printf(" %g", *i.ref); puts(""); clist_fx_remove(&list, 30); @@ -51,10 +51,10 @@ int main() { clist_fx_push_front(&list, 1964); clist_fx_iter it = clist_fx_begin(&list); printf("Full: "); - c_foreach (i, clist_fx, list) + c_FOREACH (i, clist_fx, list) printf(" %g", *i.ref); printf("\nSubs: "); - c_foreach (i, clist_fx, clist_fx_advance(it, 4), clist_fx_end(&list)) + c_FOREACH (i, clist_fx, clist_fx_advance(it, 4), clist_fx_end(&list)) printf(" %g", *i.ref); puts(""); } diff --git a/misc/examples/list_erase.c b/misc/examples/list_erase.c index c1a2aa97..18ad0d16 100644 --- a/misc/examples/list_erase.c +++ b/misc/examples/list_erase.c @@ -7,12 +7,12 @@ int main () { - c_with (IList L = IList_init(), IList_drop(&L)) + c_WITH (IList L = IList_init(), IList_drop(&L)) { - c_forlist (i, int, {10, 20, 30, 40, 50}) + c_FORLIST (i, int, {10, 20, 30, 40, 50}) IList_push(&L, *i.ref); - c_foreach (x, IList, L) + c_FOREACH (x, IList, L) printf("%d ", *x.ref); puts(""); // 10 20 30 40 50 @@ -25,7 +25,7 @@ int main () it = IList_erase_range(&L, it, end); // 10 30 // ^ printf("list contains:"); - c_foreach (x, IList, L) + c_FOREACH (x, IList, L) printf(" %d", *x.ref); puts(""); } diff --git a/misc/examples/list_splice.c b/misc/examples/list_splice.c index f7bac0d6..8a5dae76 100644 --- a/misc/examples/list_splice.c +++ b/misc/examples/list_splice.c @@ -8,7 +8,7 @@ void print_ilist(const char* s, clist_i list) { printf("%s", s); - c_foreach (i, clist_i, list) { + c_FOREACH (i, clist_i, list) { printf(" %d", *i.ref); } puts(""); @@ -16,12 +16,12 @@ void print_ilist(const char* s, clist_i list) int main () { - c_auto (clist_i, list1, list2) + c_AUTO (clist_i, list1, list2) { - c_forlist (i, int, {1, 2, 3, 4, 5}) + c_FORLIST (i, int, {1, 2, 3, 4, 5}) clist_i_push_back(&list1, *i.ref); - c_forlist (i, int, {10, 20, 30, 40, 50}) + c_FORLIST (i, int, {10, 20, 30, 40, 50}) clist_i_push_back(&list2, *i.ref); print_ilist("list1:", list1); diff --git a/misc/examples/lower_bound.c b/misc/examples/lower_bound.c index 2477bc14..2b6f3cc6 100644 --- a/misc/examples/lower_bound.c +++ b/misc/examples/lower_bound.c @@ -9,11 +9,11 @@ int main() { // TEST SORTED VECTOR - c_auto (cvec_int, vec) + c_AUTO (cvec_int, vec) { int key, *res; - c_forlist (i, int, {40, 600, 1, 7000, 2, 500, 30}) + c_FORLIST (i, int, {40, 600, 1, 7000, 2, 500, 30}) cvec_int_push(&vec, *i.ref); cvec_int_sort(&vec); @@ -36,11 +36,11 @@ int main() } // TEST SORTED SET - c_auto (csset_int, set) + c_AUTO (csset_int, set) { int key, *res; - c_forlist (i, int, {40, 600, 1, 7000, 2, 500, 30}) + c_FORLIST (i, int, {40, 600, 1, 7000, 2, 500, 30}) csset_int_push(&set, *i.ref); key = 500; diff --git a/misc/examples/mapmap.c b/misc/examples/mapmap.c index 488cc539..c361233b 100644 --- a/misc/examples/mapmap.c +++ b/misc/examples/mapmap.c @@ -30,7 +30,7 @@ void add(Departments* deps, const char* name, const char* email, const char* dep int contains(Departments* map, const char* name) { int count = 0; - c_foreach (i, Departments, *map) + c_FOREACH (i, Departments, *map) if (People_contains(&i.ref->second, name)) ++count; return count; @@ -38,7 +38,7 @@ int contains(Departments* map, const char* name) int main(void) { - c_auto (Departments, map) + c_AUTO (Departments, map) { add(&map, "Anna Kendro", "Anna@myplace.com", "Support"); add(&map, "Terry Dane", "Terry@myplace.com", "Development"); @@ -54,8 +54,8 @@ int main(void) add(&map, "Dennis Kay", "Dennis@mail.com", "Marketing"); add(&map, "Anne Dickens", "Anne@myplace.com", "Development"); - c_foreach (i, Departments, map) - c_forpair (name, email, People, i.ref->second) + c_FOREACH (i, Departments, map) + c_FORPAIR (name, email, People, i.ref->second) printf("%s: %s - %s\n", cstr_str(&i.ref->first), cstr_str(_.name), cstr_str(_.email)); puts(""); diff --git a/misc/examples/mmap.c b/misc/examples/mmap.c index 3934cf26..ada30b98 100644 --- a/misc/examples/mmap.c +++ b/misc/examples/mmap.c @@ -18,8 +18,8 @@ void print(const char* lbl, const Multimap mmap) { printf("%s ", lbl); - c_foreach (e, Multimap, mmap) { - c_foreach (s, clist_str, e.ref->second) + c_FOREACH (e, Multimap, mmap) { + c_FOREACH (s, clist_str, e.ref->second) printf("{%d,%s} ", e.ref->first, cstr_str(s.ref)); } puts(""); @@ -33,12 +33,12 @@ void insert(Multimap* mmap, int key, const char* str) int main() { - c_auto (Multimap, mmap) + c_AUTO (Multimap, mmap) { typedef struct {int a; const char* b;} pair; // list-initialize - c_forlist (i, pair, {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}) + c_FORLIST (i, pair, {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}) insert(&mmap, i.ref->a, i.ref->b); print("#1", mmap); @@ -54,7 +54,7 @@ int main() print("#4", mmap); // insert using initialization_list - c_forlist (i, pair, {{5, "one"}, {5, "two"}}) + c_FORLIST (i, pair, {{5, "one"}, {5, "two"}}) insert(&mmap, i.ref->a, i.ref->b); print("#5", mmap); @@ -65,7 +65,7 @@ int main() Multimap_clear(&mmap); - c_forlist (i, pair, {{1, "ä"}, {2, "ё"}, {2, "ö"}, {3, "ü"}}) + c_FORLIST (i, pair, {{1, "ä"}, {2, "ё"}, {2, "ö"}, {3, "ü"}}) insert(&mmap, i.ref->a, i.ref->b); print("#6", mmap); } diff --git a/misc/examples/multimap.c b/misc/examples/multimap.c index e72bdce3..8797c24e 100644 --- a/misc/examples/multimap.c +++ b/misc/examples/multimap.c @@ -60,17 +60,17 @@ OlympicLocation OlympicLocation_clone(OlympicLocation loc) { return loc; } void OlympicLocation_drop(OlympicLocation* self) { - c_drop(cstr, &self->city, &self->date); + c_DROP(cstr, &self->city, &self->date); } int main() { // Define the multimap with destructor defered to when block is completed. - c_auto (csmap_OL, multimap) + c_AUTO (csmap_OL, multimap) { const clist_OL empty = clist_OL_init(); - for (size_t i = 0; i < c_arraylen(ol_data); ++i) + for (size_t i = 0; i < c_ARRAYLEN(ol_data); ++i) { struct OlympicsData* d = &ol_data[i]; OlympicLocation loc = {.year = d->year, @@ -82,14 +82,14 @@ int main() clist_OL_push_back(list, loc); } // Sort locations by year for each country. - c_foreach (country, csmap_OL, multimap) + c_FOREACH (country, csmap_OL, multimap) clist_OL_sort(&country.ref->second); // Print the multimap: - c_foreach (country, csmap_OL, multimap) + c_FOREACH (country, csmap_OL, multimap) { // Loop the locations for a country sorted by year - c_foreach (loc, clist_OL, country.ref->second) + c_FOREACH (loc, clist_OL, country.ref->second) printf("%s: %d, %s, %s\n", cstr_str(&country.ref->first), loc.ref->year, cstr_str(&loc.ref->city), diff --git a/misc/examples/music_arc.c b/misc/examples/music_arc.c index 162c4c2f..9896c591 100644 --- a/misc/examples/music_arc.c +++ b/misc/examples/music_arc.c @@ -2,21 +2,21 @@ // based on https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=msvc-160 #include -struct Song +typedef struct { cstr artist; cstr title; -} typedef Song; +} Song; int Song_cmp(const Song* x, const Song* y) { return cstr_cmp(&x->title, &y->title); } -Song Song_from(const char* artist, const char* title) +Song Song_make(const char* artist, const char* title) { return (Song){cstr_from(artist), cstr_from(title)}; } void Song_drop(Song* s) { printf("drop: %s\n", cstr_str(&s->title)); - c_drop(cstr, &s->artist, &s->title); + c_DROP(cstr, &s->artist, &s->title); } // Define the reference counted type @@ -32,29 +32,29 @@ void Song_drop(Song* s) { void example3() { - c_auto (SongVec, vec1, vec2) + c_AUTO (SongVec, vec1, vec2) { - c_forlist (i, Song, { - Song_from("Bob Dylan", "The Times They Are A Changing"), - Song_from("Aretha Franklin", "Bridge Over Troubled Water"), - Song_from("Thalia", "Entre El Mar y Una Estrella") + c_FORLIST (i, Song, { + Song_make("Bob Dylan", "The Times They Are A Changing"), + Song_make("Aretha Franklin", "Bridge Over Troubled Water"), + Song_make("Thalia", "Entre El Mar y Una Estrella") }) SongVec_emplace(&vec1, *i.ref); // Share all entries in vec with vec2, except Bob Dylan. - c_foreach (s, SongVec, vec1) + c_FOREACH (s, SongVec, vec1) if (!cstr_equals(&s.ref->get->artist, "Bob Dylan")) SongVec_push(&vec2, SongArc_clone(*s.ref)); // Add a few more to vec2. We can use emplace when creating new entries - SongVec_emplace(&vec2, Song_from("Michael Jackson", "Billie Jean")); - SongVec_emplace(&vec2, Song_from("Rihanna", "Stay")); + SongVec_emplace(&vec2, Song_make("Michael Jackson", "Billie Jean")); + SongVec_emplace(&vec2, Song_make("Rihanna", "Stay")); // If we use push, we would need to construct the Arc explicitly (as in c++, make_shared): - // SongVec_push(&vec2, SongArc_from(Song_from("Rihanna", "Stay"))); + // SongVec_push(&vec2, SongArc_from(Song_make("Rihanna", "Stay"))); // We now have two vectors with some shared, some unique entries. - c_forlist (i, SongVec, {vec1, vec2}) { + c_FORLIST (i, SongVec, {vec1, vec2}) { puts("VEC:"); - c_foreach (s, SongVec, *i.ref) + c_FOREACH (s, SongVec, *i.ref) printf(" %s - %s, REFS: %ld\n", cstr_str(&s.ref->get->artist), cstr_str(&s.ref->get->title), *s.ref->use_count); diff --git a/misc/examples/new_arr.c b/misc/examples/new_arr.c index 871cfae0..7170d14a 100644 --- a/misc/examples/new_arr.c +++ b/misc/examples/new_arr.c @@ -13,7 +13,7 @@ int main() { int w = 7, h = 5, d = 3; - c_with (carr2_int volume = carr2_int_new_uninit(w, h), carr2_int_drop(&volume)) + c_WITH (carr2_int volume = carr2_int_new_uninit(w, h), carr2_int_drop(&volume)) { int *dat = carr2_int_data(&volume); for (size_t i = 0; i < carr2_int_size(&volume); ++i) @@ -24,12 +24,12 @@ int main() printf(" %d", volume.data[x][y]); puts(""); - c_foreach (i, carr2_int, volume) + c_FOREACH (i, carr2_int, volume) printf(" %d", *i.ref); puts("\n"); } - c_with (carr3_int volume = carr3_int_new_uninit(w, h, d), carr3_int_drop(&volume)) + c_WITH (carr3_int volume = carr3_int_new_uninit(w, h, d), carr3_int_drop(&volume)) { int *dat = carr3_int_data(&volume); for (size_t i = 0; i < carr3_int_size(&volume); ++i) @@ -41,17 +41,17 @@ int main() printf(" %d", volume.data[x][y][z]); puts(""); - c_foreach (i, carr3_int, volume) + c_FOREACH (i, carr3_int, volume) printf(" %d", *i.ref); puts(""); } - c_with (carr2_str text2d = carr2_str_with_size(h, d, cstr_NULL), carr2_str_drop(&text2d)) + c_WITH (carr2_str text2d = carr2_str_with_size(h, d, cstr_NULL), carr2_str_drop(&text2d)) { cstr_assign(&text2d.data[2][1], "hello"); cstr_assign(&text2d.data[4][0], "world"); - c_foreach (i, carr2_str, text2d) + c_FOREACH (i, carr2_str, text2d) printf("line: %s\n", cstr_str(i.ref)); } } diff --git a/misc/examples/new_deq.c b/misc/examples/new_deq.c index 39149140..df9142e7 100644 --- a/misc/examples/new_deq.c +++ b/misc/examples/new_deq.c @@ -36,25 +36,25 @@ int point_cmp(const Point* a, const Point* b) { int main() { - c_auto (cdeq_i32, vec) + c_AUTO (cdeq_i32, vec) { cdeq_i32_push_back(&vec, 123); } - c_auto (cdeq_float, fvec) + c_AUTO (cdeq_float, fvec) { cdeq_float_push_back(&fvec, 123.3f); } - c_auto (cdeq_pnt, pvec) + c_AUTO (cdeq_pnt, pvec) { cdeq_pnt_push_back(&pvec, (Point){42, 14}); cdeq_pnt_push_back(&pvec, (Point){32, 94}); cdeq_pnt_push_front(&pvec, (Point){62, 81}); cdeq_pnt_sort(&pvec); - c_foreach (i, cdeq_pnt, pvec) + c_FOREACH (i, cdeq_pnt, pvec) printf(" (%d %d)", i.ref->x, i.ref->y); puts(""); } - c_auto (cdeq_str, svec) + c_AUTO (cdeq_str, svec) { cdeq_str_emplace_back(&svec, "Hello, friend"); } diff --git a/misc/examples/new_list.c b/misc/examples/new_list.c index 6dbe80b4..c5d90ad1 100644 --- a/misc/examples/new_list.c +++ b/misc/examples/new_list.c @@ -35,27 +35,27 @@ int point_cmp(const Point* a, const Point* b) { int main() { - c_auto (clist_i32, lst) + c_AUTO (clist_i32, lst) clist_i32_push_back(&lst, 123); - c_auto (clist_pnt, plst) { - c_forlist (i, Point, {{42, 14}, {32, 94}, {62, 81}}) + c_AUTO (clist_pnt, plst) { + c_FORLIST (i, Point, {{42, 14}, {32, 94}, {62, 81}}) clist_pnt_push_back(&plst, *i.ref); clist_pnt_sort(&plst); - c_foreach (i, clist_pnt, plst) + c_FOREACH (i, clist_pnt, plst) printf(" (%d %d)", i.ref->x, i.ref->y); puts(""); } - c_auto (clist_float, flst) { - c_forlist (i, float, {123.3f, 321.2f, -32.2f, 78.2f}) + c_AUTO (clist_float, flst) { + c_FORLIST (i, float, {123.3f, 321.2f, -32.2f, 78.2f}) clist_float_push_back(&flst, *i.ref); - c_foreach (i, clist_float, flst) printf(" %g", *i.ref); + c_FOREACH (i, clist_float, flst) printf(" %g", *i.ref); } - c_auto (clist_str, slst) + c_AUTO (clist_str, slst) clist_str_emplace_back(&slst, "Hello, friend"); } diff --git a/misc/examples/new_map.c b/misc/examples/new_map.c index f43d4217..72705eb2 100644 --- a/misc/examples/new_map.c +++ b/misc/examples/new_map.c @@ -42,32 +42,32 @@ int point_cmp(const Point* a, const Point* b) { int main() { - c_auto (cmap_int, map) - c_auto (cmap_pnt, pmap) - c_auto (cmap_str, smap) - c_auto (cset_str, sset) + c_AUTO (cmap_int, map) + c_AUTO (cmap_pnt, pmap) + c_AUTO (cmap_str, smap) + c_AUTO (cset_str, sset) { cmap_int_insert(&map, 123, 321); - c_forlist (i, cmap_pnt_raw, {{{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}}) + c_FORLIST (i, cmap_pnt_raw, {{{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}}) cmap_pnt_insert(&pmap, c_PAIR(i.ref)); - c_foreach (i, cmap_pnt, pmap) + c_FOREACH (i, cmap_pnt, pmap) printf(" (%d, %d: %d)", i.ref->first.x, i.ref->first.y, i.ref->second); puts(""); - c_forlist (i, cmap_str_raw, { + c_FORLIST (i, cmap_str_raw, { {"Hello, friend", "long time no see"}, {"So long, friend", "see you around"}, }) cmap_str_emplace(&smap, c_PAIR(i.ref)); - c_forlist (i, const char*, { + c_FORLIST (i, const char*, { "Hello, friend", "Nice to see you again", "So long, friend", }) cset_str_emplace(&sset, *i.ref); - c_foreach (i, cset_str, sset) + c_FOREACH (i, cset_str, sset) printf(" %s\n", cstr_str(i.ref)); } } diff --git a/misc/examples/new_pque.c b/misc/examples/new_pque.c index 2bb1d729..d127b592 100644 --- a/misc/examples/new_pque.c +++ b/misc/examples/new_pque.c @@ -20,16 +20,16 @@ int Point_cmp(const Point* a, const Point* b) { int main() { - c_auto (cstack_int, istk) + c_AUTO (cstack_int, istk) { cstack_int_push(&istk, 123); cstack_int_push(&istk, 321); // print - c_foreach (i, cstack_int, istk) + c_FOREACH (i, cstack_int, istk) printf(" %d", *i.ref); puts(""); } - c_auto (cpque_pnt, pque) + c_AUTO (cpque_pnt, pque) { cpque_pnt_push(&pque, (Point){23, 80}); cpque_pnt_push(&pque, (Point){12, 32}); @@ -43,7 +43,7 @@ int main() } puts(""); } - c_auto (cpque_int, ique) + c_AUTO (cpque_int, ique) { cpque_int_push(&ique, 123); cpque_int_push(&ique, 321); diff --git a/misc/examples/new_queue.c b/misc/examples/new_queue.c index bc7a95c9..c72c94a0 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/new_queue.c @@ -25,15 +25,15 @@ int main() { stc64_t rng = stc64_new(time(NULL)); stc64_uniform_t dist = stc64_uniform_new(0, n); - c_auto (IQ, Q) + c_AUTO (IQ, Q) { // Push eight million random numbers onto the queue. - c_forrange (n) + c_FORRANGE (n) IQ_push(&Q, stc64_uniform(&rng, &dist)); // Push or pop on the queue 50 million times printf("befor: size %" c_ZU ", capacity %" c_ZU "\n", IQ_size(&Q), IQ_capacity(&Q)); - c_forrange (n) { + c_FORRANGE (n) { int r = stc64_uniform(&rng, &dist); if (r & 3) IQ_push(&Q, r); diff --git a/misc/examples/new_smap.c b/misc/examples/new_smap.c index c77aa185..8b1df828 100644 --- a/misc/examples/new_smap.c +++ b/misc/examples/new_smap.c @@ -42,34 +42,34 @@ int point_cmp(const Point* a, const Point* b) { int main() { - c_auto (csmap_int, imap) { + c_AUTO (csmap_int, imap) { csmap_int_insert(&imap, 123, 321); } - c_auto (PMap, pmap) { - c_forlist (i, PMap_value, { + c_AUTO (PMap, pmap) { + c_FORLIST (i, PMap_value, { {{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}, }) PMap_insert(&pmap, c_PAIR(i.ref)); - c_forpair (p, i, PMap, pmap) + c_FORPAIR (p, i, PMap, pmap) printf(" (%d,%d: %d)", _.p->x, _.p->y, *_.i); puts(""); } - c_auto (SMap, smap) { - c_forlist (i, SMap_raw, { + c_AUTO (SMap, smap) { + c_FORLIST (i, SMap_raw, { {"Hello, friend", "this is the mapped value"}, {"The brown fox", "jumped"}, {"This is the time", "for all good things"}, }) SMap_emplace(&smap, c_PAIR(i.ref)); - c_forpair (i, j, SMap, smap) + c_FORPAIR (i, j, SMap, smap) printf(" (%s: %s)\n", cstr_str(_.i), cstr_str(_.j)); } - c_auto (SSet, sset) { + c_AUTO (SSet, sset) { SSet_emplace(&sset, "Hello, friend"); SSet_emplace(&sset, "Goodbye, foe"); printf("Found? %s\n", SSet_contains(&sset, "Hello, friend") ? "true" : "false"); diff --git a/misc/examples/new_sptr.c b/misc/examples/new_sptr.c index 2c6b28d6..90ce30b2 100644 --- a/misc/examples/new_sptr.c +++ b/misc/examples/new_sptr.c @@ -42,12 +42,12 @@ Person Person_clone(Person p) { } void Person_drop(Person* p) { printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); - c_drop(cstr, &p->name, &p->last); + c_DROP(cstr, &p->name, &p->last); } int main(void) { - c_auto (PersonArc, p, q, r, s) + c_AUTO (PersonArc, p, q, r, s) { puts("Ex1"); p = PersonArc_from(Person_make("John", "Smiths")); @@ -56,7 +56,7 @@ int main(void) { s = PersonArc_from(Person_clone(*p.get)); // deep copy printf("%s %s: refs %ld\n", cstr_str(&p.get->name), cstr_str(&p.get->last), *p.use_count); } - c_auto (IPStack, vec) + c_AUTO (IPStack, vec) { puts("Ex2"); IPStack_push(&vec, IPtr_from(10)); @@ -65,7 +65,7 @@ int main(void) { IPStack_push(&vec, IPtr_clone(*IPStack_back(&vec))); IPStack_push(&vec, IPtr_clone(*IPStack_front(&vec))); - c_foreach (i, IPStack, vec) + c_FOREACH (i, IPStack, vec) printf(" (%d: refs %ld)", *i.ref->get, *i.ref->use_count); puts(""); } diff --git a/misc/examples/new_vec.c b/misc/examples/new_vec.c index 84e4c7b2..f18bf368 100644 --- a/misc/examples/new_vec.c +++ b/misc/examples/new_vec.c @@ -36,10 +36,10 @@ int point_cmp(const Point* a, const Point* b) { int main() { - c_auto (cvec_i32, vec) - c_auto (cvec_float, fvec) - c_auto (cvec_pnt, pvec) - c_auto (cvec_str, svec) + c_AUTO (cvec_i32, vec) + c_AUTO (cvec_float, fvec) + c_AUTO (cvec_pnt, pvec) + c_AUTO (cvec_str, svec) { cvec_i32_push(&vec, 123); cvec_float_push(&fvec, 123.3f); @@ -49,7 +49,7 @@ int main() cvec_pnt_push(&pvec, (Point){62, 81}); cvec_pnt_push(&pvec, (Point){32, 91}); cvec_pnt_sort(&pvec); - c_foreach (i, cvec_pnt, pvec) + c_FOREACH (i, cvec_pnt, pvec) printf(" (%d %d)", i.ref->x, i.ref->y); puts(""); diff --git a/misc/examples/person_arc.c b/misc/examples/person_arc.c index a7bf2a6f..f782c9da 100644 --- a/misc/examples/person_arc.c +++ b/misc/examples/person_arc.c @@ -24,7 +24,7 @@ Person Person_clone(Person p) { void Person_drop(Person* p) { printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); - c_drop(cstr, &p->name, &p->last); + c_DROP(cstr, &p->name, &p->last); } #define i_type PSPtr @@ -39,8 +39,8 @@ void Person_drop(Person* p) { int main() { - c_auto (Persons, vec) - c_auto (PSPtr, p, q) + c_AUTO (Persons, vec) + c_AUTO (PSPtr, p, q) { p = PSPtr_from(Person_make("Laura", "Palmer")); @@ -57,15 +57,15 @@ int main() Persons_emplace(&vec, Person_make("Dale", "Cooper")); // Clone/share p and q to the vector - c_forlist (i, PSPtr, {p, q}) + c_FORLIST (i, PSPtr, {p, q}) Persons_push(&vec, PSPtr_clone(*i.ref)); - c_foreach (i, Persons, vec) + c_FOREACH (i, Persons, vec) printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); puts(""); // Look-up Audrey! - c_with (Person a = Person_make("Audrey", "Home"), Person_drop(&a)) { + c_WITH (Person a = Person_make("Audrey", "Home"), Person_drop(&a)) { const PSPtr *v = Persons_get(&vec, a); if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); } diff --git a/misc/examples/phonebook.c b/misc/examples/phonebook.c index be068409..d0bc5b3a 100644 --- a/misc/examples/phonebook.c +++ b/misc/examples/phonebook.c @@ -32,23 +32,23 @@ void print_phone_book(cmap_str phone_book) { - c_foreach (i, cmap_str, phone_book) + c_FOREACH (i, cmap_str, phone_book) printf("%s\t- %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); } int main(int argc, char **argv) { - c_auto (cset_str, names) { - c_forlist (i, const char*, {"Hello", "Cool", "True"}) + c_AUTO (cset_str, names) { + c_FORLIST (i, const char*, {"Hello", "Cool", "True"}) cset_str_emplace(&names, *i.ref); - c_foreach (i, cset_str, names) + c_FOREACH (i, cset_str, names) printf("%s ", cstr_str(i.ref)); puts(""); } - c_auto (cmap_str, phone_book) { - c_forlist (i, cmap_str_raw, { + c_AUTO (cmap_str, phone_book) { + c_FORLIST (i, cmap_str_raw, { {"Lilia Friedman", "(892) 670-4739"}, {"Tariq Beltran", "(489) 600-7575"}, {"Laiba Juarez", "(303) 885-5692"}, diff --git a/misc/examples/prime.c b/misc/examples/prime.c index 287fb69b..41d637b8 100644 --- a/misc/examples/prime.c +++ b/misc/examples/prime.c @@ -28,7 +28,7 @@ int main(void) printf("computing prime numbers up to %" c_ZU "\n", n); clock_t t1 = clock(); - c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { + c_WITH (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { puts("done"); size_t np = cbits_count(&primes); clock_t t2 = clock(); @@ -36,14 +36,14 @@ int main(void) printf("number of primes: %" c_ZU ", time: %f\n", np, (t2 - t1) / (float)CLOCKS_PER_SEC); puts("Show all the primes in the range [2, 1000):"); printf("2"); - c_forrange (i, 3, 1000, 2) + c_FORRANGE (i, 3, 1000, 2) if (cbits_test(&primes, i>>1)) printf(" %lld", i); puts(""); puts("Show the last 50 primes using a temporary crange generator:"); - c_forfilter (i, crange, crange_literal(n - 1, 0, -2) + c_FORFILTER (i, crange, crange_literal(n - 1, 0, -2) , cbits_test(&primes, *i.ref>>1) - , c_flt_take(i, 50)) { + , c_FLT_TAKE(i, 50)) { printf("%lld ", *i.ref); if (i.count % 10 == 0) puts(""); } diff --git a/misc/examples/priority.c b/misc/examples/priority.c index f6e63205..22da6f60 100644 --- a/misc/examples/priority.c +++ b/misc/examples/priority.c @@ -12,22 +12,22 @@ int main() { size_t N = 10000000; stc64_t rng = stc64_new(time(NULL)); stc64_uniform_t dist = stc64_uniform_new(0, N * 10); - c_auto (cpque_i, heap) + c_AUTO (cpque_i, heap) { // Push ten million random numbers to priority queue printf("Push %" c_ZU " numbers\n", N); - c_forrange (N) + c_FORRANGE (N) cpque_i_push(&heap, stc64_uniform(&rng, &dist)); // push some negative numbers too. - c_forlist (i, int, {-231, -32, -873, -4, -343}) + c_FORLIST (i, int, {-231, -32, -873, -4, -343}) cpque_i_push(&heap, *i.ref); - c_forrange (N) + c_FORRANGE (N) cpque_i_push(&heap, stc64_uniform(&rng, &dist)); puts("Extract the hundred smallest."); - c_forrange (100) { + c_FORRANGE (100) { printf("%" PRId64 " ", *cpque_i_top(&heap)); cpque_i_pop(&heap); } diff --git a/misc/examples/queue.c b/misc/examples/queue.c index f39c4b8b..1d325fc6 100644 --- a/misc/examples/queue.c +++ b/misc/examples/queue.c @@ -11,15 +11,15 @@ int main() { stc64_t rng = stc64_new(1234); dist = stc64_uniform_new(0, n); - c_auto (cqueue_i, queue) + c_AUTO (cqueue_i, queue) { // Push ten million random numbers onto the queue. - c_forrange (n) + c_FORRANGE (n) cqueue_i_push(&queue, stc64_uniform(&rng, &dist)); // Push or pop on the queue ten million times printf("%d\n", n); - c_forrange (n) { // forrange uses initial n only. + c_FORRANGE (n) { // forrange uses initial n only. int r = stc64_uniform(&rng, &dist); if (r & 1) ++n, cqueue_i_push(&queue, r); diff --git a/misc/examples/random.c b/misc/examples/random.c index fe64290d..82214924 100644 --- a/misc/examples/random.c +++ b/misc/examples/random.c @@ -14,7 +14,7 @@ int main() printf("Compare speed of full and unbiased ranged random numbers...\n"); sum = 0; before = clock(); - c_forrange (N) { + c_FORRANGE (N) { sum += (uint32_t)stc64_rand(&rng); } diff = clock() - before; @@ -25,7 +25,7 @@ int main() rng = stc64_new(seed); sum = 0; before = clock(); - c_forrange (N) { + c_FORRANGE (N) { sum += stc64_uniform(&rng, &dist1); // unbiased } diff = clock() - before; @@ -35,7 +35,7 @@ int main() sum = 0; rng = stc64_new(seed); before = clock(); - c_forrange (N) { + c_FORRANGE (N) { sum += stc64_rand(&rng) % (range + 1); // biased } diff = clock() - before; diff --git a/misc/examples/rawptr_elements.c b/misc/examples/rawptr_elements.c index 4b3d2056..05910c77 100644 --- a/misc/examples/rawptr_elements.c +++ b/misc/examples/rawptr_elements.c @@ -10,10 +10,10 @@ typedef int64_t inttype; #define i_key_str #define i_val inttype* #define i_valraw inttype -#define i_valfrom(raw) c_new(inttype, raw) +#define i_valfrom(raw) c_NEW(inttype, raw) #define i_valto(x) **x -#define i_valclone(x) c_new(inttype, *x) -#define i_valdrop(x) c_free(*x) +#define i_valclone(x) c_NEW(inttype, *x) +#define i_valdrop(x) c_FREE(*x) #include // With cbox: @@ -28,12 +28,12 @@ typedef int64_t inttype; int main() { - c_auto (SIPtrMap, map, m1) - c_auto (SIBoxMap, m2) + c_AUTO (SIPtrMap, map, m1) + c_AUTO (SIBoxMap, m2) { printf("\nMap with pointer elements:\n"); - SIPtrMap_insert(&map, cstr_from("testing"), c_new(inttype, 1)); - SIPtrMap_insert(&map, cstr_from("done"), c_new(inttype, 2)); + SIPtrMap_insert(&map, cstr_from("testing"), c_NEW(inttype, 1)); + SIPtrMap_insert(&map, cstr_from("done"), c_NEW(inttype, 2)); // Emplace: implicit key, val construction: SIPtrMap_emplace(&map, "hello", 3); @@ -41,14 +41,14 @@ int main() m1 = SIPtrMap_clone(map); - c_forpair (name, number, SIPtrMap, m1) + c_FORPAIR (name, number, SIPtrMap, m1) printf("%s: %" PRId64 "\n", cstr_str(_.name), **_.number); puts("\nIBox map:"); SIBoxMap_insert(&m2, cstr_from("Hello"), IBox_make(123)); SIBoxMap_emplace(&m2, "World", 999); - c_forpair (name, number, SIBoxMap, m2) + c_FORPAIR (name, number, SIBoxMap, m2) printf("%s: %d\n", cstr_str(_.name), *_.number->get); puts(""); } diff --git a/misc/examples/read.c b/misc/examples/read.c index 4efdcfeb..ee5dd377 100644 --- a/misc/examples/read.c +++ b/misc/examples/read.c @@ -6,8 +6,8 @@ cvec_str read_file(const char* name) { cvec_str vec = cvec_str_init(); - c_with (FILE* f = fopen(name, "r"), fclose(f)) - c_with (cstr line = cstr_NULL, cstr_drop(&line)) + c_WITH (FILE* f = fopen(name, "r"), fclose(f)) + c_WITH (cstr line = cstr_NULL, cstr_drop(&line)) while (cstr_getline(&line, f)) cvec_str_push(&vec, cstr_clone(line)); return vec; @@ -16,8 +16,8 @@ cvec_str read_file(const char* name) int main() { int n = 0; - c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) - c_foreach (i, cvec_str, vec) + c_WITH (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) + c_FOREACH (i, cvec_str, vec) printf("%5d: %s\n", ++n, cstr_str(i.ref)); if (errno) diff --git a/misc/examples/regex1.c b/misc/examples/regex1.c index 7a22220d..9552db62 100644 --- a/misc/examples/regex1.c +++ b/misc/examples/regex1.c @@ -7,8 +7,8 @@ int main(int argc, char* argv[]) printf("Usage: regex1 -i\n"); return 0; } - c_auto (cstr, input) - c_auto (cregex, float_expr) + c_AUTO (cstr, input) + c_AUTO (cregex, float_expr) { int res = cregex_compile(&float_expr, "^[+-]?[0-9]+((\\.[0-9]*)?|\\.[0-9]+)$", CREG_DEFAULT); // Until "q" is given, ask for another number diff --git a/misc/examples/regex2.c b/misc/examples/regex2.c index dbf6aae4..55f8cfc2 100644 --- a/misc/examples/regex2.c +++ b/misc/examples/regex2.c @@ -13,8 +13,8 @@ int main() {"!((abc|123)+)!", "!123abcabc!"} }; - c_auto (cregex, re) - c_forrange (i, c_arraylen(s)) + c_AUTO (cregex, re) + c_FORRANGE (i, c_ARRAYLEN(s)) { int res = cregex_compile(&re, s[i].pattern, CREG_DEFAULT); if (res < 0) { @@ -23,8 +23,8 @@ int main() } printf("input: %s\n", s[i].input); - c_formatch (j, &re, s[i].input) { - c_forrange (k, cregex_captures(&re)) + c_FORMATCH (j, &re, s[i].input) { + c_FORRANGE (k, cregex_captures(&re)) printf(" submatch %lld: %.*s\n", k, c_ARGSV(j.match[k])); puts(""); } diff --git a/misc/examples/regex_match.c b/misc/examples/regex_match.c index 376b002e..b6bd6521 100644 --- a/misc/examples/regex_match.c +++ b/misc/examples/regex_match.c @@ -12,19 +12,19 @@ int main() " Boltzmann const: 1.38064852E-23, is very small." " Bohrradius is 5.29177210903e-11, and Avogadros number is 6.02214076e23."; - c_auto (cregex, re) - c_auto (cstack_float, vec) - c_auto (cstr, nums) + c_AUTO (cregex, re) + c_AUTO (cstack_float, vec) + c_AUTO (cstr, nums) { const char* pattern = "[+-]?([0-9]*\\.)?\\d+([Ee][+-]?\\d+)?"; int res = cregex_compile(&re, pattern, CREG_DEFAULT); printf("%d: %s\n", res, pattern); // extract and convert all numbers in str to floats - c_formatch (i, &re, str) + c_FORMATCH (i, &re, str) cstack_float_push(&vec, atof(i.match[0].str)); - c_foreach (i, cstack_float, vec) + c_FOREACH (i, cstack_float, vec) printf(" %g\n", *i.ref); // extracts the numbers only to a comma separated string. diff --git a/misc/examples/regex_replace.c b/misc/examples/regex_replace.c index e296dfd8..d621c0db 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regex_replace.c @@ -17,7 +17,7 @@ int main() const char* pattern = "\\b(\\d\\d\\d\\d)-(1[0-2]|0[1-9])-(3[01]|[12][0-9]|0[1-9])\\b"; const char* input = "start date: 2015-12-31, end date: 2022-02-28"; - c_auto (cstr, str) + c_AUTO (cstr, str) { printf("INPUT: %s\n", input); @@ -34,9 +34,9 @@ int main() printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ - c_with (cregex re = cregex_from(pattern, CREG_DEFAULT), cregex_drop(&re)) { + c_WITH (cregex re = cregex_from(pattern, CREG_DEFAULT), cregex_drop(&re)) { if (cregex_captures(&re) == 0) - continue; /* break c_with */ + continue; /* break c_WITH */ /* European date format. */ cstr_take(&str, cregex_replace(&re, input, "$3.$2.$1")); printf("euros: %s\n", cstr_str(&str)); diff --git a/misc/examples/replace.c b/misc/examples/replace.c index 15cf3bae..ca305ecd 100644 --- a/misc/examples/replace.c +++ b/misc/examples/replace.c @@ -11,7 +11,7 @@ int main () // Ustring positions: 0123456789*123456789*12345 cstr s = cstr_from(base); // "this is a test string." cstr m = cstr_clone(s); - c_defer (cstr_drop(&s), cstr_drop(&m)) { + c_DEFER (cstr_drop(&s), cstr_drop(&m)) { cstr_append(&m, cstr_str(&m)); cstr_append(&m, cstr_str(&m)); printf("%s\n", cstr_str(&m)); diff --git a/misc/examples/shape.c b/misc/examples/shape.c index a17208ef..4f7903da 100644 --- a/misc/examples/shape.c +++ b/misc/examples/shape.c @@ -38,7 +38,7 @@ void Shape_delete(Shape* shape) { if (shape) { shape->api->drop(shape); - c_free(shape); + c_FREE(shape); } } @@ -111,7 +111,7 @@ static void Polygon_draw(const Shape* shape) { const Polygon* self = c_dyn_cast(Polygon, shape); printf("Polygon :"); - c_foreach (i, PointVec, self->points) + c_FOREACH (i, PointVec, self->points) printf(" (%g,%g)", i.ref->x, i.ref->y); puts(""); } @@ -137,23 +137,23 @@ void testShape(const Shape* shape) int main(void) { - c_auto (Shapes, shapes) + c_AUTO (Shapes, shapes) { - Triangle* tri1 = c_new(Triangle, Triangle_from((Point){5, 7}, (Point){12, 7}, (Point){12, 20})); - Polygon* pol1 = c_new(Polygon, Polygon_init()); - Polygon* pol2 = c_new(Polygon, Polygon_init()); + Triangle* tri1 = c_NEW(Triangle, Triangle_from((Point){5, 7}, (Point){12, 7}, (Point){12, 20})); + Polygon* pol1 = c_NEW(Polygon, Polygon_init()); + Polygon* pol2 = c_NEW(Polygon, Polygon_init()); - c_forlist (i, Point, {{50, 72}, {123, 73}, {127, 201}, {828, 333}}) + c_FORLIST (i, Point, {{50, 72}, {123, 73}, {127, 201}, {828, 333}}) Polygon_addPoint(pol1, *i.ref); - c_forlist (i, Point, {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}) + c_FORLIST (i, Point, {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}) Polygon_addPoint(pol2, *i.ref); Shapes_push(&shapes, &tri1->shape); Shapes_push(&shapes, &pol1->shape); Shapes_push(&shapes, &pol2->shape); - c_foreach (i, Shapes, shapes) + c_FOREACH (i, Shapes, shapes) testShape(*i.ref); } } diff --git a/misc/examples/sidebyside.cpp b/misc/examples/sidebyside.cpp index 80c934a4..ca80664d 100644 --- a/misc/examples/sidebyside.cpp +++ b/misc/examples/sidebyside.cpp @@ -25,7 +25,7 @@ int main() { std::cout << std::endl; } - c_auto (IIMap, hist) + c_AUTO (IIMap, hist) { IIMap_insert(&hist, 12, 100).ref->second += 1; IIMap_insert(&hist, 13, 100).ref->second += 1; @@ -45,9 +45,9 @@ int main() { std::cout << std::endl; } - c_auto (SIMap, food) + c_AUTO (SIMap, food) { - c_forlist (i, SIMap_raw, {{"burger", 5}, {"pizza", 12}, {"steak", 15}}) + c_FORLIST (i, SIMap_raw, {{"burger", 5}, {"pizza", 12}, {"steak", 15}}) SIMap_emplace(&food, c_PAIR(i.ref)); c_foreach (i, SIMap, food) diff --git a/misc/examples/sorted_map.c b/misc/examples/sorted_map.c index c4a05c76..47509edb 100644 --- a/misc/examples/sorted_map.c +++ b/misc/examples/sorted_map.c @@ -9,7 +9,7 @@ int main() { // empty map containers - c_auto (csmap_int, gquiz1, gquiz2) + c_AUTO (csmap_int, gquiz1, gquiz2) { // insert elements in random order csmap_int_insert(&gquiz1, 2, 30); @@ -22,17 +22,17 @@ int main() // printing map gquiz1 printf("\nThe map gquiz1 is :\n\tKEY\tELEMENT\n"); - c_foreach (itr, csmap_int, gquiz1) + c_FOREACH (itr, csmap_int, gquiz1) printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); printf("\n"); // assigning the elements from gquiz1 to gquiz2 - c_foreach (i, csmap_int, gquiz1) + c_FOREACH (i, csmap_int, gquiz1) csmap_int_insert(&gquiz2, i.ref->first, i.ref->second); // print all elements of the map gquiz2 printf("\nThe map gquiz2 is :\n\tKEY\tELEMENT\n"); - c_foreach (itr, csmap_int, gquiz2) + c_FOREACH (itr, csmap_int, gquiz2) printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); printf("\n"); @@ -41,7 +41,7 @@ int main() printf("\tKEY\tELEMENT\n"); csmap_int_erase_range(&gquiz2, csmap_int_begin(&gquiz2), csmap_int_find(&gquiz2, 3)); - c_foreach (itr, csmap_int, gquiz2) + c_FOREACH (itr, csmap_int, gquiz2) printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); printf("\n"); @@ -49,7 +49,7 @@ int main() int num = csmap_int_erase(&gquiz2, 4); printf("\ngquiz2.erase(4) : %d removed\n", num); printf("\tKEY\tELEMENT\n"); - c_foreach (itr, csmap_int, gquiz2) + c_FOREACH (itr, csmap_int, gquiz2) printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); printf("\n"); diff --git a/misc/examples/splitstr.c b/misc/examples/splitstr.c index a3c12a3a..70d1935e 100644 --- a/misc/examples/splitstr.c +++ b/misc/examples/splitstr.c @@ -5,15 +5,15 @@ int main() { - puts("Split with c_fortoken (csview):"); + puts("Split with c_FORTOKEN (csview):"); - c_fortoken (i, "Hello World C99!", " ") + c_FORTOKEN (i, "Hello World C99!", " ") printf("'%.*s'\n", c_ARGSV(i.token)); - puts("\nSplit with c_formatch (regex):"); + puts("\nSplit with c_FORMATCH (regex):"); - c_with (cregex re = cregex_from("[^ ]+", CREG_DEFAULT), cregex_drop(&re)) - c_formatch (i, &re, " Hello World C99! ") + c_WITH (cregex re = cregex_from("[^ ]+", CREG_DEFAULT), cregex_drop(&re)) + c_FORMATCH (i, &re, " Hello World C99! ") printf("'%.*s'\n", c_ARGSV(i.match[0])); } diff --git a/misc/examples/sso_map.c b/misc/examples/sso_map.c index cc5e16a1..3627d101 100644 --- a/misc/examples/sso_map.c +++ b/misc/examples/sso_map.c @@ -5,11 +5,11 @@ int main() { - c_auto (cmap_str, m) { + c_AUTO (cmap_str, m) { cmap_str_emplace(&m, "Test short", "This is a short string."); cmap_str_emplace(&m, "Test long ", "This is a longer string."); - c_forpair (k, v, cmap_str, m) + c_FORPAIR (k, v, cmap_str, m) printf("%s: '%s' Len=%" c_ZU ", Is long: %s\n", cstr_str(_.k), cstr_str(_.v), cstr_size(_.v), cstr_is_long(_.v)?"true":"false"); diff --git a/misc/examples/sso_substr.c b/misc/examples/sso_substr.c index be372a8d..8e7450ba 100644 --- a/misc/examples/sso_substr.c +++ b/misc/examples/sso_substr.c @@ -16,5 +16,5 @@ int main () cstr s3 = cstr_from_sv(cstr_substr_ex(&str, 0, 6)); // "apples" printf("%s %s: %d, %d\n", cstr_str(&s2), cstr_str(&s3), cstr_is_long(&str), cstr_is_long(&s2)); - c_drop (cstr, &str, &s2, &s3); + c_DROP (cstr, &str, &s2, &s3); } diff --git a/misc/examples/stack.c b/misc/examples/stack.c index a6a4a492..370577b9 100644 --- a/misc/examples/stack.c +++ b/misc/examples/stack.c @@ -11,18 +11,18 @@ #include int main() { - c_auto (cstack_i, stack) - c_auto (cstack_c, chars) + c_AUTO (cstack_i, stack) + c_AUTO (cstack_c, chars) { - c_forrange (i, 101) + c_FORRANGE (i, 101) cstack_i_push(&stack, i*i); printf("%d\n", *cstack_i_top(&stack)); - c_forrange (i, 90) + c_FORRANGE (i, 90) cstack_i_pop(&stack); - c_foreach (i, cstack_i, stack) + c_FOREACH (i, cstack_i, stack) printf(" %d", *i.ref); puts(""); printf("top: %d\n", *cstack_i_top(&stack)); diff --git a/misc/examples/sview_split.c b/misc/examples/sview_split.c index d22fccd1..5658924e 100644 --- a/misc/examples/sview_split.c +++ b/misc/examples/sview_split.c @@ -13,7 +13,7 @@ int main() printf("%.*s, %.*s, %.*s\n", c_ARGSV(year), c_ARGSV(month), c_ARGSV(day)); - c_auto (cstr, y, m, d) { + c_AUTO (cstr, y, m, d) { y = cstr_from_sv(year), m = cstr_from_sv(month), d = cstr_from_sv(day); printf("%s, %s, %s\n", cstr_str(&y), cstr_str(&m), cstr_str(&d)); } diff --git a/misc/examples/unordered_set.c b/misc/examples/unordered_set.c index a0b639da..509f97e1 100644 --- a/misc/examples/unordered_set.c +++ b/misc/examples/unordered_set.c @@ -7,7 +7,7 @@ int main() { // declaring set for storing string data-type - c_auto (cset_str, stringSet) + c_AUTO (cset_str, stringSet) { // inserting various string, same string will be stored // once in set @@ -36,7 +36,7 @@ int main() // now iterating over whole set and printing its // content printf("All elements :\n"); - c_foreach (itr, cset_str, stringSet) + c_FOREACH (itr, cset_str, stringSet) printf("%s\n", cstr_str(itr.ref)); } } diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c index 22a5c990..74b765dc 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/utf8replace_c.c @@ -3,7 +3,7 @@ #include int main() { - c_auto (cstr, hello, upper) { + c_AUTO (cstr, hello, upper) { hello = cstr_lit("hell😀 w😀rld"); printf("%s\n", cstr_str(&hello)); @@ -16,7 +16,7 @@ int main() { upper = cstr_toupper_sv(cstr_sv(&hello)); - c_foreach (c, cstr, hello) + c_FOREACH (c, cstr, hello) printf("%.*s,", c_ARGSV(c.u8.chr)); puts(""); } diff --git a/misc/examples/vikings.c b/misc/examples/vikings.c index 26a74757..c65a9caa 100644 --- a/misc/examples/vikings.c +++ b/misc/examples/vikings.c @@ -50,7 +50,7 @@ static inline RViking Viking_toraw(const Viking* vp) { int main() { - c_auto (Vikings, vikings) { + c_AUTO (Vikings, vikings) { Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20); Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24); Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); @@ -59,7 +59,7 @@ int main() Vikings_value* v = Vikings_get_mut(&vikings, (RViking){"Einar", "Norway"}); v->second += 3; // add 3 hp points to Einar - c_forpair (vk, hp, Vikings, vikings) { + c_FORPAIR (vk, hp, Vikings, vikings) { printf("%s of %s has %d hp\n", cstr_str(&_.vk->name), cstr_str(&_.vk->country), *_.hp); } } diff --git a/misc/examples/words.c b/misc/examples/words.c index 097447aa..b945092f 100644 --- a/misc/examples/words.c +++ b/misc/examples/words.c @@ -10,19 +10,19 @@ int main1() { - c_auto (cvec_str, words) - c_auto (cmap_str, word_map) + c_AUTO (cvec_str, words) + c_AUTO (cmap_str, word_map) { - c_forlist (i, const char*, { + c_FORLIST (i, const char*, { "this", "sentence", "is", "not", "a", "sentence", "this", "sentence", "is", "a", "hoax" }) cvec_str_emplace_back(&words, *i.ref); - c_foreach (w, cvec_str, words) { + c_FOREACH (w, cvec_str, words) { cmap_str_emplace(&word_map, cstr_str(w.ref), 0).ref->second += 1; } - c_foreach (i, cmap_str, word_map) { + c_FOREACH (i, cmap_str, word_map) { printf("%d occurrences of word '%s'\n", i.ref->second, cstr_str(&i.ref->first)); } -- cgit v1.2.3 From 0761c13f316cc98ae7756f3527931aa86bed5016 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 29 Dec 2022 00:28:50 +0100 Subject: Restructuring of some headers into include/algo folder. Some API changes *_replace*() functions have been renamed, and a few minor API changes. --- README.md | 11 ++-- docs/ccommon_api.md | 4 +- docs/cregex_api.md | 4 +- docs/cstr_api.md | 7 ++- docs/csview_api.md | 2 +- include/stc/algo/crange.h | 72 +++++++++++++++++++++ include/stc/algo/csort.h | 127 +++++++++++++++++++++++++++++++++++++ include/stc/algo/cspan.h | 77 +++++++++++++++++++++++ include/stc/algo/filter.h | 76 ++++++++++++++++++++++ include/stc/carc.h | 7 +-- include/stc/cbox.h | 8 ++- include/stc/cregex.h | 8 +-- include/stc/cstack.h | 3 + include/stc/cstr.h | 16 +++-- include/stc/views.h | 142 ------------------------------------------ misc/examples/cpque.c | 2 +- misc/examples/demos.c | 2 +- misc/examples/forfilter.c | 8 ++- misc/examples/forloops.c | 2 +- misc/examples/prime.c | 6 +- misc/examples/regex_replace.c | 4 +- misc/examples/utf8replace_c.c | 4 +- misc/include/alt/cstr.h | 11 ++-- src/cregex.c | 4 +- 24 files changed, 411 insertions(+), 196 deletions(-) create mode 100644 include/stc/algo/crange.h create mode 100644 include/stc/algo/csort.h create mode 100644 include/stc/algo/cspan.h create mode 100644 include/stc/algo/filter.h delete mode 100644 include/stc/views.h (limited to 'misc/examples') diff --git a/README.md b/README.md index 012e3406..848da4bb 100644 --- a/README.md +++ b/README.md @@ -26,26 +26,25 @@ in the future, and do minor modifications. Containers ---------- -- [***ccommon*** - Generic algorithms and macros](docs/ccommon_api.md) - [***carc*** - **std::shared_ptr** alike type](docs/carc_api.md) -- [***carr2***, ***carr3*** - 2D and 3D **array** types](docs/carray_api.md) -- [***cbits*** - **std::bitset** alike type](docs/cbits_api.md) - [***cbox*** - **std::unique_ptr** alike type](docs/cbox_api.md) -- [***cdeq*** - **std::deque** alike type](docs/cdeq_api.md) +- [***cbits*** - **std::bitset** alike type](docs/cbits_api.md) - [***clist*** - **std::forward_list** alike type](docs/clist_api.md) -- [***cmap*** - **std::unordered_map** alike type](docs/cmap_api.md) -- [***cpque*** - **std::priority_queue** alike type](docs/cpque_api.md) - [***cqueue*** - **std::queue** alike type](docs/cqueue_api.md) +- [***cpque*** - **std::priority_queue** alike type](docs/cpque_api.md) +- [***cmap*** - **std::unordered_map** alike type](docs/cmap_api.md) - [***cset*** - **std::unordered_set** alike type](docs/cset_api.md) - [***csmap*** - **std::map** sorted map alike type](docs/csmap_api.md) - [***csset*** - **std::set** sorted set alike type](docs/csset_api.md) - [***cstack*** - **std::stack** alike type](docs/cstack_api.md) - [***cstr*** - **std::string** alike type](docs/cstr_api.md) - [***csview*** - **std::string_view** alike type](docs/csview_api.md) +- [***cdeq*** - **std::deque** alike type](docs/cdeq_api.md) - [***cvec*** - **std::vector** alike type](docs/cvec_api.md) Others ------ +- [***ccommon*** - Generic algorithms and macros](docs/ccommon_api.md) - [***cregex*** - Regular expression parser (extended from Rob Pike's regexp9)](docs/cregex_api.md) - [***crandom*** - A novel very fast *PRNG* named **stc64**](docs/crandom_api.md) - [***coption*** - getopt() alike command line args parser](docs/coption_api.md) diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index a9961002..474c80ac 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -288,13 +288,13 @@ c_FORFILTER (i, crange, r1 // 2. The 11 first primes: printf("2"); -c_FORFILTER (i, crange, crange_literal(3, crange_MAX, 2) +c_FORFILTER (i, crange, crange_LITERAL(3, INT64_MAX, 2) , isPrime(*i.ref) , c_FLT_TAKE(10)) printf(" %lld", *i.ref); // 2 3 5 7 11 13 17 19 23 29 31 ``` -### c_FIND_IF, c_find_in, c_ERASE_IF +### c_FIND_IF, c_ERASE_IF Find or erase linearily in containers using a predicate ```c // Search vec for first value > 2: diff --git a/docs/cregex_api.md b/docs/cregex_api.md index 1b3c03d6..3197a59e 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -48,8 +48,8 @@ cstr cregex_replace_sv(const cregex* re, csview input, const char* replac /* All-in-one replacement (compile + find/replace + drop) */ cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace); -cstr cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count, - bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags); +cstr cregex_replace_pattern_ex(const char* pattern, const char* input, const char* replace, unsigned count, + bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags); void cregex_drop(cregex* self); /* destroy */ ``` diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 3857633a..0ee8b2cb 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -68,7 +68,8 @@ void cstr_insert_s(cstr* self, size_t pos, cstr ins); void cstr_erase(cstr* self, size_t pos, size_t len); // erase len bytes from pos -void cstr_replace(cstr* self, const char* search, const char* repl, unsigned count); // count==0: replace all. +void cstr_replace(cstr* self, const char* search, const char* repl); +void cstr_replace_ex(cstr* self, const char* search, const char* repl, unsigned count); cstr cstr_replace_sv(csview in, csview search, csview repl, unsigned count); void cstr_replace_at(cstr* self, size_t pos, size_t len, const char* repl); // replace at a position void cstr_replace_at_sv(cstr* self, size_t pos, size_t len, const csview repl); @@ -101,7 +102,7 @@ size_t cstr_u8_size_n(const cstr self, size_t nbytes); // utf8 si size_t cstr_u8_to_pos(const cstr* self, size_t u8idx); // byte pos offset at utf8 codepoint index const char* cstr_u8_at(const cstr* self, size_t u8idx); // char* position at utf8 codepoint index csview cstr_u8_chr(const cstr* self, size_t u8idx); // get utf8 character as a csview -void cstr_u8_replace(cstr* self, size_t bytepos, size_t u8len, csview repl); // replace u8len utf8 chars +void cstr_u8_replace_at(cstr* self, size_t bytepos, size_t u8len, csview repl); // replace u8len utf8 chars void cstr_u8_erase(cstr* self, size_t bytepos, size_t u8len); // erase u8len codepoints from pos // iterate utf8 codepoints @@ -173,7 +174,7 @@ int main() { cstr_erase(&s1, 7, 5); // -nine printf("%s\n", cstr_str(&s1)); - cstr_replace(&s1, "seven", "four", 1); + cstr_replace_ex(&s1, "seven", "four", 1); printf("%s\n", cstr_str(&s1)); // reassign: diff --git a/docs/csview_api.md b/docs/csview_api.md index 05348745..b5508ace 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -153,7 +153,7 @@ int main() { c_AUTO (cstr, s1) { s1 = cstr_lit("hell😀 w😀rld"); - cstr_u8_replace(&s1, cstr_find(&s1, "😀rld"), 1, c_SV("ø")); + cstr_u8_replace_at(&s1, cstr_find(&s1, "😀rld"), 1, c_SV("ø")); printf("%s\n", cstr_str(&s1)); c_FOREACH (i, cstr, s1) diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h new file mode 100644 index 00000000..ccdd13ae --- /dev/null +++ b/include/stc/algo/crange.h @@ -0,0 +1,72 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ +/* +#include +#include +#include + +int main() +{ + crange r1 = crange_make(80, 90); + c_foreach (i, crange, r1) + printf(" %lld", *i.ref); + puts(""); + + // use a temporary crange object. + int a = 100, b = INT32_MAX; + c_forfilter (i, crange, crange_LITERAL(a, b, 8) + , i.index > 10 + , c_flt_take(i, 3)) + printf(" %lld", *i.ref); + puts(""); +} +*/ +#ifndef STC_CRANGE_H_INCLUDED +#define STC_CRANGE_H_INCLUDED + +#include + +#define crange_LITERAL(...) \ + (*(crange[]){crange_make(__VA_ARGS__)}) + +typedef long long crange_value; +typedef struct { crange_value start, end, step, value; } crange; +typedef struct { crange_value *ref, end, step; } crange_iter; + +#define crange_make(...) c_MACRO_OVERLOAD(crange_make, __VA_ARGS__) +#define crange_make1(stop) crange_make3(0, stop, 1) +#define crange_make2(start, stop) crange_make3(start, stop, 1) + +STC_INLINE crange crange_make3(crange_value start, crange_value stop, crange_value step) + { crange r = {start, stop - (step > 0), step}; return r; } + +STC_INLINE crange_iter crange_begin(crange* self) + { self->value = self->start; crange_iter it = {&self->value, self->end, self->step}; return it; } + +STC_INLINE crange_iter crange_end(crange* self) + { crange_iter it = {NULL}; return it; } + +STC_INLINE void crange_next(crange_iter* it) + { *it->ref += it->step; if ((it->step > 0) == (*it->ref > it->end)) it->ref = NULL; } + +#endif diff --git a/include/stc/algo/csort.h b/include/stc/algo/csort.h new file mode 100644 index 00000000..9b115398 --- /dev/null +++ b/include/stc/algo/csort.h @@ -0,0 +1,127 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef STC_CSORT_H_INCLUDED +#define STC_CSORT_H_INCLUDED +#include +#define c_CONCAT(a, b) a ## b +#define c_PASTE(a, b) c_CONCAT(a, b) +#endif + +/* Generic Quicksort in C +template params: +#define i_val - value type [required] +#define i_less - less function. default: *x < *y +#define i_tag NAME - define csort_NAME(). default {i_val} + +// test: +#include +#include +#include +#define i_val int +#include +#include +#ifdef __cplusplus +#include +#endif + +int testsort(csortval_int *a, size_t size, const char *desc) { + clock_t t = clock(); +#ifdef __cplusplus + puts("std::sort"); + std::sort(a, a + size); +#else + puts("csort"); + csort_int(a, size); +#endif + t = clock() - t; + + printf("%s: %zu elements sorted in %.3fms\n", + desc, size, t * 1000.0 / CLOCKS_PER_SEC); + return 0; +} + +int main(int argc, char *argv[]) { + size_t i, size = argc > 1 ? strtoull(argv[1], NULL, 0) : 10000000; + csortval_int *a = (csortval_int*)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(""); + 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"); + free(a); + } + return 0; +}*/ +#ifndef i_tag +#define i_tag i_val +#endif +#ifndef i_less +#define i_less(x, y) *x < *y +#endif + +typedef i_val c_PASTE(csortval_, i_tag); + +static inline void c_PASTE(cisort_, i_tag)(i_val arr[], intptr_t low, intptr_t high) { + for (intptr_t j = low, i = low+1; i <= high; j = i, ++i) { + i_val key = arr[i]; + while (j >= 0 && (i_less((&key), (&arr[j])))) { + arr[j + 1] = arr[j]; + --j; + } + arr[j + 1] = key; + } +} + +static inline void c_PASTE(cqsort_, i_tag)(i_val arr[], intptr_t low, intptr_t high) +{ + intptr_t i = low, j = high; + i_val pivot = arr[(i + j)/2]; + + while (i <= j) { + while (i_less((&arr[i]), (&pivot))) ++i; + while (i_less((&pivot), (&arr[j]))) --j; + if (i <= j) { + i_val t = arr[i]; arr[i] = arr[j]; arr[j] = t; + ++i; --j; + } + } + if (j > low) j - low < 65 ? c_PASTE(cisort_, i_tag)(arr, low, j) + : c_PASTE(cqsort_, i_tag)(arr, low, j); + if (i < high) high - i < 65 ? c_PASTE(cisort_, i_tag)(arr, i, high) + : c_PASTE(cqsort_, i_tag)(arr, i, high); +} + +static inline void c_PASTE(csort_, i_tag)(i_val arr[], size_t elements) +{ + elements < 65 ? c_PASTE(cisort_, i_tag)(arr, 0, (intptr_t)elements - 1) + : c_PASTE(cqsort_, i_tag)(arr, 0, (intptr_t)elements - 1); +} +#undef i_tag +#undef i_val +#undef i_less diff --git a/include/stc/algo/cspan.h b/include/stc/algo/cspan.h new file mode 100644 index 00000000..d6d6dd56 --- /dev/null +++ b/include/stc/algo/cspan.h @@ -0,0 +1,77 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ +/* +#include +#include +using_cspan(IntSpan, int); + +int main() +{ + int array[] = {1, 2, 3, 4, 5}; + IntSpan iv = {array, c_arraylen(array)}; + + c_foreach (i, IntSpan, iv) + printf(" %d", *i.ref); + puts(""); + + // use a temporary IntSpan object. + c_forfilter (i, IntSpan, cspan_LITERAL(IntSpan, {10, 20, 30, 23, 22, 21}) + , c_flt_skipwhile(i, *i.ref < 25) + && (*i.ref & 1) == 0 // even only + , c_flt_take(i, 2)) // break after 2 + printf(" %d", *i.ref); + puts(""); +} +*/ +#ifndef STC_CSPAN_H_INCLUDED +#define STC_CSPAN_H_INCLUDED + +#include + +#define cspan_LITERAL(C, ...) \ + ((C){.data = (C##_value[])__VA_ARGS__, \ + .size = sizeof((C##_value[])__VA_ARGS__)/sizeof(C##_value)}) + +#define using_cspan(Self, T) \ +typedef T Self##_raw; typedef const Self##_raw Self##_value; \ +typedef struct { Self##_value *data; size_t size; } Self; \ +typedef struct { Self##_value *ref, *end; } Self##_iter; \ + \ +STC_INLINE Self##_value* Self##_at(const Self* self, size_t idx) \ + { assert(idx < self->size); return self->data + idx; } \ + \ +STC_INLINE Self##_iter Self##_begin(const Self* self) { \ + Self##_iter it = {self->data, self->data + self->size}; \ + return it; \ +} \ + \ +STC_INLINE Self##_iter Self##_end(const Self* self) { \ + Self##_iter it = {NULL, self->data + self->size}; \ + return it; \ +} \ + \ +STC_INLINE void Self##_next(Self##_iter* it) \ + { if (++it->ref == it->end) it->ref = NULL; } \ +struct stc_nostruct + +#endif diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h new file mode 100644 index 00000000..486568f2 --- /dev/null +++ b/include/stc/algo/filter.h @@ -0,0 +1,76 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ +/* +#include +#define i_val int +#define i_capacity 10 +#include +#include + +int main() +{ + cstack_int stk = cstack_INITIALIZER(int, {1, 2, 3, 4, 5, 6, 7, 8, 9}); + + c_foreach (i, cstack_int, stk) + printf(" %d", *i.ref); + puts(""); + + c_forfilter (i, cstack_int, stk + , c_flt_skipwhile(i, *i.ref < 3) + && (*i.ref & 1) == 0 // even only + , c_flt_take(i, 2)) // break after 2 + printf(" %d", *i.ref); + puts(""); +} +*/ +#ifndef STC_FILTER_H_INCLUDED +#define STC_FILTER_H_INCLUDED + +#include + +#ifndef c_NFILTERS + #define c_NFILTERS 14 /* 22, 30, .. */ +#endif + +#define c_flt_take(i, n) (++(i).s1[(i).s1top++] <= (n)) +#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_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__) + +#define c_forfilter4(i, C, cnt, filter) \ + c_forfilter_b(i, C, C##_begin(&cnt), filter) + +#define c_forfilter5(i, C, cnt, filter, cond) \ + c_forfilter_b(i, C, C##_begin(&cnt), filter) if (!(cond)) break; else + +#define c_forfilter_b(i, C, start, filter) \ + for (struct {C##_iter it; C##_value *ref; \ + uint32_t s1[c_NFILTERS], index, count; \ + 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 + +#endif diff --git a/include/stc/carc.h b/include/stc/carc.h index 22453f1d..7f7789ab 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -72,7 +72,6 @@ int main() { #endif #define carc_NULL {NULL, NULL} -#define _cx_carc_rep struct _cx_memb(_rep_) #endif // CARC_H_INCLUDED #ifndef _i_prefix @@ -91,7 +90,7 @@ typedef i_keyraw _cx_raw; #if !c_option(c_is_forward) _cx_deftypes(_c_carc_types, _cx_self, i_key); #endif -_cx_carc_rep { catomic_long counter; i_key value; }; +struct _cx_memb(_rep_) { catomic_long counter; i_key value; }; STC_INLINE _cx_self _cx_memb(_init)(void) { return c_INIT(_cx_self){NULL, NULL}; } @@ -109,7 +108,7 @@ STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) { // c++: std::make_shared<_cx_value>(val) STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) { _cx_self ptr; - _cx_carc_rep *rep = c_alloc(_cx_carc_rep); + struct _cx_memb(_rep_)* rep = c_alloc(struct _cx_memb(_rep_)); *(ptr.use_count = &rep->counter) = 1; *(ptr.get = &rep->value) = val; return ptr; @@ -127,7 +126,7 @@ STC_INLINE _cx_self _cx_memb(_move)(_cx_self* self) { STC_INLINE void _cx_memb(_drop)(_cx_self* self) { if (self->use_count && _i_atomic_dec_and_test(self->use_count)) { i_keydrop(self->get); - if ((char *)self->get != (char *)self->use_count + offsetof(_cx_carc_rep, value)) + if ((char *)self->get != (char *)self->use_count + offsetof(struct _cx_memb(_rep_), value)) c_free(self->get); c_free((long*)self->use_count); } diff --git a/include/stc/cbox.h b/include/stc/cbox.h index bcb1b275..a0966fcc 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -77,7 +77,7 @@ typedef i_keyraw _cx_raw; _cx_deftypes(_c_cbox_types, _cx_self, i_key); #endif -// constructors (takes ownsership) +// constructors (take ownership) STC_INLINE _cx_self _cx_memb(_init)(void) { return c_INIT(_cx_self){NULL}; } @@ -110,6 +110,9 @@ STC_INLINE _cx_self _cx_memb(_move)(_cx_self* self) { return ptr; } +STC_INLINE _cx_value* _cx_memb(_release)(_cx_self* self) + { return _cx_memb(_move)(self).get; } + STC_INLINE void _cx_memb(_reset)(_cx_self* self) { _cx_memb(_drop)(self); self->get = NULL; @@ -117,8 +120,7 @@ STC_INLINE void _cx_memb(_reset)(_cx_self* self) { // take ownership of p STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) { - if (self->get) - i_keydrop(self->get); + _cx_memb(_drop)(self); self->get = p; } diff --git a/include/stc/cregex.h b/include/stc/cregex.h index b6e33879..975bd675 100644 --- a/include/stc/cregex.h +++ b/include/stc/cregex.h @@ -127,15 +127,15 @@ cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, unsi static inline cstr cregex_replace(const cregex* re, const char* input, const char* replace) { csview sv = {input, strlen(input)}; - return cregex_replace_sv(re, sv, replace, 0, NULL, CREG_DEFAULT); + return cregex_replace_sv(re, sv, replace, ~0U, NULL, CREG_DEFAULT); } /* replace + compile RE pattern, and extra arguments */ -cstr cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count, - bool (*mfun)(int i, csview match, cstr* mstr), int crflags); +cstr cregex_replace_pattern_ex(const char* pattern, const char* input, const char* replace, unsigned count, + bool (*mfun)(int i, csview match, cstr* mstr), int crflags); static inline cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace) - { return cregex_replace_pattern_n(pattern, input, replace, 0, NULL, CREG_DEFAULT); } + { return cregex_replace_pattern_ex(pattern, input, replace, ~0U, NULL, CREG_DEFAULT); } /* destroy regex */ void cregex_drop(cregex* self); diff --git a/include/stc/cstack.h b/include/stc/cstack.h index 73d0e2e1..e4b64848 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -52,6 +52,9 @@ STC_INLINE _cx_self _cx_memb(_init)(void) { } #ifdef i_capacity +#define cstack_INITIALIZER(T, ...) \ + {.data=__VA_ARGS__, ._len=sizeof((T[])__VA_ARGS__)/sizeof(T)} + STC_INLINE void _cx_memb(_create)(_cx_self* self) { self->_len = 0; } #else diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 6f774135..9748b72c 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -88,7 +88,6 @@ STC_API void cstr_u8_erase(cstr* self, size_t bytepos, size_t u8len); STC_API cstr cstr_from_fmt(const char* fmt, ...); STC_API size_t cstr_append_fmt(cstr* self, const char* fmt, ...); STC_API size_t cstr_printf(cstr* self, const char* fmt, ...); -STC_API void cstr_replace(cstr* self, const char* search, const char* repl, unsigned count); STC_API cstr cstr_replace_sv(csview sv, csview search, csview repl, unsigned count); STC_INLINE cstr_buf cstr_buffer(cstr* s) { @@ -376,6 +375,12 @@ STC_INLINE char* cstr_append_s(cstr* self, cstr s) { return cstr_append_n(self, sv.str, sv.size); } +STC_INLINE void cstr_replace_ex(cstr* self, const char* search, const char* repl, unsigned count) { + cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(search, strlen(search)), + c_SV(repl, strlen(repl)), count)); +} +STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl) + { cstr_replace_ex(self, search, repl, ~0U); } STC_INLINE void cstr_replace_at_sv(cstr* self, size_t pos, size_t len, const csview repl) { char* d = _cstr_internal_move(self, pos + len, pos + repl.size); @@ -388,7 +393,7 @@ STC_INLINE void cstr_replace_at(cstr* self, size_t pos, size_t len, const char* STC_INLINE void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl) { cstr_replace_at_sv(self, pos, len, cstr_sv(&repl)); } -STC_INLINE void cstr_u8_replace(cstr* self, size_t bytepos, size_t u8len, csview repl) +STC_INLINE void cstr_u8_replace_at(cstr* self, size_t bytepos, size_t u8len, csview repl) { cstr_replace_at_sv(self, bytepos, utf8_pos(cstr_str(self) + bytepos, u8len), repl); } @@ -583,13 +588,6 @@ cstr_replace_sv(csview in, csview search, csview repl, unsigned count) { return out; } -STC_DEF void -cstr_replace(cstr* self, const char* search, const char* repl, unsigned count) { - csview in = cstr_sv(self); - cstr_take(self, cstr_replace_sv(in, c_SV(search, strlen(search)), - c_SV(repl, strlen(repl)), count)); -} - STC_DEF void cstr_erase(cstr* self, const size_t pos, size_t len) { cstr_buf r = cstr_buffer(self); if (len > r.size - pos) len = r.size - pos; diff --git a/include/stc/views.h b/include/stc/views.h deleted file mode 100644 index ea5f4536..00000000 --- a/include/stc/views.h +++ /dev/null @@ -1,142 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ -/* -#include -#include -using_clview(IView, int); - -int main() -{ - int array[] = {1, 2, 3, 4, 5}; - IView iv = {array, c_arraylen(array)}; - - c_foreach (i, IView, iv) - printf(" %d", *i.ref); - puts(""); - - // use a temporary IView object. - c_forfilter (i, IView, clview_literal(IView, {10, 20, 30, 23, 22, 21}) - , c_flt_skipwhile(i, *i.ref < 25) - && (*i.ref & 1) == 0 // even only - , c_flt_take(i, 2)) // break after 2 - printf(" %d", *i.ref); - puts(""); - - // crange: - - crange r1 = crange_make(80, 90); - c_foreach (i, crange, r1) - printf(" %lld", *i.ref); - puts(""); - - // use a temporary crange object. - int a = 100, b = INT32_MAX; - c_forfilter (i, crange, crange_literal(a, b, 8) - , i.index > 10 - , c_flt_take(i, 3)) - printf(" %lld", *i.ref); - puts(""); -} -*/ -#ifndef STC_VIEWS_H_INCLUDED -#define STC_VIEWS_H_INCLUDED - -#include - -#ifndef c_NFILTERS - #define c_NFILTERS 14 /* 22, 30, .. */ -#endif -#define c_flt_take(i, n) (++(i).s1[(i).s1top++] <= (n)) -#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_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__) -#define c_forfilter4(i, C, cnt, filter) \ - c_forfilter_s(i, C, C##_begin(&cnt), filter) -#define c_forfilter5(i, C, cnt, filter, cond) \ - c_forfilter_s(i, C, C##_begin(&cnt), filter) if (!(cond)) break; else -#define c_forfilter_s(i, C, start, filter) \ - for (struct {C##_iter it; C##_value *ref; \ - uint32_t s1[c_NFILTERS], index, count; \ - 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 - - -// clview type - -#define clview_literal(C, ...) \ - ((C){.data = (C##_value[])__VA_ARGS__, \ - .size = sizeof((C##_value[])__VA_ARGS__)/sizeof(C##_value)}) - -#define using_clview(Self, T) \ -typedef T Self##_raw; typedef const Self##_raw Self##_value; \ -typedef struct { Self##_value *data; size_t size; } Self; \ -typedef struct { Self##_value *ref, *end; } Self##_iter; \ - \ -STC_INLINE Self##_value* Self##_at(const Self* self, size_t idx) \ - { assert(idx < self->size); return self->data + idx; } \ - \ -STC_INLINE Self##_iter Self##_begin(const Self* self) { \ - Self##_iter it = {self->data, self->data + self->size}; \ - return it; \ -} \ - \ -STC_INLINE Self##_iter Self##_end(const Self* self) { \ - Self##_iter it = {NULL, self->data + self->size}; \ - return it; \ -} \ - \ -STC_INLINE void Self##_next(Self##_iter* it) \ - { if (++it->ref == it->end) it->ref = NULL; } \ -struct stc_nostruct - - -// crange type - -#define crange_literal(...) \ - (*(crange[]){crange_make(__VA_ARGS__)}) - -typedef long long crange_value; -typedef struct { crange_value start, end, step, value; } crange; -typedef struct { crange_value *ref, end, step; } crange_iter; - -#define crange_make(...) c_MACRO_OVERLOAD(crange_make, __VA_ARGS__) -#define crange_make1(stop) crange_make3(0, stop, 1) -#define crange_make2(start, stop) crange_make3(start, stop, 1) - -STC_INLINE crange crange_make3(crange_value start, crange_value stop, crange_value step) - { crange r = {start, stop - (step > 0), step}; return r; } - -STC_INLINE crange_iter crange_begin(crange* self) - { self->value = self->start; crange_iter it = {&self->value, self->end, self->step}; return it; } - -STC_INLINE crange_iter crange_end(crange* self) - { crange_iter it = {NULL}; return it; } - -STC_INLINE void crange_next(crange_iter* it) - { *it->ref += it->step; if ((it->step > 0) == (*it->ref > it->end)) it->ref = NULL; } - -#endif diff --git a/misc/examples/cpque.c b/misc/examples/cpque.c index 47080038..2ec841ae 100644 --- a/misc/examples/cpque.c +++ b/misc/examples/cpque.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include // predeclare diff --git a/misc/examples/demos.c b/misc/examples/demos.c index b077aa73..4a9fac89 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -13,7 +13,7 @@ void stringdemo1() cstr_erase(&cs, 7, 5); // -nine printf("%s.\n", cstr_str(&cs)); - cstr_replace(&cs, "seven", "four", 1); + cstr_replace_ex(&cs, "seven", "four", 1); printf("%s.\n", cstr_str(&cs)); cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs))); diff --git a/misc/examples/forfilter.c b/misc/examples/forfilter.c index 32154904..c0a4ccad 100644 --- a/misc/examples/forfilter.c +++ b/misc/examples/forfilter.c @@ -2,7 +2,8 @@ #define i_extern #include #include -#include +#include +#include #define i_type IVec #define i_val int @@ -63,12 +64,13 @@ void demo2(void) c_AUTO (IVec, vector) { puts("demo2:"); - c_FORFILTER (x, crange, crange_literal(INT64_MAX) + c_FORFILTER (x, crange, crange_LITERAL(INT64_MAX) , c_FLT_SKIPWHILE(x, *x.ref != 11) && *x.ref % 2 != 0 , c_FLT_TAKE(x, 5)) IVec_push(&vector, *x.ref * *x.ref); - c_FOREACH (x, IVec, vector) printf(" %d", *x.ref); + c_FOREACH (x, IVec, vector) + printf(" %d", *x.ref); puts(""); } } diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c index 95a955a3..69c1c193 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/forloops.c @@ -1,5 +1,5 @@ #include -#include +#include #define i_type IVec #define i_val int diff --git a/misc/examples/prime.c b/misc/examples/prime.c index 41d637b8..f6e89e09 100644 --- a/misc/examples/prime.c +++ b/misc/examples/prime.c @@ -2,7 +2,9 @@ #include #include #include -#include +#include +#include + cbits sieveOfEratosthenes(size_t n) { @@ -41,7 +43,7 @@ int main(void) puts(""); puts("Show the last 50 primes using a temporary crange generator:"); - c_FORFILTER (i, crange, crange_literal(n - 1, 0, -2) + c_FORFILTER (i, crange, crange_LITERAL(n - 1, 0, -2) , cbits_test(&primes, *i.ref>>1) , c_FLT_TAKE(i, 50)) { printf("%lld ", *i.ref); diff --git a/misc/examples/regex_replace.c b/misc/examples/regex_replace.c index d621c0db..a170856b 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regex_replace.c @@ -26,11 +26,11 @@ int main() printf("fixed: %s\n", cstr_str(&str)); /* US date format, and add 10 years to dates: */ - cstr_take(&str, cregex_replace_pattern_n(pattern, input, "$1/$3/$2", 0, add_10_years, CREG_DEFAULT)); + cstr_take(&str, cregex_replace_pattern_ex(pattern, input, "$1/$3/$2", 0, add_10_years, CREG_DEFAULT)); printf("us+10: %s\n", cstr_str(&str)); /* Wrap first date inside []: */ - cstr_take(&str, cregex_replace_pattern_n(pattern, input, "[$0]", 1, NULL, CREG_DEFAULT)); + cstr_take(&str, cregex_replace_pattern_ex(pattern, input, "[$0]", 1, NULL, CREG_DEFAULT)); printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c index 74b765dc..3645bd0a 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/utf8replace_c.c @@ -8,10 +8,10 @@ int main() { printf("%s\n", cstr_str(&hello)); /* replace second smiley at utf8 codepoint pos 7 */ - cstr_u8_replace(&hello, cstr_u8_to_pos(&hello, 7), 1, c_SV("🐨")); + cstr_u8_replace_at(&hello, cstr_u8_to_pos(&hello, 7), 1, c_SV("🐨")); printf("%s\n", cstr_str(&hello)); - cstr_replace(&hello, "🐨", "ø", 1); + cstr_replace_ex(&hello, "🐨", "ø", 1); printf("%s\n", cstr_str(&hello)); upper = cstr_toupper_sv(cstr_sv(&hello)); diff --git a/misc/include/alt/cstr.h b/misc/include/alt/cstr.h index ecb9c9fb..8de6c4b0 100644 --- a/misc/include/alt/cstr.h +++ b/misc/include/alt/cstr.h @@ -182,12 +182,12 @@ STC_INLINE uint64_t cstr_hash(const cstr *self) { return cfasthash(self->str, _cstr_p(self)->size); } -STC_INLINE void -cstr_replace(cstr* self, const char* find, const char* repl, unsigned count) { - csview in = cstr_sv(self); - cstr_take(self, cstr_replace_sv(in, c_SV(find, strlen(find)), - c_SV(repl, strlen(repl)), count)); +STC_INLINE void cstr_replace_ex(cstr* self, const char* find, const char* repl, unsigned count) { + cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(find, strlen(find)), + c_SV(repl, strlen(repl)), count)); } +STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl) + { cstr_replace_ex(self, search, repl, ~0U); } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) @@ -324,7 +324,6 @@ STC_DEF cstr cstr_replace_sv(csview str, csview find, csview repl, unsigned count) { cstr out = cstr_NULL; size_t from = 0; char* res; - if (count == 0) count = ~0; if (find.size) while (count-- && (res = cstrnstrn(str.str + from, find.str, str.size - from, find.size))) { const size_t pos = res - str.str; diff --git a/src/cregex.c b/src/cregex.c index c30ff967..d19b063f 100644 --- a/src/cregex.c +++ b/src/cregex.c @@ -1268,8 +1268,8 @@ cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned } cstr -cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count, - bool (*mfun)(int, csview, cstr*), int crflags) { +cregex_replace_pattern_ex(const char* pattern, const char* input, const char* replace, unsigned count, + bool (*mfun)(int, csview, cstr*), int crflags) { cregex re = cregex_init(); if (cregex_compile(&re, pattern, crflags) != CREG_OK) assert(0); -- cgit v1.2.3 From 4f0f45422fb58e9b134445ad6a4ea96d806214e8 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 30 Dec 2022 12:36:13 +0100 Subject: More restructuring of files and cleanup. Moved carr2.h and carr3.h to misc/include/old/ as it is not among classic containers. Removed stctest.h: Recommending https://github.com/bvdberg/ctest instead. --- .gitattributes | 2 +- .gitignore | 2 +- README.md | 107 +++++---- docs/cstr_api.md | 2 +- include/stc/algo/filter.h | 28 ++- include/stc/carr2.h | 152 ------------ include/stc/carr3.h | 157 ------------ include/stc/cstack.h | 5 +- misc/examples/demos.c | 30 --- misc/examples/mapmap.c | 18 +- misc/examples/multimap.c | 31 +-- misc/examples/new_arr.c | 57 ----- misc/examples/sort.c | 48 ++++ misc/examples/utf8replace_c.c | 23 +- misc/examples/utf8replace_rs.rs | 11 +- misc/include/alt/csmap.h | 512 ---------------------------------------- misc/include/alt/cstr.h | 384 ------------------------------ misc/include/c11/fmt.h | 262 ++++++++++++++++++++ misc/include/fmt.h | 253 -------------------- misc/include/old/carr2.h | 152 ++++++++++++ misc/include/old/carr3.h | 157 ++++++++++++ misc/include/old/csmap.h | 512 ++++++++++++++++++++++++++++++++++++++++ misc/include/old/cstr.h | 384 ++++++++++++++++++++++++++++++ misc/include/old/new_arr.c | 57 +++++ misc/include/stctest.h | 203 ---------------- 25 files changed, 1705 insertions(+), 1844 deletions(-) delete mode 100644 include/stc/carr2.h delete mode 100644 include/stc/carr3.h delete mode 100644 misc/examples/new_arr.c create mode 100644 misc/examples/sort.c delete mode 100644 misc/include/alt/csmap.h delete mode 100644 misc/include/alt/cstr.h create mode 100644 misc/include/c11/fmt.h delete mode 100644 misc/include/fmt.h create mode 100644 misc/include/old/carr2.h create mode 100644 misc/include/old/carr3.h create mode 100644 misc/include/old/csmap.h create mode 100644 misc/include/old/cstr.h create mode 100644 misc/include/old/new_arr.c delete mode 100644 misc/include/stctest.h (limited to 'misc/examples') diff --git a/.gitattributes b/.gitattributes index 66fdcd56..489a12a4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,3 @@ -benchmarks/external/* linguist-vendored +misc/benchmarks/external/* linguist-vendored *.h linguist-language=C *.c linguist-language=C diff --git a/.gitignore b/.gitignore index 5884e998..5fc6203f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Folders stuff/* -benchmarks/external/* +misc/benchmarks/external/* # Prerequisites *.d diff --git a/README.md b/README.md index 848da4bb..f3e0cfb5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ STC - Smart Template Containers for C ===================================== -News: Version 4.0 Release Candidate 3 (Sep 2022) +News: Version 4.1 Beta (Dec 2022) ------------------------------------------------ - [See detailed changes for version 4](#version-4). @@ -44,8 +44,8 @@ Containers Others ------ -- [***ccommon*** - Generic algorithms and macros](docs/ccommon_api.md) -- [***cregex*** - Regular expression parser (extended from Rob Pike's regexp9)](docs/cregex_api.md) +- [***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) - [***coption*** - getopt() alike command line args parser](docs/coption_api.md) @@ -63,26 +63,26 @@ Highlights - **Compiles with C++ and C99** - C code can be compiled with C++ (container element types must be POD). - **Container prefix and forward declaration** - Templated containers may have user defined prefix, e.g. myvec_push_back(). They may also be forward declared without including the full API/implementation. See documentation below. -Three standout features of STC are -1. the centralized analysis of template arguments: It assigns good defaults to non-specified templates. +Three 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, additional template arguments must be defined. -2. the general "heterogeneous lookup"-like feature: Allows specification of an alternative type to use +2. ***General "heterogeneous lookup"-like feature***. Allows specification of an alternative type to use for lookup in containers. E.g. for containers with string type (**cstr**) elements, `const char*` is used as lookup type. It will then use the input `const char*` directly when comparing with the string data in the container. This avoids the construction of a new `cstr` (which possible allocates memory) for the lookup. Finally, destruction of the lookup key (i.e. string literal) after usage is not needed (or allowed), which is convenient in C. The alternative lookup type may also be used for adding entries into containers by using the *emplace*-functions. E.g. `MyCStrVec_emplace_back(&vec, "Hello")`, which further simplifies usage of STC. -3. the design of iterators: All container can be iterated the same way, and uses the +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)` may be used to iterate from `it1` up to `it2`. Performance ----------- -![Benchmark](benchmarks/pics/benchmark.gif) +![Benchmark](misc/benchmarks/pics/benchmark.gif) Benchmark notes: - The barchart shows average test times over three platforms: Mingw64 10.30, Win-Clang 12, VC19. CPU: Ryzen 7 2700X CPU @4Ghz. @@ -99,11 +99,12 @@ The usage of the containers is similar to the c++ standard containers in STL, so are familiar with them. All containers are generic/templated, except for **cstr** and **cbits**. No casting is used, so containers are type-safe like templates in c++. A basic usage example: ```c -#define i_type FVec // if not defined, vector type would be cvec_float -#define i_val float // container value type -#include // defines the FVec type +#define i_type FVec // Container type name; if not defined, it would be cvec_float +#define i_val float // Container element type +#include -int main(void) { +int main(void) +{ FVec vec = FVec_init(); FVec_push_back(&vec, 10.f); FVec_push_back(&vec, 20.f); @@ -112,7 +113,7 @@ int main(void) { for (size_t i = 0; i < FVec_size(vec); ++i) printf(" %g", vec.data[i]); - FVec_drop(&vec); // free memory + FVec_drop(&vec); // cleanup memory } ``` Below is an alternative way to write this code with STC. It uses three @@ -120,15 +121,17 @@ macros: `c_AUTO`, `c_FORLIST`, and `c_FOREACH`. These macro not only simplifies the code, but more importantly makes it less prone to errors, while maintaining readability: ```c -int main() { - c_AUTO (FVec, vec) // RAII: init + free at one location in the code. +int main() +{ + c_AUTO (FVec, vec) // RAII: define vec, init() and drop() all-in-one syntax. { - c_FORLIST (i, float, {10.f, 20.f, 30.f}) // use array literals. - FVec_push(&vec, *i.ref); // alias for push_back. + c_FORLIST (i, float, {10.f, 20.f, 30.f}) // Iterate a list of floats. + FVec_push(&vec, *i.ref); // All containers have push() method. - c_FOREACH (i, FVec, vec) // works for all containers. - printf(" %g", *i.ref); - } + c_FOREACH (i, FVec, vec) // Iterate elements of the container. + printf(" %g", *i.ref); // i.ref is a pointer to the current element. + + } // vec is auto cleaned up at end of scope } ``` For struct element types, an `i_cmp` compare function is required (uses `<` and `==` by default, @@ -160,11 +163,7 @@ With six different containers: #include struct Point { float x, y; }; - -int Point_cmp(const struct Point* a, const struct Point* b) { - int cmp = c_default_cmp(&a->x, &b->x); - return cmp ? cmp : c_default_cmp(&a->y, &b->y); -} +int Point_cmp(const struct Point* a, const struct Point* b); #define i_key int #include // cset_int: unordered set @@ -187,8 +186,14 @@ int Point_cmp(const struct Point* a, const struct Point* b) { #define i_val int #include // csmap_int: sorted map int => int -int main(void) { - /* define six containers with automatic call of init and drop (destruction after scope exit) */ +int Point_cmp(const struct Point* a, const struct Point* b) { + int cmp = c_default_cmp(&a->x, &b->x); + return cmp ? cmp : c_default_cmp(&a->y, &b->y); +} + +int main(void) +{ + /* Define six containers with automatic call of init and drop (destruction after scope exit) */ c_AUTO (cset_int, set) c_AUTO (cvec_pnt, vec) c_AUTO (cdeq_int, deq) @@ -200,40 +205,58 @@ int main(void) { struct Point pts[4] = { {10, 1}, {20, 2}, {30, 3}, {40, 4} }; int pairs[4][2] = { {20, 2}, {10, 1}, {30, 3}, {40, 4} }; - /* add some elements to each container */ + /* Add some elements to each container */ for (int i = 0; i < 4; ++i) { cset_int_insert(&set, nums[i]); cvec_pnt_push(&vec, pts[i]); cdeq_int_push_back(&deq, nums[i]); clist_int_push_back(&lst, nums[i]); - cstack_int_push(&set, nums[i]); + cstack_int_push(&stk, nums[i]); csmap_int_insert(&map, pairs[i][0], pairs[i][1]); } - /* find an element in each container (except cstack) */ + /* Find an element in each container (except cstack) */ cset_int_iter i1 = cset_int_find(&set, 20); cvec_pnt_iter i2 = cvec_pnt_find(&vec, (struct Point){20, 2}); cdeq_int_iter i3 = cdeq_int_find(&deq, 20); clist_int_iter i4 = clist_int_find(&lst, 20); csmap_int_iter i5 = csmap_int_find(&map, 20); - printf("\nFound: %d, (%g, %g), %d, %d, [%d: %d]\n", *i1.ref, i2.ref->x, i2.ref->y, - *i3.ref, *i4.ref, - i5.ref->first, i5.ref->second); - /* erase the elements found */ + + printf("\nFound: %d, (%g, %g), %d, %d, [%d: %d]\n", + *i1.ref, i2.ref->x, i2.ref->y, *i3.ref, + *i4.ref, i5.ref->first, i5.ref->second); + + /* Erase the elements found */ cset_int_erase_at(&set, i1); cvec_pnt_erase_at(&vec, i2); cdeq_int_erase_at(&deq, i3); clist_int_erase_at(&lst, i4); csmap_int_erase_at(&map, i5); - printf("After erasing elements found:"); - printf("\n set:"); c_FOREACH (i, cset_int, set) printf(" %d", *i.ref); - printf("\n vec:"); c_FOREACH (i, cvec_pnt, vec) printf(" (%g, %g)", i.ref->x, i.ref->y); - printf("\n deq:"); c_FOREACH (i, cdeq_int, deq) printf(" %d", *i.ref); - printf("\n lst:"); c_FOREACH (i, clist_int, lst) printf(" %d", *i.ref); - printf("\n stk:"); c_FOREACH (i, cstack_int, stk) printf(" %d", *i.ref); - printf("\n map:"); c_FOREACH (i, csmap_int, map) printf(" [%d: %d]", i.ref->first, - i.ref->second); + printf("After erasing the elements found:"); + printf("\n set:"); + c_FOREACH (i, cset_int, set) + printf(" %d", *i.ref); + + printf("\n vec:"); + c_FOREACH (i, cvec_pnt, vec) + printf(" (%g, %g)", i.ref->x, i.ref->y); + + printf("\n deq:"); + c_FOREACH (i, cdeq_int, deq) + printf(" %d", *i.ref); + + printf("\n lst:"); + c_FOREACH (i, clist_int, lst) + printf(" %d", *i.ref); + + printf("\n stk:"); + c_FOREACH (i, cstack_int, stk) + printf(" %d", *i.ref); + + printf("\n map:"); + c_FOREACH (i, csmap_int, map) + printf(" [%d: %d]", i.ref->first, i.ref->second); } } ``` diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 0ee8b2cb..4f895549 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -76,8 +76,8 @@ void cstr_replace_at_sv(cstr* self, size_t pos, size_t len, const csview void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl); bool cstr_equals(const cstr* self, const char* str); -bool cstr_equals_s(const cstr* self, cstr s); bool cstr_equals_sv(const cstr* self, csview sv); +bool cstr_equals_s(const cstr* self, cstr s); size_t cstr_find(const cstr* self, const char* search); size_t cstr_find_at(const cstr* self, size_t pos, const char* search); // search from pos diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index 486568f2..10aeb7e7 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -23,24 +23,26 @@ /* #include #define i_val int -#define i_capacity 10 #include #include int main() { - cstack_int stk = cstack_INITIALIZER(int, {1, 2, 3, 4, 5, 6, 7, 8, 9}); - - c_foreach (i, cstack_int, stk) - printf(" %d", *i.ref); - puts(""); - - c_forfilter (i, cstack_int, stk - , c_flt_skipwhile(i, *i.ref < 3) - && (*i.ref & 1) == 0 // even only - , c_flt_take(i, 2)) // break after 2 - printf(" %d", *i.ref); - puts(""); + c_WITH (cstack_int stk = {0}, cstack_int_drop(&stk)) { + c_FORLIST (i, int, {1, 2, 3, 4, 5, 6, 7, 8, 9}) + cstack_int_push(&stk, i); + + c_FOREACH (i, cstack_int, stk) + printf(" %d", *i.ref); + puts(""); + + c_FORFILTER (i, cstack_int, stk + , c_flt_skipwhile(i, *i.ref < 3) + && (*i.ref & 1) == 0 // even only + , c_flt_take(i, 2)) // break after 2 + printf(" %d", *i.ref); + puts(""); + } } */ #ifndef STC_FILTER_H_INCLUDED diff --git a/include/stc/carr2.h b/include/stc/carr2.h deleted file mode 100644 index 89ae9b77..00000000 --- a/include/stc/carr2.h +++ /dev/null @@ -1,152 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "ccommon.h" - -#ifndef CARR2_H_INCLUDED -#define CARR2_H_INCLUDED -#include "forward.h" -#include -#endif -/* -// carr2- 2D dynamic array in one memory block with easy indexing. -#define i_key int -#include -#include - -int main() { - int w = 7, h = 5; - c_with (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) - dat[i] = i; - - for (int x = 0; x < image.xdim; ++x) - for (int y = 0; y < image.ydim; ++y) - printf(" %d", image.data[x][y]); - puts("\n"); - - c_foreach (i, carr2_int, image) - printf(" %d", *i.ref); - puts(""); - } -} -*/ - -#ifndef _i_prefix -#define _i_prefix carr2_ -#endif -#include "priv/template.h" -#if !c_option(c_is_forward) -_cx_deftypes(_c_carr2_types, _cx_self, i_key); -#endif - -STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null); -STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* storage); -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, 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)(const _cx_self* self) - { return self->xdim*self->ydim; } - -STC_INLINE _cx_value *_cx_memb(_data)(_cx_self* self) - { return *self->data; } - -STC_INLINE const _cx_value *_cx_memb(_at)(const _cx_self* self, size_t x, size_t y) { - assert(x < self->xdim && y < self->ydim); - return *self->data + self->ydim*x + y; -} - -STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y) { - return self->ydim*x + y; -} - - -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { - size_t n = self->xdim*self->ydim; - return c_INIT(_cx_iter){n ? *self->data : NULL, *self->data + n}; -} - -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_INIT(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; } - -STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->end) it->ref = NULL; } - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* block) { - _cx_self _arr = {c_alloc_n(_cx_value*, xdim), xdim, ydim}; - for (size_t x = 0; x < xdim; ++x, block += ydim) - _arr.data[x] = block; - return _arr; -} - -STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null) { - _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim); - for (_cx_value* p = _arr.data[0], *e = p + xdim*ydim; p != e; ++p) - *p = null; - return _arr; -} - -#if !defined i_no_clone - -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) - *p = i_keyclone((*q)); - return _arr; -} - -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 - -STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) { - _cx_value *values = self->data[0]; - c_free(self->data); - self->data = NULL; - return values; -} - -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; ) { - --q; i_keydrop(q); - } - c_free(self->data[0]); /* values */ - c_free(self->data); /* pointers */ -} - -#endif -#include "priv/template.h" diff --git a/include/stc/carr3.h b/include/stc/carr3.h deleted file mode 100644 index d167dd69..00000000 --- a/include/stc/carr3.h +++ /dev/null @@ -1,157 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "ccommon.h" - -#ifndef CARR3_H_INCLUDED -#define CARR3_H_INCLUDED -#include "forward.h" -#include -#endif -/* -// carr3 - 3D dynamic array in one memory block with easy indexing. -#define i_key int -#include -#include - -int main() { - int w = 7, h = 5, d = 3; - c_with (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) - dat[i] = i; - - for (int x = 0; x < image.xdim; ++x) - for (int y = 0; y < image.ydim; ++y) - for (int z = 0; z < image.zdim; ++z) - printf(" %d", image.data[x][y][z]); - puts("\n"); - - c_foreach (i, carr3_int, image) - printf(" %d", *i.ref); - puts(""); - } -} -*/ - -#ifndef _i_prefix -#define _i_prefix carr3_ -#endif -#include "priv/template.h" - -#if !c_option(c_is_forward) -_cx_deftypes(_c_carr3_types, _cx_self, i_key); -#endif - -STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null); -STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); -STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_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, 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)(const _cx_self* self) - { return self->xdim*self->ydim*self->zdim; } - -STC_INLINE _cx_value* _cx_memb(_data)(_cx_self* self) - { return **self->data; } - -STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, size_t x, size_t y, size_t z) { - assert(x < self->xdim && y < self->ydim && z < self->zdim); - return **self->data + self->zdim*(self->ydim*x + y) + z; -} - -STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_t z) { - return self->zdim*(self->ydim*x + y) + z; -} - - -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { - size_t n = _cx_memb(_size)(self); - return c_INIT(_cx_iter){n ? **self->data : NULL, **self->data + n}; -} - -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_INIT(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; } - -STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->end) it->ref = NULL; } - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* block) { - _cx_self _arr = {c_alloc_n(_cx_value**, xdim*(ydim + 1)), xdim, ydim, zdim}; - _cx_value** p = (_cx_value**) &_arr.data[xdim]; - for (size_t x = 0, y; x < xdim; ++x, p += ydim) - for (y = 0, _arr.data[x] = p; y < ydim; ++y, block += zdim) - p[y] = block; - return _arr; -} - -STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null) { - _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim, zdim); - for (_cx_value* p = **_arr.data, *e = p + xdim*ydim*zdim; p != e; ++p) - *p = null; - return _arr; -} - -#if !defined i_no_clone - -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) - *p = i_keyclone((*q)); - return _arr; -} - -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 - -STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) { - _cx_value *values = self->data[0][0]; - c_free(self->data); - self->data = NULL; - return values; -} - -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; ) { - --q; i_keydrop(q); - } - c_free(self->data[0][0]); /* data */ - c_free(self->data); /* pointers */ -} - -#endif -#include "priv/template.h" diff --git a/include/stc/cstack.h b/include/stc/cstack.h index e4b64848..5e87cf9f 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -52,9 +52,6 @@ STC_INLINE _cx_self _cx_memb(_init)(void) { } #ifdef i_capacity -#define cstack_INITIALIZER(T, ...) \ - {.data=__VA_ARGS__, ._len=sizeof((T[])__VA_ARGS__)/sizeof(T)} - STC_INLINE void _cx_memb(_create)(_cx_self* self) { self->_len = 0; } #else @@ -71,7 +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 +#endif // i_capacity STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_value *p = self->data + self->_len; diff --git a/misc/examples/demos.c b/misc/examples/demos.c index 4a9fac89..4455b840 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -185,35 +185,6 @@ void mapdemo3() cmap_str_drop(&table); // frees key and value cstrs, and hash table. } -#define i_val float -#define i_tag f -#include - -void arraydemo1() -{ - printf("\nARRAYDEMO1\n"); - c_WITH (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), - carr3_f_drop(&arr3)) - { - arr3.data[5][4][3] = 10.2f; - float **arr2 = arr3.data[5]; - float *arr1 = arr3.data[5][4]; - - printf("arr3: %" c_ZU ": (%" c_ZU ", %" c_ZU ", %" c_ZU ") = %" c_ZU "\n", sizeof(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 - printf("%g\n", arr3.data[5][4][3]); // = 10.2 - - float x = 0.0; - c_FOREACH (i, carr3_f, arr3) - *i.ref = ++x; - printf("%g\n", arr3.data[29][19][9]); // = 6000 - } -} - - int main() { stringdemo1(); @@ -224,5 +195,4 @@ int main() mapdemo1(); mapdemo2(); mapdemo3(); - arraydemo1(); } diff --git a/misc/examples/mapmap.c b/misc/examples/mapmap.c index c361233b..d5fe9c81 100644 --- a/misc/examples/mapmap.c +++ b/misc/examples/mapmap.c @@ -4,18 +4,24 @@ // People: std::map #define i_type People -#define i_key_str -#define i_val_str +#define i_key_str // name +#define i_val_str // email #define i_keydrop(p) (printf("kdrop: %s\n", cstr_str(p)), cstr_drop(p)) // override #include // Departments: std::map #define i_type Departments -#define i_key_str +#define i_key_str // dep. name #define i_valclass People -// Shorthand for: +// i_key_str implies: +// #define i_tag str +// #define i_key cstr +// #define i_keyclone cstr_clone +// #define i_keydrop cstr_drop +// #define i_cmp cstr_cmp +// #define i_hash cstr_hash +// i_valclass implies: // #define i_val People -// #define i_cmp People_cmp // #define i_valclone People_clone // #define i_valdrop People_drop #include @@ -23,7 +29,7 @@ void add(Departments* deps, const char* name, const char* email, const char* dep) { - People *people = &Departments_insert(deps, cstr_from(dep), People_init()).ref->second; + People *people = &Departments_emplace(deps, dep, People_init()).ref->second; People_emplace_or_assign(people, name, email); } diff --git a/misc/examples/multimap.c b/misc/examples/multimap.c index 8797c24e..ba0bf71b 100644 --- a/misc/examples/multimap.c +++ b/misc/examples/multimap.c @@ -32,14 +32,14 @@ struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = {1924, "Chamonix", "France", "January 25 - February 5"}, }; -typedef struct { int year; cstr city, date; } OlympicLocation; +typedef struct { int year; cstr city, date; } OlympicLoc; -int OlympicLocation_cmp(const OlympicLocation* a, const OlympicLocation* b); -OlympicLocation OlympicLocation_clone(OlympicLocation loc); -void OlympicLocation_drop(OlympicLocation* self); +int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b); +OlympicLoc OlympicLoc_clone(OlympicLoc loc); +void OlympicLoc_drop(OlympicLoc* self); -// Create a clist, can be sorted by year. -#define i_valclass OlympicLocation // binds _cmp, _clone and _drop. +// Create a clist, can be sorted by year. +#define i_valclass OlympicLoc // binds _cmp, _clone and _drop. #define i_tag OL #define i_extern // define _clist_mergesort() #include @@ -50,19 +50,22 @@ void OlympicLocation_drop(OlympicLocation* self); #define i_tag OL #include -int OlympicLocation_cmp(const OlympicLocation* a, const OlympicLocation* b) { +int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b) { return a->year - b->year; } -OlympicLocation OlympicLocation_clone(OlympicLocation loc) { +OlympicLoc OlympicLoc_clone(OlympicLoc loc) { loc.city = cstr_clone(loc.city); loc.date = cstr_clone(loc.date); return loc; } -void OlympicLocation_drop(OlympicLocation* self) { - c_DROP(cstr, &self->city, &self->date); + +void OlympicLoc_drop(OlympicLoc* self) { + cstr_drop(&self->city); + cstr_drop(&self->date); } + int main() { // Define the multimap with destructor defered to when block is completed. @@ -73,12 +76,12 @@ int main() for (size_t i = 0; i < c_ARRAYLEN(ol_data); ++i) { struct OlympicsData* d = &ol_data[i]; - OlympicLocation loc = {.year = d->year, - .city = cstr_from(d->city), - .date = cstr_from(d->date)}; + OlympicLoc loc = {.year = d->year, + .city = cstr_from(d->city), + .date = cstr_from(d->date)}; // Insert an empty list for each new country, and append the entry to the list. // If country already exist in map, its list is returned from the insert function. - clist_OL* list = &csmap_OL_insert(&multimap, cstr_from(d->country), empty).ref->second; + clist_OL* list = &csmap_OL_emplace(&multimap, d->country, empty).ref->second; clist_OL_push_back(list, loc); } // Sort locations by year for each country. diff --git a/misc/examples/new_arr.c b/misc/examples/new_arr.c deleted file mode 100644 index 7170d14a..00000000 --- a/misc/examples/new_arr.c +++ /dev/null @@ -1,57 +0,0 @@ -#include - -#define i_val int -#include - -#define i_val int -#include - -#define i_val_str -#include - -int main() -{ - int w = 7, h = 5, d = 3; - - c_WITH (carr2_int volume = carr2_int_new_uninit(w, h), carr2_int_drop(&volume)) - { - int *dat = carr2_int_data(&volume); - for (size_t i = 0; i < carr2_int_size(&volume); ++i) - dat[i] = i; - - for (size_t x = 0; x < volume.xdim; ++x) - for (size_t y = 0; y < volume.ydim; ++y) - printf(" %d", volume.data[x][y]); - puts(""); - - c_FOREACH (i, carr2_int, volume) - printf(" %d", *i.ref); - puts("\n"); - } - - c_WITH (carr3_int volume = carr3_int_new_uninit(w, h, d), carr3_int_drop(&volume)) - { - int *dat = carr3_int_data(&volume); - for (size_t i = 0; i < carr3_int_size(&volume); ++i) - dat[i] = i; - - for (size_t x = 0; x < volume.xdim; ++x) - for (size_t y = 0; y < volume.ydim; ++y) - for (size_t z = 0; z < volume.zdim; ++z) - printf(" %d", volume.data[x][y][z]); - puts(""); - - c_FOREACH (i, carr3_int, volume) - printf(" %d", *i.ref); - puts(""); - } - - c_WITH (carr2_str text2d = carr2_str_with_size(h, d, cstr_NULL), carr2_str_drop(&text2d)) - { - cstr_assign(&text2d.data[2][1], "hello"); - cstr_assign(&text2d.data[4][0], "world"); - - c_FOREACH (i, carr2_str, text2d) - printf("line: %s\n", cstr_str(i.ref)); - } -} diff --git a/misc/examples/sort.c b/misc/examples/sort.c new file mode 100644 index 00000000..65ae7359 --- /dev/null +++ b/misc/examples/sort.c @@ -0,0 +1,48 @@ +#include +#include +#include +#define i_val int +#include +#include +#ifdef __cplusplus +#include +#endif + + +int testsort(csortval_int *a, size_t size, const char *desc) { + clock_t t = clock(); +#ifdef __cplusplus + printf("std::sort: "); + std::sort(a, a + size); +#else + printf("csort: "); + csort_int(a, size); +#endif + t = clock() - t; + + printf("%s: %d elements sorted in %.3fms\n", + desc, (int)size, t*1000.0/CLOCKS_PER_SEC); + return 0; +} + +int main(int argc, char *argv[]) { + size_t i, size = argc > 1 ? strtoull(argv[1], NULL, 0) : 10000000; + csortval_int *a = (csortval_int*)malloc(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(" %d", a[i]); + puts(""); + + 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"); + + free(a); +} diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c index 3645bd0a..2d8d1921 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/utf8replace_c.c @@ -1,23 +1,26 @@ -#define i_extern // add utf8 dependencies #include -#include int main() { - c_AUTO (cstr, hello, upper) { + c_AUTO (cstr, hello, str) { hello = cstr_lit("hell😀 w😀rld"); printf("%s\n", cstr_str(&hello)); /* replace second smiley at utf8 codepoint pos 7 */ - cstr_u8_replace_at(&hello, cstr_u8_to_pos(&hello, 7), 1, c_SV("🐨")); + cstr_u8_replace_at(&hello, + cstr_u8_to_pos(&hello, 7), + 1, + c_SV("🐨") + ); printf("%s\n", cstr_str(&hello)); - cstr_replace_ex(&hello, "🐨", "ø", 1); - printf("%s\n", cstr_str(&hello)); - - upper = cstr_toupper_sv(cstr_sv(&hello)); - c_FOREACH (c, cstr, hello) printf("%.*s,", c_ARGSV(c.u8.chr)); - puts(""); + + //csview sv = c_SV("If you find the time, you will find the winner"); + //str = cstr_replace_sv(sv, c_SV("find"), c_SV("match"), 0); + + str = cstr_lit("If you find the time, you will find the winner"); + cstr_replace(&str, "find", "match"); + printf("\n%s\n", cstr_str(&str)); } } diff --git a/misc/examples/utf8replace_rs.rs b/misc/examples/utf8replace_rs.rs index 717978aa..8b163b4e 100644 --- a/misc/examples/utf8replace_rs.rs +++ b/misc/examples/utf8replace_rs.rs @@ -1,12 +1,12 @@ - pub fn main() { - let mut hello = String::from("hell😀 world"); + let mut hello = String::from("hell😀 w😀rld"); println!("{}", hello); - + + /* replace second smiley at utf8 codepoint pos 7 */ hello.replace_range( hello .char_indices() - .nth(4) + .nth(7) .map(|(pos, ch)| (pos..pos + ch.len_utf8())) .unwrap(), "🐨", @@ -16,4 +16,7 @@ pub fn main() { for c in hello.chars() { print!("{},", c); } + + let str = "If you find the time, you will find the winner"; + println!("\n{}", str.replace("find", "match")); } diff --git a/misc/include/alt/csmap.h b/misc/include/alt/csmap.h deleted file mode 100644 index 4b4e764c..00000000 --- a/misc/include/alt/csmap.h +++ /dev/null @@ -1,512 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -// Sorted/Ordered set and map - implemented as an AA-tree. -/* -#include -#include - -#define i_tag sx // Sorted map -#define i_key_str -#define i_val double -#include - -int main(void) { - c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) - { - csmap_sx_emplace(&m, "Testing one", 1.234); - csmap_sx_emplace(&m, "Testing two", 12.34); - csmap_sx_emplace(&m, "Testing three", 123.4); - - csmap_sx_value *v = csmap_sx_get(&m, "Testing five"); // NULL - double num = *csmap_sx_at(&m, "Testing one"); - csmap_sx_emplace_or_assign(&m, "Testing three", 1000.0); // update - csmap_sx_erase(&m, "Testing two"); - - c_foreach (i, csmap_sx, m) - printf("map %s: %g\n", cstr_str(&i.ref->first), i.ref->second); - } -} -*/ -#include - -#ifndef CSMAP_H_INCLUDED -#define STC_CSMAP_V1 1 -#include -#include -#include -#endif // CSMAP_H_INCLUDED - -#ifndef _i_prefix -#define _i_prefix csmap_ -#endif -#ifdef _i_isset - #define _i_MAP_ONLY c_false - #define _i_SET_ONLY c_true - #define _i_keyref(vp) (vp) -#else - #define _i_ismap - #define _i_MAP_ONLY c_true - #define _i_SET_ONLY c_false - #define _i_keyref(vp) (&(vp)->first) -#endif -#include - -#if !c_option(c_is_forward) -_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, i_size, _i_MAP_ONLY, _i_SET_ONLY); -#endif - -_i_MAP_ONLY( struct _cx_value { - _cx_key first; - _cx_mapped second; -}; ) -struct _cx_node { - struct _cx_node *link[2]; - uint8_t level; - _cx_value value; -}; - -typedef i_keyraw _cx_rawkey; -typedef i_valraw _cx_memb(_rawmapped); -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 cx); -#if !defined i_no_emplace -STC_API _cx_result _cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)); -#endif // !i_no_emplace -#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)); -STC_API _cx_result _cx_memb(_push)(_cx_self* self, _cx_value _val); -STC_API void _cx_memb(_drop)(_cx_self* self); -STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out); -STC_API _cx_iter _cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey); -STC_API _cx_value* _cx_memb(_front)(const _cx_self* self); -STC_API _cx_value* _cx_memb(_back)(const _cx_self* self); -STC_API int _cx_memb(_erase)(_cx_self* self, i_keyraw rkey); -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 cx.size == 0; } -STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cx.size; } -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, i_keyraw rkey) - { _cx_iter it; _cx_memb(_find_it)(self, rkey, &it); return it; } -STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) - { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it) != NULL; } -STC_INLINE const _cx_value* _cx_memb(_get)(const _cx_self* self, i_keyraw rkey) - { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } -STC_INLINE _cx_value* _cx_memb(_get_mut)(_cx_self* self, i_keyraw rkey) - { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } - -STC_INLINE void -_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) { - return _i_SET_ONLY( i_keyto(val) ) - _i_MAP_ONLY( c_INIT(_cx_raw){i_keyto((&val->first)), - i_valto((&val->second))} ); -} - -STC_INLINE int -_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { - _cx_rawkey rx = i_keyto(_i_keyref(x)), ry = i_keyto(_i_keyref(y)); - return i_cmp((&rx), (&ry)); -} - -STC_INLINE void -_cx_memb(_value_drop)(_cx_value* val) { - i_keydrop(_i_keyref(val)); - _i_MAP_ONLY( i_valdrop((&val->second)); ) -} - -#if !defined i_no_clone -STC_INLINE _cx_value -_cx_memb(_value_clone)(_cx_value _val) { - *_i_keyref(&_val) = i_keyclone((*_i_keyref(&_val))); - _i_MAP_ONLY( _val.second = i_valclone(_val.second); ) - return _val; -} - -STC_INLINE void -_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); -} -#endif // !i_no_clone - -#ifndef _i_isset - #if !defined i_no_clone && !defined i_no_emplace - STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped); - #endif - STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped); - - STC_INLINE const _cx_mapped* - _cx_memb(_at)(const _cx_self* self, i_keyraw rkey) - { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } - STC_INLINE _cx_mapped* - _cx_memb(_at_mut)(_cx_self* self, i_keyraw rkey) - { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } -#endif // !_i_isset - -STC_INLINE _cx_iter -_cx_memb(_begin)(const _cx_self* self) { - _cx_iter it; - it.ref = NULL, it._top = 0, it._tn = self->root; - _cx_memb(_next)(&it); - return it; -} - -STC_INLINE _cx_iter -_cx_memb(_end)(const _cx_self* self) { - (void)self; - _cx_iter it; it.ref = NULL, it._top = 0, it._tn = NULL; - return it; -} - -STC_INLINE _cx_iter -_cx_memb(_advance)(_cx_iter it, size_t n) { - while (n-- && it.ref) - _cx_memb(_next)(&it); - return it; -} - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -#ifndef CSMAP_H_INCLUDED -static struct { void *link[2]; uint8_t level; } -_csmap_sentinel = {{&_csmap_sentinel, &_csmap_sentinel}, 0}; -#endif - -static _cx_result _cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey); - -STC_DEF _cx_self -_cx_memb(_init)(void) { - _cx_self cx = {(_cx_node *)&_csmap_sentinel, 0}; - return cx; -} - -STC_DEF _cx_value* -_cx_memb(_front)(const _cx_self* self) { - _cx_node *tn = self->root; - while (tn->link[0]->level) - tn = tn->link[0]; - return &tn->value; -} - -STC_DEF _cx_value* -_cx_memb(_back)(const _cx_self* self) { - _cx_node *tn = self->root; - while (tn->link[1]->level) - tn = tn->link[1]; - return &tn->value; -} - -STC_DEF _cx_result -_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { - _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); - if (res.inserted) - { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} - else - { i_keydrop((&key)); _i_MAP_ONLY( i_valdrop((&mapped)); )} - return res; -} - -STC_DEF _cx_result -_cx_memb(_push)(_cx_self* self, _cx_value _val) { - _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(_i_keyref(&_val))); - if (_res.inserted) - *_res.ref = _val; - else - _cx_memb(_value_drop)(&_val); - return _res; -} - -#ifndef _i_isset - STC_DEF _cx_result - _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { - _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); - if (res.inserted) - res.ref->first = key; - else - { i_keydrop((&key)); i_valdrop((&res.ref->second)); } - res.ref->second = mapped; - return res; - } - #if !defined i_no_clone && !defined i_no_emplace - STC_DEF _cx_result - _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { - _cx_result res = _cx_memb(_insert_entry_)(self, rkey); - if (res.inserted) - res.ref->first = i_keyfrom(rkey); - else - { i_valdrop((&res.ref->second)); } - res.ref->second = i_valfrom(rmapped); - return res; - } - #endif // !i_no_clone && !i_no_emplace -#endif // !_i_isset - -STC_DEF _cx_value* -_cx_memb(_find_it)(const _cx_self* self, _cx_rawkey rkey, _cx_iter* out) { - _cx_node *tn = self->root; - out->_top = 0; - while (tn->level) { - int c; _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); - if ((c = i_cmp((&raw), (&rkey))) < 0) - tn = tn->link[1]; - else if (c > 0) - { out->_st[out->_top++] = tn; tn = tn->link[0]; } - else - { out->_tn = tn->link[1]; return (out->ref = &tn->value); } - } - return (out->ref = NULL); -} - -STC_DEF _cx_iter -_cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey) { - _cx_iter it; - _cx_memb(_find_it)(self, rkey, &it); - if (!it.ref && it._top) { - _cx_node *tn = it._st[--it._top]; - it._tn = tn->link[1]; - it.ref = &tn->value; - } - return it; -} - -STC_DEF void -_cx_memb(_next)(_cx_iter *it) { - _cx_node *tn = it->_tn; - if (it->_top || tn->level) { - while (tn->level) { - it->_st[it->_top++] = tn; - tn = tn->link[0]; - } - tn = it->_st[--it->_top]; - it->_tn = tn->link[1]; - it->ref = &tn->value; - } else - it->ref = NULL; -} - -static _cx_node * -_cx_memb(_skew_)(_cx_node *tn) { - if (tn && tn->link[0]->level == tn->level && tn->level) { - _cx_node *tmp = tn->link[0]; - tn->link[0] = tmp->link[1]; - tmp->link[1] = tn; - tn = tmp; - } - return tn; -} - -static _cx_node * -_cx_memb(_split_)(_cx_node *tn) { - if (tn->link[1]->link[1]->level == tn->level && tn->level) { - _cx_node *tmp = tn->link[1]; - tn->link[1] = tmp->link[0]; - tmp->link[0] = tn; - tn = tmp; - ++tn->level; - } - return tn; -} - -static _cx_node* -_cx_memb(_insert_entry_i_)(_cx_node* tn, const _cx_rawkey* rkey, _cx_result* res) { - _cx_node *up[64], *tx = tn; - int c, top = 0, dir = 0; - while (tx->level) { - up[top++] = tx; - _cx_rawkey r = i_keyto(_i_keyref(&tx->value)); - if (!(c = (i_cmp((&r), rkey)))) - { res->ref = &tx->value; return tn; } - dir = (c < 0); - tx = tx->link[dir]; - } - tn = c_alloc(_cx_node); - tn->link[0] = tn->link[1] = (_cx_node*)&_csmap_sentinel; - tn->level = 1; - res->ref = &tn->value, res->inserted = true; - if (top == 0) - return tn; - up[top - 1]->link[dir] = tn; - while (top--) { - if (top) - dir = (up[top - 1]->link[1] == up[top]); - up[top] = _cx_memb(_skew_)(up[top]); - up[top] = _cx_memb(_split_)(up[top]); - if (top) - up[top - 1]->link[dir] = up[top]; - } - return up[0]; -} - -STC_DEF _cx_result -_cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey) { - _cx_result res = {NULL}; - self->root = _cx_memb(_insert_entry_i_)(self->root, &rkey, &res); - self->size += res.inserted; - return res; -} - -static _cx_node* -_cx_memb(_erase_r_)(_cx_node *tn, const _cx_rawkey* rkey, int *erased) { - if (tn->level == 0) - return tn; - _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); - _cx_node *tx; int c = (i_cmp((&raw), rkey)); - if (c != 0) - tn->link[c < 0] = _cx_memb(_erase_r_)(tn->link[c < 0], rkey, erased); - else { - if (!*erased) - { _cx_memb(_value_drop)(&tn->value); *erased = 1; } - if (tn->link[0]->level && tn->link[1]->level) { - tx = tn->link[0]; - while (tx->link[1]->level) - tx = tx->link[1]; - tn->value = tx->value; - raw = i_keyto(_i_keyref(&tn->value)); - tn->link[0] = _cx_memb(_erase_r_)(tn->link[0], &raw, erased); - } else { /* unlink node */ - tx = tn; - tn = tn->link[tn->link[0]->level == 0]; - c_free(tx); - } - } - if (tn->link[0]->level < tn->level - 1 || tn->link[1]->level < tn->level - 1) { - if (tn->link[1]->level > --tn->level) - tn->link[1]->level = tn->level; - tn = _cx_memb(_skew_)(tn); - tx = tn->link[0] = _cx_memb(_skew_)(tn->link[0]); - tx->link[0] = _cx_memb(_skew_)(tx->link[0]); - tn = _cx_memb(_split_)(tn); - tn->link[0] = _cx_memb(_split_)(tn->link[0]); - } - return tn; -} - -STC_DEF int -_cx_memb(_erase)(_cx_self* self, i_keyraw rkey) { - int erased = 0; - self->root = _cx_memb(_erase_r_)(self->root, &rkey, &erased); - self->size -= erased; - return erased; -} - -STC_DEF _cx_iter -_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { - _cx_rawkey raw = i_keyto(_i_keyref(it.ref)), nxt; - _cx_memb(_next)(&it); - if (it.ref) - nxt = i_keyto(_i_keyref(it.ref)); - _cx_memb(_erase)(self, raw); - if (it.ref) - _cx_memb(_find_it)(self, nxt, &it); - return it; -} - -STC_DEF _cx_iter -_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { - if (!it2.ref) { - while (it1.ref) - it1 = _cx_memb(_erase_at)(self, it1); - return it1; - } - _cx_key k1 = *_i_keyref(it1.ref), k2 = *_i_keyref(it2.ref); - _cx_rawkey r1 = i_keyto((&k1)); - for (;;) { - if (memcmp(&k1, &k2, sizeof k1) == 0) - return it1; - _cx_memb(_next)(&it1); - k1 = *_i_keyref(it1.ref); - _cx_memb(_erase)(self, r1); - r1 = i_keyto((&k1)); - _cx_memb(_find_it)(self, r1, &it1); - } -} - -#if !defined i_no_clone -static _cx_node* -_cx_memb(_clone_r_)(_cx_node *tn) { - if (! tn->level) - return tn; - _cx_node *cn = c_alloc(_cx_node); - cn->level = tn->level; - cn->value = _cx_memb(_value_clone)(tn->value); - cn->link[0] = _cx_memb(_clone_r_)(tn->link[0]); - cn->link[1] = _cx_memb(_clone_r_)(tn->link[1]); - return cn; -} - -STC_DEF _cx_self -_cx_memb(_clone)(_cx_self cx) { - return c_INIT(_cx_self){_cx_memb(_clone_r_)(cx.root), cx.size}; -} -#endif // !i_no_clone - -#if !defined i_no_emplace -STC_DEF _cx_result -_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { - _cx_result res = _cx_memb(_insert_entry_)(self, rkey); - if (res.inserted) { - *_i_keyref(res.ref) = i_keyfrom(rkey); - _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) - } - return res; -} -#endif // i_no_emplace - -static void -_cx_memb(_drop_r_)(_cx_node* tn) { - if (tn->level != 0) { - _cx_memb(_drop_r_)(tn->link[0]); - _cx_memb(_drop_r_)(tn->link[1]); - _cx_memb(_value_drop)(&tn->value); - c_free(tn); - } -} - -STC_DEF void -_cx_memb(_drop)(_cx_self* self) { - _cx_memb(_drop_r_)(self->root); -} - -#endif // i_implement -#undef _i_isset -#undef _i_ismap -#undef _i_keyref -#undef _i_MAP_ONLY -#undef _i_SET_ONLY -#define CSMAP_H_INCLUDED -#include diff --git a/misc/include/alt/cstr.h b/misc/include/alt/cstr.h deleted file mode 100644 index 8de6c4b0..00000000 --- a/misc/include/alt/cstr.h +++ /dev/null @@ -1,384 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef CSTR_H_INCLUDED -#define CSTR_H_INCLUDED - -#include -#include -#include /* malloc */ -#include -#include -#include /* vsnprintf */ -#include - -#define c_unchecked_container_of(ptr, type, member) \ - ((type*)((char*)(ptr) - offsetof(type, member))) - -typedef char cstr_value; -typedef struct { cstr_value* str; } cstr; -typedef struct { size_t size, cap; char chr[1]; } cstr_priv; -#define _cstr_p(self) c_unchecked_container_of((self)->str, cstr_priv, chr) -#ifdef i_static - static cstr_priv _cstr_nullrep = {0, 0, {0}}; - static const cstr cstr_NULL = {_cstr_nullrep.chr}; -#else - extern const cstr cstr_NULL; -#endif -/* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */ -#define _cstr_opt_mem(cap) ((((offsetof(cstr_priv, chr) + (cap) + 8)>>4)<<4) + 8) -/* optimal string capacity: 7, 23, 39, ... */ -#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(cstr_priv, chr) - 1) - -STC_API cstr cstr_from_n(const char* str, size_t n); -STC_API cstr cstr_from_fmt(const char* fmt, ...); -STC_API char* cstr_reserve(cstr* self, size_t cap); -STC_API void cstr_resize(cstr* self, size_t len, char fill); -STC_API cstr* cstr_assign_n(cstr* self, const char* str, size_t n); -STC_API int cstr_printf(cstr* self, const char* fmt, ...); -STC_API cstr* cstr_append_n(cstr* self, const char* str, size_t n); -STC_API cstr cstr_replace_sv(csview str, csview find, csview repl, unsigned count); -STC_DEF void cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl); -STC_API void cstr_erase(cstr* self, size_t pos, size_t n); -STC_API size_t cstr_find(const cstr* self, const char* needle); -STC_API size_t cstr_find_at(const cstr* self, size_t pos, const char* needle); -STC_API bool cstr_getdelim(cstr *self, int delim, FILE *stream); - -STC_INLINE cstr cstr_init() { return cstr_NULL; } -STC_INLINE const char* cstr_str(const cstr* self) { return self->str; } -#define cstr_toraw(self) (self)->str -STC_INLINE csview cstr_sv(const cstr* self) - { return c_INIT(csview){self->str, _cstr_p(self)->size}; } -#define cstr_lit(literal) \ - cstr_from_n(literal, c_strlen_lit(literal)) -STC_INLINE cstr cstr_from(const char* str) - { return cstr_from_n(str, strlen(str)); } -STC_INLINE char* cstr_data(cstr* self) { return self->str; } -STC_INLINE size_t cstr_size(const cstr* self) { return _cstr_p(self)->size; } -STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_p(&s)->cap; } -STC_INLINE bool cstr_empty(cstr s) { return _cstr_p(&s)->size == 0; } -STC_INLINE void cstr_drop(cstr* self) - { if (_cstr_p(self)->cap) c_free(_cstr_p(self)); } -STC_INLINE cstr cstr_clone(cstr s) - { return cstr_from_n(s.str, _cstr_p(&s)->size); } -STC_INLINE void cstr_clear(cstr* self) - { self->str[_cstr_p(self)->size = 0] = '\0'; } -STC_INLINE cstr* cstr_assign(cstr* self, const char* str) - { return cstr_assign_n(self, str, strlen(str)); } -STC_INLINE cstr* cstr_copy(cstr* self, cstr s) - { return cstr_assign_n(self, s.str, _cstr_p(&s)->size); } -STC_INLINE cstr* cstr_append(cstr* self, const char* str) - { return cstr_append_n(self, str, strlen(str)); } -STC_INLINE cstr* cstr_append_s(cstr* self, cstr s) - { return cstr_append_n(self, s.str, _cstr_p(&s)->size); } -STC_INLINE void cstr_push_back(cstr* self, char value) - { cstr_append_n(self, &value, 1); } -STC_INLINE void cstr_pop_back(cstr* self) - { self->str[ --_cstr_p(self)->size ] = '\0'; } -STC_INLINE void cstr_insert_n(cstr* self, const size_t pos, const char* str, const size_t n) - { cstr_replace_at_sv(self, pos, 0, c_SV(str, n)); } -STC_INLINE void cstr_insert(cstr* self, const size_t pos, const char* str) - { cstr_replace_at_sv(self, pos, 0, c_SV(str, strlen(str))); } -STC_INLINE void cstr_insert_s(cstr* self, const size_t pos, cstr s) - { cstr_replace_at_sv(self, pos, 0, c_SV(s.str, _cstr_p(&s)->size)); } -STC_INLINE void cstr_replace_at(cstr* self, const size_t pos, const size_t len, const char* str) - { cstr_replace_at_sv(self, pos, len, c_SV(str, strlen(str))); } -STC_INLINE void cstr_replace_s(cstr* self, const size_t pos, const size_t len, cstr s) - { cstr_replace_at_sv(self, pos, len, c_SV(s.str, _cstr_p(&s)->size)); } -STC_INLINE char* cstr_front(cstr* self) { return self->str; } -STC_INLINE char* cstr_back(cstr* self) - { return self->str + _cstr_p(self)->size - 1; } -STC_INLINE bool cstr_equals(const cstr* self, const char* str) - { return strcmp(self->str, str) == 0; } -STC_INLINE bool cstr_equals_s(const cstr* self, cstr s) - { return strcmp(self->str, s.str) == 0; } -STC_INLINE bool cstr_contains(const cstr* self, const char* needle) - { return strstr(self->str, needle) != NULL; } -STC_INLINE bool cstr_getline(cstr *self, FILE *stream) - { return cstr_getdelim(self, '\n', stream); } - -STC_INLINE cstr_buf cstr_buffer(cstr* s) { - cstr_priv* p = _cstr_p(s); - return c_INIT(cstr_buf){s->str, p->size, p->cap}; -} - -STC_INLINE cstr cstr_with_capacity(const size_t cap) { - cstr s = cstr_NULL; - cstr_reserve(&s, cap); - return s; -} - -STC_INLINE cstr cstr_with_size(const size_t len, const char fill) { - cstr s = cstr_NULL; - cstr_resize(&s, len, fill); - return s; -} - -STC_INLINE char* cstr_append_uninit(cstr *self, size_t n) { - size_t len = cstr_size(self); char* d; - if (!(d = cstr_reserve(self, len + n))) return NULL; - _cstr_p(self)->size += n; - return d + len; -} - -STC_INLINE cstr* cstr_take(cstr* self, cstr s) { - if (self->str != s.str && _cstr_p(self)->cap) - c_free(_cstr_p(self)); - self->str = s.str; - return self; -} - -STC_INLINE cstr cstr_move(cstr* self) { - cstr tmp = *self; - *self = cstr_NULL; - return tmp; -} - -STC_INLINE bool cstr_starts_with(const cstr* self, const char* sub) { - const char* p = self->str; - while (*sub && *p == *sub) ++p, ++sub; - return *sub == 0; -} - -STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub) { - const size_t n = strlen(sub), sz = _cstr_p(self)->size; - return n <= sz && !memcmp(self->str + sz - n, sub, n); -} - -STC_INLINE int c_strncasecmp(const char* s1, const char* s2, size_t nmax) { - int ret = 0; - while (nmax-- && (ret = tolower(*s1++) - tolower(*s2)) == 0 && *s2++) - ; - return ret; -} - -/* container adaptor functions: */ -#define cstr_cmp(xp, yp) strcmp((xp)->str, (yp)->str) - -STC_INLINE bool cstr_eq(const cstr* x, const cstr* y) { - size_t xs = _cstr_p(x)->size, ys = _cstr_p(y)->size; - return xs == ys && !memcmp(x->str, y->str, xs); -} -STC_INLINE uint64_t cstr_hash(const cstr *self) { - return cfasthash(self->str, _cstr_p(self)->size); -} - -STC_INLINE void cstr_replace_ex(cstr* self, const char* find, const char* repl, unsigned count) { - cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(find, strlen(find)), - c_SV(repl, strlen(repl)), count)); -} -STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl) - { cstr_replace_ex(self, search, repl, ~0U); } - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -#ifndef i_static -static cstr_priv _cstr_nullrep = {0, 0, {0}}; -const cstr cstr_NULL = {_cstr_nullrep.chr}; -#endif - -STC_DEF char* -cstr_reserve(cstr* self, const size_t cap) { - cstr_priv *p = _cstr_p(self); - const size_t oldcap = p->cap; - if (cap > oldcap) { - p = (cstr_priv*) c_realloc(((oldcap != 0) & (p != &_cstr_nullrep)) ? p : NULL, _cstr_opt_mem(cap)); - if (!p) return NULL; - self->str = p->chr; - if (oldcap == 0) self->str[p->size = 0] = '\0'; - p->cap = _cstr_opt_cap(cap); - } - return self->str; -} - -STC_DEF void -cstr_resize(cstr* self, const size_t len, const char fill) { - const size_t n = _cstr_p(self)->size; - cstr_reserve(self, len); - if (len > n) memset(self->str + n, fill, len - n); - if (len | n) self->str[_cstr_p(self)->size = len] = '\0'; -} - -STC_DEF cstr -cstr_from_n(const char* str, const size_t n) { - if (n == 0) return cstr_NULL; - cstr_priv* prv = (cstr_priv*) c_malloc(_cstr_opt_mem(n)); - cstr s = {(char *) memcpy(prv->chr, str, n)}; - s.str[prv->size = n] = '\0'; - prv->cap = _cstr_opt_cap(n); - return s; -} - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -#elif defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4996) -#endif - -STC_DEF int -cstr_vfmt(cstr* self, const char* fmt, va_list args) { - va_list args2; - va_copy(args2, args); - int len = vsnprintf(NULL, (size_t)0, fmt, args); - cstr_reserve(self, len); - vsprintf(self->str, fmt, args2); - va_end(args2); - return _cstr_p(self)->size = len; -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif - -STC_DEF cstr -cstr_from_fmt(const char* fmt, ...) { - cstr ret = cstr_NULL; - va_list args; va_start(args, fmt); - cstr_vfmt(&ret, fmt, args); - va_end(args); - return ret; -} - -STC_DEF int -cstr_printf(cstr* self, const char* fmt, ...) { - cstr ret = cstr_NULL; - va_list args; - va_start(args, fmt); - int n = cstr_vfmt(&ret, fmt, args); - va_end(args); - cstr_drop(self); - *self = ret; - return n; -} - -STC_DEF cstr* -cstr_assign_n(cstr* self, const char* str, const size_t n) { - if (n || _cstr_p(self)->cap) { - cstr_reserve(self, n); - memmove(self->str, str, n); - self->str[_cstr_p(self)->size = n] = '\0'; - } - return self; -} - -STC_DEF cstr* -cstr_append_n(cstr* self, const char* str, const size_t n) { - if (n == 0) return self; - const size_t oldlen = _cstr_p(self)->size, newlen = oldlen + n; - if (newlen > _cstr_p(self)->cap) { - const size_t off = (size_t) (str - self->str); /* handle self append */ - cstr_reserve(self, (oldlen*3 >> 1) + n); - if (off <= oldlen) str = self->str + off; - } - memcpy(&self->str[oldlen], str, n); - self->str[_cstr_p(self)->size = newlen] = '\0'; - return self; -} - -STC_INLINE void _cstr_internal_move(cstr* self, const size_t pos1, const size_t pos2) { - if (pos1 == pos2) - return; - const size_t len = _cstr_p(self)->size, newlen = len + pos2 - pos1; - if (newlen > _cstr_p(self)->cap) - cstr_reserve(self, (len*3 >> 1) + pos2 - pos1); - memmove(&self->str[pos2], &self->str[pos1], len - pos1); - self->str[_cstr_p(self)->size = newlen] = '\0'; -} - -STC_DEF void -cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl) { - const size_t sz = cstr_size(self); - if (len > sz - pos) len = sz - pos; - char buf[256], *xstr = repl.size > 256 ? c_malloc(repl.size) : buf; - memcpy(xstr, repl.str, repl.size); - _cstr_internal_move(self, pos + len, pos + repl.size); - memcpy(&self->str[pos], xstr, repl.size); - if (repl.size > 256) c_free(xstr); -} - -STC_DEF cstr -cstr_replace_sv(csview str, csview find, csview repl, unsigned count) { - cstr out = cstr_NULL; - size_t from = 0; char* res; - if (find.size) - while (count-- && (res = cstrnstrn(str.str + from, find.str, str.size - from, find.size))) { - const size_t pos = res - str.str; - cstr_append_n(&out, str.str + from, pos - from); - cstr_append_n(&out, repl.str, repl.size); - from = pos + find.size; - } - cstr_append_n(&out, str.str + from, str.size - from); - return out; -} - -STC_DEF void -cstr_erase(cstr* self, const size_t pos, size_t n) { - const size_t len = _cstr_p(self)->size; - if (n > len - pos) n = len - pos; - if (len) { - memmove(&self->str[pos], &self->str[pos + n], len - (pos + n)); - self->str[_cstr_p(self)->size -= n] = '\0'; - } -} - -STC_DEF bool -cstr_getdelim(cstr *self, const int delim, FILE *fp) { - size_t pos = 0, cap = _cstr_p(self)->cap; - char* d = self->str; - int c = fgetc(fp); - if (c == EOF) - return false; - for (;;) { - if (c == delim || c == EOF) { - if (cap) d[_cstr_p(self)->size = pos] = '\0'; - return true; - } - if (pos == cap) { - d = cstr_reserve(self, (cap*3 >> 1) + 16); - cap = cstr_capacity(*self); - } - d[pos++] = (char) c; - c = fgetc(fp); - } -} - -STC_DEF size_t -cstr_find(const cstr* self, const char* needle) { - char* res = strstr(self->str, needle); - return res ? res - self->str : c_NPOS; -} - -STC_DEF size_t -cstr_find_at(const cstr* self, const size_t pos, const char* needle) { - if (pos > _cstr_p(self)->size) return c_NPOS; - char* res = strstr(self->str + pos, needle); - return res ? res - self->str : c_NPOS; -} - -#endif -#endif // CSTR_H_INCLUDED -#undef i_opt diff --git a/misc/include/c11/fmt.h b/misc/include/c11/fmt.h new file mode 100644 index 00000000..d5ba3575 --- /dev/null +++ b/misc/include/c11/fmt.h @@ -0,0 +1,262 @@ +#ifndef FMT_INCLUDED +#define FMT_INCLUDED +/* +void fmt_print(dst, fmt, ...); +void fmt_destroy(fmt_buffer* buf); + + dst - destination + int 1=stdout, 2=stderr + FILE* file Write to a file + char* strbuf Write to a pre-allocated string buffer + fmt_buffer* b Auto realloc the needed memory. Set b->stream=1 for stream-mode. + b->data must be freed after usage. + + fmt - format string + {} Auto-detected format. If :MOD is not specified, + float will use ".8g" format, and double ".16g". + {:MOD} Format modifiers: < left align (replaces -), default for char*, char. + > right align, default for numbers. + Other than that MOD can be normal printf format modifiers. + {{, }} Print chars {, and }. (note: a single % prints %). + +* C11 or higher required. +* MAX 255 chars fmt string by default. MAX 12 arguments after fmt string. +* Static linking by default, shared symbols by defining FMT_HEADER / FMT_IMPLEMENT. +* (c) operamint, 2022, MIT License. +----------------------------------------------------------------------------------- +#include "fmt.h" + +int main() { + const double pi = 3.141592653589793; + const size_t x = 1234567890; + const char* string = "Hello world"; + const wchar_t* wstr = L"The whole"; + const char z = 'z'; + _Bool flag = 1; + unsigned char r = 123, g = 214, b = 90, w = 110; + char buffer[64]; + + fmt_print(1, "Color: ({} {} {}), {}\n", r, g, b, flag); + fmt_print(1, "Wide: {}, {}\n", wstr, L"wide world"); + fmt_print(1, "{:10} {:10} {:10.2f}\n", 42ull, 43, pi); + fmt_print(stdout, "{:>10} {:>10} {:>10}\n", z, z, w); + fmt_print(stdout, "{:10} {:10} {:10}\n", "Hello", "Mad", "World"); + fmt_print(stderr, "100%: {:<20} {:.*} {}\n", string, 4, pi, x); + fmt_print(buffer, "Precision: {} {:.10} {}", string, pi, x); + fmt_print(1, "{}\n", buffer); + fmt_print(1, "Vector: ({}, {}, {})\n", 3.2, 3.3, pi); + + fmt_buffer out[1] = {{.stream=1}}; + fmt_print(out, "{} {}", "Pi is:", pi); + fmt_print(1, "{}, len={}, cap={}\n", out->data, out->len, out->cap); + fmt_print(out, "{} {}", ", Pi squared is:", pi*pi); + fmt_print(1, "{}, len={}, cap={}\n", out->data, out->len, out->cap); + fmt_destroy(out); +} +*/ +#include +#include + +#define fmt_OVERLOAD(name, ...) \ + fmt_JOIN(name, fmt_NUMARGS(__VA_ARGS__))(__VA_ARGS__) +#define fmt_CONCAT(a, b) a ## b +#define fmt_JOIN(a, b) fmt_CONCAT(a, b) +#define fmt_EXPAND(...) __VA_ARGS__ +#define fmt_NUMARGS(...) _fmt_APPLY_ARG_N((__VA_ARGS__, _fmt_RSEQ_N)) + +#define _fmt_APPLY_ARG_N(args) fmt_EXPAND(_fmt_ARG_N args) +#define _fmt_RSEQ_N 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +#define _fmt_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ + _14, _15, _16, N, ...) N + +#if defined FMT_HEADER || defined FMT_IMPLEMENT +# define FMT_API +#else +# define FMT_API static inline +#endif +#if defined FMT_NDEBUG || defined NDEBUG +# define fmt_OK(exp) (void)(exp) +#else +# define fmt_OK(exp) assert(exp) +#endif + +typedef struct { + char* data; + size_t cap, len; + _Bool stream; +} fmt_buffer; + +FMT_API void fmt_destroy(fmt_buffer* buf); +FMT_API int _fmt_parse(char* p, int nargs, const char *fmt, ...); +FMT_API void _fmt_iprint(int fd, const char* fmt, ...); +FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...); + +#ifndef FMT_MAX +#define FMT_MAX 256 +#endif + +/* Primary function. */ +#define fmt_print(...) fmt_OVERLOAD(fmt_print, __VA_ARGS__) +#define fmt_print2(to, fmt) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 0, fmt); \ + fmt_OK(_n == 0); _fmt_fn(to)(to, fmt); } while (0) +#define fmt_print3(to, fmt, c) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 1, fmt, _fc(c)); \ + fmt_OK(_n == 1); _fmt_fn(to)(to, _fs, c); } while (0) +#define fmt_print4(to, fmt, c, d) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 2, fmt, _fc(c), _fc(d)); \ + fmt_OK(_n == 2); _fmt_fn(to)(to, _fs, c, d); } while (0) +#define fmt_print5(to, fmt, c, d, e) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 3, fmt, _fc(c), _fc(d), _fc(e)); \ + fmt_OK(_n == 3); _fmt_fn(to)(to, _fs, c, d, e); } while (0) +#define fmt_print6(to, fmt, c, d, e, f) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 4, fmt, _fc(c), _fc(d), _fc(e), _fc(f)); \ + fmt_OK(_n == 4); _fmt_fn(to)(to, _fs, c, d, e, f); } while (0) +#define fmt_print7(to, fmt, c, d, e, f, g) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 5, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g)); \ + fmt_OK(_n == 5); _fmt_fn(to)(to, _fs, c, d, e, f, g); } while (0) +#define fmt_print8(to, fmt, c, d, e, f, g, h) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 6, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h)); \ + fmt_OK(_n == 6); _fmt_fn(to)(to, _fs, c, d, e, f, g, h); } while (0) +#define fmt_print9(to, fmt, c, d, e, f, g, h, i) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 7, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), _fc(i)); \ + fmt_OK(_n == 7); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i); } while (0) +#define fmt_print10(to, fmt, c, d, e, f, g, h, i, j) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 8, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ + _fc(i), _fc(j)); \ + fmt_OK(_n == 8); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j); } while (0) +#define fmt_print11(to, fmt, c, d, e, f, g, h, i, j, k) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 9, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ + _fc(i), _fc(j), _fc(k)); \ + fmt_OK(_n == 9); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k); } while (0) +#define fmt_print12(to, fmt, c, d, e, f, g, h, i, j, k, m) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 10, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ + _fc(i), _fc(j), _fc(k), _fc(m)); \ + fmt_OK(_n == 10); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m); } while (0) +#define fmt_print13(to, fmt, c, d, e, f, g, h, i, j, k, m, n) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 11, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ + _fc(i), _fc(j), _fc(k), _fc(m), _fc(n)); \ + fmt_OK(_n == 11); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m, n); } while (0) +#define fmt_print14(to, fmt, c, d, e, f, g, h, i, j, k, m, n, o) \ + do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 12, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ + _fc(i), _fc(j), _fc(k), _fc(m), _fc(n), _fc(o)); \ + fmt_OK(_n == 12); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m, n, o); } while (0) + +#define _fmt_fn(x) _Generic ((x), \ + FILE*: fprintf, \ + char*: sprintf, \ + int: _fmt_iprint, \ + fmt_buffer*: _fmt_bprint) + +#if defined(_MSC_VER) && !defined(__clang__) +# define _signed_char_hhd +#else +# define _signed_char_hhd signed char: "hhd", +#endif + +#define _fc(x) _Generic (x, \ + _Bool: "d", \ + unsigned char: "hhu", \ + _signed_char_hhd \ + char: "c", \ + short: "hd", \ + unsigned short: "hu", \ + int: "d", \ + unsigned: "u", \ + long: "ld", \ + unsigned long: "lu", \ + long long: "lld", \ + unsigned long long: "llu", \ + float: "g", \ + double: "@g", \ + long double: "@Lg", \ + char*: "s", \ + wchar_t*: "ls", \ + void*: "p", \ + const char*: "s", \ + const wchar_t*: "ls", \ + const void*: "p") + +#if defined FMT_IMPLEMENT || !(defined FMT_HEADER || defined FMT_IMPLEMENT) + +#include +#include +#include + +FMT_API void fmt_destroy(fmt_buffer* buf) { + free(buf->data); +} + +FMT_API void _fmt_iprint(int fd, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vfprintf(fd == 1 ? stdout : stderr, fmt, args); + va_end(args); +} + +FMT_API void _fmt_bprint(fmt_buffer* buf, const char* fmt, ...) { + va_list args, args2; + va_start(args, fmt); + va_copy(args2, args); + const int n = vsnprintf(NULL, 0U, fmt, args); + const size_t pos = buf->stream ? buf->len : 0U; + buf->len = pos + (size_t)n; + if (buf->len > buf->cap) { + buf->cap = buf->len + buf->cap/2; + buf->data = (char*)realloc(buf->data, buf->cap + 1); + } + vsprintf(buf->data + pos, fmt, args2); + va_end(args2); + va_end(args); +} + +FMT_API int _fmt_parse(char* p, int nargs, const char *fmt, ...) { + char *arg, *p0, ch; + int n = 0, empty; + va_list args; + va_start(args, fmt); + do { + switch ((ch = *fmt)) { + case '%': + *p++ = '%'; + break; + case '}': + if (*++fmt == '}') break; /* ok */ + n = 99; + continue; + case '{': + if (*++fmt == '{') break; /* ok */ + if (++n > nargs) continue; + if (*fmt != ':' && *fmt != '}') n = 99; + fmt += (*fmt == ':'); + empty = *fmt == '}'; + arg = va_arg(args, char *); + *p++ = '%', p0 = p; + while (1) switch (*fmt) { + case '\0': n = 99; /* nobreak */ + case '}': goto done; + case '<': *p++ = '-', ++fmt; break; + case '>': p0 = NULL; /* nobreak */ + case '-': ++fmt; break; + case '*': if (++n <= nargs) arg = va_arg(args, char *); /* nobreak */ + default: *p++ = *fmt++; + } + done: + switch (*arg) { + case 'g': if (empty) memcpy(p, ".8", 2), p += 2; break; + case '@': ++arg; if (empty) memcpy(p, ".16", 3), p += 3; break; + } + if (!strchr("csdioxXufFeEaAgGnp", fmt[-1])) + while (*arg) *p++ = *arg++; + if (p0 && (p[-1] == 's' || p[-1] == 'c')) /* left-align str */ + memmove(p0 + 1, p0, p++ - p0), *p0 = '-'; + fmt += *fmt == '}'; + continue; + } + *p++ = *fmt++; + } while (ch); + va_end(args); + return n; +} +#endif +#endif diff --git a/misc/include/fmt.h b/misc/include/fmt.h deleted file mode 100644 index df1fe990..00000000 --- a/misc/include/fmt.h +++ /dev/null @@ -1,253 +0,0 @@ -#ifndef FMT_INCLUDED -#define FMT_INCLUDED -/* -void fmt_print(dst, fmt, ...); -void fmt_destroy(fmt_buffer* buf); - - dst - destination - int 1=stdout, 2=stderr - FILE* file Write to a file - char* strbuf Write to a pre-allocated string buffer - fmt_buffer* b Auto realloc the needed memory. Set b->stream=1 for stream-mode. - b->data must be freed after usage. - - fmt - format string - {} Auto-detected format. If :MOD is not specified, - float will use ".8g" format, and double ".16g". - {:MOD} Format modifiers: < left align (replaces -), default for char*, char. - > right align, default for numbers. - Other than that MOD can be normal printf format modifiers. - {{, }} Print chars {, and }. (note: a single % prints %). - -* C11 or higher required. -* MAX 255 chars fmt string by default. MAX 12 arguments after fmt string. -* Static linking by default, shared symbols by defining FMT_HEADER / FMT_IMPLEMENT. -* (c) operamint, 2022, MIT License. ------------------------------------------------------------------------------------ -#include "fmt.h" - -int main() { - const double pi = 3.141592653589793; - const size_t x = 1234567890; - const char* string = "Hello world"; - const char z = 'z'; - _Bool flag = 1; - unsigned char r = 123, g = 214, b = 90, w = 110; - char buffer[64]; - - fmt_print(1, "Color: ({} {} {}), {}\n", r, g, b, flag); - fmt_print(1, "{:10} {:10} {:10.2f}\n", 42ull, 43, pi); - fmt_print(stdout, "{:>10} {:>10} {:>10}\n", z, z, w); - fmt_print(stdout, "{:10} {:10} {:10}\n", "Hello", "Mad", "World"); - fmt_print(stderr, "100%: {:<20} {:.*} {}\n", string, 4, pi, x); - fmt_print(buffer, "Precision: {} {:.10} {}", string, pi, x); - fmt_print(1, "{}\n", buffer); - fmt_print(1, "Vector: ({}, {}, {})\n", 3.2, 3.3, pi); - - fmt_buffer out[1] = {{.stream=1}}; - fmt_print(out, "{} {}", "Pi is:", pi); - fmt_print(1, "{}, len={}, cap={}\n", out->data, out->len, out->cap); - fmt_print(out, "{} {}", ", Pi squared is:", pi*pi); - fmt_print(1, "{}, len={}, cap={}\n", out->data, out->len, out->cap); - fmt_destroy(out); -} -*/ -#include -#include - -#define fmt_OVERLOAD(name, ...) \ - fmt_JOIN(name, fmt_NUMARGS(__VA_ARGS__))(__VA_ARGS__) -#define fmt_CONCAT(a, b) a ## b -#define fmt_JOIN(a, b) fmt_CONCAT(a, b) -#define fmt_EXPAND(...) __VA_ARGS__ -#define fmt_NUMARGS(...) _fmt_APPLY_ARG_N((__VA_ARGS__, _fmt_RSEQ_N)) - -#define _fmt_APPLY_ARG_N(args) fmt_EXPAND(_fmt_ARG_N args) -#define _fmt_RSEQ_N 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 -#define _fmt_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ - _14, _15, _16, N, ...) N - -#if defined FMT_HEADER || defined FMT_IMPLEMENT -# define FMT_API -#else -# define FMT_API static inline -#endif - -typedef struct { - char* data; - size_t cap, len; - _Bool stream; -} fmt_buffer; - -FMT_API void fmt_destroy(fmt_buffer* buf); -FMT_API int _fmt_parse(char* p, int nargs, const char *fmt, ...); -FMT_API void _fmt_iprint(int fd, const char* fmt, ...); -FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...); - -#ifndef FMT_MAX -#define FMT_MAX 256 -#endif - -/* Primary function. */ -#define fmt_print(...) fmt_OVERLOAD(fmt_print, __VA_ARGS__) -#define fmt_print2(to, fmt) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 0, fmt); \ - assert(_n == 0); _fmt_fn(to)(to, fmt); } while (0) -#define fmt_print3(to, fmt, c) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 1, fmt, _fc(c)); \ - assert(_n == 1); _fmt_fn(to)(to, _fs, c); } while (0) -#define fmt_print4(to, fmt, c, d) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 2, fmt, _fc(c), _fc(d)); \ - assert(_n == 2); _fmt_fn(to)(to, _fs, c, d); } while (0) -#define fmt_print5(to, fmt, c, d, e) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 3, fmt, _fc(c), _fc(d), _fc(e)); \ - assert(_n == 3); _fmt_fn(to)(to, _fs, c, d, e); } while (0) -#define fmt_print6(to, fmt, c, d, e, f) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 4, fmt, _fc(c), _fc(d), _fc(e), _fc(f)); \ - assert(_n == 4); _fmt_fn(to)(to, _fs, c, d, e, f); } while (0) -#define fmt_print7(to, fmt, c, d, e, f, g) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 5, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g)); \ - assert(_n == 5); _fmt_fn(to)(to, _fs, c, d, e, f, g); } while (0) -#define fmt_print8(to, fmt, c, d, e, f, g, h) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 6, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h)); \ - assert(_n == 6); _fmt_fn(to)(to, _fs, c, d, e, f, g, h); } while (0) -#define fmt_print9(to, fmt, c, d, e, f, g, h, i) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 7, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), _fc(i)); \ - assert(_n == 7); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i); } while (0) -#define fmt_print10(to, fmt, c, d, e, f, g, h, i, j) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 8, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ - _fc(i), _fc(j)); \ - assert(_n == 8); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j); } while (0) -#define fmt_print11(to, fmt, c, d, e, f, g, h, i, j, k) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 9, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ - _fc(i), _fc(j), _fc(k)); \ - assert(_n == 9); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k); } while (0) -#define fmt_print12(to, fmt, c, d, e, f, g, h, i, j, k, m) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 10, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ - _fc(i), _fc(j), _fc(k), _fc(m)); \ - assert(_n == 10); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m); } while (0) -#define fmt_print13(to, fmt, c, d, e, f, g, h, i, j, k, m, n) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 11, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ - _fc(i), _fc(j), _fc(k), _fc(m), _fc(n)); \ - assert(_n == 11); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m, n); } while (0) -#define fmt_print14(to, fmt, c, d, e, f, g, h, i, j, k, m, n, o) \ - do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 12, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \ - _fc(i), _fc(j), _fc(k), _fc(m), _fc(n), _fc(o)); \ - assert(_n == 12); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m, n, o); } while (0) - -#define _fmt_fn(x) _Generic ((x), \ - FILE*: fprintf, \ - char*: sprintf, \ - int: _fmt_iprint, \ - fmt_buffer*: _fmt_bprint) - -#if defined(_MSC_VER) && !defined(__clang__) -# define _signed_char_hhd -#else -# define _signed_char_hhd signed char: "hhd", -#endif - -#define _fc(x) _Generic (x, \ - _Bool: "d", \ - unsigned char: "hhu", \ - _signed_char_hhd \ - char: "c", \ - short: "hd", \ - unsigned short: "hu", \ - int: "d", \ - unsigned: "u", \ - long: "ld", \ - unsigned long: "lu", \ - long long: "lld", \ - unsigned long long: "llu", \ - float: "g", \ - double: "@g", \ - long double: "@Lg", \ - char*: "s", \ - void*: "p", \ - const char*: "s", \ - const void*: "p") - -#if defined FMT_IMPLEMENT || !(defined FMT_HEADER || defined FMT_IMPLEMENT) - -#include -#include -#include - -FMT_API void fmt_destroy(fmt_buffer* buf) { - free(buf->data); -} - -FMT_API void _fmt_iprint(int fd, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - vfprintf(fd == 1 ? stdout : stderr, fmt, args); - va_end(args); -} - -FMT_API void _fmt_bprint(fmt_buffer* buf, const char* fmt, ...) { - va_list args, args2; - va_start(args, fmt); - va_copy(args2, args); - const int n = vsnprintf(NULL, 0U, fmt, args); - const size_t pos = buf->stream ? buf->len : 0U; - buf->len = pos + (size_t)n; - if (buf->len > buf->cap) { - buf->cap = buf->len + buf->cap/2; - buf->data = (char*)realloc(buf->data, buf->cap + 1); - } - vsprintf(buf->data + pos, fmt, args2); - va_end(args2); - va_end(args); -} - -FMT_API int _fmt_parse(char* p, int nargs, const char *fmt, ...) { - char *arg, *p0, ch; - int n = 0, empty; - va_list args; - va_start(args, fmt); - do { - switch ((ch = *fmt)) { - case '%': - *p++ = '%'; - break; - case '}': - if (*++fmt == '}') break; /* ok */ - n = 99; - continue; - case '{': - if (*++fmt == '{') break; /* ok */ - if (++n > nargs) continue; - if (*fmt != ':' && *fmt != '}') n = 99; - fmt += (*fmt == ':'); - empty = *fmt == '}'; - arg = va_arg(args, char *); - *p++ = '%', p0 = p; - while (1) switch (*fmt) { - case '\0': n = 99; /* nobreak */ - case '}': goto done; - case '<': *p++ = '-', ++fmt; break; - case '>': p0 = NULL; /* nobreak */ - case '-': ++fmt; break; - case '*': if (++n <= nargs) arg = va_arg(args, char *); /* nobreak */ - default: *p++ = *fmt++; - } - done: - switch (*arg) { - case 'g': if (empty) memcpy(p, ".8", 2), p += 2; break; - case '@': ++arg; if (empty) memcpy(p, ".16", 3), p += 3; break; - } - if (!strchr("csdioxXufFeEaAgGnp", fmt[-1])) - while (*arg) *p++ = *arg++; - if (p0 && (p[-1] == 's' || p[-1] == 'c')) /* left-align str */ - memmove(p0 + 1, p0, p++ - p0), *p0 = '-'; - fmt += *fmt == '}'; - continue; - } - *p++ = *fmt++; - } while (ch); - va_end(args); - return n; -} -#endif -#endif \ No newline at end of file diff --git a/misc/include/old/carr2.h b/misc/include/old/carr2.h new file mode 100644 index 00000000..aebaec81 --- /dev/null +++ b/misc/include/old/carr2.h @@ -0,0 +1,152 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include + +#ifndef CARR2_H_INCLUDED +#define CARR2_H_INCLUDED +#include +#include +#endif +/* +// carr2- 2D dynamic array in one memory block with easy indexing. +#define i_key int +#include +#include + +int main() { + int w = 7, h = 5; + c_with (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) + dat[i] = i; + + for (int x = 0; x < image.xdim; ++x) + for (int y = 0; y < image.ydim; ++y) + printf(" %d", image.data[x][y]); + puts("\n"); + + c_foreach (i, carr2_int, image) + printf(" %d", *i.ref); + puts(""); + } +} +*/ + +#ifndef _i_prefix +#define _i_prefix carr2_ +#endif +#include +#if !c_option(c_is_forward) +_cx_deftypes(_c_carr2_types, _cx_self, i_key); +#endif + +STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null); +STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* storage); +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, 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)(const _cx_self* self) + { return self->xdim*self->ydim; } + +STC_INLINE _cx_value *_cx_memb(_data)(_cx_self* self) + { return *self->data; } + +STC_INLINE const _cx_value *_cx_memb(_at)(const _cx_self* self, size_t x, size_t y) { + assert(x < self->xdim && y < self->ydim); + return *self->data + self->ydim*x + y; +} + +STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y) { + return self->ydim*x + y; +} + + +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + size_t n = self->xdim*self->ydim; + return c_INIT(_cx_iter){n ? *self->data : NULL, *self->data + n}; +} + +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) + { return c_INIT(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->end) it->ref = NULL; } + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* block) { + _cx_self _arr = {c_alloc_n(_cx_value*, xdim), xdim, ydim}; + for (size_t x = 0; x < xdim; ++x, block += ydim) + _arr.data[x] = block; + return _arr; +} + +STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null) { + _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim); + for (_cx_value* p = _arr.data[0], *e = p + xdim*ydim; p != e; ++p) + *p = null; + return _arr; +} + +#if !defined i_no_clone + +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) + *p = i_keyclone((*q)); + return _arr; +} + +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 + +STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) { + _cx_value *values = self->data[0]; + c_free(self->data); + self->data = NULL; + return values; +} + +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; ) { + --q; i_keydrop(q); + } + c_free(self->data[0]); /* values */ + c_free(self->data); /* pointers */ +} + +#endif +#include diff --git a/misc/include/old/carr3.h b/misc/include/old/carr3.h new file mode 100644 index 00000000..a0148992 --- /dev/null +++ b/misc/include/old/carr3.h @@ -0,0 +1,157 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include + +#ifndef CARR3_H_INCLUDED +#define CARR3_H_INCLUDED +#include +#include +#endif +/* +// carr3 - 3D dynamic array in one memory block with easy indexing. +#define i_key int +#include +#include + +int main() { + int w = 7, h = 5, d = 3; + c_with (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) + dat[i] = i; + + for (int x = 0; x < image.xdim; ++x) + for (int y = 0; y < image.ydim; ++y) + for (int z = 0; z < image.zdim; ++z) + printf(" %d", image.data[x][y][z]); + puts("\n"); + + c_foreach (i, carr3_int, image) + printf(" %d", *i.ref); + puts(""); + } +} +*/ + +#ifndef _i_prefix +#define _i_prefix carr3_ +#endif +#include + +#if !c_option(c_is_forward) +_cx_deftypes(_c_carr3_types, _cx_self, i_key); +#endif + +STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null); +STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); +STC_API _cx_value* _cx_memb(_release)(_cx_self* self); +STC_API void _cx_memb(_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, 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)(const _cx_self* self) + { return self->xdim*self->ydim*self->zdim; } + +STC_INLINE _cx_value* _cx_memb(_data)(_cx_self* self) + { return **self->data; } + +STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, size_t x, size_t y, size_t z) { + assert(x < self->xdim && y < self->ydim && z < self->zdim); + return **self->data + self->zdim*(self->ydim*x + y) + z; +} + +STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_t z) { + return self->zdim*(self->ydim*x + y) + z; +} + + +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + size_t n = _cx_memb(_size)(self); + return c_INIT(_cx_iter){n ? **self->data : NULL, **self->data + n}; +} + +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) + { return c_INIT(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->end) it->ref = NULL; } + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* block) { + _cx_self _arr = {c_alloc_n(_cx_value**, xdim*(ydim + 1)), xdim, ydim, zdim}; + _cx_value** p = (_cx_value**) &_arr.data[xdim]; + for (size_t x = 0, y; x < xdim; ++x, p += ydim) + for (y = 0, _arr.data[x] = p; y < ydim; ++y, block += zdim) + p[y] = block; + return _arr; +} + +STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null) { + _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim, zdim); + for (_cx_value* p = **_arr.data, *e = p + xdim*ydim*zdim; p != e; ++p) + *p = null; + return _arr; +} + +#if !defined i_no_clone + +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) + *p = i_keyclone((*q)); + return _arr; +} + +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 + +STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) { + _cx_value *values = self->data[0][0]; + c_free(self->data); + self->data = NULL; + return values; +} + +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; ) { + --q; i_keydrop(q); + } + c_free(self->data[0][0]); /* data */ + c_free(self->data); /* pointers */ +} + +#endif +#include diff --git a/misc/include/old/csmap.h b/misc/include/old/csmap.h new file mode 100644 index 00000000..4b4e764c --- /dev/null +++ b/misc/include/old/csmap.h @@ -0,0 +1,512 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// Sorted/Ordered set and map - implemented as an AA-tree. +/* +#include +#include + +#define i_tag sx // Sorted map +#define i_key_str +#define i_val double +#include + +int main(void) { + c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) + { + csmap_sx_emplace(&m, "Testing one", 1.234); + csmap_sx_emplace(&m, "Testing two", 12.34); + csmap_sx_emplace(&m, "Testing three", 123.4); + + csmap_sx_value *v = csmap_sx_get(&m, "Testing five"); // NULL + double num = *csmap_sx_at(&m, "Testing one"); + csmap_sx_emplace_or_assign(&m, "Testing three", 1000.0); // update + csmap_sx_erase(&m, "Testing two"); + + c_foreach (i, csmap_sx, m) + printf("map %s: %g\n", cstr_str(&i.ref->first), i.ref->second); + } +} +*/ +#include + +#ifndef CSMAP_H_INCLUDED +#define STC_CSMAP_V1 1 +#include +#include +#include +#endif // CSMAP_H_INCLUDED + +#ifndef _i_prefix +#define _i_prefix csmap_ +#endif +#ifdef _i_isset + #define _i_MAP_ONLY c_false + #define _i_SET_ONLY c_true + #define _i_keyref(vp) (vp) +#else + #define _i_ismap + #define _i_MAP_ONLY c_true + #define _i_SET_ONLY c_false + #define _i_keyref(vp) (&(vp)->first) +#endif +#include + +#if !c_option(c_is_forward) +_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, i_size, _i_MAP_ONLY, _i_SET_ONLY); +#endif + +_i_MAP_ONLY( struct _cx_value { + _cx_key first; + _cx_mapped second; +}; ) +struct _cx_node { + struct _cx_node *link[2]; + uint8_t level; + _cx_value value; +}; + +typedef i_keyraw _cx_rawkey; +typedef i_valraw _cx_memb(_rawmapped); +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 cx); +#if !defined i_no_emplace +STC_API _cx_result _cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)); +#endif // !i_no_emplace +#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)); +STC_API _cx_result _cx_memb(_push)(_cx_self* self, _cx_value _val); +STC_API void _cx_memb(_drop)(_cx_self* self); +STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out); +STC_API _cx_iter _cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey); +STC_API _cx_value* _cx_memb(_front)(const _cx_self* self); +STC_API _cx_value* _cx_memb(_back)(const _cx_self* self); +STC_API int _cx_memb(_erase)(_cx_self* self, i_keyraw rkey); +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 cx.size == 0; } +STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cx.size; } +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, i_keyraw rkey) + { _cx_iter it; _cx_memb(_find_it)(self, rkey, &it); return it; } +STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) + { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it) != NULL; } +STC_INLINE const _cx_value* _cx_memb(_get)(const _cx_self* self, i_keyraw rkey) + { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } +STC_INLINE _cx_value* _cx_memb(_get_mut)(_cx_self* self, i_keyraw rkey) + { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } + +STC_INLINE void +_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) { + return _i_SET_ONLY( i_keyto(val) ) + _i_MAP_ONLY( c_INIT(_cx_raw){i_keyto((&val->first)), + i_valto((&val->second))} ); +} + +STC_INLINE int +_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { + _cx_rawkey rx = i_keyto(_i_keyref(x)), ry = i_keyto(_i_keyref(y)); + return i_cmp((&rx), (&ry)); +} + +STC_INLINE void +_cx_memb(_value_drop)(_cx_value* val) { + i_keydrop(_i_keyref(val)); + _i_MAP_ONLY( i_valdrop((&val->second)); ) +} + +#if !defined i_no_clone +STC_INLINE _cx_value +_cx_memb(_value_clone)(_cx_value _val) { + *_i_keyref(&_val) = i_keyclone((*_i_keyref(&_val))); + _i_MAP_ONLY( _val.second = i_valclone(_val.second); ) + return _val; +} + +STC_INLINE void +_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); +} +#endif // !i_no_clone + +#ifndef _i_isset + #if !defined i_no_clone && !defined i_no_emplace + STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped); + #endif + STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped); + + STC_INLINE const _cx_mapped* + _cx_memb(_at)(const _cx_self* self, i_keyraw rkey) + { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } + STC_INLINE _cx_mapped* + _cx_memb(_at_mut)(_cx_self* self, i_keyraw rkey) + { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } +#endif // !_i_isset + +STC_INLINE _cx_iter +_cx_memb(_begin)(const _cx_self* self) { + _cx_iter it; + it.ref = NULL, it._top = 0, it._tn = self->root; + _cx_memb(_next)(&it); + return it; +} + +STC_INLINE _cx_iter +_cx_memb(_end)(const _cx_self* self) { + (void)self; + _cx_iter it; it.ref = NULL, it._top = 0, it._tn = NULL; + return it; +} + +STC_INLINE _cx_iter +_cx_memb(_advance)(_cx_iter it, size_t n) { + while (n-- && it.ref) + _cx_memb(_next)(&it); + return it; +} + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +#ifndef CSMAP_H_INCLUDED +static struct { void *link[2]; uint8_t level; } +_csmap_sentinel = {{&_csmap_sentinel, &_csmap_sentinel}, 0}; +#endif + +static _cx_result _cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey); + +STC_DEF _cx_self +_cx_memb(_init)(void) { + _cx_self cx = {(_cx_node *)&_csmap_sentinel, 0}; + return cx; +} + +STC_DEF _cx_value* +_cx_memb(_front)(const _cx_self* self) { + _cx_node *tn = self->root; + while (tn->link[0]->level) + tn = tn->link[0]; + return &tn->value; +} + +STC_DEF _cx_value* +_cx_memb(_back)(const _cx_self* self) { + _cx_node *tn = self->root; + while (tn->link[1]->level) + tn = tn->link[1]; + return &tn->value; +} + +STC_DEF _cx_result +_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { + _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); + if (res.inserted) + { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} + else + { i_keydrop((&key)); _i_MAP_ONLY( i_valdrop((&mapped)); )} + return res; +} + +STC_DEF _cx_result +_cx_memb(_push)(_cx_self* self, _cx_value _val) { + _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(_i_keyref(&_val))); + if (_res.inserted) + *_res.ref = _val; + else + _cx_memb(_value_drop)(&_val); + return _res; +} + +#ifndef _i_isset + STC_DEF _cx_result + _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { + _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); + if (res.inserted) + res.ref->first = key; + else + { i_keydrop((&key)); i_valdrop((&res.ref->second)); } + res.ref->second = mapped; + return res; + } + #if !defined i_no_clone && !defined i_no_emplace + STC_DEF _cx_result + _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { + _cx_result res = _cx_memb(_insert_entry_)(self, rkey); + if (res.inserted) + res.ref->first = i_keyfrom(rkey); + else + { i_valdrop((&res.ref->second)); } + res.ref->second = i_valfrom(rmapped); + return res; + } + #endif // !i_no_clone && !i_no_emplace +#endif // !_i_isset + +STC_DEF _cx_value* +_cx_memb(_find_it)(const _cx_self* self, _cx_rawkey rkey, _cx_iter* out) { + _cx_node *tn = self->root; + out->_top = 0; + while (tn->level) { + int c; _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); + if ((c = i_cmp((&raw), (&rkey))) < 0) + tn = tn->link[1]; + else if (c > 0) + { out->_st[out->_top++] = tn; tn = tn->link[0]; } + else + { out->_tn = tn->link[1]; return (out->ref = &tn->value); } + } + return (out->ref = NULL); +} + +STC_DEF _cx_iter +_cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey) { + _cx_iter it; + _cx_memb(_find_it)(self, rkey, &it); + if (!it.ref && it._top) { + _cx_node *tn = it._st[--it._top]; + it._tn = tn->link[1]; + it.ref = &tn->value; + } + return it; +} + +STC_DEF void +_cx_memb(_next)(_cx_iter *it) { + _cx_node *tn = it->_tn; + if (it->_top || tn->level) { + while (tn->level) { + it->_st[it->_top++] = tn; + tn = tn->link[0]; + } + tn = it->_st[--it->_top]; + it->_tn = tn->link[1]; + it->ref = &tn->value; + } else + it->ref = NULL; +} + +static _cx_node * +_cx_memb(_skew_)(_cx_node *tn) { + if (tn && tn->link[0]->level == tn->level && tn->level) { + _cx_node *tmp = tn->link[0]; + tn->link[0] = tmp->link[1]; + tmp->link[1] = tn; + tn = tmp; + } + return tn; +} + +static _cx_node * +_cx_memb(_split_)(_cx_node *tn) { + if (tn->link[1]->link[1]->level == tn->level && tn->level) { + _cx_node *tmp = tn->link[1]; + tn->link[1] = tmp->link[0]; + tmp->link[0] = tn; + tn = tmp; + ++tn->level; + } + return tn; +} + +static _cx_node* +_cx_memb(_insert_entry_i_)(_cx_node* tn, const _cx_rawkey* rkey, _cx_result* res) { + _cx_node *up[64], *tx = tn; + int c, top = 0, dir = 0; + while (tx->level) { + up[top++] = tx; + _cx_rawkey r = i_keyto(_i_keyref(&tx->value)); + if (!(c = (i_cmp((&r), rkey)))) + { res->ref = &tx->value; return tn; } + dir = (c < 0); + tx = tx->link[dir]; + } + tn = c_alloc(_cx_node); + tn->link[0] = tn->link[1] = (_cx_node*)&_csmap_sentinel; + tn->level = 1; + res->ref = &tn->value, res->inserted = true; + if (top == 0) + return tn; + up[top - 1]->link[dir] = tn; + while (top--) { + if (top) + dir = (up[top - 1]->link[1] == up[top]); + up[top] = _cx_memb(_skew_)(up[top]); + up[top] = _cx_memb(_split_)(up[top]); + if (top) + up[top - 1]->link[dir] = up[top]; + } + return up[0]; +} + +STC_DEF _cx_result +_cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey) { + _cx_result res = {NULL}; + self->root = _cx_memb(_insert_entry_i_)(self->root, &rkey, &res); + self->size += res.inserted; + return res; +} + +static _cx_node* +_cx_memb(_erase_r_)(_cx_node *tn, const _cx_rawkey* rkey, int *erased) { + if (tn->level == 0) + return tn; + _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); + _cx_node *tx; int c = (i_cmp((&raw), rkey)); + if (c != 0) + tn->link[c < 0] = _cx_memb(_erase_r_)(tn->link[c < 0], rkey, erased); + else { + if (!*erased) + { _cx_memb(_value_drop)(&tn->value); *erased = 1; } + if (tn->link[0]->level && tn->link[1]->level) { + tx = tn->link[0]; + while (tx->link[1]->level) + tx = tx->link[1]; + tn->value = tx->value; + raw = i_keyto(_i_keyref(&tn->value)); + tn->link[0] = _cx_memb(_erase_r_)(tn->link[0], &raw, erased); + } else { /* unlink node */ + tx = tn; + tn = tn->link[tn->link[0]->level == 0]; + c_free(tx); + } + } + if (tn->link[0]->level < tn->level - 1 || tn->link[1]->level < tn->level - 1) { + if (tn->link[1]->level > --tn->level) + tn->link[1]->level = tn->level; + tn = _cx_memb(_skew_)(tn); + tx = tn->link[0] = _cx_memb(_skew_)(tn->link[0]); + tx->link[0] = _cx_memb(_skew_)(tx->link[0]); + tn = _cx_memb(_split_)(tn); + tn->link[0] = _cx_memb(_split_)(tn->link[0]); + } + return tn; +} + +STC_DEF int +_cx_memb(_erase)(_cx_self* self, i_keyraw rkey) { + int erased = 0; + self->root = _cx_memb(_erase_r_)(self->root, &rkey, &erased); + self->size -= erased; + return erased; +} + +STC_DEF _cx_iter +_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { + _cx_rawkey raw = i_keyto(_i_keyref(it.ref)), nxt; + _cx_memb(_next)(&it); + if (it.ref) + nxt = i_keyto(_i_keyref(it.ref)); + _cx_memb(_erase)(self, raw); + if (it.ref) + _cx_memb(_find_it)(self, nxt, &it); + return it; +} + +STC_DEF _cx_iter +_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { + if (!it2.ref) { + while (it1.ref) + it1 = _cx_memb(_erase_at)(self, it1); + return it1; + } + _cx_key k1 = *_i_keyref(it1.ref), k2 = *_i_keyref(it2.ref); + _cx_rawkey r1 = i_keyto((&k1)); + for (;;) { + if (memcmp(&k1, &k2, sizeof k1) == 0) + return it1; + _cx_memb(_next)(&it1); + k1 = *_i_keyref(it1.ref); + _cx_memb(_erase)(self, r1); + r1 = i_keyto((&k1)); + _cx_memb(_find_it)(self, r1, &it1); + } +} + +#if !defined i_no_clone +static _cx_node* +_cx_memb(_clone_r_)(_cx_node *tn) { + if (! tn->level) + return tn; + _cx_node *cn = c_alloc(_cx_node); + cn->level = tn->level; + cn->value = _cx_memb(_value_clone)(tn->value); + cn->link[0] = _cx_memb(_clone_r_)(tn->link[0]); + cn->link[1] = _cx_memb(_clone_r_)(tn->link[1]); + return cn; +} + +STC_DEF _cx_self +_cx_memb(_clone)(_cx_self cx) { + return c_INIT(_cx_self){_cx_memb(_clone_r_)(cx.root), cx.size}; +} +#endif // !i_no_clone + +#if !defined i_no_emplace +STC_DEF _cx_result +_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { + _cx_result res = _cx_memb(_insert_entry_)(self, rkey); + if (res.inserted) { + *_i_keyref(res.ref) = i_keyfrom(rkey); + _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) + } + return res; +} +#endif // i_no_emplace + +static void +_cx_memb(_drop_r_)(_cx_node* tn) { + if (tn->level != 0) { + _cx_memb(_drop_r_)(tn->link[0]); + _cx_memb(_drop_r_)(tn->link[1]); + _cx_memb(_value_drop)(&tn->value); + c_free(tn); + } +} + +STC_DEF void +_cx_memb(_drop)(_cx_self* self) { + _cx_memb(_drop_r_)(self->root); +} + +#endif // i_implement +#undef _i_isset +#undef _i_ismap +#undef _i_keyref +#undef _i_MAP_ONLY +#undef _i_SET_ONLY +#define CSMAP_H_INCLUDED +#include diff --git a/misc/include/old/cstr.h b/misc/include/old/cstr.h new file mode 100644 index 00000000..8de6c4b0 --- /dev/null +++ b/misc/include/old/cstr.h @@ -0,0 +1,384 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef CSTR_H_INCLUDED +#define CSTR_H_INCLUDED + +#include +#include +#include /* malloc */ +#include +#include +#include /* vsnprintf */ +#include + +#define c_unchecked_container_of(ptr, type, member) \ + ((type*)((char*)(ptr) - offsetof(type, member))) + +typedef char cstr_value; +typedef struct { cstr_value* str; } cstr; +typedef struct { size_t size, cap; char chr[1]; } cstr_priv; +#define _cstr_p(self) c_unchecked_container_of((self)->str, cstr_priv, chr) +#ifdef i_static + static cstr_priv _cstr_nullrep = {0, 0, {0}}; + static const cstr cstr_NULL = {_cstr_nullrep.chr}; +#else + extern const cstr cstr_NULL; +#endif +/* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */ +#define _cstr_opt_mem(cap) ((((offsetof(cstr_priv, chr) + (cap) + 8)>>4)<<4) + 8) +/* optimal string capacity: 7, 23, 39, ... */ +#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(cstr_priv, chr) - 1) + +STC_API cstr cstr_from_n(const char* str, size_t n); +STC_API cstr cstr_from_fmt(const char* fmt, ...); +STC_API char* cstr_reserve(cstr* self, size_t cap); +STC_API void cstr_resize(cstr* self, size_t len, char fill); +STC_API cstr* cstr_assign_n(cstr* self, const char* str, size_t n); +STC_API int cstr_printf(cstr* self, const char* fmt, ...); +STC_API cstr* cstr_append_n(cstr* self, const char* str, size_t n); +STC_API cstr cstr_replace_sv(csview str, csview find, csview repl, unsigned count); +STC_DEF void cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl); +STC_API void cstr_erase(cstr* self, size_t pos, size_t n); +STC_API size_t cstr_find(const cstr* self, const char* needle); +STC_API size_t cstr_find_at(const cstr* self, size_t pos, const char* needle); +STC_API bool cstr_getdelim(cstr *self, int delim, FILE *stream); + +STC_INLINE cstr cstr_init() { return cstr_NULL; } +STC_INLINE const char* cstr_str(const cstr* self) { return self->str; } +#define cstr_toraw(self) (self)->str +STC_INLINE csview cstr_sv(const cstr* self) + { return c_INIT(csview){self->str, _cstr_p(self)->size}; } +#define cstr_lit(literal) \ + cstr_from_n(literal, c_strlen_lit(literal)) +STC_INLINE cstr cstr_from(const char* str) + { return cstr_from_n(str, strlen(str)); } +STC_INLINE char* cstr_data(cstr* self) { return self->str; } +STC_INLINE size_t cstr_size(const cstr* self) { return _cstr_p(self)->size; } +STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_p(&s)->cap; } +STC_INLINE bool cstr_empty(cstr s) { return _cstr_p(&s)->size == 0; } +STC_INLINE void cstr_drop(cstr* self) + { if (_cstr_p(self)->cap) c_free(_cstr_p(self)); } +STC_INLINE cstr cstr_clone(cstr s) + { return cstr_from_n(s.str, _cstr_p(&s)->size); } +STC_INLINE void cstr_clear(cstr* self) + { self->str[_cstr_p(self)->size = 0] = '\0'; } +STC_INLINE cstr* cstr_assign(cstr* self, const char* str) + { return cstr_assign_n(self, str, strlen(str)); } +STC_INLINE cstr* cstr_copy(cstr* self, cstr s) + { return cstr_assign_n(self, s.str, _cstr_p(&s)->size); } +STC_INLINE cstr* cstr_append(cstr* self, const char* str) + { return cstr_append_n(self, str, strlen(str)); } +STC_INLINE cstr* cstr_append_s(cstr* self, cstr s) + { return cstr_append_n(self, s.str, _cstr_p(&s)->size); } +STC_INLINE void cstr_push_back(cstr* self, char value) + { cstr_append_n(self, &value, 1); } +STC_INLINE void cstr_pop_back(cstr* self) + { self->str[ --_cstr_p(self)->size ] = '\0'; } +STC_INLINE void cstr_insert_n(cstr* self, const size_t pos, const char* str, const size_t n) + { cstr_replace_at_sv(self, pos, 0, c_SV(str, n)); } +STC_INLINE void cstr_insert(cstr* self, const size_t pos, const char* str) + { cstr_replace_at_sv(self, pos, 0, c_SV(str, strlen(str))); } +STC_INLINE void cstr_insert_s(cstr* self, const size_t pos, cstr s) + { cstr_replace_at_sv(self, pos, 0, c_SV(s.str, _cstr_p(&s)->size)); } +STC_INLINE void cstr_replace_at(cstr* self, const size_t pos, const size_t len, const char* str) + { cstr_replace_at_sv(self, pos, len, c_SV(str, strlen(str))); } +STC_INLINE void cstr_replace_s(cstr* self, const size_t pos, const size_t len, cstr s) + { cstr_replace_at_sv(self, pos, len, c_SV(s.str, _cstr_p(&s)->size)); } +STC_INLINE char* cstr_front(cstr* self) { return self->str; } +STC_INLINE char* cstr_back(cstr* self) + { return self->str + _cstr_p(self)->size - 1; } +STC_INLINE bool cstr_equals(const cstr* self, const char* str) + { return strcmp(self->str, str) == 0; } +STC_INLINE bool cstr_equals_s(const cstr* self, cstr s) + { return strcmp(self->str, s.str) == 0; } +STC_INLINE bool cstr_contains(const cstr* self, const char* needle) + { return strstr(self->str, needle) != NULL; } +STC_INLINE bool cstr_getline(cstr *self, FILE *stream) + { return cstr_getdelim(self, '\n', stream); } + +STC_INLINE cstr_buf cstr_buffer(cstr* s) { + cstr_priv* p = _cstr_p(s); + return c_INIT(cstr_buf){s->str, p->size, p->cap}; +} + +STC_INLINE cstr cstr_with_capacity(const size_t cap) { + cstr s = cstr_NULL; + cstr_reserve(&s, cap); + return s; +} + +STC_INLINE cstr cstr_with_size(const size_t len, const char fill) { + cstr s = cstr_NULL; + cstr_resize(&s, len, fill); + return s; +} + +STC_INLINE char* cstr_append_uninit(cstr *self, size_t n) { + size_t len = cstr_size(self); char* d; + if (!(d = cstr_reserve(self, len + n))) return NULL; + _cstr_p(self)->size += n; + return d + len; +} + +STC_INLINE cstr* cstr_take(cstr* self, cstr s) { + if (self->str != s.str && _cstr_p(self)->cap) + c_free(_cstr_p(self)); + self->str = s.str; + return self; +} + +STC_INLINE cstr cstr_move(cstr* self) { + cstr tmp = *self; + *self = cstr_NULL; + return tmp; +} + +STC_INLINE bool cstr_starts_with(const cstr* self, const char* sub) { + const char* p = self->str; + while (*sub && *p == *sub) ++p, ++sub; + return *sub == 0; +} + +STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub) { + const size_t n = strlen(sub), sz = _cstr_p(self)->size; + return n <= sz && !memcmp(self->str + sz - n, sub, n); +} + +STC_INLINE int c_strncasecmp(const char* s1, const char* s2, size_t nmax) { + int ret = 0; + while (nmax-- && (ret = tolower(*s1++) - tolower(*s2)) == 0 && *s2++) + ; + return ret; +} + +/* container adaptor functions: */ +#define cstr_cmp(xp, yp) strcmp((xp)->str, (yp)->str) + +STC_INLINE bool cstr_eq(const cstr* x, const cstr* y) { + size_t xs = _cstr_p(x)->size, ys = _cstr_p(y)->size; + return xs == ys && !memcmp(x->str, y->str, xs); +} +STC_INLINE uint64_t cstr_hash(const cstr *self) { + return cfasthash(self->str, _cstr_p(self)->size); +} + +STC_INLINE void cstr_replace_ex(cstr* self, const char* find, const char* repl, unsigned count) { + cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(find, strlen(find)), + c_SV(repl, strlen(repl)), count)); +} +STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl) + { cstr_replace_ex(self, search, repl, ~0U); } + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +#ifndef i_static +static cstr_priv _cstr_nullrep = {0, 0, {0}}; +const cstr cstr_NULL = {_cstr_nullrep.chr}; +#endif + +STC_DEF char* +cstr_reserve(cstr* self, const size_t cap) { + cstr_priv *p = _cstr_p(self); + const size_t oldcap = p->cap; + if (cap > oldcap) { + p = (cstr_priv*) c_realloc(((oldcap != 0) & (p != &_cstr_nullrep)) ? p : NULL, _cstr_opt_mem(cap)); + if (!p) return NULL; + self->str = p->chr; + if (oldcap == 0) self->str[p->size = 0] = '\0'; + p->cap = _cstr_opt_cap(cap); + } + return self->str; +} + +STC_DEF void +cstr_resize(cstr* self, const size_t len, const char fill) { + const size_t n = _cstr_p(self)->size; + cstr_reserve(self, len); + if (len > n) memset(self->str + n, fill, len - n); + if (len | n) self->str[_cstr_p(self)->size = len] = '\0'; +} + +STC_DEF cstr +cstr_from_n(const char* str, const size_t n) { + if (n == 0) return cstr_NULL; + cstr_priv* prv = (cstr_priv*) c_malloc(_cstr_opt_mem(n)); + cstr s = {(char *) memcpy(prv->chr, str, n)}; + s.str[prv->size = n] = '\0'; + prv->cap = _cstr_opt_cap(n); + return s; +} + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4996) +#endif + +STC_DEF int +cstr_vfmt(cstr* self, const char* fmt, va_list args) { + va_list args2; + va_copy(args2, args); + int len = vsnprintf(NULL, (size_t)0, fmt, args); + cstr_reserve(self, len); + vsprintf(self->str, fmt, args2); + va_end(args2); + return _cstr_p(self)->size = len; +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(_MSC_VER) +# pragma warning(pop) +#endif + +STC_DEF cstr +cstr_from_fmt(const char* fmt, ...) { + cstr ret = cstr_NULL; + va_list args; va_start(args, fmt); + cstr_vfmt(&ret, fmt, args); + va_end(args); + return ret; +} + +STC_DEF int +cstr_printf(cstr* self, const char* fmt, ...) { + cstr ret = cstr_NULL; + va_list args; + va_start(args, fmt); + int n = cstr_vfmt(&ret, fmt, args); + va_end(args); + cstr_drop(self); + *self = ret; + return n; +} + +STC_DEF cstr* +cstr_assign_n(cstr* self, const char* str, const size_t n) { + if (n || _cstr_p(self)->cap) { + cstr_reserve(self, n); + memmove(self->str, str, n); + self->str[_cstr_p(self)->size = n] = '\0'; + } + return self; +} + +STC_DEF cstr* +cstr_append_n(cstr* self, const char* str, const size_t n) { + if (n == 0) return self; + const size_t oldlen = _cstr_p(self)->size, newlen = oldlen + n; + if (newlen > _cstr_p(self)->cap) { + const size_t off = (size_t) (str - self->str); /* handle self append */ + cstr_reserve(self, (oldlen*3 >> 1) + n); + if (off <= oldlen) str = self->str + off; + } + memcpy(&self->str[oldlen], str, n); + self->str[_cstr_p(self)->size = newlen] = '\0'; + return self; +} + +STC_INLINE void _cstr_internal_move(cstr* self, const size_t pos1, const size_t pos2) { + if (pos1 == pos2) + return; + const size_t len = _cstr_p(self)->size, newlen = len + pos2 - pos1; + if (newlen > _cstr_p(self)->cap) + cstr_reserve(self, (len*3 >> 1) + pos2 - pos1); + memmove(&self->str[pos2], &self->str[pos1], len - pos1); + self->str[_cstr_p(self)->size = newlen] = '\0'; +} + +STC_DEF void +cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl) { + const size_t sz = cstr_size(self); + if (len > sz - pos) len = sz - pos; + char buf[256], *xstr = repl.size > 256 ? c_malloc(repl.size) : buf; + memcpy(xstr, repl.str, repl.size); + _cstr_internal_move(self, pos + len, pos + repl.size); + memcpy(&self->str[pos], xstr, repl.size); + if (repl.size > 256) c_free(xstr); +} + +STC_DEF cstr +cstr_replace_sv(csview str, csview find, csview repl, unsigned count) { + cstr out = cstr_NULL; + size_t from = 0; char* res; + if (find.size) + while (count-- && (res = cstrnstrn(str.str + from, find.str, str.size - from, find.size))) { + const size_t pos = res - str.str; + cstr_append_n(&out, str.str + from, pos - from); + cstr_append_n(&out, repl.str, repl.size); + from = pos + find.size; + } + cstr_append_n(&out, str.str + from, str.size - from); + return out; +} + +STC_DEF void +cstr_erase(cstr* self, const size_t pos, size_t n) { + const size_t len = _cstr_p(self)->size; + if (n > len - pos) n = len - pos; + if (len) { + memmove(&self->str[pos], &self->str[pos + n], len - (pos + n)); + self->str[_cstr_p(self)->size -= n] = '\0'; + } +} + +STC_DEF bool +cstr_getdelim(cstr *self, const int delim, FILE *fp) { + size_t pos = 0, cap = _cstr_p(self)->cap; + char* d = self->str; + int c = fgetc(fp); + if (c == EOF) + return false; + for (;;) { + if (c == delim || c == EOF) { + if (cap) d[_cstr_p(self)->size = pos] = '\0'; + return true; + } + if (pos == cap) { + d = cstr_reserve(self, (cap*3 >> 1) + 16); + cap = cstr_capacity(*self); + } + d[pos++] = (char) c; + c = fgetc(fp); + } +} + +STC_DEF size_t +cstr_find(const cstr* self, const char* needle) { + char* res = strstr(self->str, needle); + return res ? res - self->str : c_NPOS; +} + +STC_DEF size_t +cstr_find_at(const cstr* self, const size_t pos, const char* needle) { + if (pos > _cstr_p(self)->size) return c_NPOS; + char* res = strstr(self->str + pos, needle); + return res ? res - self->str : c_NPOS; +} + +#endif +#endif // CSTR_H_INCLUDED +#undef i_opt diff --git a/misc/include/old/new_arr.c b/misc/include/old/new_arr.c new file mode 100644 index 00000000..1006439d --- /dev/null +++ b/misc/include/old/new_arr.c @@ -0,0 +1,57 @@ +#include + +#define i_val int +#include "carr2.h" + +#define i_val int +#include "carr3.h" + +#define i_val_str +#include "carr2.h" + +int main() +{ + int w = 7, h = 5, d = 3; + + c_WITH (carr2_int volume = carr2_int_new_uninit(w, h), carr2_int_drop(&volume)) + { + int *dat = carr2_int_data(&volume); + for (size_t i = 0; i < carr2_int_size(&volume); ++i) + dat[i] = i; + + for (size_t x = 0; x < volume.xdim; ++x) + for (size_t y = 0; y < volume.ydim; ++y) + printf(" %d", volume.data[x][y]); + puts(""); + + c_FOREACH (i, carr2_int, volume) + printf(" %d", *i.ref); + puts("\n"); + } + + c_WITH (carr3_int volume = carr3_int_new_uninit(w, h, d), carr3_int_drop(&volume)) + { + int *dat = carr3_int_data(&volume); + for (size_t i = 0; i < carr3_int_size(&volume); ++i) + dat[i] = i; + + for (size_t x = 0; x < volume.xdim; ++x) + for (size_t y = 0; y < volume.ydim; ++y) + for (size_t z = 0; z < volume.zdim; ++z) + printf(" %d", volume.data[x][y][z]); + puts(""); + + c_FOREACH (i, carr3_int, volume) + printf(" %d", *i.ref); + puts(""); + } + + c_WITH (carr2_str text2d = carr2_str_with_size(h, d, cstr_NULL), carr2_str_drop(&text2d)) + { + cstr_assign(&text2d.data[2][1], "hello"); + cstr_assign(&text2d.data[4][0], "world"); + + c_FOREACH (i, carr2_str, text2d) + printf("line: %s\n", cstr_str(i.ref)); + } +} diff --git a/misc/include/stctest.h b/misc/include/stctest.h deleted file mode 100644 index 9718af7f..00000000 --- a/misc/include/stctest.h +++ /dev/null @@ -1,203 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* stctest: A small and simple C11 unit-testing framework. - - Features: - - Requires C11. Should work with any C compiler supporting _Generic. - - No library dependencies. Not even itself. Just a header file. - - Reports assertion failures, including expressions and line numbers. - - ANSI color output for maximum visibility. - - Easy to embed in apps for runtime tests (e.g. environment tests). - - Example: - - #include "stctest.h" - #include "mylib.h" - - void test_sheep() - { - EXPECT_EQ("Sheep are cool", are_sheep_cool()); - EXPECT_EQ(4, sheep.legs); - } - - void test_cheese() - { - EXPECT_GT(cheese.tanginess, 0); - EXPECT_EQ("Wensleydale", cheese.name); - } - - int main() - { - RUN_TEST(test_sheep); - RUN_TEST(test_cheese); - return REPORT_TESTS(); - } - */ - -#ifndef STCTEST_INCLUDED -#define STCTEST_INCLUDED - -#include -#include -#include -#include -#include -#include - -#define STC_FLOAT_EPSILON 1e-6 -#define STC_DOUBLE_EPSILON 1e-13 - - -#define EXPECT_TRUE(expr) \ - do { if (!_stctest_assert(__FILE__, __LINE__, #expr, (expr) != 0)) puts(""); } while (0) - -#define EXPECT_TRUE1(expr, v) \ - do { if (!_stctest_assert(__FILE__, __LINE__, #expr, (expr) != 0)) { \ - char _fmt[32]; sprintf(_fmt, " ; %%s --> %s\n", _stctest_FMT(v)); \ - printf(_fmt, #v, v); \ - }} while (0) - -#define EXPECT_FALSE(expr) EXPECT_TRUE(!(expr)) -#define EXPECT_FALSE1(expr, v) EXPECT_TRUE1(!(expr), v) - -/* NB! (char*) are compared as strings. Cast to (void*) to compare pointers only */ -#define EXPECT_EQ(a, b) _stctest_CHECK(a, ==, b, -STC_DOUBLE_EPSILON) -#define EXPECT_NE(a, b) _stctest_CHECK(a, !=, b, -STC_DOUBLE_EPSILON) -#define EXPECT_GT(a, b) _stctest_CHECK(a, >, b, -STC_DOUBLE_EPSILON) -#define EXPECT_LT(a, b) _stctest_CHECK(a, <, b, -STC_DOUBLE_EPSILON) -#define EXPECT_LE(a, b) _stctest_CHECK(a, <=, b, -STC_DOUBLE_EPSILON) -#define EXPECT_GE(a, b) _stctest_CHECK(a, >=, b, -STC_DOUBLE_EPSILON) -#define EXPECT_FLOAT_EQ(a, b) _stctest_CHECK((float)(a), ==, (float)(b), -STC_FLOAT_EPSILON) -#define EXPECT_DOUBLE_EQ(a, b) _stctest_CHECK((double)(a), ==, (double)(b), -STC_DOUBLE_EPSILON) -#define EXPECT_NEAR(a, b, abs_error) _stctest_CHECK((double)(a), ==, (double)(b), abs_error) - -/* Run a test() function */ -#define RUN_TEST(test, ...) do { \ - puts(#test "(" #__VA_ARGS__ "):"); \ - const int ps = _stctest_s.passes; \ - const int fs = _stctest_s.fails; \ - const clock_t _start = clock(); \ - test(__VA_ARGS__); \ - const int _sum = (clock() - _start)*1000 / CLOCKS_PER_SEC; \ - _stctest_s.total_ms += _sum; \ - printf(" passed: %d/%d. duration: %d ms\n", \ - _stctest_s.passes - ps, _stctest_s.passes + _stctest_s.fails - (ps + fs), _sum); \ -} while (0) - -#define REPORT_TESTS() stctest_report() - -/* ----------------------------------------------------------------------------- */ - -#define _stctest_CHECK(a, OP, b, e) \ - do { if (!_stctest_assert(__FILE__, __LINE__, #a " " #OP " " #b, _stctest_CMP(a, OP, b, e))) { \ - char _fmt[32]; sprintf(_fmt, " ; %s %s %s\n", _stctest_FMT(a), #OP, _stctest_FMT(b)); \ - printf(_fmt, a, b); \ - }} while (0) - -#define _stctest_CMP(a, OP, b, e) _Generic((a), \ - const char*: _stctest_strcmp, char*: _stctest_strcmp, \ - double: _Generic((b), double: _stctest_dblcmp, float: _stctest_dblcmp, default: _stctest_valcmp), \ - float: _Generic((b), double: _stctest_dblcmp, float: _stctest_dblcmp, default: _stctest_valcmp), \ - default: _stctest_valcmp)((a) OP (b), #OP, a, b, (double)(e)) - -#define _stctest_FMT(a) _Generic((a), \ - float: "%.8gf", double: "%.15g", \ - int64_t: "%" PRId64, int32_t: "%" PRId32, int16_t: "%" PRId16, int8_t: "%" PRId8, \ - uint64_t: "%" PRIu64 "u", uint32_t: "%" PRIu32 "u", uint16_t: "%" PRIu16 "u", uint8_t: "%" PRIu8 "u", \ - char*: "`%s`", const char*: "`%s`", \ - default: "%p") - -static int _stctest_strcmp(int res, const char* OP, ...) { - va_list ap; - va_start(ap, OP); - const char* a = va_arg(ap, const char *); - const char* b = va_arg(ap, const char *); - va_end(ap); - int c = strcmp(a, b); - if (OP[0] == '<') return OP[1] == '=' ? c <= 0 : c < 0; - if (OP[0] == '>') return OP[1] == '=' ? c >= 0 : c > 0; - return (OP[0] == '!') ^ (c == 0); -} - -// Knuth: -static int approximately_equal(double a, double b, double epsilon) { - double d = a - b; if (d < 0) d = -d; - if (a < 0) a = -a; if (b < 0) b = -b; - return d <= ((a < b ? b : a) * epsilon); // (a > b ? b : a) => essentially_equal: -} - -static int _stctest_dblcmp(int res, const char* OP, ...) { - va_list ap; - va_start(ap, OP); - double a = va_arg(ap, double); - double b = va_arg(ap, double); - double e = va_arg(ap, double); - double c = a - b; - va_end(ap); - if (OP[0] == '<') return OP[1] == '=' ? c <= 0 : c < 0; - if (OP[0] == '>') return OP[1] == '=' ? c >= 0 : c > 0; - return (OP[0] == '!') ^ (e < 0 ? approximately_equal(a, b, -e) : (c < 0 ? -c : c) <= e); -} - -static int _stctest_valcmp(int res, const char* OP, ...) - { return res; } - -#define _stctest_COLOR_CODE 0x1B -#define _stctest_COLOR_RED "[1;31m" -#define _stctest_COLOR_GREEN "[1;32m" -#define _stctest_COLOR_RESET "[0m" - -static struct stctest_s { - int passes; - int fails; - const char* current_file; - int total_ms; -} _stctest_s = {0}; - -static int _stctest_assert(const char* file, int line, const char* expression, int pass) { - if (pass) - _stctest_s.passes++; - else { - _stctest_s.fails++; - printf(" failed \"%s:%d\": (%s)", file, line, expression); - } - _stctest_s.current_file = file; - return pass; -} - -static int stctest_report(void) { - if (_stctest_s.fails) { - printf("%c%sFAILED%c%s: \"%s\": (failed %d, passed %d, total %d)\n", - _stctest_COLOR_CODE, _stctest_COLOR_RED, _stctest_COLOR_CODE, _stctest_COLOR_RESET, - _stctest_s.current_file, _stctest_s.fails, _stctest_s.passes, _stctest_s.passes + _stctest_s.fails); - } else { - printf("%c%sPASSED%c%s: \"%s\": (total %d)\n", - _stctest_COLOR_CODE, _stctest_COLOR_GREEN, _stctest_COLOR_CODE, _stctest_COLOR_RESET, - _stctest_s.current_file, _stctest_s.passes); - } - printf(" duration: %d ms\n", _stctest_s.total_ms); \ - return -_stctest_s.fails; -} - -#endif -- cgit v1.2.3