Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <type_traits>
- #include <limits>
- constexpr bool native_asr = (-2 >> 1) == -1;
- template <typename T>
- constexpr inline typename std::make_signed<T>::type sign_extend_shift(const T value, const std::size_t shift) noexcept
- {
- return (value << shift) >> shift;
- }
- template <typename T>
- constexpr inline typename std::make_signed<T>::type sign_extend_mask(const T value, const T mask) noexcept
- {
- return (value ^ mask) - mask;
- }
- template <typename T>
- constexpr inline typename std::make_signed<T>::type sign_extend(const T value, const std::size_t bit_count) noexcept
- {
- return (native_asr)
- ? sign_extend_shift(value, std::numeric_limits<typename std::make_unsigned<T>::type>::digits - bit_count)
- : sign_extend_mask<T>(value, static_cast<typename std::make_unsigned<T>::type>(1) << (bit_count - 1));
- }
- template <typename T>
- constexpr inline T arithmetic_shift_right(const T value, const std::size_t shift) noexcept
- {
- return (native_asr)
- ? (value >> shift)
- : sign_extend<T>(
- static_cast<typename std::make_unsigned<T>::type>(value) >> shift,
- std::numeric_limits<typename std::make_unsigned<T>::type>::digits - shift);
- }
Advertisement