summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Lovset <[email protected]>2023-01-28 22:07:28 +0100
committerTyge Lovset <[email protected]>2023-01-28 22:07:28 +0100
commita344b43728ff40a2e1ee25f2f1b592f33432aee7 (patch)
treeba44cf2e8256281ea406c2c39d4eeedaf13ddf4f
parent8b7561225a22bf15958a2d19da29c9822811fce6 (diff)
downloadSTC-modified-a344b43728ff40a2e1ee25f2f1b592f33432aee7.tar.gz
STC-modified-a344b43728ff40a2e1ee25f2f1b592f33432aee7.zip
Generalized cspan_slice(), and improved usage/ergonomics.
-rw-r--r--docs/cspan_api.md3
-rw-r--r--include/stc/cspan.h52
-rw-r--r--misc/examples/multidim.c2
3 files changed, 21 insertions, 36 deletions
diff --git a/docs/cspan_api.md b/docs/cspan_api.md
index c0b86239..32ef49c4 100644
--- a/docs/cspan_api.md
+++ b/docs/cspan_api.md
@@ -41,8 +41,7 @@ SpanType cspan_at2(SpanType2* self, size_t x); // retur
SpanTypeN cspan_at3(SpanType3* self, size_t x, ...); // return a 1d or 2d subspan from a 3d span.
SpanTypeN cspan_at4(SpanType4* self, size_t x, ...); // number of args determines rank of output span.
-void cspan_slice(SpanTypeN* self, uint32_t xslice[2], ...); // slice multidim span into a md subspan.
-uint32_t[2] c_SLICE(a, b) // use to specify a:b xslice, ... b is optional.
+void cspan_slice(SpanTypeN* self, {x0,x1}, {y0,y1},...); // slice multidim span into a md subspan.
// return a subspan of same rank:
SpanType cspan_subspan(const SpanType* self, size_t offset, size_t count);
diff --git a/include/stc/cspan.h b/include/stc/cspan.h
index 41ad8c8b..19dd74d4 100644
--- a/include/stc/cspan.h
+++ b/include/stc/cspan.h
@@ -151,12 +151,13 @@ typedef struct { uint32_t d[4]; } cspan_idx4;
{.data=cspan_at(self, x, y, z, 0), .dim={(self)->dim[3]}}
// cspan_slice:
-// e.g.: cspan_slice(&ms3, c_SLICE(1,3), c_SLICE(0), c_SLICE(1,4));
-
-#define c_SLICE(...) ((const uint32_t[2]){__VA_ARGS__})
+// e.g.: cspan_slice(&ms3, {1,3}, {0}, {1,4});
#define cspan_slice(self, ...) \
- ((void)((self)->data += c_PASTE(_cspan_slice, c_NUMARGS(__VA_ARGS__))((self)->dim, (self)->stride, __VA_ARGS__)))
+ ((void)((self)->data += _cspan_slice(cspan_rank(self), (self)->dim, (self)->stride.d, \
+ (const uint32_t[][2]){__VA_ARGS__}) + \
+ c_static_assert(cspan_rank(self) == \
+ sizeof((const uint32_t[][2]){__VA_ARGS__})/8)))
// FUNCTIONS
@@ -198,35 +199,20 @@ static inline size_t _cspan_next_2(int rank, uint32_t pos[], const uint32_t dim[
return off;
}
-STC_INLINE size_t _cspan_slice2(uint32_t dim[2], const cspan_idx2 stri, const uint32_t x[2], const uint32_t y[2]) {
- const uint32_t x1 = x[1] ? x[1] : dim[0], y1 = y[1] ? y[1] : dim[1];
- const size_t ret = _cspan_i2(dim, stri, x[0], y[0]);
-
- c_ASSERT(x1 <= dim[0] && y1 <= dim[1]);
- dim[0] = x1 - x[0], dim[1] = y1 - y[0];
- return ret;
-}
-
-STC_INLINE size_t _cspan_slice3(uint32_t dim[3], const cspan_idx3 stri, const uint32_t x[2], const uint32_t y[2],
- const uint32_t z[2]) {
- const uint32_t x1 = x[1] ? x[1] : dim[0], y1 = y[1] ? y[1] : dim[1], z1 = z[1] ? z[1] : dim[2];
- const size_t ret = stri.d[2]*(stri.d[1]*x[0] + y[0]) + z[0];
-
- c_ASSERT(x1 <= dim[0] && y1 <= dim[1] && z1 <= dim[2]);
- dim[0] = x1 - x[0], dim[1] = y1 - y[0], dim[2] = z1 - z[0];
- return ret;
-}
-
-STC_INLINE size_t _cspan_slice4(uint32_t dim[4], const cspan_idx4 stri, const uint32_t x[2], const uint32_t y[2],
- const uint32_t z[2], const uint32_t w[2]) {
- const uint32_t x1 = x[1] ? x[1] : dim[0], y1 = y[1] ? y[1] : dim[1];
- const uint32_t z1 = z[1] ? z[1] : dim[2], w1 = w[1] ? w[1] : dim[3];
- const size_t ret = stri.d[3]*(stri.d[2]*(stri.d[1]*x[0] + y[0]) + z[0]) + w[0];
-
- c_ASSERT(x1 <= dim[0] && y1 <= dim[1] && z1 <= dim[2] && w1 <= dim[3]);
- dim[0] = x1 - x[0], dim[1] = y1 - y[0];
- dim[2] = z1 - z[0], dim[3] = w1 - w[0];
- return ret;
+STC_INLINE size_t _cspan_slice(int rank, uint32_t dim[], const uint32_t stri[], const uint32_t a[][2]) {
+ uint32_t t = a[0][1] ? a[0][1] : dim[0];
+ c_ASSERT(t <= dim[0]);
+ dim[0] = t - a[0][0];
+
+ size_t off = a[0][0];
+ for (int i = 1; i < rank; ++i) {
+ off *= stri[i];
+ off += a[i][0];
+ t = a[i][1] ? a[i][1] : dim[i];
+ c_ASSERT(t <= dim[i]);
+ dim[i] = t - a[i][0];
+ }
+ return off;
}
#endif
diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c
index f3d9e865..e25d727e 100644
--- a/misc/examples/multidim.c
+++ b/misc/examples/multidim.c
@@ -30,7 +30,7 @@ int main()
}
puts("ss3 = ms3[:, 1:3, 1:3]");
ispan3 ss3 = ms3;
- cspan_slice(&ss3, c_SLICE(0), c_SLICE(1,3), c_SLICE(1,3));
+ cspan_slice(&ss3, {0}, {1,3}, {1,3});
for (unsigned i=0; i != ss3.dim[0]; i++) {
for (unsigned j=0; j != ss3.dim[1]; j++) {