exprkt: Add maxIgnoreNaN to ignore the NaN value

The max function in exprtk uses std::max() to get the max value.
Comparing a value with nan has special rule and is not expected in
virtual sensor's case. E.g. `max(nan, 1)` gives `nan`.

Adding a new exprkt function `maxIgnoreNaN` to handle the above case so
that it ignores all `nan` values. If all values are `nan` then it
returns `nan`, otherwise it returns the max value of the valid values.

Example usage in json config:
```
"Expression": "maxIgnoreNaN(T0, T1, T2, T3)"
```

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: Idd345cd2ce325e5a186b9816458ba3d3bc66a187
diff --git a/exprtkTools.hpp b/exprtkTools.hpp
index 18a4af7..c26a1b1 100644
--- a/exprtkTools.hpp
+++ b/exprtkTools.hpp
@@ -37,3 +37,35 @@
 
 /* include main exprtk header library */
 #include <exprtk.hpp>
+
+#include <cmath>
+#include <limits>
+#include <numeric>
+
+/* For floating types. (float, double, long double et al) */
+template <typename T>
+struct FuncMaxIgnoreNaN : public exprtk::ivararg_function<T>
+{
+    FuncMaxIgnoreNaN()
+    {
+        exprtk::set_min_num_args(*this, 2);
+        exprtk::set_max_num_args(*this, 255);
+    }
+
+    inline T operator()(const std::vector<T>& argList)
+    {
+        return std::reduce(std::begin(argList), std::end(argList),
+                           std::numeric_limits<double>::quiet_NaN(),
+                           [](auto a, auto b) {
+            if (std::isnan(b))
+            {
+                return a;
+            }
+            if (std::isnan(a))
+            {
+                return b;
+            }
+            return std::max(a, b);
+        });
+    }
+};