diff options
Diffstat (limited to 'runtime/utils.h')
| -rw-r--r-- | runtime/utils.h | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/runtime/utils.h b/runtime/utils.h index 1c2576c2d4..0fbc9df5a7 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -22,6 +22,7 @@ #include <limits> #include <memory> #include <string> +#include <type_traits> #include <vector> #include "arch/instruction_set.h" @@ -115,32 +116,45 @@ static inline bool IsInt(int N, intptr_t value) { return (-limit <= value) && (value < limit); } -static inline bool IsInt32(int N, int32_t value) { - CHECK_LT(0, N); - CHECK_LT(static_cast<size_t>(N), 8 * sizeof(int32_t)); - int32_t limit = static_cast<int32_t>(1) << (N - 1); - return (-limit <= value) && (value < limit); -} - -static inline bool IsInt64(int N, int64_t value) { - CHECK_LT(0, N); - CHECK_LT(static_cast<size_t>(N), 8 * sizeof(int64_t)); - int64_t limit = static_cast<int64_t>(1) << (N - 1); - return (-limit <= value) && (value < limit); -} - -static inline bool IsUint(int N, intptr_t value) { - CHECK_LT(0, N); - CHECK_LT(N, kBitsPerIntPtrT); - intptr_t limit = static_cast<intptr_t>(1) << N; - return (0 <= value) && (value < limit); -} - -static inline bool IsAbsoluteUint(int N, intptr_t value) { - CHECK_LT(0, N); - CHECK_LT(N, kBitsPerIntPtrT); - if (value < 0) value = -value; - return IsUint(N, value); +template <typename T> +static constexpr T GetIntLimit(size_t bits) { + return + DCHECK_CONSTEXPR(bits > 0, "bits cannot be zero", 0) + DCHECK_CONSTEXPR(bits < kBitsPerByte * sizeof(T), "kBits must be < max.", 0) + static_cast<T>(1) << (bits - 1); +} + +template <size_t kBits, typename T> +static constexpr bool IsInt(T value) { + static_assert(kBits > 0, "kBits cannot be zero."); + static_assert(kBits <= kBitsPerByte * sizeof(T), "kBits must be <= max."); + static_assert(std::is_signed<T>::value, "Needs a signed type."); + // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is + // trivially true. + return (kBits == kBitsPerByte * sizeof(T)) ? + true : + (-GetIntLimit<T>(kBits) <= value) && (value < GetIntLimit<T>(kBits)); +} + +template <size_t kBits, typename T> +static constexpr bool IsUint(T value) { + static_assert(kBits > 0, "kBits cannot be zero."); + static_assert(kBits <= kBitsPerByte * sizeof(T), "kBits must be <= max."); + static_assert(std::is_integral<T>::value, "Needs an integral type."); + // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is + // trivially true. + return (0 <= value) && + (kBits == kBitsPerByte * sizeof(T) || + (static_cast<typename std::make_unsigned<T>::type>(value) <= + GetIntLimit<typename std::make_unsigned<T>::type>(kBits + 1) - 1)); +} + +template <size_t kBits, typename T> +static constexpr bool IsAbsoluteUint(T value) { + static_assert(kBits <= kBitsPerByte * sizeof(T), "kBits must be < max."); + return (kBits == kBitsPerByte * sizeof(T)) ? + true : + IsUint<kBits, T>(value < 0 ? -value : value); } static inline uint16_t Low16Bits(uint32_t value) { |