Files
AronaCore/core/misc/core_math.h
2024-07-17 19:18:07 +08:00

55 lines
1.8 KiB
C++

#pragma once
template <typename Type, size_t N>
constexpr int numElementsInArray(Type (&)[N]) noexcept { return N; }
/** Remaps a value from a source range to a target range. */
template <typename Type>
auto jmap(Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targetRangeMin, Type targetRangeMax) -> Type
{
check(sourceRangeMax != sourceRangeMin); // mapping from a range of zero will produce NaN!
return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax -
sourceRangeMin);
}
template <typename FloatType>
auto RoundToInt(const FloatType value) noexcept -> int
{
#ifdef __INTEL_COMPILER
#pragma float_control (precise, on, push)
#endif
union
{
int asInt[2];
double asDouble;
} n;
n.asDouble = static_cast<double>(value) + 6755399441055744.0;
#if JUCE_BIG_ENDIAN
return n.asInt [1];
#else
return n.asInt[0];
#endif
}
/** Returns true if a value is at least zero, and also below a specified upper limit.
This is basically a quicker way to write:
@code valueToTest >= 0 && valueToTest < upperLimit
@endcode
*/
template <typename Type1, typename Type2>
auto IsPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept -> bool
{
check(Type1() <= static_cast<Type1> (upperLimit));
// makes no sense to call this if the upper limit is itself below zero..
return Type1() <= valueToTest && valueToTest < static_cast<Type1>(upperLimit);
}
template <typename Type>
auto IsPositiveAndBelow(int valueToTest, Type upperLimit) noexcept -> bool
{
check(upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
return static_cast<unsigned int>(valueToTest) < static_cast<unsigned int>(upperLimit);
}