Brick

Signed Integer Operations

Oct 19th, 2017
307
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.20 KB | None | 0 0
  1. #include <type_traits>
  2. #include <limits>
  3.  
  4. constexpr bool native_asr = (-2 >> 1) == -1;
  5.  
  6. template <typename T>
  7. constexpr inline typename std::make_signed<T>::type sign_extend_shift(const T value, const std::size_t shift) noexcept
  8. {
  9.     return (value << shift) >> shift;
  10. }
  11.  
  12. template <typename T>
  13. constexpr inline typename std::make_signed<T>::type sign_extend_mask(const T value, const T mask) noexcept
  14. {
  15.     return (value ^ mask) - mask;
  16. }
  17.  
  18. template <typename T>
  19. constexpr inline typename std::make_signed<T>::type sign_extend(const T value, const std::size_t bit_count) noexcept
  20. {
  21.     return (native_asr)
  22.         ? sign_extend_shift(value, std::numeric_limits<typename std::make_unsigned<T>::type>::digits - bit_count)
  23.         : sign_extend_mask<T>(value, static_cast<typename std::make_unsigned<T>::type>(1) << (bit_count - 1));
  24. }
  25.  
  26. template <typename T>
  27. constexpr inline T arithmetic_shift_right(const T value, const std::size_t shift) noexcept
  28. {
  29.     return (native_asr)
  30.         ? (value >> shift)
  31.         : sign_extend<T>(
  32.             static_cast<typename std::make_unsigned<T>::type>(value) >> shift,
  33.             std::numeric_limits<typename std::make_unsigned<T>::type>::digits - shift);
  34. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment