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>
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;
267constexpr bool IsInsideMM(
const size_t x,
const size_t min,
const size_t max)
noexcept
269 return static_cast<size_t>(x - min) < (max - min);
306 return i * 101 >> 16;
319 return (a + b - 1) / b;
328constexpr uint
Ceil(uint a, uint b)
343 return (a +
static_cast<int>(b) / 2) /
static_cast<int>(b);
346 return (a - (
static_cast<int>(b) - 1) / 2) /
static_cast<int>(b);
357 assert(power >= 0 && power <= 20 );
359 for (
int i = 0; i < power; i++) result *= 10;
A type is considered 'convertible through base()' when it has a 'base()' function that returns someth...
Concept for unifying the convert through 'base()' behaviour of several 'strong' types.
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.
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
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 void Swap(T &a, T &b)
Type safe swap operation.