From c5e071c622d6f460aa1ad07b6543ceaaed5209fc Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 14 Jan 2023 00:05:33 +0100 Subject: Merged cmspan into cspan. cspan is now multi-dimensional array view (also 1-dimensional). --- include/stc/algo/cmspan.h | 74 --------------------------------- include/stc/algo/cspan.h | 104 ++++++++++++++++++++++++++++++++++------------ include/stc/ccommon.h | 2 +- include/stc/cpque.h | 6 +-- misc/examples/multidim.c | 36 ++++++++-------- 5 files changed, 101 insertions(+), 121 deletions(-) delete mode 100644 include/stc/algo/cmspan.h diff --git a/include/stc/algo/cmspan.h b/include/stc/algo/cmspan.h deleted file mode 100644 index 8edf956f..00000000 --- a/include/stc/algo/cmspan.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -#include -#include -using_cmspan(S3f, float, 3); - -int main() -{ - float raw[3*4*5]; - S3f span = cmspan_make(raw, 3, 4, 5); - *cmspan_at(&span, 2, 3, 4) = 100; - - printf("%f\n", *cmspan_at(&span, 2, 3, 4)); -} -*/ -#ifndef STC_CMSPAN_H_INCLUDED -#define STC_CMSPAN_H_INCLUDED - -#include - -#define using_cmspan(Self, T, DIM) \ - typedef struct { T *data; uint32_t dim[DIM]; } Self; \ - typedef T Self##_raw, Self##_value; \ - typedef struct { Self##_value *ref, *end; } Self##_iter; \ - \ - STC_INLINE Self##_iter Self##_begin(const Self* self) { \ - Self##_iter it = {self->data, self->data + cmspan_size(self)}; \ - return it; \ - } \ - STC_INLINE Self##_iter Self##_end(const Self* self) { \ - Self##_iter it = {NULL, self->data + cmspan_size(self)}; \ - return it; \ - } \ - STC_INLINE void Self##_next(Self##_iter* it) \ - { if (++it->ref == it->end) it->ref = NULL; } \ - struct stc_nostruct - -#define cmspan_assert(self, rank) c_STATIC_ASSERT(cmspan_rank(self) == rank) - -#define cmspan_init() {NULL} -#define cmspan_make(data, ...) {data, {__VA_ARGS__}} - -#define cmspan_reshape(self, ...) \ - memcpy((self)->dim, (uint32_t[]){__VA_ARGS__}, \ - sizeof((self)->dim) + cmspan_assert(self, c_NUMARGS(__VA_ARGS__))) - -#define cmspan_at(self, ...) \ - ((self)->data + c_PASTE(_cmspan_i, c_NUMARGS(__VA_ARGS__))((self)->dim, __VA_ARGS__) \ - + cmspan_assert(self, c_NUMARGS(__VA_ARGS__))) - -#define cmspan_size(self) _cmspan_size((self)->dim, cmspan_rank(self)) -#define cmspan_rank(self) c_ARRAYLEN((self)->dim) - -STC_INLINE uint32_t _cmspan_i1(const uint32_t dim[1], uint32_t x) - { assert(x < dim[0]); return x; } - -STC_INLINE uint32_t _cmspan_i2(const uint32_t dim[2], uint32_t x, uint32_t y) - { assert(x < dim[0] && y < dim[1]); return dim[1]*x + y; } - -STC_INLINE uint32_t _cmspan_i3(const uint32_t dim[3], uint32_t x, uint32_t y, uint32_t z) { - assert(x < dim[0] && y < dim[1] && z < dim[2]); - return dim[2]*(dim[1]*x + y) + z; -} -STC_INLINE uint32_t _cmspan_i4(const uint32_t dim[4], uint32_t x, uint32_t y, uint32_t z, uint32_t w) { - assert(x < dim[0] && y < dim[1] && z < dim[3] && w < dim[3]); - return dim[3]*(dim[2]*(dim[1]*x + y) + z) + w; -} - -STC_INLINE size_t _cmspan_size(const uint32_t dim[], unsigned rank) { - size_t sz = dim[0]; - while (rank --> 1) sz *= dim[rank]; - return sz; -} - -#endif diff --git a/include/stc/algo/cspan.h b/include/stc/algo/cspan.h index 23507fde..03cb8622 100644 --- a/include/stc/algo/cspan.h +++ b/include/stc/algo/cspan.h @@ -19,23 +19,33 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. -*/ -/* + */ +/* #include #include -using_cspan(IntSpan, int); -int main() -{ +using_cspan(Span3f, float, 3); + +int demo1() { + float raw[3*4*5]; + Span3f span = cspan_make(raw, 3, 4, 5); + *cspan_at(&span, 2, 3, 4) = 100; + + printf("%f\n", *cspan_at(&span, 2, 3, 4)); +} + +using_cspan(Intspan, int, 1); + +int demo2() { int array[] = {1, 2, 3, 4, 5}; - IntSpan span = cspan_from(array); + Intspan span = cspan_from(array); - c_FOREACH (i, IntSpan, span) + c_FOREACH (i, Intspan, span) printf(" %d", *i.ref); puts(""); // use a temporary IntSpan object. - c_FORFILTER (i, IntSpan, cspan_object(IntSpan, {10, 20, 30, 23, 22, 21}) + c_FORFILTER (i, Intspan, cspan_object(Intspan, {10, 20, 30, 23, 22, 21}) , c_FLT_SKIPWHILE(i, *i.ref < 25) && (*i.ref & 1) == 0 // even only , c_FLT_TAKE(i, 2)) // break after 2 @@ -46,35 +56,77 @@ int main() #ifndef STC_CSPAN_H_INCLUDED #define STC_CSPAN_H_INCLUDED -#include +#include "../ccommon.h" -#define cspan_object(C, ...) \ - ((C){.data = (C##_value[])__VA_ARGS__, \ - .size = sizeof((C##_value[])__VA_ARGS__)/sizeof(C##_value)}) - -#define cspan_from(data) \ - {data + c_STATIC_ASSERT(sizeof(data) != sizeof(void*)), c_ARRAYLEN(data)} -#define cspan_make(data, size) \ - {data + c_STATIC_ASSERT(c_ARRAYLEN(data) >= size || sizeof(data) == sizeof(void*)), size} -#define cspan_size(self) ((size_t)(self)->size) - -#define using_cspan(Self, T) \ - typedef T Self##_raw, Self##_value; \ - typedef struct { Self##_value *data; size_t size; } Self; \ +#define using_cspan(Self, T, RANK) \ + typedef T Self##_value, Self##_raw; \ + typedef struct { Self##_value *data; uint32_t dim[RANK]; } Self; \ typedef struct { Self##_value *ref, *end; } Self##_iter; \ \ - STC_INLINE Self##_value* Self##_at(const Self* self, size_t idx) \ - { assert(idx < self->size); return self->data + idx; } \ STC_INLINE Self##_iter Self##_begin(const Self* self) { \ - Self##_iter it = {self->data, self->data + self->size}; \ + 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 + self->size}; \ + Self##_iter it = {NULL, self->data + cspan_size(self)}; \ return it; \ } \ STC_INLINE void Self##_next(Self##_iter* it) \ { if (++it->ref == it->end) it->ref = NULL; } \ struct stc_nostruct +#define cspan_assert(self, rank) c_STATIC_ASSERT(cspan_rank(self) == rank) + +#define cspan_object(S, ...) \ + ((S){.data = (S##_value[])__VA_ARGS__, \ + .dim = {sizeof((S##_value[])__VA_ARGS__)/sizeof(S##_value)}}) + +#define cspan_make(data, ...) {data, {__VA_ARGS__}} +#define cspan_from(data) \ + {data + c_STATIC_ASSERT(sizeof(data) != sizeof(void*)), {c_ARRAYLEN(data)}} + +#define cspan_size(self) _cspan_size((self)->dim, cspan_rank(self)) +#define cspan_rank(self) c_ARRAYLEN((self)->dim) + +#define cspan_reshape(self, ...) \ + memcpy((self)->dim, (uint32_t[]){__VA_ARGS__}, \ + sizeof((self)->dim) + cspan_assert(self, c_NUMARGS(__VA_ARGS__))) + +#define cspan_at(self, ...) \ + ((self)->data + c_PASTE(_cspan_i, c_NUMARGS(__VA_ARGS__))((self)->dim, __VA_ARGS__) \ + + cspan_assert(self, c_NUMARGS(__VA_ARGS__))) + +#define cspan_4to3(self, x) \ + {cspan_at(self, x, 0, 0, 0), {(self)->dim[1], (self)->dim[2], (self)->dim[3]}} +#define cspan_4to2(self, x, y) \ + {cspan_at(self, x, y, 0, 0), {(self)->dim[2], (self)->dim[3]}} +#define cspan_4to1(self, x, y, z) \ + {cspan_at(self, x, y, z, 0), {(self)->dim[3]}} +#define cspan_3to2(self, x) \ + {cspan_at(self, x, 0, 0), {(self)->dim[1], (self)->dim[2]}} +#define cspan_3to1(self, x, y) \ + {cspan_at(self, x, y, 0), {(self)->dim[2]}} +#define cspan_2to1(self, x) \ + {cspan_at(self, x, 0), {(self)->dim[1]}} + +STC_INLINE uint32_t _cspan_i1(const uint32_t dim[1], uint32_t x) + { assert(x < dim[0]); return x; } + +STC_INLINE uint32_t _cspan_i2(const uint32_t dim[2], uint32_t x, uint32_t y) + { assert(x < dim[0] && y < dim[1]); return dim[1]*x + y; } + +STC_INLINE uint32_t _cspan_i3(const uint32_t dim[3], uint32_t x, uint32_t y, uint32_t z) { + assert(x < dim[0] && y < dim[1] && z < dim[2]); + return dim[2]*(dim[1]*x + y) + z; +} +STC_INLINE uint32_t _cspan_i4(const uint32_t dim[4], uint32_t x, uint32_t y, uint32_t z, uint32_t w) { + assert(x < dim[0] && y < dim[1] && z < dim[3] && w < dim[3]); + return dim[3]*(dim[2]*(dim[1]*x + y) + z) + w; +} +STC_INLINE size_t _cspan_size(const uint32_t dim[], unsigned rank) { + size_t sz = dim[0]; + while (rank --> 1) sz *= dim[rank]; + return sz; +} + #endif diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index aa22976f..a2c529a7 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -80,7 +80,7 @@ #define c_FREE(p) free(p) #endif -#define c_STATIC_ASSERT(b, ...) ((int)(0*sizeof(int[(b) ? 1 : -1]))) +#define c_STATIC_ASSERT(b) ((int)(0*sizeof(int[(b) ? 1 : -1]))) #define c_CONTAINER_OF(p, T, m) ((T*)((char*)(p) + 0*sizeof((p) == &((T*)0)->m) - offsetof(T, m))) #define c_DELETE(T, ptr) do { T *_tp = ptr; T##_drop(_tp); c_FREE(_tp); } while (0) #define c_SWAP(T, xp, yp) do { T *_xp = xp, *_yp = yp, \ diff --git a/include/stc/cpque.h b/include/stc/cpque.h index 74e0a5b7..28b5eb86 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -112,11 +112,11 @@ STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_raw raw) STC_DEF void _cx_memb(_sift_down_)(_cx_self* self, const size_t idx, const size_t n) { - _cx_value* arr = self->data - 1; + _cx_value t, *arr = self->data - 1; for (size_t r = idx, c = idx*2; c <= n; c *= 2) { - c += (c < n && (i_less_functor(self, (&arr[c]), (&arr[c + 1])))); + c += i_less_functor(self, (&arr[c]), (&arr[c + (c < n)])); if (!(i_less_functor(self, (&arr[r]), (&arr[c])))) return; - _cx_value t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; + t = arr[r], arr[r] = arr[c], arr[r = c] = t; } } diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c index 044693be..2cf16b7f 100644 --- a/misc/examples/multidim.c +++ b/misc/examples/multidim.c @@ -1,12 +1,14 @@ // Example from https://en.cppreference.com/w/cpp/container/mdspan #define i_val int #include -#include +#include #include -using_cmspan(ispan1, int, 1); -using_cmspan(ispan2, int, 2); -using_cmspan(ispan3, int, 3); - + +using_cspan(ispan1, int, 1); +using_cspan(ispan2, int, 2); +using_cspan(ispan3, int, 3); + + int main() { cstack_int v = {0}; @@ -14,20 +16,20 @@ int main() cstack_int_push(&v, *i.ref); // View data as contiguous memory representing 12 ints - ispan1 ms1 = cmspan_make(v.data, 12); + ispan1 ms1 = cspan_make(v.data, 12); // View data as contiguous memory representing 2 rows of 6 ints each - ispan2 ms2 = cmspan_make(v.data, 2, 6); + ispan2 ms2 = cspan_make(v.data, 2, 6); // View the same data as a 3D array 2 x 3 x 2 - ispan3 ms3 = cmspan_make(v.data, 2, 3, 2); + ispan3 ms3 = cspan_make(v.data, 2, 3, 2); // write data using 2D view - for(unsigned i=0; i != ms2.dim[0]; i++) - for(unsigned j=0; j != ms2.dim[1]; j++) - *cmspan_at(&ms2, i, j) = i*1000 + j; + 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; // print data using 1D view - for(unsigned i=0; i != ms1.dim[0]; i++) - printf(" %d", *cmspan_at(&ms1, i)); + for (unsigned i=0; i != ms1.dim[0]; i++) + printf(" %d", *cspan_at(&ms1, i)); puts(""); c_FOREACH (i, ispan1, ms1) @@ -35,13 +37,13 @@ int main() puts(""); // read back using 3D view - for(unsigned i=0; i != ms3.dim[0]; i++) + for (unsigned i=0; i != ms3.dim[0]; i++) { printf("slice @ i = %u\n", i); - for(unsigned j=0; j != ms3.dim[1]; j++) + for (unsigned j=0; j != ms3.dim[1]; j++) { - for(unsigned k=0; k != ms3.dim[2]; k++) - printf("%d ", *cmspan_at(&ms3, i, j, k)); + for (unsigned k=0; k != ms3.dim[2]; k++) + printf("%d ", *cspan_at(&ms3, i, j, k)); puts(""); } } -- cgit v1.2.3