Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Well, you <em>could</em> extract the casts:</p> <pre><code>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) &lt;= convert(limits-&gt;max) &amp;&amp; loadptr(pData) &gt;= convert(limits-&gt;min); } switch(key-&gt;type) { case TYPE_UINT8: isWithinLimits = testLimits(&amp;limits, pData, loadptr_uint8, convert_uint8); break; // etc } </code></pre> <p>Or, if the various types form a contiguous range of values from 0, you could even make two arrays of function pointers and do:</p> <pre><code>bool isWithinLimits = testLimits(&amp;limits, pData, loadptrs[key-&gt;type], converts[key-&gt;type]); </code></pre> <p>Notes:</p> <ul> <li>You still have to write two functions for each type, although they're easily macro-generated if you prefer.</li> <li>It doesn't really seem worth it for this little code.</li> <li>I've chosen <code>int64_t</code> since it is capable of representing all the values of all the integer types you use, so the conversions to <code>int64_t</code> never discard information and never change the result of a comparison with respect to with doing the same comparison in the source type. But if you also wanted to cover <code>uint64_t</code>, then you can't use the same type for everything, since there is no integer type that can represent all the values of all integer types. You'd also need a separate <code>testLimitsf</code> function for <code>float</code>, perhaps using <code>long double</code> as the common type for future flexibility.</li> <li>[Edit: I just realised, assuming IEEE-754, <code>double</code> actually can exactly represent all the values of all the types you use. So with a slight portability restriction, you could use <code>testLimitsf</code> for everything and deal in doubles]</li> <li>Are you sure that it's worth converting to (for example) <code>uint8_t</code> before comparison? Either the value is in range for a <code>uint8_t</code>, in which case you don't need to convert, you can just do the comparison. Or else the value isn't in range, in which case the modulo reduction makes the comparison a bit meaningless except in the special cases of 0 and -1. So it might be worth it, if something you haven't stated makes it so, but it looks fishy to me.</li> <li>You said in a comment, "I am trying to make that function more efficient". This might go against that. It's logically possible to inline <code>testLimits</code> and also the calls to the casting functions in the <code>switch</code>, but I wouldn't count on it.</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload