Just some thouhghts line 407-415 can be put away in one function like bool get_float_value(uint8_t* typecode, float*value) and then used whenever needed. The other places where the same loop gets repeated for each typecode and operation is where C++ templates would really shine.. Personally I'd first investigate how to do that because I know it would shorten the code tremendously, but in C I'm not sure and YMMV. Probably a macro like (pseudocode)Here is an ugly example: https://github.com/v923z/micropython-ul ... ray.c#L402
Code: Select all
#define DO_LOOP(TYPE, OPERATION) \
TYPE *outdata = (TYPE *)out->data->items; \
for(size_t i=0; i < ol->data->len; i++) { \
value = ndarray_get_float_value(or->data->items, or->data->typecode, i); \
outdata[i] = ndarray_get_float_value(ol->data->items, ol->data->typecode, i) OPERATION value; \
} \
....
if(op == MP_BINARY_OP_ADD) { //Note: this one outside of the loop should be faster than inside of it!
if(typecode == NDARRAY_UINT8) {
DO_LOOP(uint_8, +)
}
... and so on
}
... and so on
but then you still need to branch manually on the typecode to type mapping and on the op to OPERATION mapping, no idea how do do that at runtime in C; for the operation you could have a lookup table for function pointers, but I don't know for the type <-> typecode things. Something with unions perhaps.
The upcasting function could be replaced with a lookup table in which the key would be an uint16_t which is (type_left << 8 | type_right), or something along those lines. I can probably come up with more ideas like these but sorry, I just don't have the time..