exprkt: Add ifNan to ignore the NaN value

Arithmetic with `nan` values is not expected in virtual sensor's case.

Adding a new exprkt function `ifNan` to handle this case, that if a
value is `nan`, then use the other value.

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

The above expression get max value of T0, T1 ignoring nan, and if it's
still nana, it uses the value T2.

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: Ib323f6e18ef9f3317437753018857ad53732f54b
diff --git a/exprtkTools.hpp b/exprtkTools.hpp
index a11e10a..be85895 100644
--- a/exprtkTools.hpp
+++ b/exprtkTools.hpp
@@ -90,3 +90,23 @@
         });
     }
 };
+
+template <typename T>
+struct FuncIfNan : public exprtk::ifunction<T>
+{
+    using exprtk::ifunction<T>::operator();
+
+    FuncIfNan() : exprtk::ifunction<T>(2) {}
+
+    inline T operator()(const T& arg1, const T& arg2)
+    {
+        if (std::isnan(arg1))
+        {
+            return arg2;
+        }
+        else
+        {
+            return arg1;
+        }
+    }
+};
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index ea18c61..9b682cb 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -46,6 +46,7 @@
 
 FuncMaxIgnoreNaN<double> VirtualSensor::funcMaxIgnoreNaN;
 FuncSumIgnoreNaN<double> VirtualSensor::funcSumIgnoreNaN;
+FuncIfNan<double> VirtualSensor::funcIfNan;
 
 void printParams(const VirtualSensor::ParamMap& paramMap)
 {
@@ -369,6 +370,7 @@
     symbols.add_package(vecopsPackage);
     symbols.add_function("maxIgnoreNaN", funcMaxIgnoreNaN);
     symbols.add_function("sumIgnoreNaN", funcSumIgnoreNaN);
+    symbols.add_function("ifNan", funcIfNan);
 
     expression.register_symbol_table(symbols);
 
diff --git a/virtualSensor.hpp b/virtualSensor.hpp
index 6c4bbb7..01e3221 100644
--- a/virtualSensor.hpp
+++ b/virtualSensor.hpp
@@ -171,6 +171,7 @@
 
     static FuncMaxIgnoreNaN<double> funcMaxIgnoreNaN;
     static FuncSumIgnoreNaN<double> funcSumIgnoreNaN;
+    static FuncIfNan<double> funcIfNan;
 
     /** @brief Read config from json object and initialize sensor data
      * for each virtual sensor