192d648b2SVijay Khemka /*
292d648b2SVijay Khemka  * This define will disable the ability for expressions to have comments.
392d648b2SVijay Khemka  * Expressions that have comments when parsed with a build that has this
492d648b2SVijay Khemka  * option, will result in a compilation failure.
592d648b2SVijay Khemka  */
692d648b2SVijay Khemka // #define exprtk_disable_comments
792d648b2SVijay Khemka /*
892d648b2SVijay Khemka  * This define will disable the loop-wise 'break' and 'continue'
992d648b2SVijay Khemka  * capabilities. Any expression that contains those keywords will result
1092d648b2SVijay Khemka  * in a compilation failure.
1192d648b2SVijay Khemka  */
1292d648b2SVijay Khemka #define exprtk_disable_break_continue
1392d648b2SVijay Khemka /*
1492d648b2SVijay Khemka  * This define will disable the short-circuit '&' (and) and '|' (or)
1592d648b2SVijay Khemka  * operators
1692d648b2SVijay Khemka  */
1792d648b2SVijay Khemka #define exprtk_disable_sc_andor
1892d648b2SVijay Khemka /*
1992d648b2SVijay Khemka  * This define will disable all enhanced features such as strength
2092d648b2SVijay Khemka  * reduction and special function optimisations and expression specific
2192d648b2SVijay Khemka  * type instantiations. This feature will reduce compilation times and
2292d648b2SVijay Khemka  * binary sizes but will also result in massive performance degradation
2392d648b2SVijay Khemka  * of expression evaluations.
2492d648b2SVijay Khemka  */
2592d648b2SVijay Khemka #define exprtk_disable_enhanced_features
2692d648b2SVijay Khemka /*
2792d648b2SVijay Khemka  * This define will disable all string processing capabilities. Any
2892d648b2SVijay Khemka  * expression that contains a string or string related syntax will result
2992d648b2SVijay Khemka  * in a compilation failure.
3092d648b2SVijay Khemka  */
3192d648b2SVijay Khemka #define exprtk_disable_string_capabilities
3292d648b2SVijay Khemka 
3392d648b2SVijay Khemka #define exprtk_disable_rtl_io_file
3492d648b2SVijay Khemka #define exprtk_disable_return_statement
3592d648b2SVijay Khemka #define exprtk_disable_rtl_io
3692d648b2SVijay Khemka #define exprtk_disable_superscalar_unroll
3792d648b2SVijay Khemka 
3892d648b2SVijay Khemka /* include main exprtk header library */
3992d648b2SVijay Khemka #include <exprtk.hpp>
400ab9d838SLei YU 
410ab9d838SLei YU #include <cmath>
420ab9d838SLei YU #include <limits>
430ab9d838SLei YU #include <numeric>
440ab9d838SLei YU 
450ab9d838SLei YU /* For floating types. (float, double, long double et al) */
460ab9d838SLei YU template <typename T>
470ab9d838SLei YU struct FuncMaxIgnoreNaN : public exprtk::ivararg_function<T>
480ab9d838SLei YU {
FuncMaxIgnoreNaNFuncMaxIgnoreNaN490ab9d838SLei YU     FuncMaxIgnoreNaN()
500ab9d838SLei YU     {
510ab9d838SLei YU         exprtk::set_min_num_args(*this, 2);
520ab9d838SLei YU         exprtk::set_max_num_args(*this, 255);
530ab9d838SLei YU     }
540ab9d838SLei YU 
operator ()FuncMaxIgnoreNaN550ab9d838SLei YU     inline T operator()(const std::vector<T>& argList)
560ab9d838SLei YU     {
570ab9d838SLei YU         return std::reduce(std::begin(argList), std::end(argList),
580ab9d838SLei YU                            std::numeric_limits<double>::quiet_NaN(),
590ab9d838SLei YU                            [](auto a, auto b) {
600ab9d838SLei YU             if (std::isnan(b))
610ab9d838SLei YU             {
620ab9d838SLei YU                 return a;
630ab9d838SLei YU             }
640ab9d838SLei YU             if (std::isnan(a))
650ab9d838SLei YU             {
660ab9d838SLei YU                 return b;
670ab9d838SLei YU             }
680ab9d838SLei YU             return std::max(a, b);
690ab9d838SLei YU         });
700ab9d838SLei YU     }
710ab9d838SLei YU };
7287d35115SLei YU 
7387d35115SLei YU template <typename T>
7487d35115SLei YU struct FuncSumIgnoreNaN : public exprtk::ivararg_function<T>
7587d35115SLei YU {
operator ()FuncSumIgnoreNaN7687d35115SLei YU     inline T operator()(const std::vector<T>& argList)
7787d35115SLei YU     {
7887d35115SLei YU         return std::reduce(std::begin(argList), std::end(argList),
7987d35115SLei YU                            std::numeric_limits<double>::quiet_NaN(),
8087d35115SLei YU                            [](auto a, auto b) {
8187d35115SLei YU             if (std::isnan(b))
8287d35115SLei YU             {
8387d35115SLei YU                 return a;
8487d35115SLei YU             }
8587d35115SLei YU             if (std::isnan(a))
8687d35115SLei YU             {
8787d35115SLei YU                 return b;
8887d35115SLei YU             }
8987d35115SLei YU             return a + b;
9087d35115SLei YU         });
9187d35115SLei YU     }
9287d35115SLei YU };
93*c77b6b3fSLei YU 
94*c77b6b3fSLei YU template <typename T>
95*c77b6b3fSLei YU struct FuncIfNan : public exprtk::ifunction<T>
96*c77b6b3fSLei YU {
97*c77b6b3fSLei YU     using exprtk::ifunction<T>::operator();
98*c77b6b3fSLei YU 
FuncIfNanFuncIfNan99*c77b6b3fSLei YU     FuncIfNan() : exprtk::ifunction<T>(2) {}
100*c77b6b3fSLei YU 
operator ()FuncIfNan101*c77b6b3fSLei YU     inline T operator()(const T& arg1, const T& arg2)
102*c77b6b3fSLei YU     {
103*c77b6b3fSLei YU         if (std::isnan(arg1))
104*c77b6b3fSLei YU         {
105*c77b6b3fSLei YU             return arg2;
106*c77b6b3fSLei YU         }
107*c77b6b3fSLei YU         else
108*c77b6b3fSLei YU         {
109*c77b6b3fSLei YU             return arg1;
110*c77b6b3fSLei YU         }
111*c77b6b3fSLei YU     }
112*c77b6b3fSLei YU };
113