summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authortylo <[email protected]>2021-08-25 12:04:46 +0200
committertylo <[email protected]>2021-08-25 12:04:46 +0200
commita4bacdaf0feae20d417e53d8467ff332ac29413e (patch)
tree38dd5edd8d9d256056b0213fa487a11354fd9d45
parentd80bf9bb4ef1b5a5a6d4edb550b93b93a75972f4 (diff)
downloadSTC-modified-a4bacdaf0feae20d417e53d8467ff332ac29413e.tar.gz
STC-modified-a4bacdaf0feae20d417e53d8467ff332ac29413e.zip
BREAKING CHANGE: c_forvar_initdel() macro renamed to c_forauto().
Updated doc and improved csmap_erase.c example.
-rw-r--r--docs/ccommon_api.md48
-rw-r--r--docs/csview_api.md2
-rw-r--r--examples/csmap_erase.c154
-rw-r--r--examples/priority.c2
-rw-r--r--include/stc/ccommon.h8
5 files changed, 121 insertions, 93 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index ddf3783c..d8125642 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -2,25 +2,53 @@
The following handy macros are safe to use, i.e. have no side-effects.
-### c_fordefer, c_forscope, c_forvar, c_forvar_initdel
+### c_fordefer, c_forscope, c_forvar, c_forauto
General ***defer*** mechanics for resource acquisition. These macros allows to specify the release of the
resource where the resource acquisition takes place. Makes it easier to verify that resources are released.
-**Note**: These macros are one-time executed **for-loops**. Use ***only*** `continue` in order to break out
-of a `c_for*`-block. ***Do not*** use `return`, `goto` or `break`, as they will prevent the `end`-statement to
-be executed when leaving scope. This is not particular to the `c_for*()` macros, as one must always make sure
-to unwind temporary allocated resources before a `return` in C.
+**NB**: These macros are one-time executed **for-loops**. Use ***only*** `continue` in order to break out
+of these four `c_for`-blocks. ***Do not*** use `return` or `goto` (or `break`) inside them, as they will
+prevent the `end`-statement to be executed when leaving scope. This is not particular to the `c_for*()`
+macros, as one must always make sure to unwind temporary allocated resources before a `return` in C.
| Usage | Description |
|:---------------------------------------|:--------------------------------------------------|
-| `c_fordefer (end...)` | Defer execution of `end` to end of block |
-| `c_forscope (start, end)` | Execute `start`. Defer `end` to end of block |
| `c_forvar (Type var=init, end...)` | Declare `var`. Defer `end` to end of block |
-| `c_forvar_initdel (Type, var...)` | `c_forvar (Type var=Type_init(), Type_del(&var))` |
+| `c_forauto (Type, var...)` | `c_forvar (Type var=Type_init(), Type_del(&var))` |
+| `c_forscope (start, end)` | Execute `start`. Defer `end` to end of block |
+| `c_fordefer (end...)` | Defer execution of `end` to end of block |
-For multiple variables, use either multiple **c_forvar** in sequence, or declare variable outside
-scope and use **c_fordefer** or **c_forscope**. Also, **c_forvar_initdel** support up to 3 vars.
+For multiple variables, use either multiple **c_forvar** in sequence, or declare variable outside
+scope and use **c_forscope** or **c_fordefer**. Also, **c_forauto** support up to 3 vars.
```c
+c_forvar (cstr s = cstr_lit("Hello"), cstr_del(&s))
+{
+ cstr_append(&s, " world");
+ printf("%s\n", s.str);
+}
+
+c_forauto (cstr, s1, s2)
+{
+ cstr_append(&s1, "Hello");
+ cstr_append(&s1, " world");
+
+ cstr_append(&s2, "Cool");
+ cstr_append(&s2, " stuff");
+
+ printf("%s %s\n", s1.str, s2.str);
+}
+
+using_cvec(i32, int32_t);
+...
+cvec_i32 vec;
+c_forscope (vec = cvec_i32_init(), cvec_i32_del(&vec))
+{
+ cvec_i32_push_back(&vec, 123);
+ cvec_i32_push_back(&vec, 321);
+
+ c_foreach (i, cvec_i32, vec) printf(" %d", *i.ref);
+}
+
cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world");
c_fordefer (cstr_del(&s1), cstr_del(&s2))
{
diff --git a/docs/csview_api.md b/docs/csview_api.md
index 2906acdc..70bc9b41 100644
--- a/docs/csview_api.md
+++ b/docs/csview_api.md
@@ -220,7 +220,7 @@ int main()
csview suffix = csview_substr(text, -12, cstr_npos); // from pos -12 to end
printf("%.*s\n", csview_ARG(suffix));
- c_forvar_initdel (cmap_si, map)
+ c_forauto (cmap_si, map)
{
cmap_si_emplace(&map, c_sv("hello"), 100);
cmap_si_emplace(&map, c_sv("world"), 200);
diff --git a/examples/csmap_erase.c b/examples/csmap_erase.c
index 35afbe3a..6cebffb7 100644
--- a/examples/csmap_erase.c
+++ b/examples/csmap_erase.c
@@ -1,77 +1,77 @@
-// map_erase.c
-// https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-16
-#include <stc/csmap.h>
-#include <stc/cstr.h>
-#include <stdio.h>
-
-using_csmap_strval(my, int);
-
-void printmap(csmap_my map)
-{
- c_foreach (e, csmap_my, map)
- printf(" [%d, %s]", e.ref->first, e.ref->second.str);
- printf("\nsize() == %zu\n\n", csmap_my_size(map));
-}
-
-int main()
-{
- c_forvar (csmap_my m1 = csmap_my_init(), csmap_my_del(&m1))
- {
- // Fill in some data to test with, one at a time
- csmap_my_emplace(&m1, 1, "A");
- csmap_my_emplace(&m1, 2, "B");
- csmap_my_emplace(&m1, 3, "C");
- csmap_my_emplace(&m1, 4, "D");
- csmap_my_emplace(&m1, 5, "E");
-
- puts("Starting data of map m1 is:");
- printmap(m1);
- // The 1st member function removes an element at a given position
- csmap_my_erase_at(&m1, csmap_my_fwd(csmap_my_begin(&m1), 1));
- puts("After the 2nd element is deleted, the map m1 is:");
- printmap(m1);
- }
-
- c_forvar (csmap_my m2 = csmap_my_init(), csmap_my_del(&m2))
- {
- // Fill in some data to test with, one at a time, using emplace
- c_emplace(csmap_my, m2, {
- {10, "Bob"},
- {11, "Rob"},
- {12, "Robert"},
- {13, "Bert"},
- {14, "Bobby"}
- });
-
- puts("Starting data of map m2 is:");
- printmap(m2);
- csmap_my_iter_t it1 = csmap_my_fwd(csmap_my_begin(&m2), 1);
- csmap_my_iter_t it2 = csmap_my_find(&m2, csmap_my_back(&m2)->first);
- // The 2nd member function removes elements
- // in the range [First, Last)
- csmap_my_erase_range(&m2, it1, it2);
- puts("After the middle elements are deleted, the map m2 is:");
- printmap(m2);
- }
-
- c_forvar (csmap_my m3 = csmap_my_init(), csmap_my_del(&m3))
- {
- // Fill in some data to test with, one at a time, using emplace
- csmap_my_emplace(&m3, 1, "red");
- csmap_my_emplace(&m3, 2, "yellow");
- csmap_my_emplace(&m3, 3, "blue");
- csmap_my_emplace(&m3, 4, "green");
- csmap_my_emplace(&m3, 5, "orange");
- csmap_my_emplace(&m3, 5, "purple");
- csmap_my_emplace(&m3, 5, "pink");
-
- puts("Starting data of map m3 is:");
- printmap(m3);
- // The 3rd member function removes elements with a given Key
- size_t count = csmap_my_erase(&m3, 2);
- // The 3rd member function also returns the number of elements removed
- printf("The number of elements removed from m3 is: %zu\n", count);
- puts("After the element with a key of 2 is deleted, the map m3 is:");
- printmap(m3);
- }
-} \ No newline at end of file
+// map_erase.c
+// From C++ example: https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-16
+#include <stc/csmap.h>
+#include <stc/cstr.h>
+#include <stdio.h>
+
+using_csmap_strval(my, int);
+
+void printmap(csmap_my map)
+{
+ c_foreach (e, csmap_my, map)
+ printf(" [%d, %s]", e.ref->first, e.ref->second.str);
+ printf("\nsize() == %zu\n\n", csmap_my_size(map));
+}
+
+int main()
+{
+ c_forauto (csmap_my, m1)
+ {
+ // Fill in some data to test with, one at a time
+ csmap_my_insert(&m1, 1, cstr_lit("A"));
+ csmap_my_insert(&m1, 2, cstr_lit("B"));
+ csmap_my_insert(&m1, 3, cstr_lit("C"));
+ csmap_my_insert(&m1, 4, cstr_lit("D"));
+ csmap_my_insert(&m1, 5, cstr_lit("E"));
+
+ puts("Starting data of map m1 is:");
+ printmap(m1);
+ // The 1st member function removes an element at a given position
+ csmap_my_erase_at(&m1, csmap_my_fwd(csmap_my_begin(&m1), 1));
+ puts("After the 2nd element is deleted, the map m1 is:");
+ printmap(m1);
+ }
+
+ c_forauto (csmap_my, m2)
+ {
+ // Fill in some data to test with, one at a time, using c_emplace()
+ c_emplace(csmap_my, m2, {
+ {10, "Bob"},
+ {11, "Rob"},
+ {12, "Robert"},
+ {13, "Bert"},
+ {14, "Bobby"}
+ });
+
+ puts("Starting data of map m2 is:");
+ printmap(m2);
+ csmap_my_iter_t it1 = csmap_my_fwd(csmap_my_begin(&m2), 1);
+ csmap_my_iter_t it2 = csmap_my_find(&m2, csmap_my_back(&m2)->first);
+ // The 2nd member function removes elements
+ // in the range [First, Last)
+ csmap_my_erase_range(&m2, it1, it2);
+ puts("After the middle elements are deleted, the map m2 is:");
+ printmap(m2);
+ }
+
+ c_forauto (csmap_my, m3)
+ {
+ // Fill in some data to test with, one at a time, using emplace
+ csmap_my_emplace(&m3, 1, "red");
+ csmap_my_emplace(&m3, 2, "yellow");
+ csmap_my_emplace(&m3, 3, "blue");
+ csmap_my_emplace(&m3, 4, "green");
+ csmap_my_emplace(&m3, 5, "orange");
+ csmap_my_emplace(&m3, 6, "purple");
+ csmap_my_emplace(&m3, 7, "pink");
+
+ puts("Starting data of map m3 is:");
+ printmap(m3);
+ // The 3rd member function removes elements with a given Key
+ size_t count = csmap_my_erase(&m3, 2);
+ // The 3rd member function also returns the number of elements removed
+ printf("The number of elements removed from m3 is: %zu\n", count);
+ puts("After the element with a key of 2 is deleted, the map m3 is:");
+ printmap(m3);
+ }
+}
diff --git a/examples/priority.c b/examples/priority.c
index ee64bf42..4824a294 100644
--- a/examples/priority.c
+++ b/examples/priority.c
@@ -13,7 +13,7 @@ int main() {
size_t N = 10000000;
stc64_t rng = stc64_init(time(NULL));
stc64_uniform_t dist = stc64_uniform_init(0, N * 10);
- c_forvar (cpque_i heap = cpque_i_init(), cpque_i_del(&heap))
+ c_forauto (cpque_i, heap)
{
// Push ten million random numbers to priority queue
c_forrange (N)
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index cdfb1e61..f79060a8 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -133,13 +133,13 @@
#define c_forscope(start, end) for (int _c_ii = (start, 0); !_c_ii; ++_c_ii, end)
#define c_fordefer(...) for (int _c_ii = 0; !_c_ii; ++_c_ii, __VA_ARGS__)
-#define c_forvar_initdel(...) c_MACRO_OVERLOAD(c_forvar_initdel, __VA_ARGS__)
-#define c_forvar_initdel_2(CX, a) \
+#define c_forauto(...) c_MACRO_OVERLOAD(c_forauto, __VA_ARGS__)
+#define c_forauto_2(CX, a) \
c_forvar(CX a = CX##_init(), CX##_del(&a))
-#define c_forvar_initdel_3(CX, a, b) \
+#define c_forauto_3(CX, a, b) \
c_forvar(c_EXPAND(CX a = CX##_init(), b = CX##_init()), \
CX##_del(&b), CX##_del(&a))
-#define c_forvar_initdel_4(CX, a, b, c) \
+#define c_forauto_4(CX, a, b, c) \
c_forvar(c_EXPAND(CX a = CX##_init(), b = CX##_init(), c = CX##_init()), \
CX##_del(&c), CX##_del(&b), CX##_del(&a))