diff options
| -rw-r--r-- | docs/cspan_api.md | 66 | ||||
| -rw-r--r-- | include/stc/cspan.h | 72 | ||||
| -rw-r--r-- | misc/examples/multidim.c | 8 |
3 files changed, 73 insertions, 73 deletions
diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 23301fe4..b9879a6f 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -10,7 +10,7 @@ See the c++ class [std::mdspan](https://en.cppreference.com/w/cpp/container/mdsp ```c #include <stc/cspan.h> using_cspan(SpanType, ValueType, Rank); // define SpanType with ValueType elements. - // Rank is number of dimensions (max 4 atm.) + // Rank is number of dimensions (max 4) // Shorthands: using_cspan2(S, ValueType); // define span types S1, S2 with Ranks 1, 2. using_cspan3(S, ValueType); // define span types S1, S2, S3 with Ranks 1, 2, 3. @@ -20,30 +20,30 @@ using_cspan4(S, ValueType); // define span types S1.., S4 with R Note that `cspan_make()`, `cmake_from*()`, `cspan_sliceX()` `and cspan_XtoY()` require a (safe) cast to its span-type on assignment, but not on initialization of a span variable. ```c -SpanType cspan_make(ValueType* data, size_t xdim, ...); // make N-dimensional cspan -SpanType cspan_from(STCContainer* cnt); // create a 1D cspan from a compatible STC container -SpanType cspan_from_array(ValueType array[]); // create a 1D cspan from a C array -SpanType cspan_from_list(T ValueType, {val0, val1, ...}); // create a 1D cspan from an initializer list -SpanType& cspan_literal(T SpanType, {val0, val1, ...}); // create a 1D cspan compound literal from init list - -void cspan_resize(SpanType* self, size_t xdim, ...); // change the extent of each dimension - -size_t cspan_size(const SpanType* self); // return number of elements -unsigned cspan_rank(const SpanType* self); // return number of dimensions -ValueType* cspan_at(SpanType* self, size_t x, ...); // access element -size_t cspan_index(const SpanType* self, size_t x, ...); // index of element - -SpanType1 cspan_slice1(const SpanType1* self, size_t x0, size_t width); // get a slice of a 1D cspan -SpanType2 cspan_slice2(const SpanType2* self, size_t x0, size_t width); // get a slice of a 2D cspan -SpanType3 cspan_slice3(const SpanType3* self, size_t x0, size_t width); // get a slice of a 3D cspan -SpanType4 cspan_slice4(const SpanType4* self, size_t x0, size_t width); // get a slice of a 4D cspan - -SpanType1 cspan_2to1(const SpanType2* self, size_t x); // return a 1D subspan -SpanType1 cspan_3to1(const SpanType3* self, size_t x, size_t y); // return a 1D subspan -SpanType2 cspan_3to2(const SpanType3* self, size_t x); // return a 2D subspan -SpanType1 cspan_4to1(const SpanType4* self, size_t x, size_t y, size_t z);// return a 1D subspan -SpanType2 cspan_4to2(const SpanType4* self, size_t x, size_t y); // return a 2D subspan -SpanType3 cspan_4to3(const SpanType4* self, size_t x); // return a 3D subspan +SpanType cspan_make(ValueType* data, size_t xdim, ...); // make N-dimensional cspan +SpanType cspan_from(STCContainer* cnt); // create a 1D cspan from a compatible STC container +SpanType cspan_from_array(ValueType array[]); // create a 1D cspan from a C array +SpanType cspan_from_list(T ValueType, {val0, val1, ...}); // create a 1D cspan from an initializer list +SpanType& cspan_literal(T SpanType, {val0, val1, ...}); // create a 1D cspan compound literal from init list + +void cspan_resize(SpanType* self, size_t xdim, ...); // change the extent of each dimension + +size_t cspan_size(SpanType spn); // return number of elements +unsigned cspan_rank(SpanType spn); // return number of dimensions +ValueType* cspan_at(SpanType spn, size_t x, ...); // access element +size_t cspan_index(SpanType spn, size_t x, ...); // index of element + +SpanType1 cspan_subspan1(SpanType1 spn, size_t offset, size_t count); // get a slice of a 1D cspan +SpanType2 cspan_subspan2(SpanType2 spn, size_t offset, size_t count); // get a slice of a 2D cspan +SpanType3 cspan_subspan3(SpanType3 spn, size_t offset, size_t count); // get a slice of a 3D cspan +SpanType4 cspan_subspan4(SpanType4 spn, size_t offset, size_t count); // get a slice of a 4D cspan + +SpanType1 cspan_2to1(SpanType2 spn, size_t x); // return a 1D subspan +SpanType1 cspan_3to1(SpanType3 spn, size_t x, size_t y); // return a 1D subspan +SpanType2 cspan_3to2(SpanType3 spn, size_t x); // return a 2D subspan +SpanType1 cspan_4to1(SpanType4 spn, size_t x, size_t y, size_t z); // return a 1D subspan +SpanType2 cspan_4to2(SpanType4 spn, size_t x, size_t y); // return a 2D subspan +SpanType3 cspan_4to3(SpanType4 spn, size_t x); // return a 3D subspan SpanType_iter SpanType_begin(const SpanType* self); SpanType_iter SpanType_end(const SpanType* self); @@ -75,15 +75,15 @@ int main() // define arr[xd][yd][zd] cspan FS3 span3 = cspan_make(vec.data, xd, yd, zd); - *cspan_at(&span3, 4, 3, 2) = 3.14f; - printf("index: %d", (int)cspan_index(&span3, 4, 3, 2)); + *cspan_at(span3, 4, 3, 2) = 3.14f; + printf("index: %d", (int)cspan_index(span3, 4, 3, 2)); - FS1 span1 = cspan_3to1(&span3, 4, 3); + FS1 span1 = cspan_3to1(span3, 4, 3); printf("\niterate span1: "); c_FOREACH (i, FS1, span1) printf("%g ", *i.ref); - FS2 span2 = cspan_3to2(&span3, 4); + FS2 span2 = cspan_3to2(span3, 4); printf("\niterate span2: "); c_FOREACH (i, FS2, span2) printf("%g ", *i.ref); @@ -92,15 +92,15 @@ int main() c_FORRANGE (i, span3.dim[0]) { c_FORRANGE (j, span3.dim[1]) { c_FORRANGE (k, span3.dim[2]) - printf(" %g", *cspan_at(&span3, i, j, k)); + printf(" %g", *cspan_at(span3, i, j, k)); printf(" |"); } puts(""); } - printf("%g\n", *cspan_at(&span3, 4, 3, 2)); - printf("%g\n", *cspan_at(&span2, 3, 2)); - printf("%g\n", *cspan_at(&span1, 2)); + printf("%g\n", *cspan_at(span3, 4, 3, 2)); + printf("%g\n", *cspan_at(span2, 3, 2)); + printf("%g\n", *cspan_at(span1, 2)); } } ``` diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 71db232e..ba4c7daa 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -33,9 +33,9 @@ int demo1() { for (size_t i=0; i<ms.dim[0]; i++) for (size_t j=0; j<ms.dim[1]; j++) - *cspan_at(&ms, i, j) = i*1000 + j; + *cspan_at(ms, i, j) = i*1000 + j; - printf("%f\n", *cspan_at(&ms, 3, 4)); + printf("%f\n", *cspan_at(ms, 3, 4)); } int demo2() { @@ -66,11 +66,11 @@ int demo2() { typedef struct { Self##_value *data; uint32_t dim[RANK]; } Self; \ \ STC_INLINE Self##_iter Self##_begin(const Self* self) { \ - Self##_iter it = {self->data, self->data + cspan_size(self)}; \ + Self##_iter it = {self->data, self->data + cspan_size(*self)}; \ return it; \ } \ STC_INLINE Self##_iter Self##_end(const Self* self) { \ - Self##_iter it = {NULL, self->data + cspan_size(self)}; \ + Self##_iter it = {NULL, self->data + cspan_size(*self)}; \ return it; \ } \ STC_INLINE void Self##_next(Self##_iter* it) \ @@ -81,7 +81,7 @@ int demo2() { #define using_cspan3(Self, T) using_cspan2(Self, T); using_cspan(Self##3, T, 3) #define using_cspan4(Self, T) using_cspan3(Self, T); using_cspan(Self##4, T, 4) -#define cspan_rank_ok(self, rank) c_STATIC_ASSERT(cspan_rank(self) == rank) +#define cspan_rank_ok(spn, rank) c_STATIC_ASSERT(cspan_rank(spn) == rank) #define cspan_make(array, ...) \ {.data=array, .dim={__VA_ARGS__}} @@ -99,39 +99,39 @@ int demo2() { #define cspan_literal(SpanType, ...) \ (c_INIT(SpanType)cspan_from_list(SpanType##_value, __VA_ARGS__)) -#define cspan_size(self) _cspan_size((self)->dim, cspan_rank(self)) -#define cspan_rank(self) c_ARRAYLEN((self)->dim) -#define cspan_index(self, ...) \ - c_PASTE(_cspan_i, c_NUMARGS(__VA_ARGS__))((self)->dim, __VA_ARGS__) + \ - cspan_rank_ok(self, c_NUMARGS(__VA_ARGS__)) +#define cspan_size(spn) _cspan_size((spn).dim, cspan_rank(spn)) +#define cspan_rank(spn) c_ARRAYLEN((spn).dim) +#define cspan_index(spn, ...) \ + c_PASTE(_cspan_i, c_NUMARGS(__VA_ARGS__))((spn).dim, __VA_ARGS__) + \ + cspan_rank_ok(spn, c_NUMARGS(__VA_ARGS__)) #define cspan_resize(self, ...) \ (void)memcpy((self)->dim, (uint32_t[]){__VA_ARGS__}, \ - sizeof((self)->dim) + cspan_rank_ok(self, c_NUMARGS(__VA_ARGS__))) - -#define cspan_at(self, ...) ((self)->data + cspan_index(self, __VA_ARGS__)) - -#define cspan_slice1(self, x0, width) \ - {.data=cspan_at(self, x0), .dim={width}} -#define cspan_slice2(self, x0, width) \ - {.data=cspan_at(self, x0, 0), .dim={width, (self)->dim[1]}} -#define cspan_slice3(self, x0, width) \ - {.data=cspan_at(self, x0, 0, 0), .dim={width, (self)->dim[1], (self)->dim[2]}} -#define cspan_slice4(self, x0, width) \ - {.data=cspan_at(self, x0, 0, 0, 0), .dim={width, (self)->dim[1], (self)->dim[2], (self)->dim[3]}} - -#define cspan_2to1(self, x) \ - {.data=cspan_at(self, x, 0), .dim={(self)->dim[1]}} -#define cspan_3to1(self, x, y) \ - {.data=cspan_at(self, x, y, 0), .dim={(self)->dim[2]}} -#define cspan_3to2(self, x) \ - {.data=cspan_at(self, x, 0, 0), .dim={(self)->dim[1], (self)->dim[2]}} -#define cspan_4to1(self, x, y, z) \ - {.data=cspan_at(self, x, y, z, 0), .dim={(self)->dim[3]}} -#define cspan_4to2(self, x, y) \ - {.data=cspan_at(self, x, y, 0, 0), .dim={(self)->dim[2], (self)->dim[3]}} -#define cspan_4to3(self, x) \ - {.data=cspan_at(self, x, 0, 0, 0), .dim={(self)->dim[1], (self)->dim[2], (self)->dim[3]}} + sizeof((self)->dim) + cspan_rank_ok(*(self), c_NUMARGS(__VA_ARGS__))) + +#define cspan_at(spn, ...) ((spn).data + cspan_index((spn), __VA_ARGS__)) + +#define cspan_subspan1(spn, offset, count) \ + {.data=cspan_at(spn, offset), .dim={count}} +#define cspan_subspan2(spn, offset, count) \ + {.data=cspan_at(spn, offset, 0), .dim={count, (spn).dim[1]}} +#define cspan_subspan3(spn, offset, count) \ + {.data=cspan_at(spn, offset, 0, 0), .dim={count, (spn).dim[1], (spn).dim[2]}} +#define cspan_subspan4(spn, offset, count) \ + {.data=cspan_at(spn, offset, 0, 0, 0), .dim={count, (spn).dim[1], (spn).dim[2], (spn).dim[3]}} + +#define cspan_2to1(spn, x) \ + {.data=cspan_at(spn, x, 0), .dim={(spn).dim[1]}} +#define cspan_3to1(spn, x, y) \ + {.data=cspan_at(spn, x, y, 0), .dim={(spn).dim[2]}} +#define cspan_3to2(spn, x) \ + {.data=cspan_at(spn, x, 0, 0), .dim={(spn).dim[1], (spn).dim[2]}} +#define cspan_4to1(spn, x, y, z) \ + {.data=cspan_at(spn, x, y, z, 0), .dim={(spn).dim[3]}} +#define cspan_4to2(spn, x, y) \ + {.data=cspan_at(spn, x, y, 0, 0), .dim={(spn).dim[2], (spn).dim[3]}} +#define cspan_4to3(spn, x) \ + {.data=cspan_at(spn, x, 0, 0, 0), .dim={(spn).dim[1], (spn).dim[2], (spn).dim[3]}} STC_INLINE size_t _cspan_i1(const uint32_t dim[1], uint32_t x) { c_ASSERT(x < dim[0]); return x; } @@ -149,7 +149,7 @@ STC_INLINE size_t _cspan_i4(const uint32_t dim[4], uint32_t x, uint32_t y, uint3 } STC_INLINE size_t _cspan_size(const uint32_t dim[], unsigned rank) { size_t sz = dim[0]; - while (rank --> 1) sz *= dim[rank]; + while (rank-- > 1) sz *= dim[rank]; return sz; } diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c index 99310847..4f31548e 100644 --- a/misc/examples/multidim.c +++ b/misc/examples/multidim.c @@ -27,16 +27,16 @@ int main() // write data using 2D view for (unsigned i=0; i != ms2.dim[0]; i++) for (unsigned j=0; j != ms2.dim[1]; j++) - *cspan_at(&ms2, i, j) = i*1000 + j; + *cspan_at(ms2, i, j) = i*1000 + j; // print all items using 1D view printf("all: "); for (unsigned i=0; i != ms1.dim[0]; i++) - printf(" %d", *cspan_at(&ms1, i)); + printf(" %d", *cspan_at(ms1, i)); puts(""); // or iterate a subspan... - ispan2 sub = cspan_3to2(&ms3, 1); + ispan2 sub = cspan_3to2(ms3, 1); printf("sub: "); c_FOREACH (i, ispan2, sub) printf(" %d", *i.ref); @@ -49,7 +49,7 @@ int main() for (unsigned j=0; j != ms3.dim[1]; j++) { for (unsigned k=0; k != ms3.dim[2]; k++) - printf("%d ", *cspan_at(&ms3, i, j, k)); + printf("%d ", *cspan_at(ms3, i, j, k)); puts(""); } } |
