ART: Templatize IsInt & IsUint
Ensure that things are used correctly.
Change-Id: I76f082b32dcee28bbfb4c519daa401ac595873b3
diff --git a/runtime/utils.h b/runtime/utils.h
index 1c2576c..0fbc9df 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 @@
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);
+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);
}
-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);
+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));
}
-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);
+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));
}
-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 <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) {