diff options
| -rw-r--r-- | README.md | 25 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 1 | ||||
| -rw-r--r-- | docs/cspan_api.md | 6 | ||||
| -rw-r--r-- | include/stc/algo/raii.h | 3 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 5 | ||||
| -rw-r--r-- | include/stc/cspan.h | 9 | ||||
| -rw-r--r-- | misc/examples/astar.c | 1 | ||||
| -rw-r--r-- | misc/examples/bits.c | 1 | ||||
| -rw-r--r-- | misc/examples/box2.c | 1 | ||||
| -rw-r--r-- | misc/examples/convert.c | 1 | ||||
| -rw-r--r-- | misc/examples/person_arc.c | 1 | ||||
| -rw-r--r-- | misc/examples/regex_replace.c | 1 | ||||
| -rw-r--r-- | misc/examples/sorted_map.c | 1 | ||||
| -rw-r--r-- | misc/examples/unordered_set.c | 1 |
14 files changed, 24 insertions, 33 deletions
@@ -83,7 +83,7 @@ non-specified template parameters (based on the specified ones) using meta-progr that you don't have to! You may specify a set of "standard" template parameters for each container, but as a minimum *only one is required*: `i_key` (+ `i_val` for maps). In this case, STC assumes that the elements are of basic types. For non-trivial types, additional -template parameters must be given. +template parameters must be given. 2. ***Alternative insert/lookup type***. You may specify an alternative type to use for lookup in containers. E.g., containers with STC string elements (**cstr**) uses `const char*` as lookup type, so constructing a `cstr` (which may allocate memory) for the lookup @@ -147,9 +147,9 @@ Benchmark notes: STC containers have similar functionality to C++ STL standard containers. All containers except for a few, like **cstr** and **cbits** are generic/templated. No type casting is used, so containers are type-safe like templated types in C++. However, to specify template parameters with STC, you define them as macros prior to -including the container: +including the container. ```c -#define i_type Floats // Container type name; unless defined name would be cvec_float +#define i_type Floats // Container type name (optional); if not defined name would be cvec_float #define i_key float // Container element type #include <stc/cvec.h> // "instantiate" the desired container type #include <stdio.h> @@ -164,15 +164,15 @@ int main(void) for (int i = 0; i < Floats_size(&nums); ++i) printf(" %g", nums.data[i]); - Floats_sort(&nums); - c_foreach (i, Floats, nums) // Alternative and recommended way to iterate. printf(" %g", *i.ref); // i.ref is a pointer to the current element. Floats_drop(&nums); // cleanup memory } ``` -You may switch to a different container type, e.g. a sorted set (csset): +Note that `i_val*` template parameters can be used instead of `i_key*` for *non-map* containers. + +Switching to a different container type, e.g. a sorted set (csset): [ [Run this code](https://godbolt.org/z/qznfa65e1) ] ```c @@ -188,14 +188,14 @@ int main() Floats_push(&nums, 10.f); Floats_push(&nums, 20.f); - // already sorted, print the numbers + // print the numbers (sorted) c_foreach (i, Floats, nums) printf(" %g", *i.ref); Floats_drop(&nums); } ``` -For user-defined struct elements, `i_cmp` compare function should be defined as the default `<` and `==` +For user-defined struct elements, `i_cmp` compare function should be defined because the default `<` and `==` only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching*. Similarily, if an element destructor `i_keydrop` is defined, `i_keyclone` function is required. *Alternatively `#define i_opt c_no_clone` to disable container cloning.* @@ -210,8 +210,8 @@ Let's make a vector of vectors, which can be cloned. All of its element vectors #include <stc/cvec.h> #define i_type Vec2D -#define i_keyclass Vec // Use i_keyclass when element type has "members" _clone(), _drop() and _cmp(). -#define i_opt c_no_cmp // Disable cmp (search/sort) for Vec2D because Vec_cmp() is not defined. +#define i_keyclass Vec // Use i_keyclass instead i_key when element type has "members" _clone(), _drop() and _cmp(). +#define i_opt c_no_cmp // Disable cmp (search/sort) for Vec2D because Vec_cmp() does not exist. #include <stc/cvec.h> int main(void) @@ -242,16 +242,17 @@ This example uses four different container types: #include <stdio.h> #define i_key int -#include <stc/cset.h> // cset_int: unordered set +#include <stc/cset.h> // cset_int: unordered set (assume i_key is basic type, uses `==` operator) struct Point { float x, y; }; // Define cvec_pnt with a less-comparison function for Point. #define i_key struct Point -#define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) +#define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) // enable sort/search #define i_tag pnt #include <stc/cvec.h> // cvec_pnt: vector of struct Point #define i_key int +#define i_native_cmp // enable sort/search. Use native `<` and `==` operators #include <stc/clist.h> // clist_int: singly linked list #define i_key int diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 52ad88e4..6bce56af 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -436,6 +436,7 @@ The **checkauto** utility described below, ensures that the `c_auto*` macros are #include <stc/algo/raii.h> // or <stc/calgo.h> ... // `c_defer` executes the expression(s) when leaving scope. +// Note: does not require inclusion of "raii.h". cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world"); c_defer (cstr_drop(&s1), cstr_drop(&s2)) { diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 1aeeb4f7..1d3177da 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -47,12 +47,12 @@ SpanTypeN_iter SpanType_begin(const SpanTypeN* self); SpanTypeN_iter SpanType_end(const SpanTypeN* self); void SpanType_next(SpanTypeN_iter* it); -SpanTypeN cspan_md(ValueType* data, d1, d2, ...); // make a multi-dim cspan, row-major order. -SpanTypeN cspan_md_left(ValueType* data, d1, d2, ...); // column-major ordered cspan (layout left). -SpanTypeN cspan_md_ordered(char order, ValueType* data, d1, d2, ...); // order='C': row-major, 'F' (Fortran): column-major. +SpanTypeN cspan_md(ValueType* data, d1, d2, ...); // make a multi-dim cspan, row-major order. +SpanTypeN cspan_md_order(char order, ValueType* data, d1, d2, ...); // order='C': row-major, 'F': column-major (FORTRAN). // transpose a md span (inverse axes). no changes to the underlying array. void cspan_transpose(const SpanTypeN* self); +bool cspan_is_order_F(const SpanTypeN* self); // create a sub md span of lower rank. Like e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL}); OutSpan1 cspan_submd2(TYPE OutSpan1, const SpanType2* parent, intptr_t x); // return a 1d subspan from a 2d span. diff --git a/include/stc/algo/raii.h b/include/stc/algo/raii.h index b0008a96..584f5c59 100644 --- a/include/stc/algo/raii.h +++ b/include/stc/algo/raii.h @@ -23,9 +23,6 @@ #ifndef STC_RAII_INCLUDED #define STC_RAII_INCLUDED -#define c_defer(...) \ - for (int _i = 1; _i; _i = 0, __VA_ARGS__) - #define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__) #define c_with_2(declvar, drop) \ for (declvar, *_i, **_ip = &_i; _ip; _ip = 0, drop) diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index efbebdc3..45c3a360 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -69,6 +69,7 @@ typedef long long _llong; #define c_new(T, ...) ((T*)memcpy(malloc(sizeof(T)), ((T[]){__VA_ARGS__}), sizeof(T))) #define c_LITERAL(T) (T) #endif +#define c_new_n(T, n) ((T*)malloc(sizeof(T)*(n))) #define c_malloc(sz) malloc(c_i2u(sz)) #define c_calloc(n, sz) calloc(c_i2u(n), c_i2u(sz)) #define c_realloc(p, sz) realloc(p, c_i2u(sz)) @@ -89,12 +90,12 @@ typedef long long _llong; _tv = *_xp; *_xp = *_yp; *_yp = _tv; } while (0) #define c_sizeof (intptr_t)sizeof #define c_strlen(s) (intptr_t)strlen(s) + #define c_strncmp(a, b, ilen) strncmp(a, b, c_i2u(ilen)) #define c_memcpy(d, s, ilen) memcpy(d, s, c_i2u(ilen)) #define c_memmove(d, s, ilen) memmove(d, s, c_i2u(ilen)) #define c_memset(d, val, ilen) memset(d, val, c_i2u(ilen)) #define c_memcmp(a, b, ilen) memcmp(a, b, c_i2u(ilen)) - #define c_u2i(u) ((intptr_t)((u) + 0*sizeof((u) == 1U))) #define c_i2u(i) ((size_t)(i) + 0*sizeof((i) == 1)) #define c_LTu(a, b) ((size_t)(a) < (size_t)(b)) @@ -228,6 +229,8 @@ STC_INLINE intptr_t cnextpow2(intptr_t n) { ; it.index < it.size; ++it.ref, ++it.index) #endif +#define c_defer(...) \ + for (int _i = 1; _i; _i = 0, __VA_ARGS__) #define c_drop(C, ...) \ do { c_forlist (_i, C*, {__VA_ARGS__}) C##_drop(*_i.ref); } while(0) diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 4d091395..358d5bf0 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -130,9 +130,7 @@ using_cspan_tuple(7); using_cspan_tuple(8); #define cspan_size(self) _cspan_size((self)->shape, cspan_rank(self)) #define cspan_rank(self) c_arraylen((self)->shape) #define cspan_is_order_F(self) ((self)->stride.d[0] < (self)->stride.d[cspan_rank(self) - 1]) - #define cspan_index(self, ...) c_PASTE(cspan_idx_, c_NUMARGS(__VA_ARGS__))(self, __VA_ARGS__) - #define cspan_at(self, ...) ((self)->data + cspan_index(self, __VA_ARGS__)) #define cspan_front(self) ((self)->data) #define cspan_back(self) ((self)->data + cspan_size(self) - 1) @@ -151,7 +149,7 @@ using_cspan_tuple(7); using_cspan_tuple(8); #define cspan_submd4(OutSpan, self, ...) _cspan_submdN(OutSpan, 4, self, __VA_ARGS__) #define _cspan_submdN(OutSpan, N, self, ...) \ - _cspan_submd##N(c_static_assert(cspan_rank((OutSpan*)0) == N - c_NUMARGS(__VA_ARGS__)), self, __VA_ARGS__) + (OutSpan)_cspan_submd##N(c_static_assert(cspan_rank((OutSpan*)0) == N - c_NUMARGS(__VA_ARGS__)), self, __VA_ARGS__) #define _cspan_submd2(ok, self, x) \ {.data=cspan_at(self, x, 0) + ok, .shape={(self)->shape[1]}, .stride={.d={(self)->stride.d[1]}}} @@ -171,9 +169,8 @@ using_cspan_tuple(7); using_cspan_tuple(8); #define _cspan_submd4_5(ok, self, x, y, z) \ {.data=cspan_at(self, x, y, z, 0) + ok, .shape={(self)->shape[3]}, .stride={.d={(self)->stride.d[3]}}} -#define cspan_md(array, ...) cspan_md_ordered('C', array, __VA_ARGS__) -#define cspan_md_left(array, ...) cspan_md_ordered('F', array, __VA_ARGS__) -#define cspan_md_ordered(order, array, ...) \ +#define cspan_md(array, ...) cspan_md_order('C', array, __VA_ARGS__) +#define cspan_md_order(order, array, ...) /* order='C' or 'F' */ \ {.data=array, .shape={__VA_ARGS__}, \ .stride=*(c_PASTE(cspan_tuple, c_NUMARGS(__VA_ARGS__))*)_cspan_shape2stride(order, ((int32_t[]){__VA_ARGS__}), c_NUMARGS(__VA_ARGS__))} diff --git a/misc/examples/astar.c b/misc/examples/astar.c index 44cdefee..590b7952 100644 --- a/misc/examples/astar.c +++ b/misc/examples/astar.c @@ -6,7 +6,6 @@ // https://www.redblobgames.com/pathfinding/a-star/introduction.html #define i_implement #include <stc/cstr.h> -#include <stc/algo/raii.h> #include <stdio.h> typedef struct diff --git a/misc/examples/bits.c b/misc/examples/bits.c index ce8e1de4..e0a11346 100644 --- a/misc/examples/bits.c +++ b/misc/examples/bits.c @@ -1,6 +1,5 @@ #include <stdio.h> #include <stc/cbits.h> -#include <stc/algo/raii.h> int main(void) { diff --git a/misc/examples/box2.c b/misc/examples/box2.c index 5ac706d4..eaab1c47 100644 --- a/misc/examples/box2.c +++ b/misc/examples/box2.c @@ -1,6 +1,5 @@ // example: https://doc.rust-lang.org/rust-by-example/std/box.html #include <stdio.h> -#include <stc/algo/raii.h> typedef struct { double x; diff --git a/misc/examples/convert.c b/misc/examples/convert.c index 3b9dc3ec..3f2f60f6 100644 --- a/misc/examples/convert.c +++ b/misc/examples/convert.c @@ -1,6 +1,5 @@ #define i_implement #include <stc/cstr.h> -#include <stc/algo/raii.h> #define i_key_str #define i_val_str diff --git a/misc/examples/person_arc.c b/misc/examples/person_arc.c index c78b541c..3a759610 100644 --- a/misc/examples/person_arc.c +++ b/misc/examples/person_arc.c @@ -1,7 +1,6 @@ /* cbox: heap allocated boxed type */ #define i_implement #include <stc/cstr.h> -#include <stc/algo/raii.h> typedef struct { cstr name, last; } Person; diff --git a/misc/examples/regex_replace.c b/misc/examples/regex_replace.c index 3a33efde..76664b1b 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regex_replace.c @@ -1,7 +1,6 @@ #define i_import #include <stc/cregex.h> #include <stc/csview.h> -#include <stc/algo/raii.h> bool add_10_years(int i, csview match, cstr* out) { if (i == 1) { // group 1 matches year diff --git a/misc/examples/sorted_map.c b/misc/examples/sorted_map.c index 2199846c..ff727632 100644 --- a/misc/examples/sorted_map.c +++ b/misc/examples/sorted_map.c @@ -1,7 +1,6 @@ // https://iq.opengenus.org/containers-cpp-stl/ #include <stdio.h> -#include <stc/algo/raii.h> #define i_key int #define i_val int #include <stc/csmap.h> diff --git a/misc/examples/unordered_set.c b/misc/examples/unordered_set.c index 006a1e80..14d69ce5 100644 --- a/misc/examples/unordered_set.c +++ b/misc/examples/unordered_set.c @@ -2,7 +2,6 @@ // C program to demonstrate various function of stc cset #define i_implement #include <stc/cstr.h> -#include <stc/algo/raii.h> #define i_key_str #include <stc/cset.h> |
