Common: Add MathUtil::SignExtend

This commit is contained in:
MerryMage 2016-03-28 00:14:57 +01:00
parent e3eb4c068d
commit 7aaef09f7d

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <type_traits> #include <type_traits>
@ -16,14 +17,24 @@ inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start
} }
template<typename T> template<typename T>
inline T Clamp(const T val, const T& min, const T& max) inline T Clamp(const T val, const T& min, const T& max) {
{
return std::max(min, std::min(max, val)); return std::max(min, std::min(max, val));
} }
/// Sign-extends a val of type T that has NBits bits.
template<size_t NBits, typename T>
inline T SignExtend(const T val) {
static_assert(std::numeric_limits<T>::is_signed, "T must be signed");
static_assert(NBits <= 8 * sizeof(T), "NBits larger that bitsize of T");
using unsignedT = typename std::make_unsigned<T>::type;
constexpr size_t shift = 8 * sizeof(T) - NBits;
return static_cast<T>(static_cast<unsignedT>(val) << shift) >> shift;
}
template<class T> template<class T>
struct Rectangle struct Rectangle {
{
T left; T left;
T top; T top;
T right; T right;