From 2e51101a5d4846cd47679505378dcf862d72ccec Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sun, 9 Aug 2020 22:47:53 +0200 Subject: Simplified carray API. --- stc/carray.h | 120 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 54 insertions(+), 66 deletions(-) (limited to 'stc') diff --git a/stc/carray.h b/stc/carray.h index 0b0a7751..cc3f84e0 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -20,8 +20,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef CARR__H__ -#define CARR__H__ +#ifndef CARRAY__H__ +#define CARRAY__H__ #include #include "cdefs.h" @@ -35,17 +35,11 @@ declare_carray(f, float); int main() { carray3f a3 = carray3f_make(30, 20, 10, 0.f); - carray3f_data(a3, 5, 4)[3] = 10.2f; // a3[5][4][3] - carray2f a2 = carray3f_at(a3, 5); // sub-array reference (no data copy). + *carray3f_at(a3, 5, 4, 3) = 10.2f; // a3[5][4][3] + carray2f a2 = carray3f_at1(a3, 5); // sub-array reference: a2 = a3[5] + printf("%f\n", *carray2f_at(a2, 4, 3)); // lookup a2[4][3] (=10.2f) + printf("%f\n", *carray3f_at(a3, 5, 4, 3)); // same data location, via a3 array. - printf("%f\n", carray2f_value(a2, 4, 3)); // readonly lookup a2[4][3] (=10.2f) - printf("%f\n", carray2f_data(a2, 4)[3]); // same, but this is writable. - printf("%f\n", carray2f_at(a2, 4).data[3]); // same, via sub-array access. - - printf("%f\n", carray3f_value(a3, 5, 4, 3)); // same data location, via a3 array. - printf("%f\n", carray3f_data(a3, 5, 4)[3]); - printf("%f\n", carray3f_at2(a3, 5, 4).data[3]); - carray2f_destroy(&a2); // does nothing, since it is a sub-array. carray3f_destroy(&a3); // also invalidates a2. } @@ -66,16 +60,33 @@ int main() #define _carray_SUB (SIZE_MAX >> 1) #define _carray_OWN (_carray_SUB + 1) -static inline size_t _carray2_ydim(const size_t* yxdim) { +STC_INLINE size_t _carray2_ydim(const size_t* yxdim) { return yxdim[0] / (yxdim[-1] & _carray_SUB); } -static inline size_t _carray3_size(const size_t* zdim) { +STC_INLINE size_t _carray3_size(const size_t* zdim) { return zdim[0] * zdim[-1]; } +#define declare_carray_common(D, tag, Value, valueDestroy) \ + typedef struct { Value *item, *end; } carray##D##tag##_iter_t; \ + \ + STC_INLINE carray##D##tag##_iter_t \ + carray##D##tag##_begin(carray##D##tag* a) { \ + carray##D##tag##_iter_t it = {a->data, a->data + carray##D##_size(*a)}; return it; \ + } \ + STC_INLINE void \ + carray##D##tag##_next(carray##D##tag##_iter_t* it) { ++it->item; } \ + \ + STC_INLINE void \ + carray##D##tag##_destroy(carray##D##tag* self) { \ + if (self->_xdim & _carray_OWN) { \ + c_foreach (i, carray##D##tag, *self) \ + valueDestroy(i.item); \ + free(self->data); \ + } \ + } #define declare_carray(...) c_MACRO_OVERLOAD(declare_carray, __VA_ARGS__) - #define declare_carray_2(tag, Value) \ declare_carray_3(tag, Value, c_default_destroy) @@ -96,14 +107,18 @@ static inline size_t _carray3_size(const size_t* zdim) { size_t _xdim, _yxdim, _zdim; \ } carray3##tag; \ \ - static inline carray1##tag \ + declare_carray_common(1, tag, Value, valueDestroy) \ + declare_carray_common(2, tag, Value, valueDestroy) \ + declare_carray_common(3, tag, Value, valueDestroy) \ + \ + STC_INLINE carray1##tag \ carray1##tag##_make(size_t xdim, Value val) { \ Value* m = c_new_n(Value, xdim); \ for (size_t i=0; i_xdim & _carray_OWN) { \ - size_t n = carray1_size(*self); Value* a = self->data; \ - while (n--) valueDestroy(&a[n]); free(a); \ - } \ - } \ - static inline void \ - carray2##tag##_destroy(carray2##tag* self) { \ - if (self->_xdim & _carray_OWN) { \ - size_t n = carray2_size(*self); Value* a = self->data; \ - while (n--) valueDestroy(&a[n]); free(a); \ - } \ - } \ - static inline void \ - carray3##tag##_destroy(carray3##tag* self) { \ - if (self->_xdim & _carray_OWN) { \ - size_t n = carray3_size(*self); Value* a = self->data; \ - while (n--) valueDestroy(&a[n]); free(a); \ - } \ - } \ + STC_INLINE Value* \ + carray1##tag##_at(carray1##tag *a, size_t x) { return a->data + x; } \ \ - static inline carray1##tag \ - carray2##tag##_at(carray2##tag a, size_t y) { \ - carray1##tag sub = {a.data + y*carray2_xdim(a), carray2_xdim(a)}; \ + STC_INLINE carray1##tag \ + carray2##tag##_at1(carray2##tag *a, size_t y) { \ + carray1##tag sub = {a->data + y*carray2_xdim(*a), carray2_xdim(*a)}; \ return sub; \ } \ - static inline Value* \ - carray2##tag##_data(carray2##tag a, size_t y) { \ - return a.data + y*carray2_xdim(a); \ - } \ - static inline Value \ - carray2##tag##_value(carray2##tag a, size_t y, size_t x) { \ - return a.data[ y*carray2_xdim(a) + x ]; \ + STC_INLINE Value* \ + carray2##tag##_at(carray2##tag *a, size_t y, size_t x) { \ + return a->data + y*carray2_xdim(*a) + x; \ } \ \ - static inline carray2##tag \ - carray3##tag##_at(carray3##tag a, size_t z) { \ - carray2##tag sub = {a.data + z*a._yxdim, carray3_xdim(a), a._yxdim}; \ + STC_INLINE carray2##tag \ + carray3##tag##_at1(carray3##tag *a, size_t z) { \ + carray2##tag sub = {a->data + z*a->_yxdim, carray3_xdim(*a), a->_yxdim}; \ return sub; \ } \ - static inline carray1##tag \ - carray3##tag##_at2(carray3##tag a, size_t z, size_t y) { \ - carray1##tag sub = {a.data + z*a._yxdim + y*carray3_xdim(a), carray3_xdim(a)}; \ + STC_INLINE carray1##tag \ + carray3##tag##_at2(carray3##tag *a, size_t z, size_t y) { \ + carray1##tag sub = {a->data + z*a->_yxdim + y*carray3_xdim(*a), carray3_xdim(*a)}; \ return sub; \ } \ - static inline Value* \ - carray3##tag##_data(carray3##tag a, size_t z, size_t y) { \ - return a.data + z*a._yxdim + y*carray3_xdim(a); \ - } \ - static inline Value \ - carray3##tag##_value(carray3##tag a, size_t z, size_t y, size_t x) { \ - return a.data[ z*a._yxdim + y*carray3_xdim(a) + x ]; \ + STC_INLINE Value* \ + carray3##tag##_at(carray3##tag *a, size_t z, size_t y, size_t x) { \ + return a->data + z*a->_yxdim + y*carray3_xdim(*a) + x; \ } \ - typedef Value carrayValue_##tag + typedef Value carray_##tag##_value_t #endif -- cgit v1.2.3