diff options
| author | Tyge Løvset <[email protected]> | 2023-01-27 14:39:02 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-01-27 14:39:02 +0100 |
| commit | 5c1b1616f5a20a54c32e57b0bea49f366441356b (patch) | |
| tree | a9f03820446339fce6bb6b04136be7cf92aa3776 | |
| parent | 0c7e627aa27ba42b9a9a4472a4f1cdf857c1a833 (diff) | |
| download | STC-modified-5c1b1616f5a20a54c32e57b0bea49f366441356b.tar.gz STC-modified-5c1b1616f5a20a54c32e57b0bea49f366441356b.zip | |
Added stride to cspan (md), prepared for cspan_slice() function.
| -rw-r--r-- | include/stc/cspan.h | 50 | ||||
| -rw-r--r-- | misc/examples/multidim.c | 22 | ||||
| -rw-r--r-- | misc/tests/ctest.h | 11 |
3 files changed, 48 insertions, 35 deletions
diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 5b0358e2..fabefc06 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -63,7 +63,11 @@ int demo2() { #define using_cspan(Self, T, RANK) \ typedef T Self##_value; typedef T Self##_raw; \ typedef struct { Self##_value *ref, *end; } Self##_iter; \ - typedef struct { Self##_value *data; uint32_t dim[RANK]; } Self; \ + typedef struct { \ + Self##_value *data; \ + uint32_t dim[RANK]; \ + cspan_idx##RANK stride; \ + } Self; \ \ STC_INLINE Self Self##_from_n(Self##_raw* raw, const size_t n) { \ return (Self){.data=raw, .dim={(uint32_t)n}}; \ @@ -84,11 +88,13 @@ int demo2() { #define using_cspan2(Self, T) using_cspan(Self, T, 1); using_cspan(Self##2, T, 2) #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) +typedef struct { uint32_t d[1]; } cspan_idx1; +typedef struct { uint32_t d[2]; } cspan_idx2; +typedef struct { uint32_t d[3]; } cspan_idx3; +typedef struct { uint32_t d[4]; } cspan_idx4; #define cspan_multidim(array, ...) \ - {.data=array, .dim={__VA_ARGS__}} + {.data=array, .dim={__VA_ARGS__}, .stride={.d={__VA_ARGS__}}} /* For static initialization, use cspan_make(). c_make() for non-static only. */ #define cspan_make(SpanType, ...) \ @@ -107,12 +113,7 @@ int demo2() { #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_resize(self, ...) \ - (void)memcpy((self)->dim, (uint32_t[]){__VA_ARGS__}, \ - sizeof((self)->dim) + cspan_rank_ok(self, c_NUMARGS(__VA_ARGS__))) + c_PASTE(_cspan_i, c_NUMARGS(__VA_ARGS__))((self)->dim, (self)->stride, __VA_ARGS__) #define cspan_at(self, ...) ((self)->data + cspan_index(self, __VA_ARGS__)) #define cspan_front(self) ((self)->data) @@ -121,40 +122,43 @@ int demo2() { #define cspan_subspan(self, offset, count) \ {.data=cspan_at(self, offset), .dim={count}} #define cspan_subspan2(self, offset, count) \ - {.data=cspan_at(self, offset, 0), .dim={count, (self)->dim[1]}} + {.data=cspan_at(self, offset, 0), .dim={count, (self)->dim[1]}, .stride={(self)->stride}} #define cspan_subspan3(self, offset, count) \ - {.data=cspan_at(self, offset, 0, 0), .dim={count, (self)->dim[1], (self)->dim[2]}} + {.data=cspan_at(self, offset, 0, 0), .dim={count, (self)->dim[1], (self)->dim[2]}, .stride={(self)->stride}} #define cspan_subspan4(self, offset, count) \ - {.data=cspan_at(self, offset, 0, 0, 0), .dim={count, (self)->dim[1], (self)->dim[2], (self)->dim[3]}} + {.data=cspan_at(self, offset, 0, 0, 0), .dim={count, (self)->dim[1], (self)->dim[2], (self)->dim[3]}, .stride={(self)->stride}} #define cspan_at4(...) c_MACRO_OVERLOAD(cspan_at4, __VA_ARGS__) #define cspan_at3(...) c_MACRO_OVERLOAD(cspan_at3, __VA_ARGS__) #define cspan_at2(self, x) \ {.data=cspan_at(self, x, 0), .dim={(self)->dim[1]}} #define cspan_at3_2(self, x) \ - {.data=cspan_at(self, x, 0, 0), .dim={(self)->dim[1], (self)->dim[2]}} + {.data=cspan_at(self, x, 0, 0), .dim={(self)->dim[1], (self)->dim[2]}, \ + .stride={.d={0, (self)->stride.d[2]}}} #define cspan_at3_3(self, x, y) \ {.data=cspan_at(self, x, y, 0), .dim={(self)->dim[2]}} #define cspan_at4_2(self, x) \ - {.data=cspan_at(self, x, 0, 0, 0), .dim={(self)->dim[1], (self)->dim[2], (self)->dim[3]}} + {.data=cspan_at(self, x, 0, 0, 0), .dim={(self)->dim[1], (self)->dim[2], (self)->dim[3]}, \ + .stride={.d={0, (self)->stride.d[2], (self)->stride.d[3]}}} #define cspan_at4_3(self, x, y) \ - {.data=cspan_at(self, x, y, 0, 0), .dim={(self)->dim[2], (self)->dim[3]}} + {.data=cspan_at(self, x, y, 0, 0), .dim={(self)->dim[2], (self)->dim[3]}, \ + .stride={.d={0, (self)->stride.d[3]}}} #define cspan_at4_4(self, x, y, z) \ {.data=cspan_at(self, x, y, z, 0), .dim={(self)->dim[3]}} -STC_INLINE size_t _cspan_i1(const uint32_t dim[1], uint32_t x) +STC_INLINE size_t _cspan_i1(const uint32_t dim[1], const cspan_idx1 stri, uint32_t x) { c_ASSERT(x < dim[0]); return x; } -STC_INLINE size_t _cspan_i2(const uint32_t dim[2], uint32_t x, uint32_t y) - { c_ASSERT(x < dim[0] && y < dim[1]); return dim[1]*x + y; } +STC_INLINE size_t _cspan_i2(const uint32_t dim[2], const cspan_idx2 stri, uint32_t x, uint32_t y) + { c_ASSERT(x < dim[0] && y < dim[1]); return stri.d[1]*x + y; } -STC_INLINE size_t _cspan_i3(const uint32_t dim[3], uint32_t x, uint32_t y, uint32_t z) { +STC_INLINE size_t _cspan_i3(const uint32_t dim[3], const cspan_idx3 stri, uint32_t x, uint32_t y, uint32_t z) { c_ASSERT(x < dim[0] && y < dim[1] && z < dim[2]); - return dim[2]*(dim[1]*x + y) + z; + return stri.d[2]*(stri.d[1]*x + y) + z; } -STC_INLINE size_t _cspan_i4(const uint32_t dim[4], uint32_t x, uint32_t y, uint32_t z, uint32_t w) { +STC_INLINE size_t _cspan_i4(const uint32_t dim[4], const cspan_idx4 stri, uint32_t x, uint32_t y, uint32_t z, uint32_t w) { c_ASSERT(x < dim[0] && y < dim[1] && z < dim[3] && w < dim[3]); - return dim[3]*(dim[2]*(dim[1]*x + y) + z) + w; + return stri.d[3]*(stri.d[2]*(stri.d[1]*x + y) + z) + w; } STC_INLINE size_t _cspan_size(const uint32_t dim[], unsigned rank) { size_t sz = dim[0]; diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c index 8a5492dc..d69a04fb 100644 --- a/misc/examples/multidim.c +++ b/misc/examples/multidim.c @@ -9,15 +9,27 @@ using_cspan3(ispan, int); int main() { cstack_int v = {0}; - c_FORLIST (i, unsigned, {1,2,3,4,5,6,7,8,9,10,11,12}) + c_FORLIST (i, unsigned, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}) cstack_int_push(&v, *i.ref); - // View data as contiguous memory representing 12 ints + // View data as contiguous memory representing 24 ints ispan ms1 = cspan_from(&v); + + // View the same data as a 3D array 2 x 3 x 4 + ispan3 ms3 = cspan_multidim(v.data, 2, 2, 6); + // View data as contiguous memory representing 2 rows of 6 ints each - ispan2 ms2 = cspan_multidim(v.data, 2, 6); - // View the same data as a 3D array 2 x 3 x 2 - ispan3 ms3 = cspan_multidim(v.data, 2, 3, 2); + ispan2 ms2 = cspan_at3(&ms3, 0); + ms2.data = cspan_at(&ms2, 1, 1); + ms2.dim[0] = 2; + ms2.dim[1] = 3; + for (unsigned i=0; i != ms2.dim[0]; i++) { + for (unsigned j=0; j != ms2.dim[1]; j++) + printf(" %2d", *cspan_at(&ms2, i, j)); + puts(""); + } + + ms2 = (ispan2)cspan_at3(&ms3, 0); // write data using 2D view for (unsigned i=0; i != ms2.dim[0]; i++) diff --git a/misc/tests/ctest.h b/misc/tests/ctest.h index 7edd41cc..294a6ca2 100644 --- a/misc/tests/ctest.h +++ b/misc/tests/ctest.h @@ -113,14 +113,14 @@ struct ctest { #ifdef __cplusplus #define CTEST_SETUP(sname) \ - template <> void CTEST_IMPL_SETUP_FNAME(sname)(struct CTEST_IMPL_DATA_SNAME(sname)* data) + template <> void CTEST_IMPL_SETUP_FNAME(sname)(struct CTEST_IMPL_DATA_SNAME(sname)* self) #define CTEST_TEARDOWN(sname) \ - template <> void CTEST_IMPL_TEARDOWN_FNAME(sname)(struct CTEST_IMPL_DATA_SNAME(sname)* data) + template <> void CTEST_IMPL_TEARDOWN_FNAME(sname)(struct CTEST_IMPL_DATA_SNAME(sname)* self) #define CTEST_FIXTURE(sname) \ - template <typename T> void CTEST_IMPL_SETUP_FNAME(sname)(T* data) { } \ - template <typename T> void CTEST_IMPL_TEARDOWN_FNAME(sname)(T* data) { } \ + template <typename T> void CTEST_IMPL_SETUP_FNAME(sname)(T* self) { } \ + template <typename T> void CTEST_IMPL_TEARDOWN_FNAME(sname)(T* self) { } \ struct CTEST_IMPL_DATA_SNAME(sname) #define CTEST_IMPL_CTEST(sname, tname, tskip) \ @@ -176,7 +176,6 @@ void CTEST_ERR(const char* fmt, ...) CTEST_IMPL_FORMAT_PRINTF(1, 2); // doesn't #define CTEST_F(sname, tname) CTEST_IMPL_CTEST_F(sname, tname, 0) #define CTEST_F_SKIP(sname, tname) CTEST_IMPL_CTEST_F(sname, tname, 1) - void assert_str(const char* cmp, const char* exp, const char* real, const char* caller, int line); #define ASSERT_STREQ(exp, real) assert_str("==", exp, real, __FILE__, __LINE__) #define ASSERT_STRNE(exp, real) assert_str("!=", exp, real, __FILE__, __LINE__) @@ -186,8 +185,6 @@ void assert_str(const char* cmp, const char* exp, const char* real, const char* void assert_wstr(const char* cmp, const wchar_t *exp, const wchar_t *real, const char* caller, int line); #define ASSERT_WSTREQ(exp, real) assert_wstr("==", exp, real, __FILE__, __LINE__) #define ASSERT_WSTRNE(exp, real) assert_wstr("!=", exp, real, __FILE__, __LINE__) -#define ASSERT_SUBWSTR(substr, real) assert_wstr("=~", substr, real, __FILE__, __LINE__) -#define ASSERT_NOT_SUBWSTR(substr, real) assert_wstr("!~", substr, real, __FILE__, __LINE__) void assert_data(const unsigned char* exp, size_t expsize, const unsigned char* real, size_t realsize, |
