From c9be5f66a481bd040b36a25314f6589dd939daa5 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sun, 12 Mar 2023 13:30:15 +0100 Subject: Safer state machine in coroutine.h (internal). Removed c_forwhile() macro. Redundant, use c_forfilter(). Removed find and eq in cspan (use general c_find_if() instead for search). --- src/checkauto.l | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/checkauto.l b/src/checkauto.l index ab71403c..349da70b 100644 --- a/src/checkauto.l +++ b/src/checkauto.l @@ -35,7 +35,6 @@ c_foreach | c_forpair | c_forrange | c_forfilter | -c_forwhile | c_formatch | c_fortoken | for | -- cgit v1.2.3 From ede39bc98a758674485796174ea860515ec281e6 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sun, 26 Mar 2023 22:33:45 +0200 Subject: Remove more c_with, c_auto --- include/stc/algo/filter.h | 30 +++++++-------- include/stc/cbits.h | 40 +++++++++---------- include/stc/cmap.h | 28 +++++++------- include/stc/csmap.h | 28 +++++++------- misc/examples/books.c | 97 +++++++++++++++++++++++------------------------ misc/examples/splitstr.c | 8 ++-- misc/tests/cregex_test.c | 25 ++++++------ src/checkauto.l | 6 +-- 8 files changed, 130 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index 7729799f..111d3273 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -24,24 +24,24 @@ #include #define i_val int #include -#include +#include int main() { - c_with (cstack_int stk = c_make(cstack_int, {1, 2, 3, 4, 5, 6, 7, 8, 9}), - cstack_int_drop(&stk)) - { - 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(""); - } + cstack_int stk = c_make(cstack_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(""); + + cstack_int_drop(&stk); } */ #ifndef STC_FILTER_H_INCLUDED diff --git a/include/stc/cbits.h b/include/stc/cbits.h index fa0da665..826df847 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -27,26 +27,26 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbits.h" int main() { - c_with (cbits bset = cbits_with_size(23, true), cbits_drop(&bset)) - { - cbits_reset(&bset, 9); - cbits_resize(&bset, 43, false); - - printf("%4zu: ", cbits_size(&bset)); - c_forrange (i, cbits_size(&bset)) - printf("%d", cbits_at(&bset, i)); - puts(""); - cbits_set(&bset, 28); - cbits_resize(&bset, 77, true); - cbits_resize(&bset, 93, false); - cbits_resize(&bset, 102, true); - cbits_set_value(&bset, 99, false); - - printf("%4zu: ", cbits_size(&bset)); - c_forrange (i, cbits_size(&bset)) - printf("%d", cbits_at(&bset, i)); - puts(""); - } + cbits bset = cbits_with_size(23, true); + cbits_reset(&bset, 9); + cbits_resize(&bset, 43, false); + + printf("%4zu: ", cbits_size(&bset)); + c_forrange (i, cbits_size(&bset)) + printf("%d", cbits_at(&bset, i)); + puts(""); + cbits_set(&bset, 28); + cbits_resize(&bset, 77, true); + cbits_resize(&bset, 93, false); + cbits_resize(&bset, 102, true); + cbits_set_value(&bset, 99, false); + + printf("%4zu: ", cbits_size(&bset)); + c_forrange (i, cbits_size(&bset)) + printf("%d", cbits_at(&bset, i)); + puts(""); + + cbits_drop(&bset); } */ #ifndef CBITS_H_INCLUDED diff --git a/include/stc/cmap.h b/include/stc/cmap.h index d9081ae0..402038cb 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -31,20 +31,20 @@ #include int main(void) { - c_with (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m)) - { - cmap_ichar_emplace(&m, 5, 'a'); - cmap_ichar_emplace(&m, 8, 'b'); - cmap_ichar_emplace(&m, 12, 'c'); - - cmap_ichar_value* v = cmap_ichar_get(&m, 10); // NULL - char val = *cmap_ichar_at(&m, 5); // 'a' - cmap_ichar_emplace_or_assign(&m, 5, 'd'); // update - cmap_ichar_erase(&m, 8); - - c_foreach (i, cmap_ichar, m) - printf("map %d: %c\n", i.ref->first, i.ref->second); - } + cmap_ichar m = {0}; + cmap_ichar_emplace(&m, 5, 'a'); + cmap_ichar_emplace(&m, 8, 'b'); + cmap_ichar_emplace(&m, 12, 'c'); + + cmap_ichar_value* v = cmap_ichar_get(&m, 10); // NULL + char val = *cmap_ichar_at(&m, 5); // 'a' + cmap_ichar_emplace_or_assign(&m, 5, 'd'); // update + cmap_ichar_erase(&m, 8); + + c_foreach (i, cmap_ichar, m) + printf("map %d: %c\n", i.ref->first, i.ref->second); + + cmap_ichar_drop(&m); } */ #include "ccommon.h" diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 0f72ca2d..2b1910e9 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -32,20 +32,20 @@ #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); - } + csmap_sx m = {0}; + 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); + + csmap_sx_drop(&m); } */ #ifdef STC_CSMAP_V1 diff --git a/misc/examples/books.c b/misc/examples/books.c index e43c0bc3..40fe877f 100644 --- a/misc/examples/books.c +++ b/misc/examples/books.c @@ -9,54 +9,53 @@ int main() { cmap_str book_reviews = {0}; - c_defer( - cmap_str_drop(&book_reviews) - ){ - // Review some books. - cmap_str_emplace(&book_reviews, - "Adventures of Huckleberry Finn", - "My favorite book." - ); - cmap_str_emplace(&book_reviews, - "Grimms' Fairy Tales", - "Masterpiece." - ); - cmap_str_emplace(&book_reviews, - "Pride and Prejudice", - "Very enjoyable" - ); - cmap_str_insert(&book_reviews, - cstr_lit("The Adventures of Sherlock Holmes"), - cstr_lit("Eye lyked it alot.") - ); - - // Check for a specific one. - // When collections store owned values (String), they can still be - // queried using references (&str). - if (cmap_str_contains(&book_reviews, "Les Misérables")) { - printf("We've got %" c_ZI " reviews, but Les Misérables ain't one.", - cmap_str_size(&book_reviews)); - } - - // oops, this review has a lot of spelling mistakes, let's delete it. - cmap_str_erase(&book_reviews, "The Adventures of Sherlock Holmes"); - - // 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)) { - 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)); - else - printf("%s is unreviewed.\n", to_find[i]); - } - - // Look up the value for a key (will panic if the key is not found). - 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) { - printf("%s: \"%s\"\n", cstr_str(_.book), cstr_str(_.review)); - } + + // Review some books. + cmap_str_emplace(&book_reviews, + "Adventures of Huckleberry Finn", + "My favorite book." + ); + cmap_str_emplace(&book_reviews, + "Grimms' Fairy Tales", + "Masterpiece." + ); + cmap_str_emplace(&book_reviews, + "Pride and Prejudice", + "Very enjoyable" + ); + cmap_str_insert(&book_reviews, + cstr_lit("The Adventures of Sherlock Holmes"), + cstr_lit("Eye lyked it alot.") + ); + + // Check for a specific one. + // When collections store owned values (String), they can still be + // queried using references (&str). + if (cmap_str_contains(&book_reviews, "Les Misérables")) { + printf("We've got %" c_ZI " reviews, but Les Misérables ain't one.", + cmap_str_size(&book_reviews)); + } + + // oops, this review has a lot of spelling mistakes, let's delete it. + cmap_str_erase(&book_reviews, "The Adventures of Sherlock Holmes"); + + // 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)) { + 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)); + else + printf("%s is unreviewed.\n", to_find[i]); } + + // Look up the value for a key (will panic if the key is not found). + 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) { + printf("%s: \"%s\"\n", cstr_str(_.book), cstr_str(_.review)); + } + + cmap_str_drop(&book_reviews); } diff --git a/misc/examples/splitstr.c b/misc/examples/splitstr.c index 5bf02d42..bf90b5d4 100644 --- a/misc/examples/splitstr.c +++ b/misc/examples/splitstr.c @@ -10,10 +10,10 @@ int main() c_fortoken (i, "Hello World C99!", " ") printf("'%.*s'\n", c_SV(i.token)); - puts("\nSplit with c_formatch (regex):"); - c_with (cregex re = cregex_from("[^ ]+"), cregex_drop(&re)) - c_formatch (i, &re, " Hello World C99! ") - printf("'%.*s'\n", c_SV(i.match[0])); + cregex re = cregex_from("[^ ]+"); + c_formatch (i, &re, " Hello World C99! ") + printf("'%.*s'\n", c_SV(i.match[0])); + cregex_drop(&re); } diff --git a/misc/tests/cregex_test.c b/misc/tests/cregex_test.c index b3cc9f0a..aa4b2a65 100644 --- a/misc/tests/cregex_test.c +++ b/misc/tests/cregex_test.c @@ -248,8 +248,12 @@ CTEST(cregex, replace) { 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) { + cstr str = {0}; + cregex re = {0}; + c_defer( + cstr_drop(&str), + cregex_drop(&re) + ){ // replace with a fixed string, extended all-in-one call: cstr_take(&str, cregex_replace_pattern(pattern, input, "YYYY-MM-DD")); ASSERT_STREQ(cstr_str(&str), "start date: YYYY-MM-DD, end date: YYYY-MM-DD"); @@ -267,16 +271,15 @@ CTEST(cregex, replace) ASSERT_STREQ(cstr_str(&str), "52 ${apples} ${and} 31 ${mangoes}"); // Compile RE separately - c_with (cregex re = cregex_from(pattern), cregex_drop(&re)) { - ASSERT_EQ(cregex_captures(&re), 4); + re = cregex_from(pattern); + ASSERT_EQ(cregex_captures(&re), 4); - // European date format. - cstr_take(&str, cregex_replace(&re, input, "$3.$2.$1")); - ASSERT_STREQ(cstr_str(&str), "start date: 31.12.2015, end date: 28.02.2022"); + // European date format. + cstr_take(&str, cregex_replace(&re, input, "$3.$2.$1")); + ASSERT_STREQ(cstr_str(&str), "start date: 31.12.2015, end date: 28.02.2022"); - // Strip out everything but the matches - cstr_take(&str, cregex_replace_sv(&re, csview_from(input), "$3.$2.$1;", 0, NULL, CREG_R_STRIP)); - ASSERT_STREQ(cstr_str(&str), "31.12.2015;28.02.2022;"); - } + // Strip out everything but the matches + cstr_take(&str, cregex_replace_sv(&re, csview_from(input), "$3.$2.$1;", 0, NULL, CREG_R_STRIP)); + ASSERT_STREQ(cstr_str(&str), "31.12.2015;28.02.2022;"); } } diff --git a/src/checkauto.l b/src/checkauto.l index 349da70b..a8f14abb 100644 --- a/src/checkauto.l +++ b/src/checkauto.l @@ -41,13 +41,9 @@ for | while | switch { block_type |= LOOP; state = BRACES; } do { block_type |= LOOP; state = BRACESDONE; } -c_with | -c_scope | c_defer | -c_auto | -c_with | c_scope | -c_defer | +c_with | c_auto { block_type = AUTO; state = BRACES; } \( { if (state == BRACES) ++braces_lev; } \) { if (state == BRACES && --braces_lev == 0) { -- cgit v1.2.3 From 26cd0a73422cdbcd4998170e179fa0f3ce48e9a5 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 27 Mar 2023 20:17:57 +0200 Subject: Some missing files. --- README.md | 98 ++++++++++++++++++----------------------------- docs/ccommon_api.md | 14 ++++--- docs/cpque_api.md | 2 +- include/stc/algo/crange.h | 4 +- include/stc/cspan.h | 8 ++-- src/utf8code.c | 2 +- 6 files changed, 55 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index 8d816bc6..75a5357e 100644 --- a/README.md +++ b/README.md @@ -165,13 +165,13 @@ int main(void) Floats_sort(&nums); - c_foreach (i, Floats, nums) // Alternative way to iterate nums. + c_foreach (i, Floats, nums) // Alternative and recommended way to iterate nums. printf(" %g", *i.ref); // i.ref is a pointer to the current element. Floats_drop(&nums); // cleanup memory } ``` -To switch to a different container type is easy when using `c_foreach`: +Switching to a different container type is easy: ```c #define i_type Floats #define i_val float @@ -185,7 +185,7 @@ int main() Floats_push(&nums, 40.f); // print the sorted numbers - c_foreach (i, Floats, nums) + c_foreach (i, Floats, nums) // c_foreach works with any container printf(" %g", *i.ref); Floats_drop(&nums); @@ -197,21 +197,22 @@ only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disab Let's make a vector of vectors that can be cloned. All of its element vectors will be destroyed when destroying the Vec2D. ```c +#include + #define i_type Vec #define i_val float #include -#include #define i_type Vec2D -#define i_valclass Vec // Use i_valclass when element type has "member" functions Vec_clone(), Vec_drop() and Vec_cmp(). -#define i_opt c_no_cmp // Disable search/sort for Vec2D because Vec_cmp() is not defined. +#define i_valclass Vec // Use i_valclass when the element type has "member" functions _clone(), _drop() and _cmp(). +#define i_opt c_no_cmp // However, disable search/sort for Vec2D because Vec_cmp() is not defined. #include int main(void) { Vec* v; Vec2D vec = {0}; // All containers in STC can be initialized with {0}. - v = Vec2D_push(&vec, Vec_init()); // Returns a pointer to the new element in vec. + v = Vec2D_push(&vec, Vec_init()); // push() returns a pointer to the new element in vec. Vec_push(v, 10.f); Vec_push(v, 20.f); @@ -228,84 +229,69 @@ int main(void) c_drop(Vec2D, &vec, &clone); // Cleanup all (6) vectors. } ``` -Here is an example of using six different container types: +Here is an example of using four different container types: ```c #include -#include - -struct Point { float x, y; }; #define i_key int #include // cset_int: unordered set +struct Point { float x, y; }; +// Define cvec_pnt with a less-comparison function for Point. #define i_val struct Point -// Define a i_less template parameter (alternative to i_cmp) for Point. #define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) #define i_tag pnt #include // cvec_pnt: vector of struct Point -#define i_val int -#include // cdeq_int: deque of int - #define i_val int #include // clist_int: singly linked list -#define i_val int -#include // cstack_int - #define i_key int #define i_val int #include // csmap_int: sorted map int => int int main(void) { - // Define six empty containers + // Define four empty containers cset_int set = {0}; cvec_pnt vec = {0}; - cdeq_int deq = {0}; clist_int lst = {0}; - cstack_int stk = {0}; csmap_int map = {0}; - c_defer( // Drop the containers after the scope is executed + c_defer( // Drop the containers at scope exit cset_int_drop(&set), cvec_pnt_drop(&vec), - cdeq_int_drop(&deq), clist_int_drop(&lst), - cstack_int_drop(&stk), csmap_int_drop(&map) ){ - int nums[4] = {10, 20, 30, 40}; - struct Point pts[4] = { {10, 1}, {20, 2}, {30, 3}, {40, 4} }; - int pairs[4][2] = { {20, 2}, {10, 1}, {30, 3}, {40, 4} }; + enum{N = 5}; + int nums[N] = {10, 20, 30, 40, 50}; + struct Point pts[N] = { {10, 1}, {20, 2}, {30, 3}, {40, 4}, {50, 5} }; + int pairs[N][2] = { {20, 2}, {10, 1}, {30, 3}, {40, 4}, {50, 5} }; // Add some elements to each container - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < N; ++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(&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 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); + clist_int_iter i3 = clist_int_find(&lst, 20); + csmap_int_iter i4 = 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); + printf("\nFound: %d, (%g, %g), %d, [%d: %d]\n", + *i1.ref, i2.ref->x, i2.ref->y, *i3.ref, + i4.ref->first, i4.ref->second); // Erase all 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); + clist_int_erase_at(&lst, i3); + csmap_int_erase_at(&map, i4); printf("After erasing the elements found:"); printf("\n set:"); @@ -316,18 +302,10 @@ int main(void) 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); @@ -337,14 +315,12 @@ int main(void) Output ``` -Found: 20, (20, 2), 20, 20, [20: 2] -After erasing elements found: - set: 10 30 40 - vec: (10, 1) (30, 3) (40, 4) - deq: 5 10 30 - lst: 5 10 30 - stk: 10 20 30 40 - map: [10: 1] [30: 3] [40: 4] +Found: 20, (20, 2), 20, [20: 2] +After erasing the elements found: + set: 40 10 30 50 + vec: (10, 1) (30, 3) (40, 4) (50, 5) + lst: 10 30 40 50 + map: [10: 1] [30: 3] [40: 4] [50: 5] ``` Installation @@ -480,12 +456,12 @@ cvec_str vec = {0}; cstr s = cstr_lit("a string literal"); const char* hello = "Hello"; -cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* -cvec_str_push_back(&vec, cstr_clone(s)); // clone and append a cstr +cvec_str_push(&vec, cstr_from(hello); // make a cstr from const char* and move it onto vec +cvec_str_push(&vec, cstr_clone(s)); // make a cstr clone and move it onto vec -cvec_str_emplace_back(&vec, "Yay, literal"); // internally constructs cstr from const char* -cvec_str_emplace_back(&vec, cstr_clone(s)); // <-- COMPILE ERROR: expects const char* -cvec_str_emplace_back(&vec, cstr_str(&s)); // Ok: const char* input type. +cvec_str_emplace(&vec, "Yay, literal"); // internally make a cstr from const char* +cvec_str_emplace(&vec, cstr_clone(s)); // <-- COMPILE ERROR: expects const char* +cvec_str_emplace(&vec, cstr_str(&s)); // Ok: const char* input type. cstr_drop(&s) cvec_str_drop(&vec); diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 010ea204..53ba096a 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -113,8 +113,10 @@ int main() { isPrime(*i.ref) && c_flt_skip(i, 24) && c_flt_count(i) % 15 == 1 && - c_flt_take(i, 10)) + c_flt_take(i, 10) + ){ printf(" %lld", *i.ref); + } puts(""); } // out: 1171 1283 1409 1493 1607 1721 1847 1973 2081 2203 @@ -126,7 +128,7 @@ Note that `c_flt_take()` and `c_flt_takewhile()`breaks the loop on false. ### crange A number sequence generator type, similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html). The **crange_value** type is `long long`. Below *start*, *stop*, and *step* are of type *crange_value*: ```c -crange& crange_obj(...) // create a compound literal crange object +crange& crange_object(...) // create a compound literal crange object crange crange_make(stop); // will generate 0, 1, ..., stop-1 crange crange_make(start, stop); // will generate start, start+1, ... stop-1 crange crange_make(start, stop, step); // will generate start, start+step, ... upto-not-including stop @@ -144,10 +146,12 @@ c_forfilter (i, crange, r1, isPrime(*i.ref)) // 2. The 11 first primes: printf("2"); -c_forfilter (i, crange, crange_obj(3, INT64_MAX, 2), - isPrime(*i.ref) && - c_flt_take(10)) +c_forfilter (i, crange, crange_object(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 ``` ## Algorithms diff --git a/docs/cpque_api.md b/docs/cpque_api.md index b3a1a9ec..134a920f 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -84,7 +84,7 @@ int main() // Add some negative ones. int nums[] = {-231, -32, -873, -4, -343}; - c_forrange (i, c_ARRAYLEN(nums)) + c_forrange (i, c_arraylen(nums)) cpque_i_push(&heap, nums[i]); // Extract and display the fifty smallest. diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h index ca06c258..91ffdd56 100644 --- a/include/stc/algo/crange.h +++ b/include/stc/algo/crange.h @@ -34,7 +34,7 @@ int main() // use a temporary crange object. int a = 100, b = INT32_MAX; - c_forfilter (i, crange, crange_obj(a, b, 8), + c_forfilter (i, crange, crange_object(a, b, 8), c_flt_skip(i, 10) && c_flt_take(i, 3)) printf(" %lld", *i.ref); @@ -46,7 +46,7 @@ int main() #include -#define crange_obj(...) \ +#define crange_object(...) \ (*(crange[]){crange_make(__VA_ARGS__)}) typedef long long crange_value; diff --git a/include/stc/cspan.h b/include/stc/cspan.h index d5482200..ac3e9206 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -48,10 +48,12 @@ int demo2() { puts(""); c_forfilter (i, Intspan, span, - c_flt_skipwhile(i, *i.ref < 25) && - (*i.ref & 1) == 0 && // even only - c_flt_take(i, 2)) // break after 2 + 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(""); } */ diff --git a/src/utf8code.c b/src/utf8code.c index ecfdd24d..496f5eef 100644 --- a/src/utf8code.c +++ b/src/utf8code.c @@ -142,7 +142,7 @@ bool utf8_isalpha(uint32_t c) { static int16_t groups[] = {U8G_Latin, U8G_Nl, U8G_Greek, U8G_Cyrillic, U8G_Han, U8G_Devanagari, U8G_Arabic}; if (c < 128) return isalpha((int)c) != 0; - for (int j=0; j < c_ARRAYLEN(groups); ++j) + for (int j=0; j < c_arraylen(groups); ++j) if (utf8_isgroup(groups[j], c)) return true; return false; -- cgit v1.2.3 From 7a9b07ea97f70da96807a80b2e087bd08a0316a3 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Sun, 9 Apr 2023 21:18:42 +0200 Subject: Added "Run this code" in Compiler Explorer a few places. New example in csmap_api.md --- README.md | 4 +-- docs/csmap_api.md | 71 +++++++++++++++++++++++++++-------------------------- src/singleupdate.sh | 27 ++++++++++++++++++++ 3 files changed, 65 insertions(+), 37 deletions(-) create mode 100644 src/singleupdate.sh (limited to 'src') diff --git a/README.md b/README.md index 13cedb10..15778ddd 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ For user-defined struct elements, `i_cmp` compare function should be defined as only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching*. Similarily, if an element destructor `i_valdrop` is defined, `i_valclone` function is required. *Alternatively `#define i_opt c_no_clone` to disable container cloning.* -Let's make a vector of vectors, which can be cloned. All of its element vectors will be destroyed when destroying the Vec2D. +Let's make a vector of vectors, which can be cloned. All of its element vectors will be destroyed when destroying the Vec2D. [ [Run this code](https://godbolt.org/z/5EY56qnfM) ] ```c #include @@ -231,7 +231,7 @@ int main(void) c_drop(Vec2D, &vec, &clone); // Cleanup all (6) vectors. } ``` -This example uses four different container types: +This example uses four different container types: [ [Run this code](https://godbolt.org/z/x5YKeMrEh) ] ```c #include diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 0eff8c26..59914369 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -142,7 +142,42 @@ The HEX of color RED is:[#FF0000] The HEX of color BLACK is:[#000000] ``` + ### Example 2 +Translate a +[C++ example using *insert* and *emplace*](https://en.cppreference.com/w/cpp/container/map/try_emplace) + to STC: [ [Run this code](https://godbolt.org/z/9d1PP77Pa) ] +```c +#include +#define i_type strmap +#define i_key_str +#define i_val_str +#include + +static void print_node(const strmap_value* node) { + printf("[%s] = %s\n", cstr_str(&node->first), cstr_str(&node->second)); +} + +static void print_result(strmap_result result) { + printf("%s", result.inserted ? "inserted: " : "ignored: "); + print_node(result.ref); +} + +int main() +{ + strmap m = {0}; + + print_result( strmap_emplace(&m, "a", "a") ); + print_result( strmap_emplace(&m, "b", "abcd") ); + print_result( strmap_insert(&m, cstr_from("c"), cstr_with_size(10, 'c') ) ); + print_result( strmap_emplace(&m, "c", "Won't be inserted") ); + + c_foreach (p, strmap, m) { print_node(p.ref); } + strmap_drop(&m); +} +``` + +### Example 3 This example uses a csmap with cstr as mapped value. ```c #include @@ -179,7 +214,7 @@ Output: 120: #cc7744ff ``` -### Example 3 +### Example 4 Demonstrate csmap with plain-old-data key type Vec3i and int as mapped type: csmap. ```c typedef struct { int x, y, z; } Vec3i; @@ -220,37 +255,3 @@ Output: { 100, 0, 0 }: 1 { 100, 100, 100 }: 4 ``` - -### Example 4 -Inverse: demonstrate csmap with mapped POD type Vec3i: csmap: -```c -typedef struct { int x, y, z; } Vec3i; - -#define i_key int -#define i_val Vec3i -#define i_tag iv -#include -#include - -int main() -{ - csmap_iv imap = {0}; - - csmap_iv_insert(&imap, 1, (Vec3i){100, 0, 0}); - csmap_iv_insert(&imap, 2, (Vec3i){0, 100, 0}); - csmap_iv_insert(&imap, 3, (Vec3i){0, 0, 100}); - csmap_iv_insert(&imap, 4, (Vec3i){100, 100, 100}); - - c_forpair (n, v, csmap_iv, imap) - printf("%d: { %3d, %3d, %3d }\n", *_.n, _.v->x, _.v->y, _.v->z); - - csmap_iv_drop(&imap); -} -``` -Output: -```c -1: { 100, 0, 0 } -2: { 0, 100, 0 } -3: { 0, 0, 100 } -4: { 100, 100, 100 } -``` diff --git a/src/singleupdate.sh b/src/singleupdate.sh new file mode 100644 index 00000000..d9a16568 --- /dev/null +++ b/src/singleupdate.sh @@ -0,0 +1,27 @@ +d=$(git rev-parse --show-toplevel) +mkdir -p $d/../stcsingle/c11 $d/../stcsingle/stc +python singleheader.py $d/include/c11/print.h > $d/../stcsingle/c11/print.h +python singleheader.py $d/include/stc/calgo.h > $d/../stcsingle/stc/calgo.h +python singleheader.py $d/include/stc/carc.h > $d/../stcsingle/stc/carc.h +python singleheader.py $d/include/stc/cbits.h > $d/../stcsingle/stc/cbits.h +python singleheader.py $d/include/stc/cbox.h > $d/../stcsingle/stc/cbox.h +python singleheader.py $d/include/stc/ccommon.h > $d/../stcsingle/stc/ccommon.h +python singleheader.py $d/include/stc/cdeq.h > $d/../stcsingle/stc/cdeq.h +python singleheader.py $d/include/stc/clist.h > $d/../stcsingle/stc/clist.h +python singleheader.py $d/include/stc/cmap.h > $d/../stcsingle/stc/cmap.h +python singleheader.py $d/include/stc/coption.h > $d/../stcsingle/stc/coption.h +python singleheader.py $d/include/stc/cpque.h > $d/../stcsingle/stc/cpque.h +python singleheader.py $d/include/stc/cqueue.h > $d/../stcsingle/stc/cqueue.h +python singleheader.py $d/include/stc/crand.h > $d/../stcsingle/stc/crand.h +python singleheader.py $d/include/stc/cregex.h > $d/../stcsingle/stc/cregex.h +python singleheader.py $d/include/stc/cset.h > $d/../stcsingle/stc/cset.h +python singleheader.py $d/include/stc/csmap.h > $d/../stcsingle/stc/csmap.h +python singleheader.py $d/include/stc/cspan.h > $d/../stcsingle/stc/cspan.h +python singleheader.py $d/include/stc/csset.h > $d/../stcsingle/stc/csset.h +python singleheader.py $d/include/stc/cstack.h > $d/../stcsingle/stc/cstack.h +python singleheader.py $d/include/stc/cstr.h > $d/../stcsingle/stc/cstr.h +python singleheader.py $d/include/stc/csview.h > $d/../stcsingle/stc/csview.h +python singleheader.py $d/include/stc/cvec.h > $d/../stcsingle/stc/cvec.h +python singleheader.py $d/include/stc/extend.h > $d/../stcsingle/stc/extend.h +python singleheader.py $d/include/stc/forward.h > $d/../stcsingle/stc/forward.h +echo "stcsingle headers updated" \ No newline at end of file -- cgit v1.2.3