Simplify hb_in_range()

It's both faster and produces smaller code.  Now I feel stupid for
not writing it this way before.
This commit is contained in:
Behdad Esfahbod 2014-07-11 14:18:01 -04:00
parent db8934faa1
commit a8b89a09f6
1 changed files with 6 additions and 10 deletions

View File

@ -786,20 +786,16 @@ struct hb_auto_trace_t<0, ret_t> {
/* Misc */ /* Misc */
template <typename T> class hb_assert_unsigned_t;
template <> class hb_assert_unsigned_t<unsigned char> {};
template <> class hb_assert_unsigned_t<unsigned int> {};
template <> class hb_assert_unsigned_t<unsigned long> {};
/* Pre-mature optimization:
* Checks for lo <= u <= hi but with an optimization if lo and hi
* are only different in a contiguous set of lower-most bits.
*/
template <typename T> static inline bool template <typename T> static inline bool
hb_in_range (T u, T lo, T hi) hb_in_range (T u, T lo, T hi)
{ {
if ( ((lo^hi) & lo) == 0 && hb_assert_unsigned_t<T> error_hb_in_range_called_with_signed_type HB_UNUSED;
((lo^hi) & hi) == (lo^hi) && return (u - lo) <= (hi - lo);
((lo^hi) & ((lo^hi) + 1)) == 0 )
return (u & ~(lo^hi)) == lo;
else
return lo <= u && u <= hi;
} }
template <typename T> static inline bool template <typename T> static inline bool