23constexpr T
abs(
const T a)
25 return (a <
static_cast<T
>(0)) ? -a : a;
37constexpr T
Align(
const T x, uint n)
39 assert((n & (n - 1)) == 0 && n != 0);
41 return static_cast<T
>((x + n) & ~
static_cast<T
>(n));
57 static_assert(
sizeof(uintptr_t) ==
sizeof(
void *));
58 return reinterpret_cast<T *
>(
Align(
reinterpret_cast<uintptr_t
>(x), n));
79constexpr T
Clamp(
const T a,
const T min,
const T max)
82 if (a <= min)
return min;
83 if (a >= max)
return max;
102constexpr T
SoftClamp(
const T a,
const T min,
const T max)
105 using U = std::make_unsigned_t<T>;
106 return min - (U(min) - max) / 2;
108 if (a <= min)
return min;
109 if (a >= max)
return max;
129constexpr int Clamp(
const int a,
const int min,
const int max)
131 return Clamp<int>(a, min, max);
150constexpr uint
ClampU(
const uint a,
const uint min,
const uint max)
152 return Clamp<uint>(a, min, max);
166template <typename To, typename From, std::enable_if_t<std::is_integral<From>::value,
int> = 0>
169 static_assert(std::numeric_limits<To>::is_integer,
"Do not clamp from non-integer values");
170 static_assert(std::numeric_limits<From>::is_integer,
"Do not clamp to non-integer values");
172 if constexpr (
sizeof(To) >=
sizeof(From) && std::numeric_limits<To>::is_signed == std::numeric_limits<From>::is_signed) {
174 return static_cast<To
>(value);
177 if constexpr (
sizeof(To) >
sizeof(From) && std::numeric_limits<To>::is_signed) {
179 return static_cast<To
>(value);
183 using BiggerType =
typename std::conditional<
sizeof(From) >=
sizeof(To), From, To>::type;
185 if constexpr (std::numeric_limits<To>::is_signed) {
187 if constexpr (std::numeric_limits<From>::is_signed) {
189 return static_cast<To
>(std::clamp<BiggerType>(value,
190 std::numeric_limits<To>::lowest(), std::numeric_limits<To>::max()));
194 using BiggerUnsignedType =
typename std::make_unsigned<BiggerType>::type;
195 return static_cast<To
>(std::min<BiggerUnsignedType>(std::numeric_limits<To>::max(), value));
200 if constexpr (std::numeric_limits<From>::is_signed) {
202 if constexpr (
sizeof(To) >=
sizeof(From)) {
204 return static_cast<To
>(std::max<From>(value, 0));
208 using BiggerSignedType =
typename std::make_signed<BiggerType>::type;
209 return static_cast<To
>(std::clamp<BiggerSignedType>(value,
210 std::numeric_limits<To>::lowest(), std::numeric_limits<To>::max()));
214 return static_cast<To
>(std::min<BiggerType>(value, std::numeric_limits<To>::max()));
220template <typename To, typename From, std::enable_if_t<std::is_base_of<StrongTypedefBase, From>::value,
int> = 0>
221constexpr To
ClampTo(From value)
223 return ClampTo<To>(value.base());
234constexpr T
Delta(
const T a,
const T b)
236 return (a < b) ? b - a : a - b;
252constexpr bool IsInsideBS(
const T x,
const size_t base,
const size_t size)
254 return static_cast<size_t>(x - base) < size;
267template <
typename T, std::enable_if_t<std::disjunction_v<std::is_convertible<T,
size_t>, std::is_base_of<StrongTypedefBase, T>>,
int> = 0>
268constexpr bool IsInsideMM(
const T x,
const size_t min,
const size_t max)
noexcept
270 if constexpr (std::is_base_of_v<StrongTypedefBase, T>) {
271 return static_cast<size_t>(x.base() - min) < (max - min);
273 return static_cast<size_t>(x - min) < (max - min);
309 return i * 101 >> 16;
322 return (a + b - 1) / b;
331constexpr uint
Ceil(uint a, uint b)
346 return (a +
static_cast<int>(b) / 2) /
static_cast<int>(b);
349 return (a - (
static_cast<int>(b) - 1) / 2) /
static_cast<int>(b);
360 assert(power >= 0 && power <= 20 );
362 for (
int i = 0; i < power; i++) result *= 10;
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
int DivideApprox(int a, int b)
Deterministic approximate division.
constexpr uint ToPercent16(uint i)
Converts a "fract" value 0..65535 to "percent" value 0..100.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
constexpr T * AlignPtr(T *x, uint n)
Return the smallest multiple of n equal or greater than x Applies to pointers only.
constexpr uint64_t PowerOfTen(int power)
Computes ten to the given power.
constexpr T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
uint32_t IntSqrt(uint32_t num)
Compute the integer square root.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr T SoftClamp(const T a, const T min, const T max)
Clamp a value between an interval.
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
constexpr T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
constexpr uint ToPercent8(uint i)
Converts a "fract" value 0..255 to "percent" value 0..100.
constexpr uint Ceil(uint a, uint b)
Computes ceil(a / b) * b for non-negative a and b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
constexpr uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
constexpr To ClampTo(From value)
Clamp the given value down to lie within the requested type.
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr void Swap(T &a, T &b)
Type safe swap operation.
Type (helpers) for making a strong typedef that is a distinct type.