diff options
| author | Tyge Løvset <[email protected]> | 2023-01-13 16:57:32 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-01-13 16:57:32 +0100 |
| commit | bb92cdbeaa279d8ef90dff0cf088585a50e7d52c (patch) | |
| tree | a357ad9f39e979b5354a20a78511e253d577f31d /include/stc | |
| parent | 350bb65a2f68b14ce16a21ea8670cc087e39f4ce (diff) | |
| download | STC-modified-bb92cdbeaa279d8ef90dff0cf088585a50e7d52c.tar.gz STC-modified-bb92cdbeaa279d8ef90dff0cf088585a50e7d52c.zip | |
Added algo/cmspan.h: multi-dim span, similar to c++23 mdspan. May get some API changes. Changed cspan.h, these may merge.
Diffstat (limited to 'include/stc')
| -rw-r--r-- | include/stc/algo/cmspan.h | 74 | ||||
| -rw-r--r-- | include/stc/algo/crange.h | 4 | ||||
| -rw-r--r-- | include/stc/algo/cspan.h | 49 |
3 files changed, 102 insertions, 25 deletions
diff --git a/include/stc/algo/cmspan.h b/include/stc/algo/cmspan.h new file mode 100644 index 00000000..8edf956f --- /dev/null +++ b/include/stc/algo/cmspan.h @@ -0,0 +1,74 @@ +/* +#include <stdio.h> +#include <stc/algo/cmspan.h> +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 <stc/ccommon.h> + +#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/crange.h b/include/stc/algo/crange.h index 0c4d8465..518320b5 100644 --- a/include/stc/algo/crange.h +++ b/include/stc/algo/crange.h @@ -34,7 +34,7 @@ int main() // use a temporary crange object. int a = 100, b = INT32_MAX; - c_FORFILTER (i, crange, crange_LITERAL(a, b, 8) + c_FORFILTER (i, crange, crange_object(a, b, 8) , i.index > 10 , c_FLT_TAKE(i, 3)) printf(" %lld", *i.ref); @@ -46,7 +46,7 @@ int main() #include <stc/ccommon.h> -#define crange_LITERAL(...) \ +#define crange_object(...) \ (*(crange[]){crange_make(__VA_ARGS__)}) typedef long long crange_value; diff --git a/include/stc/algo/cspan.h b/include/stc/algo/cspan.h index 8378bfe3..23507fde 100644 --- a/include/stc/algo/cspan.h +++ b/include/stc/algo/cspan.h @@ -28,14 +28,14 @@ using_cspan(IntSpan, int); int main() { int array[] = {1, 2, 3, 4, 5}; - IntSpan span = {array, c_ARRAYLEN(array)}; + IntSpan span = cspan_from(array); c_FOREACH (i, IntSpan, span) printf(" %d", *i.ref); puts(""); // use a temporary IntSpan object. - c_FORFILTER (i, IntSpan, cspan_LITERAL(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 @@ -48,30 +48,33 @@ int main() #include <stc/ccommon.h> -#define cspan_LITERAL(C, ...) \ +#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; typedef const Self##_raw Self##_value; \ -typedef struct { Self##_value *data; size_t size; } 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}; \ - return it; \ -} \ - \ -STC_INLINE Self##_iter Self##_end(const Self* self) { \ - Self##_iter it = {NULL, self->data + self->size}; \ - return it; \ -} \ - \ -STC_INLINE void Self##_next(Self##_iter* it) \ - { if (++it->ref == it->end) it->ref = NULL; } \ -struct stc_nostruct + typedef T Self##_raw, Self##_value; \ + typedef struct { Self##_value *data; size_t size; } 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}; \ + return it; \ + } \ + STC_INLINE Self##_iter Self##_end(const Self* self) { \ + Self##_iter it = {NULL, self->data + self->size}; \ + return it; \ + } \ + STC_INLINE void Self##_next(Self##_iter* it) \ + { if (++it->ref == it->end) it->ref = NULL; } \ + struct stc_nostruct #endif |
