Chromium Code Reviews| Index: src/IceUtils.h |
| diff --git a/src/IceUtils.h b/src/IceUtils.h |
| index 6bdd95e2f355e5829a7b2200a3978ef3831ecac6..f9b03bc75b1f65da97b6f1dc5494750b36af500f 100644 |
| --- a/src/IceUtils.h |
| +++ b/src/IceUtils.h |
| @@ -19,114 +19,111 @@ |
| #include <cmath> // std::signbit() |
| namespace Ice { |
| - |
| -/// Similar to bit_cast, but allows copying from types of unrelated sizes. This |
| -/// method was introduced to enable the strict aliasing optimizations of GCC |
| -/// 4.4. Basically, GCC mindlessly relies on obscure details in the C++ standard |
| -/// that make reinterpret_cast virtually useless. |
| -template <class D, class S> inline D bit_copy(const S &source) { |
| - D destination; |
| +namespace Utils { |
| + |
| +/// Allows copying from types of unrelated sizes. This method was introduced to |
| +/// enable the strict aliasing optimizations of GCC 4.4. Basically, GCC |
| +/// mindlessly relies on obscure details in the C++ standard that make |
| +/// reinterpret_cast virtually useless. |
| +template <typename D, typename S> inline D bitCopy(const S &Source) { |
| + static_assert(sizeof(D) <= sizeof(S), |
| + "bitCopy between incompatible type widths"); |
| + static_assert(!std::is_pointer<S>::value, ""); |
| + D Destination; |
| // This use of memcpy is safe: source and destination cannot overlap. |
| - memcpy(&destination, reinterpret_cast<const void *>(&source), |
| - sizeof(destination)); |
| - return destination; |
| + memcpy(&Destination, reinterpret_cast<const void *>(&Source), sizeof(D)); |
| + return Destination; |
| +} |
| + |
| +/// Check whether an N-bit two's-complement representation can hold value. |
|
Jim Stichnoth
2016/01/13 19:30:33
Changes here and below are only indentation change
|
| +template <typename T> static inline bool IsInt(int N, T value) { |
| + assert((0 < N) && |
| + (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value)))); |
| + T limit = static_cast<T>(1) << (N - 1); |
| + return (-limit <= value) && (value < limit); |
| } |
| -class Utils { |
| - Utils() = delete; |
| - Utils(const Utils &) = delete; |
| - Utils &operator=(const Utils &) = delete; |
| - |
| -public: |
| - /// Check whether an N-bit two's-complement representation can hold value. |
| - template <typename T> static inline bool IsInt(int N, T value) { |
| - assert((0 < N) && |
| - (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value)))); |
| - T limit = static_cast<T>(1) << (N - 1); |
| - return (-limit <= value) && (value < limit); |
| - } |
| - |
| - template <typename T> static inline bool IsUint(int N, T value) { |
| - assert((0 < N) && |
| - (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value)))); |
| - T limit = static_cast<T>(1) << N; |
| - return (0 <= value) && (value < limit); |
| - } |
| - |
| - /// Check whether the magnitude of value fits in N bits, i.e., whether an |
| - /// (N+1)-bit sign-magnitude representation can hold value. |
| - template <typename T> static inline bool IsAbsoluteUint(int N, T Value) { |
| - assert((0 < N) && |
| - (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(Value)))); |
| - if (Value < 0) |
| - Value = -Value; |
| - return IsUint(N, Value); |
| - } |
| - |
| - /// Return true if the addition X + Y will cause integer overflow for integers |
| - /// of type T. |
| - template <typename T> static inline bool WouldOverflowAdd(T X, T Y) { |
| - return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) || |
| - (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y))); |
| - } |
| - |
| - /// Adds x to y and stores the result in sum. Returns true if the addition |
| - /// overflowed. |
| - static inline bool add_overflow(uint32_t x, uint32_t y, uint32_t *sum) { |
| - static_assert(std::is_same<uint32_t, unsigned>::value, "Must match type"); |
| +template <typename T> static inline bool IsUint(int N, T value) { |
| + assert((0 < N) && |
| + (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value)))); |
| + T limit = static_cast<T>(1) << N; |
| + return (0 <= value) && (value < limit); |
| +} |
| + |
| +/// Check whether the magnitude of value fits in N bits, i.e., whether an |
| +/// (N+1)-bit sign-magnitude representation can hold value. |
| +template <typename T> static inline bool IsAbsoluteUint(int N, T Value) { |
| + assert((0 < N) && |
| + (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(Value)))); |
| + if (Value < 0) |
| + Value = -Value; |
| + return IsUint(N, Value); |
| +} |
| + |
| +/// Return true if the addition X + Y will cause integer overflow for integers |
| +/// of type T. |
| +template <typename T> static inline bool WouldOverflowAdd(T X, T Y) { |
| + return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) || |
| + (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y))); |
| +} |
| + |
| +/// Adds x to y and stores the result in sum. Returns true if the addition |
| +/// overflowed. |
| +static inline bool add_overflow(uint32_t x, uint32_t y, uint32_t *sum) { |
| + static_assert(std::is_same<uint32_t, unsigned>::value, "Must match type"); |
| #if __has_builtin(__builtin_uadd_overflow) |
| - return __builtin_uadd_overflow(x, y, sum); |
| + return __builtin_uadd_overflow(x, y, sum); |
| #else |
| - *sum = x + y; |
| - return WouldOverflowAdd(x, y); |
| + *sum = x + y; |
| + return WouldOverflowAdd(x, y); |
| #endif |
| - } |
| - |
| - /// Return true if X is already aligned by N, where N is a power of 2. |
| - template <typename T> static inline bool IsAligned(T X, intptr_t N) { |
| - assert(llvm::isPowerOf2_64(N)); |
| - return (X & (N - 1)) == 0; |
| - } |
| - |
| - /// Return Value adjusted to the next highest multiple of Alignment. |
| - static inline uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) { |
| - assert(llvm::isPowerOf2_32(Alignment)); |
| - return (Value + Alignment - 1) & -Alignment; |
| - } |
| - |
| - /// Return amount which must be added to adjust Pos to the next highest |
| - /// multiple of Align. |
| - static inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) { |
| - assert(llvm::isPowerOf2_64(Align)); |
| - uint64_t Mod = Pos & (Align - 1); |
| - if (Mod == 0) |
| - return 0; |
| - return Align - Mod; |
| - } |
| - |
| - /// Rotate the value bit pattern to the left by shift bits. |
| - /// Precondition: 0 <= shift < 32 |
| - static inline uint32_t rotateLeft32(uint32_t value, uint32_t shift) { |
| - if (shift == 0) |
| - return value; |
| - return (value << shift) | (value >> (32 - shift)); |
| - } |
| - |
| - /// Rotate the value bit pattern to the right by shift bits. |
| - static inline uint32_t rotateRight32(uint32_t value, uint32_t shift) { |
| - if (shift == 0) |
| - return value; |
| - return (value >> shift) | (value << (32 - shift)); |
| - } |
| - |
| - /// Returns true if Val is +0.0. It requires T to be a floating point type. |
| - template <typename T> static bool isPositiveZero(T Val) { |
| - static_assert(std::is_floating_point<T>::value, |
| - "Input type must be floating point"); |
| - return Val == 0 && !std::signbit(Val); |
| - } |
| -}; |
| +} |
| + |
| +/// Return true if X is already aligned by N, where N is a power of 2. |
| +template <typename T> static inline bool IsAligned(T X, intptr_t N) { |
| + assert(llvm::isPowerOf2_64(N)); |
| + return (X & (N - 1)) == 0; |
| +} |
| + |
| +/// Return Value adjusted to the next highest multiple of Alignment. |
| +static inline uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) { |
| + assert(llvm::isPowerOf2_32(Alignment)); |
| + return (Value + Alignment - 1) & -Alignment; |
| +} |
| + |
| +/// Return amount which must be added to adjust Pos to the next highest |
| +/// multiple of Align. |
| +static inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) { |
| + assert(llvm::isPowerOf2_64(Align)); |
| + uint64_t Mod = Pos & (Align - 1); |
| + if (Mod == 0) |
| + return 0; |
| + return Align - Mod; |
| +} |
| + |
| +/// Rotate the value bit pattern to the left by shift bits. |
| +/// Precondition: 0 <= shift < 32 |
| +static inline uint32_t rotateLeft32(uint32_t value, uint32_t shift) { |
| + if (shift == 0) |
| + return value; |
| + return (value << shift) | (value >> (32 - shift)); |
| +} |
| + |
| +/// Rotate the value bit pattern to the right by shift bits. |
| +static inline uint32_t rotateRight32(uint32_t value, uint32_t shift) { |
| + if (shift == 0) |
| + return value; |
| + return (value >> shift) | (value << (32 - shift)); |
| +} |
| + |
| +/// Returns true if Val is +0.0. It requires T to be a floating point type. |
| +template <typename T> static bool isPositiveZero(T Val) { |
| + static_assert(std::is_floating_point<T>::value, |
| + "Input type must be floating point"); |
| + return Val == 0 && !std::signbit(Val); |
| +} |
| +} // end of namespace Utils |
| } // end of namespace Ice |
| #endif // SUBZERO_SRC_ICEUTILS_H |