summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/ccommon_api.md17
-rw-r--r--include/stc/ccommon.h3
-rw-r--r--include/stc/cvec.h22
3 files changed, 26 insertions, 16 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index b4b548a8..2d671cd8 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -8,19 +8,20 @@ resource near the resource acquisition, and makes it easier to verify that resou
**Note**: These macros are one-time executed **for**-loops. ***Only*** use `continue` in order to break out
of a `c_forvar` / `c_fordefer`-block. ***Do not*** use `return`, `goto` or `break`, as it will prevent the
-`release`-statement to be executed at the end. The same applies for `c_forbuffer`. This is not particular to
+`end`-statement to be executed at the end. The same applies for `c_forbuffer`. This is not particular to
the `c_for*()` macros, as one must always make sure to unwind temporary allocated resources before `return` in C.
The **c_forbuffer** uses stack memory if buffer is <= to 256 bytes, othewise it uses the slower heap memory.
-| Usage | Description |
-|:---------------------------------|:--------------------------------------------------|
-| `c_forvar (acquire, release...)` | Do `acquire`. Defer `release` to end of block |
-| `c_fordefer (release...)` | Defer execution of `release` to end of block |
-| `c_forbuffer (buf, type, n)` | Declare, allocate and free memory buffer |
+| Usage | Description |
+|:---------------------------------------|:--------------------------------------------------|
+| `c_forvar (Type var=init, end...)` | Declare `var`. Defer `end` to end of block |
+| `c_forscope (start, end)` | Execute `start`. Defer `end` to end of block |
+| `c_fordefer (end...)` | Defer execution of `end` to end of block |
+| `c_forbuffer (buf, type, n)` | Declare, allocate and free memory buffer |
-The `acquire`argument must be of the form: `type var = GetResource`. For multiple variables, use multiple
-**c_forvar** in sequence, or if variables are of same type, the **c_arg** macro can be used:
+For multiple variables, use either multiple **c_forvar** in sequence, or if variables are of same type,
+the **c_arg** macro can be used:
```c
c_forvar (c_arg(cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world")), cstr_del(&s1), cstr_del(&s2))
{
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index d15d5951..a650d6d8 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -123,8 +123,9 @@
for (type i=start, _c_inc=step, _c_end=(stop) - (0 < _c_inc) \
; (i <= _c_end) == (0 < _c_inc); i += _c_inc)
-#define c_forvar(acquire, ...) for (acquire, *_c_ii = NULL; !_c_ii; ++_c_ii, __VA_ARGS__)
+#define c_forvar(declvar, ...) for (declvar, *_c_ii = NULL; !_c_ii; ++_c_ii, __VA_ARGS__)
#define c_arg(...) __VA_ARGS__
+#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_forbuffer(b, type, n) c_forbuffer_N(b, type, n, 256)
diff --git a/include/stc/cvec.h b/include/stc/cvec.h
index 3e7e37f2..02537081 100644
--- a/include/stc/cvec.h
+++ b/include/stc/cvec.h
@@ -27,6 +27,8 @@
#include <stdlib.h>
#include <string.h>
+#define forward_cvec(X, Value) _cvec_types(cvec_##X, Value)
+
#define using_cvec(...) c_MACRO_OVERLOAD(using_cvec, __VA_ARGS__)
#define using_cvec_2(X, Value) \
@@ -38,22 +40,28 @@
#define using_cvec_5(X, Value, valueCompare, valueDel, valueClone) \
using_cvec_7(X, Value, valueCompare, valueDel, valueClone, c_default_toraw, Value)
#define using_cvec_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
- _c_using_cvec(cvec_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue)
+ _c_using_cvec(cvec_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, c_true)
+#define using_cvec_8(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defineTypes) \
+ _c_using_cvec(cvec_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defineTypes)
#define using_cvec_str() \
- _c_using_cvec(cvec_str, cstr, c_rawstr_compare, cstr_del, cstr_from, cstr_toraw, const char*)
-
+ using_cvec_7(str, cstr, c_rawstr_compare, cstr_del, cstr_from, cstr_toraw, const char*)
struct cvec_rep { size_t size, cap; void* data[]; };
#define _cvec_rep(self) c_container_of((self)->data, struct cvec_rep, data)
+#define c_true(...) __VA_ARGS__
+#define c_false(...)
-#define _c_using_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
-\
+#define _cvec_types(CX, Value) \
typedef Value CX##_value_t; \
+ typedef struct { CX##_value_t *ref; } CX##_iter_t; \
+ typedef struct { CX##_value_t *data; } CX
+
+#define _c_using_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defineTypes) \
+\
+ defineTypes( _cvec_types(CX, Value); ) \
typedef RawValue CX##_rawvalue_t; \
- typedef struct {CX##_value_t *ref;} CX##_iter_t; \
- typedef struct {CX##_value_t *data;} CX; \
\
STC_API CX CX##_init(void); \
STC_API CX CX##_clone(CX cx); \