| @@ -1018,6 +1018,7 @@ add_library( ${BINARY_NAME} | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -3075,6 +3076,7 @@ set_source_files_properties( | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -1316,6 +1316,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1930,6 +1930,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1316,6 +1316,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1930,6 +1930,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1316,6 +1316,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1930,6 +1930,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -894,6 +894,7 @@ add_library( ${BINARY_NAME} | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -2649,6 +2650,7 @@ set_source_files_properties( | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -1156,6 +1156,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1639,6 +1639,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -927,6 +927,7 @@ add_library( ${BINARY_NAME} | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -2837,6 +2838,7 @@ set_source_files_properties( | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -1164,6 +1164,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1714,6 +1714,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1164,6 +1164,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1714,6 +1714,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1164,6 +1164,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1714,6 +1714,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -226,6 +226,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -163,6 +163,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -898,6 +898,7 @@ add_library( ${BINARY_NAME} | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -2733,6 +2734,7 @@ set_source_files_properties( | |||
| "../../../../../modules/juce_core/maths/juce_Expression.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Expression.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions.h" | |||
| "../../../../../modules/juce_core/maths/juce_MathsFunctions_test.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_NormalisableRange.h" | |||
| "../../../../../modules/juce_core/maths/juce_Random.cpp" | |||
| "../../../../../modules/juce_core/maths/juce_Random.h" | |||
| @@ -1156,6 +1156,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1669,6 +1669,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -362,6 +362,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -640,6 +640,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -362,6 +362,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -640,6 +640,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -362,6 +362,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -640,6 +640,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1172,6 +1172,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1738,6 +1738,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1172,6 +1172,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1738,6 +1738,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1172,6 +1172,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1738,6 +1738,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -1155,6 +1155,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1666,6 +1666,9 @@ | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Expression.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_MathsFunctions_test.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> | |||
| <Filter>JUCE Modules\juce_core\maths</Filter> | |||
| </ClCompile> | |||
| @@ -276,8 +276,8 @@ | |||
| //============================================================================== | |||
| #if JUCE_UNIT_TESTS | |||
| #include "containers/juce_HashMap_test.cpp" | |||
| #include "containers/juce_Optional_test.cpp" | |||
| #include "maths/juce_MathsFunctions_test.cpp" | |||
| #include "misc/juce_EnumHelpers_test.cpp" | |||
| #endif | |||
| @@ -86,16 +86,112 @@ using uint32 = unsigned int; | |||
| using ssize_t = pointer_sized_int; | |||
| #endif | |||
| /** Returns true if the two numbers are approximately equal. This is useful for floating-point | |||
| and double comparisons. | |||
| //============================================================================== | |||
| /** Handy function for avoiding unused variables warning. */ | |||
| template <typename... Types> | |||
| void ignoreUnused (Types&&...) noexcept {} | |||
| /** Handy function for getting the number of elements in a simple const C array. | |||
| E.g. | |||
| @code | |||
| static int myArray[] = { 1, 2, 3 }; | |||
| int numElements = numElementsInArray (myArray) // returns 3 | |||
| @endcode | |||
| */ | |||
| template <typename Type, size_t N> | |||
| constexpr int numElementsInArray (Type (&)[N]) noexcept { return N; } | |||
| //============================================================================== | |||
| // Some useful maths functions that aren't always present with all compilers and build settings. | |||
| /** Using juce_hypot is easier than dealing with the different types of hypot function | |||
| that are provided by the various platforms and compilers. */ | |||
| template <typename Type> | |||
| bool approximatelyEqual (Type a, Type b) noexcept | |||
| Type juce_hypot (Type a, Type b) noexcept | |||
| { | |||
| return std::abs (a - b) <= (std::numeric_limits<Type>::epsilon() * std::max (a, b)) | |||
| || std::abs (a - b) < std::numeric_limits<Type>::min(); | |||
| #if JUCE_MSVC | |||
| return static_cast<Type> (_hypot (a, b)); | |||
| #else | |||
| return static_cast<Type> (hypot (a, b)); | |||
| #endif | |||
| } | |||
| #ifndef DOXYGEN | |||
| template <> | |||
| inline float juce_hypot (float a, float b) noexcept | |||
| { | |||
| #if JUCE_MSVC | |||
| return _hypotf (a, b); | |||
| #else | |||
| return hypotf (a, b); | |||
| #endif | |||
| } | |||
| #endif | |||
| //============================================================================== | |||
| /** Commonly used mathematical constants | |||
| @tags{Core} | |||
| */ | |||
| template <typename FloatType> | |||
| struct MathConstants | |||
| { | |||
| /** A predefined value for Pi */ | |||
| static constexpr FloatType pi = static_cast<FloatType> (3.141592653589793238L); | |||
| /** A predefined value for 2 * Pi */ | |||
| static constexpr FloatType twoPi = static_cast<FloatType> (2 * 3.141592653589793238L); | |||
| /** A predefined value for Pi / 2 */ | |||
| static constexpr FloatType halfPi = static_cast<FloatType> (3.141592653589793238L / 2); | |||
| /** A predefined value for Euler's number */ | |||
| static constexpr FloatType euler = static_cast<FloatType> (2.71828182845904523536L); | |||
| /** A predefined value for sqrt(2) */ | |||
| static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L); | |||
| }; | |||
| #ifndef DOXYGEN | |||
| /** A double-precision constant for pi. */ | |||
| [[deprecated ("This is deprecated in favour of MathConstants<double>::pi.")]] | |||
| const constexpr double double_Pi = MathConstants<double>::pi; | |||
| /** A single-precision constant for pi. */ | |||
| [[deprecated ("This is deprecated in favour of MathConstants<float>::pi.")]] | |||
| const constexpr float float_Pi = MathConstants<float>::pi; | |||
| #endif | |||
| /** Converts an angle in degrees to radians. */ | |||
| template <typename FloatType> | |||
| constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); } | |||
| /** Converts an angle in radians to degrees. */ | |||
| template <typename FloatType> | |||
| constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); } | |||
| //============================================================================== | |||
| /** The isfinite() method seems to vary between platforms, so this is a | |||
| platform-independent function for it. | |||
| */ | |||
| template <typename NumericType> | |||
| bool juce_isfinite (NumericType value) noexcept | |||
| { | |||
| if constexpr (std::numeric_limits<NumericType>::has_infinity | |||
| || std::numeric_limits<NumericType>::has_quiet_NaN | |||
| || std::numeric_limits<NumericType>::has_signaling_NaN) | |||
| { | |||
| return std::isfinite (value); | |||
| } | |||
| else | |||
| { | |||
| ignoreUnused (value); | |||
| return true; | |||
| } | |||
| } | |||
| //============================================================================== | |||
| /** Equivalent to operator==, but suppresses float-equality warnings. | |||
| This allows code to be explicit about float-equality checks that are known to have the correct | |||
| @@ -109,6 +205,128 @@ constexpr bool exactlyEqual (Type a, Type b) | |||
| JUCE_END_IGNORE_WARNINGS_GCC_LIKE | |||
| } | |||
| /** A class encapsulating both relative and absolute tolerances for use in floating-point comparisons. | |||
| @see approximatelyEqual, absoluteTolerance, relativeTolerance | |||
| */ | |||
| template <typename Type> | |||
| class Tolerance | |||
| { | |||
| public: | |||
| Tolerance() = default; | |||
| /** Returns a copy of this Tolerance object with a new absolute tolerance. | |||
| If you just need a Tolerance object with an absolute tolerance, it might be worth using the | |||
| absoluteTolerance() function. | |||
| @see getAbsolute, absoluteTolerance | |||
| */ | |||
| [[nodiscard]] Tolerance withAbsolute (Type newAbsolute) | |||
| { | |||
| return withMember (*this, &Tolerance::absolute, std::abs (newAbsolute)); | |||
| } | |||
| /** Returns a copy of this Tolerance object with a new relative tolerance. | |||
| If you just need a Tolerance object with a relative tolerance, it might be worth using the | |||
| relativeTolerance() function. | |||
| @see getRelative, relativeTolerance | |||
| */ | |||
| [[nodiscard]] Tolerance withRelative (Type newRelative) | |||
| { | |||
| return withMember (*this, &Tolerance::relative, std::abs (newRelative)); | |||
| } | |||
| [[nodiscard]] Type getAbsolute() const { return absolute; } | |||
| [[nodiscard]] Type getRelative() const { return relative; } | |||
| private: | |||
| Type absolute{}; | |||
| Type relative{}; | |||
| }; | |||
| /** Returns a type deduced Tolerance object containing only an absolute tolerance. | |||
| @see Tolerance::withAbsolute, approximatelyEqual | |||
| */ | |||
| template <typename Type> | |||
| static Tolerance<Type> absoluteTolerance (Type tolerance) | |||
| { | |||
| return Tolerance<Type>{}.withAbsolute (tolerance); | |||
| } | |||
| /** Returns a type deduced Tolerance object containing only a relative tolerance. | |||
| @see Tolerance::withRelative, approximatelyEqual | |||
| */ | |||
| template <typename Type> | |||
| static Tolerance<Type> relativeTolerance (Type tolerance) | |||
| { | |||
| return Tolerance<Type>{}.withRelative (tolerance); | |||
| } | |||
| /** Returns true if the two numbers are approximately equal. This is useful for floating-point | |||
| comparisons. | |||
| If a and b are not floating-point types, returns a == b. | |||
| If either a or b are not finite, returns exactlyEqual (a, b). | |||
| The default absolute tolerance is equal to the minimum normal value. This ensures | |||
| differences that are subnormal are always considered equal. It is highly recommend this | |||
| value is reviewed depending on the calculation being carried out. In general specifying an | |||
| absolute value is useful when considering values close to zero. For example you might | |||
| expect sin(pi) to return 0, but what it actually returns is close to the error of the value pi. | |||
| Therefore, in this example it might be better to set the absolute tolerance to sin(pi). | |||
| The default relative tolerance is equal to the machine epsilon which is the difference between | |||
| 1.0 and the next floating-point value that can be represented by Type. In most cases this value | |||
| is probably reasonable. This value is multiplied by the largest absolute value of a and b so as | |||
| to scale relatively according to the input parameters. For example, specifying a relative value | |||
| of 0.05 will ensure values return equal if the difference between them is less than or equal to | |||
| 5% of the larger of the two absolute values. | |||
| @param tolerance An object that represents both absolute and relative tolerances | |||
| when evaluating if a and b are equal. | |||
| @see exactlyEqual | |||
| */ | |||
| template <typename Type> | |||
| constexpr bool approximatelyEqual (Type a, Type b, | |||
| Tolerance<Type> tolerance = Tolerance<Type>{} | |||
| .withAbsolute (std::numeric_limits<Type>::min()) | |||
| .withRelative (std::numeric_limits<Type>::epsilon())) | |||
| { | |||
| if constexpr (! std::is_floating_point_v<Type>) | |||
| return a == b; | |||
| if (! (juce_isfinite (a) && juce_isfinite (b))) | |||
| return exactlyEqual (a, b); | |||
| const auto diff = std::abs (a - b); | |||
| return diff <= tolerance.getAbsolute() | |||
| || diff <= tolerance.getRelative() * std::max (std::abs (a), std::abs (b)); | |||
| } | |||
| //============================================================================== | |||
| /** Returns the next representable value by FloatType in the direction of the largest representable value. */ | |||
| template <typename FloatType> | |||
| FloatType nextFloatUp (FloatType value) noexcept | |||
| { | |||
| return std::nextafter (value, std::numeric_limits<FloatType>::max()); | |||
| } | |||
| /** Returns the next representable value by FloatType in the direction of the lowest representable value. */ | |||
| template <typename FloatType> | |||
| FloatType nextFloatDown (FloatType value) noexcept | |||
| { | |||
| return std::nextafter (value, std::numeric_limits<FloatType>::lowest()); | |||
| } | |||
| //============================================================================== | |||
| // Some indispensable min/max functions | |||
| @@ -340,122 +558,6 @@ bool isWithin (Type a, Type b, Type tolerance) noexcept | |||
| return std::abs (a - b) <= tolerance; | |||
| } | |||
| //============================================================================== | |||
| /** Handy function for avoiding unused variables warning. */ | |||
| template <typename... Types> | |||
| void ignoreUnused (Types&&...) noexcept {} | |||
| /** Handy function for getting the number of elements in a simple const C array. | |||
| E.g. | |||
| @code | |||
| static int myArray[] = { 1, 2, 3 }; | |||
| int numElements = numElementsInArray (myArray) // returns 3 | |||
| @endcode | |||
| */ | |||
| template <typename Type, size_t N> | |||
| constexpr int numElementsInArray (Type (&)[N]) noexcept { return N; } | |||
| //============================================================================== | |||
| // Some useful maths functions that aren't always present with all compilers and build settings. | |||
| /** Using juce_hypot is easier than dealing with the different types of hypot function | |||
| that are provided by the various platforms and compilers. */ | |||
| template <typename Type> | |||
| Type juce_hypot (Type a, Type b) noexcept | |||
| { | |||
| #if JUCE_MSVC | |||
| return static_cast<Type> (_hypot (a, b)); | |||
| #else | |||
| return static_cast<Type> (hypot (a, b)); | |||
| #endif | |||
| } | |||
| #ifndef DOXYGEN | |||
| template <> | |||
| inline float juce_hypot (float a, float b) noexcept | |||
| { | |||
| #if JUCE_MSVC | |||
| return _hypotf (a, b); | |||
| #else | |||
| return hypotf (a, b); | |||
| #endif | |||
| } | |||
| #endif | |||
| //============================================================================== | |||
| /** Commonly used mathematical constants | |||
| @tags{Core} | |||
| */ | |||
| template <typename FloatType> | |||
| struct MathConstants | |||
| { | |||
| /** A predefined value for Pi */ | |||
| static constexpr FloatType pi = static_cast<FloatType> (3.141592653589793238L); | |||
| /** A predefined value for 2 * Pi */ | |||
| static constexpr FloatType twoPi = static_cast<FloatType> (2 * 3.141592653589793238L); | |||
| /** A predefined value for Pi / 2 */ | |||
| static constexpr FloatType halfPi = static_cast<FloatType> (3.141592653589793238L / 2); | |||
| /** A predefined value for Euler's number */ | |||
| static constexpr FloatType euler = static_cast<FloatType> (2.71828182845904523536L); | |||
| /** A predefined value for sqrt(2) */ | |||
| static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L); | |||
| }; | |||
| #ifndef DOXYGEN | |||
| /** A double-precision constant for pi. */ | |||
| [[deprecated ("This is deprecated in favour of MathConstants<double>::pi.")]] | |||
| const constexpr double double_Pi = MathConstants<double>::pi; | |||
| /** A single-precision constant for pi. */ | |||
| [[deprecated ("This is deprecated in favour of MathConstants<float>::pi.")]] | |||
| const constexpr float float_Pi = MathConstants<float>::pi; | |||
| #endif | |||
| /** Converts an angle in degrees to radians. */ | |||
| template <typename FloatType> | |||
| constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); } | |||
| /** Converts an angle in radians to degrees. */ | |||
| template <typename FloatType> | |||
| constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); } | |||
| //============================================================================== | |||
| /** The isfinite() method seems to vary between platforms, so this is a | |||
| platform-independent function for it. | |||
| */ | |||
| template <typename NumericType> | |||
| bool juce_isfinite (NumericType) noexcept | |||
| { | |||
| return true; // Integer types are always finite | |||
| } | |||
| template <> | |||
| inline bool juce_isfinite (float value) noexcept | |||
| { | |||
| #if JUCE_WINDOWS && ! JUCE_MINGW | |||
| return _finite (value) != 0; | |||
| #else | |||
| return std::isfinite (value); | |||
| #endif | |||
| } | |||
| template <> | |||
| inline bool juce_isfinite (double value) noexcept | |||
| { | |||
| #if JUCE_WINDOWS && ! JUCE_MINGW | |||
| return _finite (value) != 0; | |||
| #else | |||
| return std::isfinite (value); | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_MSVC | |||
| #pragma optimize ("t", off) | |||
| @@ -0,0 +1,483 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2022 - Raw Material Software Limited | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| The code included in this file is provided under the terms of the ISC license | |||
| http://www.isc.org/downloads/software-support-policy/isc-license. Permission | |||
| To use, copy, modify, and/or distribute this software for any purpose with or | |||
| without fee is hereby granted provided that the above copyright notice and | |||
| this permission notice appear in all copies. | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| //============================================================================== | |||
| template <typename T> | |||
| String getTemplatedMathsFunctionUnitTestName (const String& functionName) | |||
| { | |||
| const auto getTypeName = []() -> String | |||
| { | |||
| if constexpr (std::is_same_v<float, T>) | |||
| return "float"; | |||
| if constexpr (std::is_same_v<double, T>) | |||
| return "double"; | |||
| if constexpr (std::is_same_v<long double, T>) | |||
| return "long double"; | |||
| }; | |||
| return functionName + "<" + getTypeName() + ">"; | |||
| } | |||
| template <typename T> | |||
| class ApproximatelyEqualTests final : public UnitTest | |||
| { | |||
| public: | |||
| ApproximatelyEqualTests() | |||
| : UnitTest { getTemplatedMathsFunctionUnitTestName<T> ("approximatelyEqual"), UnitTestCategories::maths } | |||
| {} | |||
| void runTest() final | |||
| { | |||
| using limits = std::numeric_limits<T>; | |||
| constexpr auto zero = T{}; | |||
| constexpr auto one = T (1); | |||
| constexpr auto min = limits::min(); | |||
| constexpr auto max = limits::max(); | |||
| constexpr auto epsilon = limits::epsilon(); | |||
| constexpr auto oneThird = one / (T) 3; | |||
| beginTest ("Equal values are always equal"); | |||
| { | |||
| expect (approximatelyEqual (zero, zero)); | |||
| expect (approximatelyEqual (zero, -zero)); | |||
| expect (approximatelyEqual (-zero, -zero)); | |||
| expect (approximatelyEqual (min, min)); | |||
| expect (approximatelyEqual (-min, -min)); | |||
| expect (approximatelyEqual (one, one)); | |||
| expect (approximatelyEqual (-one, -one)); | |||
| expect (approximatelyEqual (max, max)); | |||
| expect (approximatelyEqual (-max, -max)); | |||
| const Tolerance<T> zeroTolerance{}; | |||
| expect (approximatelyEqual (zero, zero, zeroTolerance)); | |||
| expect (approximatelyEqual (zero, -zero, zeroTolerance)); | |||
| expect (approximatelyEqual (-zero, -zero, zeroTolerance)); | |||
| expect (approximatelyEqual (min, min, zeroTolerance)); | |||
| expect (approximatelyEqual (-min, -min, zeroTolerance)); | |||
| expect (approximatelyEqual (one, one, zeroTolerance)); | |||
| expect (approximatelyEqual (-one, -one, zeroTolerance)); | |||
| expect (approximatelyEqual (max, max, zeroTolerance)); | |||
| expect (approximatelyEqual (-max, -max, zeroTolerance)); | |||
| } | |||
| beginTest ("Comparing subnormal values to zero, returns true"); | |||
| { | |||
| expect (! exactlyEqual (zero, nextFloatUp (zero))); | |||
| expect (approximatelyEqual (zero, nextFloatUp (zero))); | |||
| expect (! exactlyEqual (zero, nextFloatDown (zero))); | |||
| expect (approximatelyEqual (zero, nextFloatDown (zero))); | |||
| expect (! exactlyEqual (zero, nextFloatDown (min))); | |||
| expect (approximatelyEqual (zero, nextFloatDown (min))); | |||
| expect (! exactlyEqual (zero, nextFloatUp (-min))); | |||
| expect (approximatelyEqual (zero, nextFloatUp (-min))); | |||
| } | |||
| beginTest ("Comparing the minimum normal value to zero, returns true"); | |||
| { | |||
| expect (approximatelyEqual (zero, min)); | |||
| expect (approximatelyEqual (zero, -min)); | |||
| } | |||
| beginTest ("Comparing normal values greater than the minimum to zero, returns true"); | |||
| { | |||
| expect (! approximatelyEqual (zero, one)); | |||
| expect (! approximatelyEqual (zero, epsilon)); | |||
| expect (! approximatelyEqual (zero, nextFloatUp (min))); | |||
| expect (! approximatelyEqual (zero, nextFloatDown (-min))); | |||
| } | |||
| beginTest ("Values with large ranges can be compared"); | |||
| { | |||
| expect (! approximatelyEqual (zero, max)); | |||
| expect ( approximatelyEqual (zero, max, absoluteTolerance (max))); | |||
| expect ( approximatelyEqual (zero, max, relativeTolerance (one))); | |||
| expect (! approximatelyEqual (-one, max)); | |||
| expect (! approximatelyEqual (-max, max)); | |||
| } | |||
| beginTest ("Larger values have a boundary that is a factor of the epsilon"); | |||
| { | |||
| for (auto exponent = 0; exponent < 127; ++exponent) | |||
| { | |||
| const auto value = std::pow ((T) 2, (T) exponent); | |||
| const auto boundaryValue = value * (one + epsilon); | |||
| expect (juce_isfinite (value)); | |||
| expect (juce_isfinite (boundaryValue)); | |||
| expect ( approximatelyEqual (value, boundaryValue)); | |||
| expect (! approximatelyEqual (value, nextFloatUp (boundaryValue))); | |||
| expect ( approximatelyEqual (-value, -boundaryValue)); | |||
| expect (! approximatelyEqual (-value, nextFloatDown (-boundaryValue))); | |||
| } | |||
| } | |||
| beginTest ("Tolerances scale with the values being compared"); | |||
| { | |||
| expect (approximatelyEqual ((T) 100'000'000'000'000.01, | |||
| (T) 100'000'000'000'000.011)); | |||
| expect (! approximatelyEqual ((T) 100.01, | |||
| (T) 100.011)); | |||
| expect (! approximatelyEqual ((T) 123'000, (T) 121'000, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 123'000, (T) 122'000, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 123'000, (T) 123'000, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 123'000, (T) 124'000, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 123'000, (T) 125'000, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 123, (T) 121, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 123, (T) 122, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 123, (T) 123, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 123, (T) 124, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 123, (T) 125, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 12.3, (T) 12.1, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 12.3, (T) 12.2, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 12.3, (T) 12.3, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 12.3, (T) 12.4, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 12.3, (T) 12.5, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 1.23, (T) 1.21, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 1.23, (T) 1.22, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 1.23, (T) 1.23, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 1.23, (T) 1.24, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 1.23, (T) 1.25, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 0.123, (T) 0.121, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 0.123, (T) 0.122, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 0.123, (T) 0.123, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 0.123, (T) 0.124, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 0.123, (T) 0.125, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 0.000123, (T) 0.000121, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 0.000123, (T) 0.000122, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 0.000123, (T) 0.000123, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual ((T) 0.000123, (T) 0.000124, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual ((T) 0.000123, (T) 0.000125, relativeTolerance ((T) 1e-2))); | |||
| } | |||
| beginTest ("The square of the square root of 2 is approximately 2"); | |||
| { | |||
| constexpr auto two = (T) 2; | |||
| const auto sqrtOfTwo = std::sqrt (two); | |||
| expect (approximatelyEqual (sqrtOfTwo * sqrtOfTwo, two)); | |||
| expect (approximatelyEqual (-sqrtOfTwo * sqrtOfTwo, -two)); | |||
| expect (approximatelyEqual (two / sqrtOfTwo, sqrtOfTwo)); | |||
| } | |||
| if constexpr (limits::has_quiet_NaN) | |||
| { | |||
| beginTest ("Values are never equal to NaN"); | |||
| { | |||
| const auto nan = limits::quiet_NaN(); | |||
| expect (! approximatelyEqual (nan, nan)); | |||
| const auto expectNotEqualTo = [&](auto value) | |||
| { | |||
| expect (! approximatelyEqual (value, nan)); | |||
| expect (! approximatelyEqual (nan, value)); | |||
| }; | |||
| expectNotEqualTo (zero); | |||
| expectNotEqualTo (-zero); | |||
| expectNotEqualTo (min); | |||
| expectNotEqualTo (-min); | |||
| expectNotEqualTo (one); | |||
| expectNotEqualTo (-one); | |||
| expectNotEqualTo (max); | |||
| expectNotEqualTo (-max); | |||
| } | |||
| } | |||
| if constexpr (limits::has_infinity) | |||
| { | |||
| beginTest ("Only infinity is equal to infinity"); | |||
| { | |||
| const auto inf = limits::infinity(); | |||
| expect (approximatelyEqual (inf, inf)); | |||
| expect (approximatelyEqual (-inf, -inf)); | |||
| expect (! approximatelyEqual (inf, -inf)); | |||
| expect (! approximatelyEqual (-inf, inf)); | |||
| const auto expectNotEqualTo = [&](auto value) | |||
| { | |||
| expect (! approximatelyEqual (value, inf)); | |||
| expect (! approximatelyEqual (value, -inf)); | |||
| expect (! approximatelyEqual (inf, value)); | |||
| expect (! approximatelyEqual (-inf, value)); | |||
| }; | |||
| expectNotEqualTo (zero); | |||
| expectNotEqualTo (-zero); | |||
| expectNotEqualTo (min); | |||
| expectNotEqualTo (-min); | |||
| expectNotEqualTo (one); | |||
| expectNotEqualTo (-one); | |||
| expectNotEqualTo (max); | |||
| expectNotEqualTo (-max); | |||
| } | |||
| } | |||
| beginTest ("Can set an absolute tolerance"); | |||
| { | |||
| constexpr std::array<T, 7> negativePowersOfTwo | |||
| { | |||
| (T) 0.5 /* 2^-1 */, | |||
| (T) 0.25 /* 2^-2 */, | |||
| (T) 0.125 /* 2^-3 */, | |||
| (T) 0.0625 /* 2^-4 */, | |||
| (T) 0.03125 /* 2^-5 */, | |||
| (T) 0.015625 /* 2^-6 */, | |||
| (T) 0.0078125 /* 2^-7 */ | |||
| }; | |||
| const auto testTolerance = [&](auto tolerance) | |||
| { | |||
| const auto t = Tolerance<T>{}.withAbsolute ((T) tolerance); | |||
| const auto testValue= [&](auto value) | |||
| { | |||
| const auto boundary = value + tolerance; | |||
| expect (approximatelyEqual (value, boundary, t)); | |||
| expect (! approximatelyEqual (value, nextFloatUp (boundary), t)); | |||
| expect (approximatelyEqual (-value, -boundary, t)); | |||
| expect (! approximatelyEqual (-value, nextFloatDown (-boundary), t)); | |||
| }; | |||
| testValue (zero); | |||
| testValue (min); | |||
| testValue (epsilon); | |||
| testValue (one); | |||
| for (const auto value : negativePowersOfTwo) | |||
| testValue (value); | |||
| }; | |||
| for (const auto toleranceValue : negativePowersOfTwo) | |||
| testTolerance (toleranceValue); | |||
| } | |||
| beginTest ("Can set a relative tolerance"); | |||
| { | |||
| expect (! approximatelyEqual (oneThird, (T) 0.34, relativeTolerance ((T) 1e-2))); | |||
| expect ( approximatelyEqual (oneThird, (T) 0.334, relativeTolerance ((T) 1e-2))); | |||
| expect (! approximatelyEqual (oneThird, (T) 0.334, relativeTolerance ((T) 1e-3))); | |||
| expect ( approximatelyEqual (oneThird, (T) 0.3334, relativeTolerance ((T) 1e-3))); | |||
| expect (! approximatelyEqual (oneThird, (T) 0.3334, relativeTolerance ((T) 1e-4))); | |||
| expect ( approximatelyEqual (oneThird, (T) 0.33334, relativeTolerance ((T) 1e-4))); | |||
| expect (! approximatelyEqual (oneThird, (T) 0.33334, relativeTolerance ((T) 1e-5))); | |||
| expect ( approximatelyEqual (oneThird, (T) 0.333334, relativeTolerance ((T) 1e-5))); | |||
| expect (! approximatelyEqual (oneThird, (T) 0.333334, relativeTolerance ((T) 1e-6))); | |||
| expect ( approximatelyEqual (oneThird, (T) 0.3333334, relativeTolerance ((T) 1e-6))); | |||
| expect (! approximatelyEqual (oneThird, (T) 0.3333334, relativeTolerance ((T) 1e-7))); | |||
| expect ( approximatelyEqual (oneThird, (T) 0.33333334, relativeTolerance ((T) 1e-7))); | |||
| expect ( approximatelyEqual ((T) 1e6, (T) 1e6 + (T) 1, relativeTolerance ((T) 1e-6))); | |||
| expect (! approximatelyEqual ((T) 1e6, (T) 1e6 + (T) 1, relativeTolerance ((T) 1e-7))); | |||
| expect ( approximatelyEqual ((T) -1e-6, (T) -1.0000009e-6, relativeTolerance ((T) 1e-6))); | |||
| expect (! approximatelyEqual ((T) -1e-6, (T) -1.0000009e-6, relativeTolerance ((T) 1e-7))); | |||
| const auto a = (T) 1.234567; | |||
| const auto b = (T) 1.234568; | |||
| for (auto exponent = 0; exponent < 39; ++exponent) | |||
| { | |||
| const auto m = std::pow ((T) 10, (T) exponent); | |||
| expect ( approximatelyEqual (a * m, b * m, relativeTolerance ((T) 1e-6))); | |||
| expect (! approximatelyEqual (a * m, b * m, relativeTolerance ((T) 1e-7))); | |||
| } | |||
| } | |||
| beginTest ("A relative tolerance is always scaled by the maximum value"); | |||
| { | |||
| expect ( approximatelyEqual ((T) 9, (T) 10, absoluteTolerance ((T) 10.0 * (T) 0.1))); | |||
| expect (! approximatelyEqual ((T) 9, (T) 10, absoluteTolerance ((T) 9.0 * (T) 0.1))); | |||
| expect (approximatelyEqual ((T) 9, (T) 10, relativeTolerance ((T) 0.1))); | |||
| expect (approximatelyEqual ((T) 10, (T) 9, relativeTolerance ((T) 0.1))); | |||
| } | |||
| beginTest ("Documentation examples"); | |||
| { | |||
| constexpr auto pi = MathConstants<T>::pi; | |||
| expect (! approximatelyEqual (zero, std::sin (pi))); | |||
| expect ( approximatelyEqual (zero, std::sin (pi), absoluteTolerance (std::sin (pi)))); | |||
| expect ( approximatelyEqual ((T) 100, (T) 95, relativeTolerance ((T) 0.05))); | |||
| expect (! approximatelyEqual ((T) 100, (T) 94, relativeTolerance ((T) 0.05))); | |||
| } | |||
| } | |||
| }; | |||
| template <typename T> | |||
| class IsFiniteTests final : public UnitTest | |||
| { | |||
| public: | |||
| IsFiniteTests() | |||
| : UnitTest { getTemplatedMathsFunctionUnitTestName<T> ("juce_isfinite"), UnitTestCategories::maths } | |||
| {} | |||
| void runTest() final | |||
| { | |||
| using limits = std::numeric_limits<T>; | |||
| constexpr auto zero = T{}; | |||
| constexpr auto one = (T) 1; | |||
| constexpr auto max = limits::max(); | |||
| constexpr auto inf = limits::infinity(); | |||
| constexpr auto nan = limits::quiet_NaN(); | |||
| beginTest ("Zero is finite"); | |||
| { | |||
| expect (juce_isfinite (zero)); | |||
| expect (juce_isfinite (-zero)); | |||
| } | |||
| beginTest ("Subnormals are finite"); | |||
| { | |||
| expect (juce_isfinite (nextFloatUp (zero))); | |||
| expect (juce_isfinite (nextFloatDown (zero))); | |||
| } | |||
| beginTest ("One is finite"); | |||
| { | |||
| expect (juce_isfinite (one)); | |||
| expect (juce_isfinite (-one)); | |||
| } | |||
| beginTest ("Max is finite"); | |||
| { | |||
| expect (juce_isfinite (max)); | |||
| expect (juce_isfinite (-max)); | |||
| } | |||
| beginTest ("Infinity is not finite"); | |||
| { | |||
| expect (! juce_isfinite (inf)); | |||
| expect (! juce_isfinite (-inf)); | |||
| } | |||
| beginTest ("NaN is not finite"); | |||
| { | |||
| expect (! juce_isfinite (nan)); | |||
| expect (! juce_isfinite (-nan)); | |||
| expect (! juce_isfinite (std::sqrt ((T) -1))); | |||
| expect (! juce_isfinite (inf * zero)); | |||
| } | |||
| } | |||
| }; | |||
| template <typename T> | |||
| class NextFloatTests final : public UnitTest | |||
| { | |||
| public: | |||
| NextFloatTests() | |||
| : UnitTest { getTemplatedMathsFunctionUnitTestName<T> ("nextFloat"), UnitTestCategories::maths } | |||
| {} | |||
| void runTest() final | |||
| { | |||
| using limits = std::numeric_limits<T>; | |||
| constexpr auto zero = T{}; | |||
| constexpr auto one = T (1); | |||
| constexpr auto min = limits::min(); | |||
| constexpr auto epsilon = limits::epsilon(); | |||
| beginTest ("nextFloat from zero is subnormal"); | |||
| { | |||
| expect (juce_isfinite (nextFloatUp (zero))); | |||
| expect (! exactlyEqual (zero, nextFloatUp (zero))); | |||
| expect (! std::isnormal (nextFloatUp (zero))); | |||
| expect (juce_isfinite (nextFloatDown (zero))); | |||
| expect (! exactlyEqual (zero, nextFloatDown (zero))); | |||
| expect (! std::isnormal (nextFloatDown (zero))); | |||
| } | |||
| beginTest ("nextFloat from min, towards zero, is subnormal"); | |||
| { | |||
| expect (std::isnormal (min)); | |||
| expect (std::isnormal (-min)); | |||
| expect (! std::isnormal (nextFloatDown (min))); | |||
| expect (! std::isnormal (nextFloatUp (-min))); | |||
| } | |||
| beginTest ("nextFloat from one matches epsilon"); | |||
| { | |||
| expect (! exactlyEqual (one, nextFloatUp (one))); | |||
| expect ( exactlyEqual (one + epsilon, nextFloatUp (one))); | |||
| expect (! exactlyEqual (-one, nextFloatDown (-one))); | |||
| expect ( exactlyEqual (-one - epsilon, nextFloatDown (-one))); | |||
| } | |||
| } | |||
| }; | |||
| template <typename Type> | |||
| struct MathsFloatingPointFunctionsTests | |||
| { | |||
| IsFiniteTests<Type> isFiniteTests; | |||
| NextFloatTests<Type> nextFloatTests; | |||
| ApproximatelyEqualTests<Type> approximatelyEqualTests; | |||
| }; | |||
| struct MathsFunctionsTests | |||
| { | |||
| MathsFloatingPointFunctionsTests<float> floatFunctionTests; | |||
| MathsFloatingPointFunctionsTests<double> doubleFunctionTests; | |||
| MathsFloatingPointFunctionsTests<long double> longDoubleFunctionTests; | |||
| }; | |||
| static MathsFunctionsTests mathsFunctionsTests; | |||
| } // namespace juce | |||
| @@ -44,7 +44,7 @@ namespace ColourHelpers | |||
| float hue = 0.0f; | |||
| if (hi > 0 && ! approximatelyEqual (hi, lo)) | |||
| if (hi > 0 && ! exactlyEqual (hi, lo)) | |||
| { | |||
| auto invDiff = 1.0f / (float) (hi - lo); | |||
| @@ -66,7 +66,7 @@ public: | |||
| constexpr bool isOrigin() const noexcept { return operator== (Point()); } | |||
| /** Returns true if the coordinates are finite values. */ | |||
| constexpr inline bool isFinite() const noexcept { return juce_isfinite(x) && juce_isfinite(y); } | |||
| constexpr inline bool isFinite() const noexcept { return juce_isfinite (x) && juce_isfinite (y); } | |||
| /** Returns the point's x coordinate. */ | |||
| constexpr inline ValueType getX() const noexcept { return x; } | |||