diff --git a/src/stdfunctions.cpp b/src/stdfunctions.cpp index d452dfb..9934138 100644 --- a/src/stdfunctions.cpp +++ b/src/stdfunctions.cpp @@ -15,16 +15,16 @@ float sign( float x ) template float minv( float arg0, Args... args ) { - float r; - ( ( r = std::min( arg0, args ) ), ... ); + float r = arg0; + ( ( r = std::min( r, args ) ), ... ); return r; } template float maxv( float arg0, Args... args ) { - float r; - ( ( r = std::max( arg0, args ) ), ... ); + float r = arg0; + ( ( r = std::max( r, args ) ), ... ); return r; } diff --git a/tests/functions.cpp b/tests/functions.cpp index ff40d18..cf39c47 100644 --- a/tests/functions.cpp +++ b/tests/functions.cpp @@ -191,3 +191,24 @@ TEST( Functions, CanUseStandardFunctions ) ASSERT_EQ( 1, TestEval( "cos(0)" ) ); ASSERT_EQ( 3, TestEval( "max(1, 2, 3)" ) ); } + +TEST( Functions, MinMaxFoldThroughAccumulator ) +{ + // Smallest/largest is neither the first nor the last argument: a + // buggy fold that compares each tail element against arg0 (rather + // than folding through the running result) would return the wrong + // answer here. + ASSERT_EQ( 3, TestEval( "min(5, 3, 7)" ) ); + ASSERT_EQ( 9, TestEval( "max(1, 9, 4)" ) ); + ASSERT_EQ( 1, TestEval( "min(5, 1, 5, 5, 5)" ) ); + ASSERT_EQ( 9, TestEval( "max(2, 9, 2, 2, 2)" ) ); +} + +TEST( Functions, MinMaxSingleArgument ) +{ + // One-arg form: a fold over an empty parameter pack must still + // produce a defined result equal to that single argument. + ASSERT_EQ( 7, TestEval( "min(7)" ) ); + ASSERT_EQ( 7, TestEval( "max(7)" ) ); + ASSERT_EQ( -3, TestEval( "min(-3)" ) ); +}