2024-01-25 11:21:15 +08:00

55 lines
1.7 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>
Type jmap(Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targetRangeMin, Type targetRangeMax)
{
check(sourceRangeMax != sourceRangeMin); // mapping from a range of zero will produce NaN!
return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax -
sourceRangeMin);
}
template <typename FloatType>
int RoundToInt(const FloatType value) noexcept
{
#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>
bool IsPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
{
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>
bool IsPositiveAndBelow(int valueToTest, Type upperLimit) noexcept
{
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);
}