summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/stc/algo/cmspan.h74
-rw-r--r--include/stc/algo/cspan.h104
-rw-r--r--include/stc/ccommon.h2
-rw-r--r--include/stc/cpque.h6
-rw-r--r--misc/examples/multidim.c36
5 files changed, 101 insertions, 121 deletions
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 <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/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 <stdio.h>
#include <stc/algo/cspan.h>
-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 <stc/ccommon.h>
+#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 <stc/cstack.h>
-#include <stc/algo/cmspan.h>
+#include <stc/algo/cspan.h>
#include <stdio.h>
-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("");
}
}