1 /*
2  * This define will disable the ability for expressions to have comments.
3  * Expressions that have comments when parsed with a build that has this
4  * option, will result in a compilation failure.
5  */
6 // #define exprtk_disable_comments
7 /*
8  * This define will disable the loop-wise 'break' and 'continue'
9  * capabilities. Any expression that contains those keywords will result
10  * in a compilation failure.
11  */
12 #define exprtk_disable_break_continue
13 /*
14  * This define will disable the short-circuit '&' (and) and '|' (or)
15  * operators
16  */
17 #define exprtk_disable_sc_andor
18 /*
19  * This define will disable all enhanced features such as strength
20  * reduction and special function optimisations and expression specific
21  * type instantiations. This feature will reduce compilation times and
22  * binary sizes but will also result in massive performance degradation
23  * of expression evaluations.
24  */
25 #define exprtk_disable_enhanced_features
26 /*
27  * This define will disable all string processing capabilities. Any
28  * expression that contains a string or string related syntax will result
29  * in a compilation failure.
30  */
31 #define exprtk_disable_string_capabilities
32 
33 #define exprtk_disable_rtl_io_file
34 #define exprtk_disable_return_statement
35 #define exprtk_disable_rtl_io
36 #define exprtk_disable_superscalar_unroll
37 
38 /* include main exprtk header library */
39 #include <exprtk.hpp>
40 
41 #include <cmath>
42 #include <limits>
43 #include <numeric>
44 
45 /* For floating types. (float, double, long double et al) */
46 template <typename T>
47 struct FuncMaxIgnoreNaN : public exprtk::ivararg_function<T>
48 {
49     FuncMaxIgnoreNaN()
50     {
51         exprtk::set_min_num_args(*this, 2);
52         exprtk::set_max_num_args(*this, 255);
53     }
54 
55     inline T operator()(const std::vector<T>& argList)
56     {
57         return std::reduce(std::begin(argList), std::end(argList),
58                            std::numeric_limits<double>::quiet_NaN(),
59                            [](auto a, auto b) {
60             if (std::isnan(b))
61             {
62                 return a;
63             }
64             if (std::isnan(a))
65             {
66                 return b;
67             }
68             return std::max(a, b);
69         });
70     }
71 };
72 
73 template <typename T>
74 struct FuncSumIgnoreNaN : public exprtk::ivararg_function<T>
75 {
76     inline T operator()(const std::vector<T>& argList)
77     {
78         return std::reduce(std::begin(argList), std::end(argList),
79                            std::numeric_limits<double>::quiet_NaN(),
80                            [](auto a, auto b) {
81             if (std::isnan(b))
82             {
83                 return a;
84             }
85             if (std::isnan(a))
86             {
87                 return b;
88             }
89             return a + b;
90         });
91     }
92 };
93 
94 template <typename T>
95 struct FuncIfNan : public exprtk::ifunction<T>
96 {
97     using exprtk::ifunction<T>::operator();
98 
99     FuncIfNan() : exprtk::ifunction<T>(2) {}
100 
101     inline T operator()(const T& arg1, const T& arg2)
102     {
103         if (std::isnan(arg1))
104         {
105             return arg2;
106         }
107         else
108         {
109             return arg1;
110         }
111     }
112 };
113