summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md25
-rw-r--r--docs/ccommon_api.md1
-rw-r--r--docs/cspan_api.md6
-rw-r--r--include/stc/algo/raii.h3
-rw-r--r--include/stc/ccommon.h5
-rw-r--r--include/stc/cspan.h9
-rw-r--r--misc/examples/astar.c1
-rw-r--r--misc/examples/bits.c1
-rw-r--r--misc/examples/box2.c1
-rw-r--r--misc/examples/convert.c1
-rw-r--r--misc/examples/person_arc.c1
-rw-r--r--misc/examples/regex_replace.c1
-rw-r--r--misc/examples/sorted_map.c1
-rw-r--r--misc/examples/unordered_set.c1
14 files changed, 24 insertions, 33 deletions
diff --git a/README.md b/README.md
index 67c4d7fd..1601204d 100644
--- a/README.md
+++ b/README.md
@@ -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>