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);
+ });
+ }
+};