#pragma once template constexpr int numElementsInArray(Type (&)[N]) noexcept { return N; } /** Remaps a value from a source range to a target range. */ template 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 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(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 bool IsPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept { check(Type1() <= static_cast (upperLimit)); // makes no sense to call this if the upper limit is itself below zero.. return Type1() <= valueToTest && valueToTest < static_cast(upperLimit); } template 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(valueToTest) < static_cast(upperLimit); }