Well, you can extract the broadcasts:
int64_t loadptr_uint8(const void *p) { return *(uint8_t*)p; } int64_t convert_uint8(int64_t val) { return (uint8_t)val; } int testLimits(const limits_t *plimits, const void *pData, int64_t(*loadptr)(void*), int64_t (*convert)(int64_t)) { return loadptr(pData) <= convert(limits->max) && loadptr(pData) >= convert(limits->min); } switch(key->type) { case TYPE_UINT8: isWithinLimits = testLimits(&limits, pData, loadptr_uint8, convert_uint8); break;
Or, if different types form an adjacent range of values ββfrom 0, you could even create two arrays of function pointers and do:
bool isWithinLimits = testLimits(&limits, pData, loadptrs[key->type], converts[key->type]);
Notes:
- You still have to write two functions for each type, although they are easily generated by macros if you prefer.
- Actually this is not like this little code.
- I chose
int64_t , because it is able to display all the values ββof all the integer types you use, so conversions to int64_t never discard information and never change the result of the comparison with respect to performing the same comparison in the source type. But if you would also like to cover uint64_t , you cannot use the same type for everything, since there is no integer type that can represent all the values ββof all integer types. You will also need a separate testLimitsf function for float , possibly using long double as a generic type for future flexibility. - [Edit: I just realized, assuming that IEEE-754,
double can really accurately represent all the values ββof all types that you use. Therefore, with a slight portability limit, you can use testLimitsf for everything and deal in double-locale numbers] - Are you sure that before matching it is worth converting (for example)
uint8_t ? Or the value is in the range for uint8_t , in which case you do not need to convert, you can just do the comparison. Or the value is not in the range, and in this case the modular reduction makes the comparison a little pointless, except in special cases 0 and -1. So it might be worth it if something you didn't say it does it that way, but it seems suspicious to me. - You said in a comment: "I'm trying to make this function more efficient." It may go against it. It is logically possible to embed
testLimits , as well as calls to cast functions in switch , but I would not count on it.
source share