2 ******************************************************************
3 * C++ Mathematical Expression Toolkit Library *
5 * Author: Arash Partow (1999-2020) *
6 * URL: http://www.partow.net/programming/exprtk/index.html *
9 * Free use of the C++ Mathematical Expression Toolkit Library is *
10 * permitted under the guidelines and in accordance with the most *
11 * current version of the MIT License. *
12 * http://www.opensource.org/licenses/MIT *
14 * Example expressions: *
15 * (00) (y + x / y) * (x - y / x) *
16 * (01) (x^2 / sin(2 * pi / y)) - x / 2 *
17 * (02) sqrt(1 - (x^2)) *
18 * (03) 1 - sin(2 * x) + cos(pi / y) *
19 * (04) a * exp(2 * t) + c *
20 * (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z) *
21 * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x *
22 * (07) z := x + sin(2 * pi / y) *
23 * (08) u := 2 * (pi * z) / (w := x + cos(y / pi)) *
24 * (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1) *
25 * (10) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0) *
26 * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) *
27 * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] *
29 ******************************************************************
33 #ifndef INCLUDE_EXPRTK_HPP
34 #define INCLUDE_EXPRTK_HPP
61 #ifdef exprtk_enable_debugging
62 #define exprtk_debug(params) printf params
64 #define exprtk_debug(params) (void)0
67 #define exprtk_error_location \
68 "exprtk.hpp:" + details::to_str(__LINE__) \
70 #if defined(__GNUC__) && (__GNUC__ >= 7)
72 #define exprtk_disable_fallthrough_begin \
73 _Pragma ("GCC diagnostic push") \
74 _Pragma ("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \
76 #define exprtk_disable_fallthrough_end \
77 _Pragma ("GCC diagnostic pop") \
80 #define exprtk_disable_fallthrough_begin (void)0;
81 #define exprtk_disable_fallthrough_end (void)0;
86 typedef unsigned char uchar_t
;
88 typedef uchar_t
* uchar_ptr
;
89 typedef char_t
* char_ptr
;
90 typedef uchar_t
const* uchar_cptr
;
91 typedef char_t
const* char_cptr
;
92 typedef unsigned long long int _uint64_t
;
93 typedef long long int _int64_t
;
95 inline bool is_whitespace(const char_t c
)
97 return (' ' == c
) || ('\n' == c
) ||
98 ('\r' == c
) || ('\t' == c
) ||
99 ('\b' == c
) || ('\v' == c
) ||
103 inline bool is_operator_char(const char_t c
)
105 return ('+' == c
) || ('-' == c
) ||
106 ('*' == c
) || ('/' == c
) ||
107 ('^' == c
) || ('<' == c
) ||
108 ('>' == c
) || ('=' == c
) ||
109 (',' == c
) || ('!' == c
) ||
110 ('(' == c
) || (')' == c
) ||
111 ('[' == c
) || (']' == c
) ||
112 ('{' == c
) || ('}' == c
) ||
113 ('%' == c
) || (':' == c
) ||
114 ('?' == c
) || ('&' == c
) ||
115 ('|' == c
) || (';' == c
) ;
118 inline bool is_letter(const char_t c
)
120 return (('a' <= c
) && (c
<= 'z')) ||
121 (('A' <= c
) && (c
<= 'Z')) ;
124 inline bool is_digit(const char_t c
)
126 return ('0' <= c
) && (c
<= '9');
129 inline bool is_letter_or_digit(const char_t c
)
131 return is_letter(c
) || is_digit(c
);
134 inline bool is_left_bracket(const char_t c
)
136 return ('(' == c
) || ('[' == c
) || ('{' == c
);
139 inline bool is_right_bracket(const char_t c
)
141 return (')' == c
) || (']' == c
) || ('}' == c
);
144 inline bool is_bracket(const char_t c
)
146 return is_left_bracket(c
) || is_right_bracket(c
);
149 inline bool is_sign(const char_t c
)
151 return ('+' == c
) || ('-' == c
);
154 inline bool is_invalid(const char_t c
)
156 return !is_whitespace (c
) &&
157 !is_operator_char(c
) &&
167 #ifndef exprtk_disable_caseinsensitivity
168 inline void case_normalise(std::string
& s
)
170 for (std::size_t i
= 0; i
< s
.size(); ++i
)
172 s
[i
] = static_cast<std::string::value_type
>(std::tolower(s
[i
]));
176 inline bool imatch(const char_t c1
, const char_t c2
)
178 return std::tolower(c1
) == std::tolower(c2
);
181 inline bool imatch(const std::string
& s1
, const std::string
& s2
)
183 if (s1
.size() == s2
.size())
185 for (std::size_t i
= 0; i
< s1
.size(); ++i
)
187 if (std::tolower(s1
[i
]) != std::tolower(s2
[i
]))
201 inline bool operator() (const std::string
& s1
, const std::string
& s2
) const
203 const std::size_t length
= std::min(s1
.size(),s2
.size());
205 for (std::size_t i
= 0; i
< length
; ++i
)
207 const char_t c1
= static_cast<char>(std::tolower(s1
[i
]));
208 const char_t c2
= static_cast<char>(std::tolower(s2
[i
]));
216 return s1
.size() < s2
.size();
221 inline void case_normalise(std::string
&)
224 inline bool imatch(const char_t c1
, const char_t c2
)
229 inline bool imatch(const std::string
& s1
, const std::string
& s2
)
236 inline bool operator() (const std::string
& s1
, const std::string
& s2
) const
243 inline bool is_valid_sf_symbol(const std::string
& symbol
)
245 // Special function: $f12 or $F34
246 return (4 == symbol
.size()) &&
247 ('$' == symbol
[0]) &&
248 imatch('f',symbol
[1]) &&
249 is_digit(symbol
[2]) &&
253 inline const char_t
& front(const std::string
& s
)
258 inline const char_t
& back(const std::string
& s
)
260 return s
[s
.size() - 1];
263 inline std::string
to_str(int i
)
266 return std::string("0");
274 result
+= '0' + char(-(i
% 10));
283 result
+= '0' + char(i
% 10);
287 std::reverse(result
.begin(), result
.end());
292 inline std::string
to_str(std::size_t i
)
294 return to_str(static_cast<int>(i
));
297 inline bool is_hex_digit(const std::string::value_type digit
)
299 return (('0' <= digit
) && (digit
<= '9')) ||
300 (('A' <= digit
) && (digit
<= 'F')) ||
301 (('a' <= digit
) && (digit
<= 'f')) ;
304 inline uchar_t
hex_to_bin(uchar_t h
)
306 if (('0' <= h
) && (h
<= '9'))
309 return static_cast<unsigned char>(std::toupper(h
) - 'A');
312 template <typename Iterator
>
313 inline void parse_hex(Iterator
& itr
, Iterator end
, std::string::value_type
& result
)
317 (end
!= (itr
+ 1)) &&
318 (end
!= (itr
+ 2)) &&
319 (end
!= (itr
+ 3)) &&
322 ('x' == *(itr
+ 1)) ||
325 (is_hex_digit(*(itr
+ 2))) &&
326 (is_hex_digit(*(itr
+ 3)))
329 result
= hex_to_bin(static_cast<uchar_t
>(*(itr
+ 2))) << 4 |
330 hex_to_bin(static_cast<uchar_t
>(*(itr
+ 3))) ;
337 inline void cleanup_escapes(std::string
& s
)
339 typedef std::string::iterator str_itr_t
;
341 str_itr_t itr1
= s
.begin();
342 str_itr_t itr2
= s
.begin();
343 str_itr_t end
= s
.end ();
345 std::size_t removal_count
= 0;
355 else if ('\\' != (*itr1
))
359 case 'n' : (*itr1
) = '\n'; break;
360 case 'r' : (*itr1
) = '\r'; break;
361 case 't' : (*itr1
) = '\t'; break;
362 case '0' : parse_hex(itr1
, end
, (*itr1
));
380 s
.resize(s
.size() - removal_count
);
387 build_string(const std::size_t& initial_size
= 64)
389 data_
.reserve(initial_size
);
392 inline build_string
& operator << (const std::string
& s
)
398 inline build_string
& operator << (char_cptr s
)
400 data_
+= std::string(s
);
404 inline operator std::string () const
409 inline std::string
as_string() const
419 const std::string reserved_words
[] =
421 "break", "case", "continue", "default", "false", "for",
422 "if", "else", "ilike", "in", "like", "and", "nand", "nor",
423 "not", "null", "or", "repeat", "return", "shl", "shr",
424 "swap", "switch", "true", "until", "var", "while", "xnor",
428 static const std::size_t reserved_words_size
= sizeof(reserved_words
) / sizeof(std::string
);
430 const std::string reserved_symbols
[] =
432 "abs", "acos", "acosh", "and", "asin", "asinh", "atan",
433 "atanh", "atan2", "avg", "break", "case", "ceil", "clamp",
434 "continue", "cos", "cosh", "cot", "csc", "default",
435 "deg2grad", "deg2rad", "equal", "erf", "erfc", "exp",
436 "expm1", "false", "floor", "for", "frac", "grad2deg",
437 "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
438 "like", "log", "log10", "log2", "logn", "log1p", "mand",
439 "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor",
440 "not", "not_equal", "null", "or", "pow", "rad2deg",
441 "repeat", "return", "root", "round", "roundn", "sec", "sgn",
442 "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap",
443 "switch", "tan", "tanh", "true", "trunc", "until", "var",
444 "while", "xnor", "xor", "&", "|"
447 static const std::size_t reserved_symbols_size
= sizeof(reserved_symbols
) / sizeof(std::string
);
449 const std::string base_function_list
[] =
451 "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh",
452 "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot",
453 "csc", "equal", "erf", "erfc", "exp", "expm1", "floor",
454 "frac", "hypot", "iclamp", "like", "log", "log10", "log2",
455 "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul",
456 "ncdf", "pow", "root", "round", "roundn", "sec", "sgn",
457 "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
458 "trunc", "not_equal", "inrange", "deg2grad", "deg2rad",
459 "rad2deg", "grad2deg"
462 static const std::size_t base_function_list_size
= sizeof(base_function_list
) / sizeof(std::string
);
464 const std::string logic_ops_list
[] =
466 "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|"
469 static const std::size_t logic_ops_list_size
= sizeof(logic_ops_list
) / sizeof(std::string
);
471 const std::string cntrl_struct_list
[] =
473 "if", "switch", "for", "while", "repeat", "return"
476 static const std::size_t cntrl_struct_list_size
= sizeof(cntrl_struct_list
) / sizeof(std::string
);
478 const std::string arithmetic_ops_list
[] =
480 "+", "-", "*", "/", "%", "^"
483 static const std::size_t arithmetic_ops_list_size
= sizeof(arithmetic_ops_list
) / sizeof(std::string
);
485 const std::string assignment_ops_list
[] =
491 static const std::size_t assignment_ops_list_size
= sizeof(assignment_ops_list
) / sizeof(std::string
);
493 const std::string inequality_ops_list
[] =
500 static const std::size_t inequality_ops_list_size
= sizeof(inequality_ops_list
) / sizeof(std::string
);
502 inline bool is_reserved_word(const std::string
& symbol
)
504 for (std::size_t i
= 0; i
< reserved_words_size
; ++i
)
506 if (imatch(symbol
, reserved_words
[i
]))
515 inline bool is_reserved_symbol(const std::string
& symbol
)
517 for (std::size_t i
= 0; i
< reserved_symbols_size
; ++i
)
519 if (imatch(symbol
, reserved_symbols
[i
]))
528 inline bool is_base_function(const std::string
& function_name
)
530 for (std::size_t i
= 0; i
< base_function_list_size
; ++i
)
532 if (imatch(function_name
, base_function_list
[i
]))
541 inline bool is_control_struct(const std::string
& cntrl_strct
)
543 for (std::size_t i
= 0; i
< cntrl_struct_list_size
; ++i
)
545 if (imatch(cntrl_strct
, cntrl_struct_list
[i
]))
554 inline bool is_logic_opr(const std::string
& lgc_opr
)
556 for (std::size_t i
= 0; i
< logic_ops_list_size
; ++i
)
558 if (imatch(lgc_opr
, logic_ops_list
[i
]))
569 static inline bool cmp(const char_t c0
, const char_t c1
)
577 static inline bool cmp(const char_t c0
, const char_t c1
)
579 return (std::tolower(c0
) == std::tolower(c1
));
583 template <typename Iterator
, typename Compare
>
584 inline bool match_impl(const Iterator pattern_begin
,
585 const Iterator pattern_end
,
586 const Iterator data_begin
,
587 const Iterator data_end
,
588 const typename
std::iterator_traits
<Iterator
>::value_type
& zero_or_more
,
589 const typename
std::iterator_traits
<Iterator
>::value_type
& zero_or_one
)
591 const Iterator
null_itr(0);
593 Iterator d_itr
= data_begin
;
594 Iterator p_itr
= pattern_begin
;
595 Iterator tb_p_itr
= null_itr
;
596 Iterator tb_d_itr
= null_itr
;
598 while (d_itr
!= data_end
)
600 if (zero_or_more
== *p_itr
)
602 while ((pattern_end
!= p_itr
) && ((zero_or_more
== *p_itr
) || (zero_or_one
== *p_itr
)))
607 if (pattern_end
== p_itr
)
610 const typename
std::iterator_traits
<Iterator
>::value_type c
= *(p_itr
);
612 while ((data_end
!= d_itr
) && !Compare::cmp(c
,*d_itr
))
622 else if (!Compare::cmp(*p_itr
, *d_itr
) && (zero_or_one
!= *p_itr
))
624 if (null_itr
== tb_d_itr
)
637 while ((pattern_end
!= p_itr
) && ((zero_or_more
== *p_itr
) || (zero_or_one
== *p_itr
)))
642 return (pattern_end
== p_itr
);
645 inline bool wc_match(const std::string
& wild_card
,
646 const std::string
& str
)
648 return match_impl
<char_cptr
,cs_match
>(wild_card
.data(),
649 wild_card
.data() + wild_card
.size(),
651 str
.data() + str
.size(),
656 inline bool wc_imatch(const std::string
& wild_card
,
657 const std::string
& str
)
659 return match_impl
<char_cptr
,cis_match
>(wild_card
.data(),
660 wild_card
.data() + wild_card
.size(),
662 str
.data() + str
.size(),
667 inline bool sequence_match(const std::string
& pattern
,
668 const std::string
& str
,
669 std::size_t& diff_index
,
674 return ("Z" == pattern
);
676 else if ('*' == pattern
[0])
679 typedef std::string::const_iterator itr_t
;
681 itr_t p_itr
= pattern
.begin();
682 itr_t s_itr
= str
.begin();
684 itr_t p_end
= pattern
.end();
685 itr_t s_end
= str
.end();
687 while ((s_end
!= s_itr
) && (p_end
!= p_itr
))
691 const char_t target
= static_cast<char>(std::toupper(*(p_itr
- 1)));
695 diff_index
= static_cast<std::size_t>(std::distance(str
.begin(),s_itr
));
696 diff_value
= static_cast<char>(std::toupper(*p_itr
));
703 while (s_itr
!= s_end
)
705 if (target
!= std::toupper(*s_itr
))
715 std::toupper(*p_itr
) != std::toupper(*s_itr
)
718 diff_index
= static_cast<std::size_t>(std::distance(str
.begin(),s_itr
));
719 diff_value
= static_cast<char>(std::toupper(*p_itr
));
737 static const double pow10
[] = {
739 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
740 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
741 1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
742 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
745 static const std::size_t pow10_size
= sizeof(pow10
) / sizeof(double);
751 static const double e
= 2.71828182845904523536028747135266249775724709369996;
752 static const double pi
= 3.14159265358979323846264338327950288419716939937510;
753 static const double pi_2
= 1.57079632679489661923132169163975144209858469968755;
754 static const double pi_4
= 0.78539816339744830961566084581987572104929234984378;
755 static const double pi_180
= 0.01745329251994329576923690768488612713442871888542;
756 static const double _1_pi
= 0.31830988618379067153776752674502872406891929148091;
757 static const double _2_pi
= 0.63661977236758134307553505349005744813783858296183;
758 static const double _180_pi
= 57.29577951308232087679815481410517033240547246656443;
759 static const double log2
= 0.69314718055994530941723212145817656807550013436026;
760 static const double sqrt2
= 1.41421356237309504880168872420969807856967187537695;
765 struct unknown_type_tag
{ unknown_type_tag() {} };
766 struct real_type_tag
{ real_type_tag () {} };
767 struct complex_type_tag
{ complex_type_tag() {} };
768 struct int_type_tag
{ int_type_tag () {} };
770 template <typename T
>
773 typedef unknown_type_tag type
;
777 #define exprtk_register_real_type_tag(T) \
778 template<> struct number_type<T> \
779 { typedef real_type_tag type; number_type() {} }; \
781 #define exprtk_register_complex_type_tag(T) \
782 template<> struct number_type<std::complex<T> > \
783 { typedef complex_type_tag type; number_type() {} }; \
785 #define exprtk_register_int_type_tag(T) \
786 template<> struct number_type<T> \
787 { typedef int_type_tag type; number_type() {} }; \
789 exprtk_register_real_type_tag(double )
790 exprtk_register_real_type_tag(long double)
791 exprtk_register_real_type_tag(float )
793 exprtk_register_complex_type_tag(double )
794 exprtk_register_complex_type_tag(long double)
795 exprtk_register_complex_type_tag(float )
797 exprtk_register_int_type_tag(short )
798 exprtk_register_int_type_tag(int )
799 exprtk_register_int_type_tag(_int64_t
)
800 exprtk_register_int_type_tag(unsigned short)
801 exprtk_register_int_type_tag(unsigned int )
802 exprtk_register_int_type_tag(_uint64_t
)
804 #undef exprtk_register_real_type_tag
805 #undef exprtk_register_int_type_tag
807 template <typename T
>
810 static inline T
value()
812 const T epsilon
= T(0.0000000001);
818 struct epsilon_type
<float>
820 static inline float value()
822 const float epsilon
= float(0.000001f
);
828 struct epsilon_type
<long double>
830 static inline long double value()
832 const long double epsilon
= (long double)(0.000000000001);
837 template <typename T
>
838 inline bool is_nan_impl(const T v
, real_type_tag
)
840 return std::not_equal_to
<T
>()(v
,v
);
843 template <typename T
>
844 inline int to_int32_impl(const T v
, real_type_tag
)
846 return static_cast<int>(v
);
849 template <typename T
>
850 inline _int64_t
to_int64_impl(const T v
, real_type_tag
)
852 return static_cast<_int64_t
>(v
);
855 template <typename T
>
856 inline bool is_true_impl(const T v
)
858 return std::not_equal_to
<T
>()(T(0),v
);
861 template <typename T
>
862 inline bool is_false_impl(const T v
)
864 return std::equal_to
<T
>()(T(0),v
);
867 template <typename T
>
868 inline T
abs_impl(const T v
, real_type_tag
)
870 return ((v
< T(0)) ? -v
: v
);
873 template <typename T
>
874 inline T
min_impl(const T v0
, const T v1
, real_type_tag
)
876 return std::min
<T
>(v0
,v1
);
879 template <typename T
>
880 inline T
max_impl(const T v0
, const T v1
, real_type_tag
)
882 return std::max
<T
>(v0
,v1
);
885 template <typename T
>
886 inline T
equal_impl(const T v0
, const T v1
, real_type_tag
)
888 const T epsilon
= epsilon_type
<T
>::value();
889 return (abs_impl(v0
- v1
,real_type_tag()) <= (std::max(T(1),std::max(abs_impl(v0
,real_type_tag()),abs_impl(v1
,real_type_tag()))) * epsilon
)) ? T(1) : T(0);
892 inline float equal_impl(const float v0
, const float v1
, real_type_tag
)
894 const float epsilon
= epsilon_type
<float>::value();
895 return (abs_impl(v0
- v1
,real_type_tag()) <= (std::max(1.0f
,std::max(abs_impl(v0
,real_type_tag()),abs_impl(v1
,real_type_tag()))) * epsilon
)) ? 1.0f
: 0.0f
;
898 template <typename T
>
899 inline T
equal_impl(const T v0
, const T v1
, int_type_tag
)
901 return (v0
== v1
) ? 1 : 0;
904 template <typename T
>
905 inline T
expm1_impl(const T v
, real_type_tag
)
907 // return std::expm1<T>(v);
908 if (abs_impl(v
,real_type_tag()) < T(0.00001))
909 return v
+ (T(0.5) * v
* v
);
911 return std::exp(v
) - T(1);
914 template <typename T
>
915 inline T
expm1_impl(const T v
, int_type_tag
)
917 return T(std::exp
<double>(v
)) - T(1);
920 template <typename T
>
921 inline T
nequal_impl(const T v0
, const T v1
, real_type_tag
)
923 typedef real_type_tag rtg
;
924 const T epsilon
= epsilon_type
<T
>::value();
925 return (abs_impl(v0
- v1
,rtg()) > (std::max(T(1),std::max(abs_impl(v0
,rtg()),abs_impl(v1
,rtg()))) * epsilon
)) ? T(1) : T(0);
928 inline float nequal_impl(const float v0
, const float v1
, real_type_tag
)
930 typedef real_type_tag rtg
;
931 const float epsilon
= epsilon_type
<float>::value();
932 return (abs_impl(v0
- v1
,rtg()) > (std::max(1.0f
,std::max(abs_impl(v0
,rtg()),abs_impl(v1
,rtg()))) * epsilon
)) ? 1.0f
: 0.0f
;
935 template <typename T
>
936 inline T
nequal_impl(const T v0
, const T v1
, int_type_tag
)
938 return (v0
!= v1
) ? 1 : 0;
941 template <typename T
>
942 inline T
modulus_impl(const T v0
, const T v1
, real_type_tag
)
944 return std::fmod(v0
,v1
);
947 template <typename T
>
948 inline T
modulus_impl(const T v0
, const T v1
, int_type_tag
)
953 template <typename T
>
954 inline T
pow_impl(const T v0
, const T v1
, real_type_tag
)
956 return std::pow(v0
,v1
);
959 template <typename T
>
960 inline T
pow_impl(const T v0
, const T v1
, int_type_tag
)
962 return std::pow(static_cast<double>(v0
),static_cast<double>(v1
));
965 template <typename T
>
966 inline T
logn_impl(const T v0
, const T v1
, real_type_tag
)
968 return std::log(v0
) / std::log(v1
);
971 template <typename T
>
972 inline T
logn_impl(const T v0
, const T v1
, int_type_tag
)
974 return static_cast<T
>(logn_impl
<double>(static_cast<double>(v0
),static_cast<double>(v1
),real_type_tag()));
977 template <typename T
>
978 inline T
log1p_impl(const T v
, real_type_tag
)
982 if (abs_impl(v
,real_type_tag()) > T(0.0001))
984 return std::log(T(1) + v
);
987 return (T(-0.5) * v
+ T(1)) * v
;
990 return std::numeric_limits
<T
>::quiet_NaN();
993 template <typename T
>
994 inline T
log1p_impl(const T v
, int_type_tag
)
998 return std::log(T(1) + v
);
1001 return std::numeric_limits
<T
>::quiet_NaN();
1004 template <typename T
>
1005 inline T
root_impl(const T v0
, const T v1
, real_type_tag
)
1008 return std::numeric_limits
<T
>::quiet_NaN();
1010 const std::size_t n
= static_cast<std::size_t>(v1
);
1012 if ((v0
< T(0)) && (0 == (n
% 2)))
1013 return std::numeric_limits
<T
>::quiet_NaN();
1015 return std::pow(v0
, T(1) / n
);
1018 template <typename T
>
1019 inline T
root_impl(const T v0
, const T v1
, int_type_tag
)
1021 return root_impl
<double>(static_cast<double>(v0
),static_cast<double>(v1
),real_type_tag());
1024 template <typename T
>
1025 inline T
round_impl(const T v
, real_type_tag
)
1027 return ((v
< T(0)) ? std::ceil(v
- T(0.5)) : std::floor(v
+ T(0.5)));
1030 template <typename T
>
1031 inline T
roundn_impl(const T v0
, const T v1
, real_type_tag
)
1033 const int index
= std::max
<int>(0, std::min
<int>(pow10_size
- 1, (int)std::floor(v1
)));
1034 const T p10
= T(pow10
[index
]);
1037 return T(std::ceil ((v0
* p10
) - T(0.5)) / p10
);
1039 return T(std::floor((v0
* p10
) + T(0.5)) / p10
);
1042 template <typename T
>
1043 inline T
roundn_impl(const T v0
, const T
, int_type_tag
)
1048 template <typename T
>
1049 inline T
hypot_impl(const T v0
, const T v1
, real_type_tag
)
1051 return std::sqrt((v0
* v0
) + (v1
* v1
));
1054 template <typename T
>
1055 inline T
hypot_impl(const T v0
, const T v1
, int_type_tag
)
1057 return static_cast<T
>(std::sqrt(static_cast<double>((v0
* v0
) + (v1
* v1
))));
1060 template <typename T
>
1061 inline T
atan2_impl(const T v0
, const T v1
, real_type_tag
)
1063 return std::atan2(v0
,v1
);
1066 template <typename T
>
1067 inline T
atan2_impl(const T
, const T
, int_type_tag
)
1072 template <typename T
>
1073 inline T
shr_impl(const T v0
, const T v1
, real_type_tag
)
1075 return v0
* (T(1) / std::pow(T(2),static_cast<T
>(static_cast<int>(v1
))));
1078 template <typename T
>
1079 inline T
shr_impl(const T v0
, const T v1
, int_type_tag
)
1084 template <typename T
>
1085 inline T
shl_impl(const T v0
, const T v1
, real_type_tag
)
1087 return v0
* std::pow(T(2),static_cast<T
>(static_cast<int>(v1
)));
1090 template <typename T
>
1091 inline T
shl_impl(const T v0
, const T v1
, int_type_tag
)
1096 template <typename T
>
1097 inline T
sgn_impl(const T v
, real_type_tag
)
1099 if (v
> T(0)) return T(+1);
1100 else if (v
< T(0)) return T(-1);
1104 template <typename T
>
1105 inline T
sgn_impl(const T v
, int_type_tag
)
1107 if (v
> T(0)) return T(+1);
1108 else if (v
< T(0)) return T(-1);
1112 template <typename T
>
1113 inline T
and_impl(const T v0
, const T v1
, real_type_tag
)
1115 return (is_true_impl(v0
) && is_true_impl(v1
)) ? T(1) : T(0);
1118 template <typename T
>
1119 inline T
and_impl(const T v0
, const T v1
, int_type_tag
)
1124 template <typename T
>
1125 inline T
nand_impl(const T v0
, const T v1
, real_type_tag
)
1127 return (is_false_impl(v0
) || is_false_impl(v1
)) ? T(1) : T(0);
1130 template <typename T
>
1131 inline T
nand_impl(const T v0
, const T v1
, int_type_tag
)
1136 template <typename T
>
1137 inline T
or_impl(const T v0
, const T v1
, real_type_tag
)
1139 return (is_true_impl(v0
) || is_true_impl(v1
)) ? T(1) : T(0);
1142 template <typename T
>
1143 inline T
or_impl(const T v0
, const T v1
, int_type_tag
)
1148 template <typename T
>
1149 inline T
nor_impl(const T v0
, const T v1
, real_type_tag
)
1151 return (is_false_impl(v0
) && is_false_impl(v1
)) ? T(1) : T(0);
1154 template <typename T
>
1155 inline T
nor_impl(const T v0
, const T v1
, int_type_tag
)
1160 template <typename T
>
1161 inline T
xor_impl(const T v0
, const T v1
, real_type_tag
)
1163 return (is_false_impl(v0
) != is_false_impl(v1
)) ? T(1) : T(0);
1166 template <typename T
>
1167 inline T
xor_impl(const T v0
, const T v1
, int_type_tag
)
1172 template <typename T
>
1173 inline T
xnor_impl(const T v0
, const T v1
, real_type_tag
)
1175 const bool v0_true
= is_true_impl(v0
);
1176 const bool v1_true
= is_true_impl(v1
);
1178 if ((v0_true
&& v1_true
) || (!v0_true
&& !v1_true
))
1184 template <typename T
>
1185 inline T
xnor_impl(const T v0
, const T v1
, int_type_tag
)
1187 const bool v0_true
= is_true_impl(v0
);
1188 const bool v1_true
= is_true_impl(v1
);
1190 if ((v0_true
&& v1_true
) || (!v0_true
&& !v1_true
))
1196 #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1197 #define exprtk_define_erf(TT,impl) \
1198 inline TT erf_impl(TT v) { return impl(v); } \
1200 exprtk_define_erf( float,::erff)
1201 exprtk_define_erf( double,::erf
)
1202 exprtk_define_erf(long double,::erfl
)
1203 #undef exprtk_define_erf
1206 template <typename T
>
1207 inline T
erf_impl(T v
, real_type_tag
)
1209 #if defined(_MSC_VER) && (_MSC_VER < 1900)
1210 // Credits: Abramowitz & Stegun Equations 7.1.25-28
1211 static const T c
[] = {
1212 T( 1.26551223), T(1.00002368),
1213 T( 0.37409196), T(0.09678418),
1214 T(-0.18628806), T(0.27886807),
1215 T(-1.13520398), T(1.48851587),
1216 T(-0.82215223), T(0.17087277)
1219 const T t
= T(1) / (T(1) + T(0.5) * abs_impl(v
,real_type_tag()));
1221 T result
= T(1) - t
* std::exp((-v
* v
) -
1222 c
[0] + t
* (c
[1] + t
*
1223 (c
[2] + t
* (c
[3] + t
*
1224 (c
[4] + t
* (c
[5] + t
*
1225 (c
[6] + t
* (c
[7] + t
*
1226 (c
[8] + t
* (c
[9]))))))))));
1228 return (v
>= T(0)) ? result
: -result
;
1234 template <typename T
>
1235 inline T
erf_impl(T v
, int_type_tag
)
1237 return erf_impl(static_cast<double>(v
),real_type_tag());
1240 #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1241 #define exprtk_define_erfc(TT,impl) \
1242 inline TT erfc_impl(TT v) { return impl(v); } \
1244 exprtk_define_erfc( float,::erfcf)
1245 exprtk_define_erfc( double,::erfc
)
1246 exprtk_define_erfc(long double,::erfcl
)
1247 #undef exprtk_define_erfc
1250 template <typename T
>
1251 inline T
erfc_impl(T v
, real_type_tag
)
1253 #if defined(_MSC_VER) && (_MSC_VER < 1900)
1254 return T(1) - erf_impl(v
,real_type_tag());
1256 return erfc_impl(v
);
1260 template <typename T
>
1261 inline T
erfc_impl(T v
, int_type_tag
)
1263 return erfc_impl(static_cast<double>(v
),real_type_tag());
1266 template <typename T
>
1267 inline T
ncdf_impl(T v
, real_type_tag
)
1269 T cnd
= T(0.5) * (T(1) + erf_impl(
1270 abs_impl(v
,real_type_tag()) /
1271 T(numeric::constant::sqrt2
),real_type_tag()));
1272 return (v
< T(0)) ? (T(1) - cnd
) : cnd
;
1275 template <typename T
>
1276 inline T
ncdf_impl(T v
, int_type_tag
)
1278 return ncdf_impl(static_cast<double>(v
),real_type_tag());
1281 template <typename T
>
1282 inline T
sinc_impl(T v
, real_type_tag
)
1284 if (std::abs(v
) >= std::numeric_limits
<T
>::epsilon())
1285 return(std::sin(v
) / v
);
1290 template <typename T
>
1291 inline T
sinc_impl(T v
, int_type_tag
)
1293 return sinc_impl(static_cast<double>(v
),real_type_tag());
1296 template <typename T
> inline T
acos_impl(const T v
, real_type_tag
) { return std::acos (v
); }
1297 template <typename T
> inline T
acosh_impl(const T v
, real_type_tag
) { return std::log(v
+ std::sqrt((v
* v
) - T(1))); }
1298 template <typename T
> inline T
asin_impl(const T v
, real_type_tag
) { return std::asin (v
); }
1299 template <typename T
> inline T
asinh_impl(const T v
, real_type_tag
) { return std::log(v
+ std::sqrt((v
* v
) + T(1))); }
1300 template <typename T
> inline T
atan_impl(const T v
, real_type_tag
) { return std::atan (v
); }
1301 template <typename T
> inline T
atanh_impl(const T v
, real_type_tag
) { return (std::log(T(1) + v
) - std::log(T(1) - v
)) / T(2); }
1302 template <typename T
> inline T
ceil_impl(const T v
, real_type_tag
) { return std::ceil (v
); }
1303 template <typename T
> inline T
cos_impl(const T v
, real_type_tag
) { return std::cos (v
); }
1304 template <typename T
> inline T
cosh_impl(const T v
, real_type_tag
) { return std::cosh (v
); }
1305 template <typename T
> inline T
exp_impl(const T v
, real_type_tag
) { return std::exp (v
); }
1306 template <typename T
> inline T
floor_impl(const T v
, real_type_tag
) { return std::floor(v
); }
1307 template <typename T
> inline T
log_impl(const T v
, real_type_tag
) { return std::log (v
); }
1308 template <typename T
> inline T
log10_impl(const T v
, real_type_tag
) { return std::log10(v
); }
1309 template <typename T
> inline T
log2_impl(const T v
, real_type_tag
) { return std::log(v
)/T(numeric::constant::log2
); }
1310 template <typename T
> inline T
neg_impl(const T v
, real_type_tag
) { return -v
; }
1311 template <typename T
> inline T
pos_impl(const T v
, real_type_tag
) { return +v
; }
1312 template <typename T
> inline T
sin_impl(const T v
, real_type_tag
) { return std::sin (v
); }
1313 template <typename T
> inline T
sinh_impl(const T v
, real_type_tag
) { return std::sinh (v
); }
1314 template <typename T
> inline T
sqrt_impl(const T v
, real_type_tag
) { return std::sqrt (v
); }
1315 template <typename T
> inline T
tan_impl(const T v
, real_type_tag
) { return std::tan (v
); }
1316 template <typename T
> inline T
tanh_impl(const T v
, real_type_tag
) { return std::tanh (v
); }
1317 template <typename T
> inline T
cot_impl(const T v
, real_type_tag
) { return T(1) / std::tan(v
); }
1318 template <typename T
> inline T
sec_impl(const T v
, real_type_tag
) { return T(1) / std::cos(v
); }
1319 template <typename T
> inline T
csc_impl(const T v
, real_type_tag
) { return T(1) / std::sin(v
); }
1320 template <typename T
> inline T
r2d_impl(const T v
, real_type_tag
) { return (v
* T(numeric::constant::_180_pi
)); }
1321 template <typename T
> inline T
d2r_impl(const T v
, real_type_tag
) { return (v
* T(numeric::constant::pi_180
)); }
1322 template <typename T
> inline T
d2g_impl(const T v
, real_type_tag
) { return (v
* T(20.0/9.0)); }
1323 template <typename T
> inline T
g2d_impl(const T v
, real_type_tag
) { return (v
* T(9.0/20.0)); }
1324 template <typename T
> inline T
notl_impl(const T v
, real_type_tag
) { return (std::not_equal_to
<T
>()(T(0),v
) ? T(0) : T(1)); }
1325 template <typename T
> inline T
frac_impl(const T v
, real_type_tag
) { return (v
- static_cast<long long>(v
)); }
1326 template <typename T
> inline T
trunc_impl(const T v
, real_type_tag
) { return T(static_cast<long long>(v
)); }
1328 template <typename T
> inline T
const_pi_impl(real_type_tag
) { return T(numeric::constant::pi
); }
1329 template <typename T
> inline T
const_e_impl (real_type_tag
) { return T(numeric::constant::e
); }
1331 template <typename T
> inline T
abs_impl(const T v
, int_type_tag
) { return ((v
>= T(0)) ? v
: -v
); }
1332 template <typename T
> inline T
exp_impl(const T v
, int_type_tag
) { return std::exp (v
); }
1333 template <typename T
> inline T
log_impl(const T v
, int_type_tag
) { return std::log (v
); }
1334 template <typename T
> inline T
log10_impl(const T v
, int_type_tag
) { return std::log10(v
); }
1335 template <typename T
> inline T
log2_impl(const T v
, int_type_tag
) { return std::log(v
)/T(numeric::constant::log2
); }
1336 template <typename T
> inline T
neg_impl(const T v
, int_type_tag
) { return -v
; }
1337 template <typename T
> inline T
pos_impl(const T v
, int_type_tag
) { return +v
; }
1338 template <typename T
> inline T
ceil_impl(const T v
, int_type_tag
) { return v
; }
1339 template <typename T
> inline T
floor_impl(const T v
, int_type_tag
) { return v
; }
1340 template <typename T
> inline T
round_impl(const T v
, int_type_tag
) { return v
; }
1341 template <typename T
> inline T
notl_impl(const T v
, int_type_tag
) { return !v
; }
1342 template <typename T
> inline T
sqrt_impl(const T v
, int_type_tag
) { return std::sqrt (v
); }
1343 template <typename T
> inline T
frac_impl(const T
, int_type_tag
) { return T(0); }
1344 template <typename T
> inline T
trunc_impl(const T v
, int_type_tag
) { return v
; }
1345 template <typename T
> inline T
acos_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1346 template <typename T
> inline T
acosh_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1347 template <typename T
> inline T
asin_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1348 template <typename T
> inline T
asinh_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1349 template <typename T
> inline T
atan_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1350 template <typename T
> inline T
atanh_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1351 template <typename T
> inline T
cos_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1352 template <typename T
> inline T
cosh_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1353 template <typename T
> inline T
sin_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1354 template <typename T
> inline T
sinh_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1355 template <typename T
> inline T
tan_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1356 template <typename T
> inline T
tanh_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1357 template <typename T
> inline T
cot_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1358 template <typename T
> inline T
sec_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1359 template <typename T
> inline T
csc_impl(const T
, int_type_tag
) { return std::numeric_limits
<T
>::quiet_NaN(); }
1361 template <typename T
>
1362 inline bool is_integer_impl(const T
& v
, real_type_tag
)
1364 return std::equal_to
<T
>()(T(0),std::fmod(v
,T(1)));
1367 template <typename T
>
1368 inline bool is_integer_impl(const T
&, int_type_tag
)
1374 template <typename Type
>
1375 struct numeric_info
{ enum { length
= 0, size
= 32, bound_length
= 0, min_exp
= 0, max_exp
= 0 }; };
1377 template<> struct numeric_info
<int> { enum { length
= 10, size
= 16, bound_length
= 9}; };
1378 template<> struct numeric_info
<float> { enum { min_exp
= -38, max_exp
= +38}; };
1379 template<> struct numeric_info
<double> { enum { min_exp
= -308, max_exp
= +308}; };
1380 template<> struct numeric_info
<long double> { enum { min_exp
= -308, max_exp
= +308}; };
1382 template <typename T
>
1383 inline int to_int32(const T v
)
1385 const typename
details::number_type
<T
>::type num_type
;
1386 return to_int32_impl(v
, num_type
);
1389 template <typename T
>
1390 inline _int64_t
to_int64(const T v
)
1392 const typename
details::number_type
<T
>::type num_type
;
1393 return to_int64_impl(v
, num_type
);
1396 template <typename T
>
1397 inline bool is_nan(const T v
)
1399 const typename
details::number_type
<T
>::type num_type
;
1400 return is_nan_impl(v
, num_type
);
1403 template <typename T
>
1404 inline T
min(const T v0
, const T v1
)
1406 const typename
details::number_type
<T
>::type num_type
;
1407 return min_impl(v0
, v1
, num_type
);
1410 template <typename T
>
1411 inline T
max(const T v0
, const T v1
)
1413 const typename
details::number_type
<T
>::type num_type
;
1414 return max_impl(v0
, v1
, num_type
);
1417 template <typename T
>
1418 inline T
equal(const T v0
, const T v1
)
1420 const typename
details::number_type
<T
>::type num_type
;
1421 return equal_impl(v0
, v1
, num_type
);
1424 template <typename T
>
1425 inline T
nequal(const T v0
, const T v1
)
1427 const typename
details::number_type
<T
>::type num_type
;
1428 return nequal_impl(v0
, v1
, num_type
);
1431 template <typename T
>
1432 inline T
modulus(const T v0
, const T v1
)
1434 const typename
details::number_type
<T
>::type num_type
;
1435 return modulus_impl(v0
, v1
, num_type
);
1438 template <typename T
>
1439 inline T
pow(const T v0
, const T v1
)
1441 const typename
details::number_type
<T
>::type num_type
;
1442 return pow_impl(v0
, v1
, num_type
);
1445 template <typename T
>
1446 inline T
logn(const T v0
, const T v1
)
1448 const typename
details::number_type
<T
>::type num_type
;
1449 return logn_impl(v0
, v1
, num_type
);
1452 template <typename T
>
1453 inline T
root(const T v0
, const T v1
)
1455 const typename
details::number_type
<T
>::type num_type
;
1456 return root_impl(v0
, v1
, num_type
);
1459 template <typename T
>
1460 inline T
roundn(const T v0
, const T v1
)
1462 const typename
details::number_type
<T
>::type num_type
;
1463 return roundn_impl(v0
, v1
, num_type
);
1466 template <typename T
>
1467 inline T
hypot(const T v0
, const T v1
)
1469 const typename
details::number_type
<T
>::type num_type
;
1470 return hypot_impl(v0
, v1
, num_type
);
1473 template <typename T
>
1474 inline T
atan2(const T v0
, const T v1
)
1476 const typename
details::number_type
<T
>::type num_type
;
1477 return atan2_impl(v0
, v1
, num_type
);
1480 template <typename T
>
1481 inline T
shr(const T v0
, const T v1
)
1483 const typename
details::number_type
<T
>::type num_type
;
1484 return shr_impl(v0
, v1
, num_type
);
1487 template <typename T
>
1488 inline T
shl(const T v0
, const T v1
)
1490 const typename
details::number_type
<T
>::type num_type
;
1491 return shl_impl(v0
, v1
, num_type
);
1494 template <typename T
>
1495 inline T
and_opr(const T v0
, const T v1
)
1497 const typename
details::number_type
<T
>::type num_type
;
1498 return and_impl(v0
, v1
, num_type
);
1501 template <typename T
>
1502 inline T
nand_opr(const T v0
, const T v1
)
1504 const typename
details::number_type
<T
>::type num_type
;
1505 return nand_impl(v0
, v1
, num_type
);
1508 template <typename T
>
1509 inline T
or_opr(const T v0
, const T v1
)
1511 const typename
details::number_type
<T
>::type num_type
;
1512 return or_impl(v0
, v1
, num_type
);
1515 template <typename T
>
1516 inline T
nor_opr(const T v0
, const T v1
)
1518 const typename
details::number_type
<T
>::type num_type
;
1519 return nor_impl(v0
, v1
, num_type
);
1522 template <typename T
>
1523 inline T
xor_opr(const T v0
, const T v1
)
1525 const typename
details::number_type
<T
>::type num_type
;
1526 return xor_impl(v0
, v1
, num_type
);
1529 template <typename T
>
1530 inline T
xnor_opr(const T v0
, const T v1
)
1532 const typename
details::number_type
<T
>::type num_type
;
1533 return xnor_impl(v0
, v1
, num_type
);
1536 template <typename T
>
1537 inline bool is_integer(const T v
)
1539 const typename
details::number_type
<T
>::type num_type
;
1540 return is_integer_impl(v
, num_type
);
1543 template <typename T
, unsigned int N
>
1546 static inline T
result(T v
)
1567 template <typename T
> struct fast_exp
<T
,10> { static inline T
result(T v
) { T v_5
= fast_exp
<T
,5>::result(v
); return v_5
* v_5
; } };
1568 template <typename T
> struct fast_exp
<T
, 9> { static inline T
result(T v
) { return fast_exp
<T
,8>::result(v
) * v
; } };
1569 template <typename T
> struct fast_exp
<T
, 8> { static inline T
result(T v
) { T v_4
= fast_exp
<T
,4>::result(v
); return v_4
* v_4
; } };
1570 template <typename T
> struct fast_exp
<T
, 7> { static inline T
result(T v
) { return fast_exp
<T
,6>::result(v
) * v
; } };
1571 template <typename T
> struct fast_exp
<T
, 6> { static inline T
result(T v
) { T v_3
= fast_exp
<T
,3>::result(v
); return v_3
* v_3
; } };
1572 template <typename T
> struct fast_exp
<T
, 5> { static inline T
result(T v
) { return fast_exp
<T
,4>::result(v
) * v
; } };
1573 template <typename T
> struct fast_exp
<T
, 4> { static inline T
result(T v
) { T v_2
= v
* v
; return v_2
* v_2
; } };
1574 template <typename T
> struct fast_exp
<T
, 3> { static inline T
result(T v
) { return v
* v
* v
; } };
1575 template <typename T
> struct fast_exp
<T
, 2> { static inline T
result(T v
) { return v
* v
; } };
1576 template <typename T
> struct fast_exp
<T
, 1> { static inline T
result(T v
) { return v
; } };
1577 template <typename T
> struct fast_exp
<T
, 0> { static inline T
result(T
) { return T(1); } };
1579 #define exprtk_define_unary_function(FunctionName) \
1580 template <typename T> \
1581 inline T FunctionName (const T v) \
1583 const typename details::number_type<T>::type num_type; \
1584 return FunctionName##_impl(v,num_type); \
1587 exprtk_define_unary_function(abs )
1588 exprtk_define_unary_function(acos
)
1589 exprtk_define_unary_function(acosh
)
1590 exprtk_define_unary_function(asin
)
1591 exprtk_define_unary_function(asinh
)
1592 exprtk_define_unary_function(atan
)
1593 exprtk_define_unary_function(atanh
)
1594 exprtk_define_unary_function(ceil
)
1595 exprtk_define_unary_function(cos
)
1596 exprtk_define_unary_function(cosh
)
1597 exprtk_define_unary_function(exp
)
1598 exprtk_define_unary_function(expm1
)
1599 exprtk_define_unary_function(floor
)
1600 exprtk_define_unary_function(log
)
1601 exprtk_define_unary_function(log10
)
1602 exprtk_define_unary_function(log2
)
1603 exprtk_define_unary_function(log1p
)
1604 exprtk_define_unary_function(neg
)
1605 exprtk_define_unary_function(pos
)
1606 exprtk_define_unary_function(round
)
1607 exprtk_define_unary_function(sin
)
1608 exprtk_define_unary_function(sinc
)
1609 exprtk_define_unary_function(sinh
)
1610 exprtk_define_unary_function(sqrt
)
1611 exprtk_define_unary_function(tan
)
1612 exprtk_define_unary_function(tanh
)
1613 exprtk_define_unary_function(cot
)
1614 exprtk_define_unary_function(sec
)
1615 exprtk_define_unary_function(csc
)
1616 exprtk_define_unary_function(r2d
)
1617 exprtk_define_unary_function(d2r
)
1618 exprtk_define_unary_function(d2g
)
1619 exprtk_define_unary_function(g2d
)
1620 exprtk_define_unary_function(notl
)
1621 exprtk_define_unary_function(sgn
)
1622 exprtk_define_unary_function(erf
)
1623 exprtk_define_unary_function(erfc
)
1624 exprtk_define_unary_function(ncdf
)
1625 exprtk_define_unary_function(frac
)
1626 exprtk_define_unary_function(trunc
)
1627 #undef exprtk_define_unary_function
1630 template <typename T
>
1631 inline T
compute_pow10(T d
, const int exponent
)
1633 static const double fract10
[] =
1636 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010,
1637 1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020,
1638 1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030,
1639 1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040,
1640 1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050,
1641 1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060,
1642 1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070,
1643 1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080,
1644 1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090,
1645 1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100,
1646 1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110,
1647 1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120,
1648 1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130,
1649 1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140,
1650 1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150,
1651 1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160,
1652 1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170,
1653 1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180,
1654 1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190,
1655 1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200,
1656 1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210,
1657 1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220,
1658 1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230,
1659 1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240,
1660 1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250,
1661 1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260,
1662 1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270,
1663 1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280,
1664 1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290,
1665 1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300,
1666 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
1669 static const int fract10_size
= static_cast<int>(sizeof(fract10
) / sizeof(double));
1671 const int e
= std::abs(exponent
);
1673 if (exponent
>= std::numeric_limits
<T
>::min_exponent10
)
1675 if (e
< fract10_size
)
1678 return T(d
* fract10
[e
]);
1680 return T(d
/ fract10
[e
]);
1683 return T(d
* std::pow(10.0, 10.0 * exponent
));
1687 d
/= T(fract10
[ -std::numeric_limits
<T
>::min_exponent10
]);
1688 return T(d
/ fract10
[-exponent
+ std::numeric_limits
<T
>::min_exponent10
]);
1692 template <typename Iterator
, typename T
>
1693 inline bool string_to_type_converter_impl_ref(Iterator
& itr
, const Iterator end
, T
& result
)
1698 const bool negative
= ('-' == (*itr
));
1700 if (negative
|| ('+' == (*itr
)))
1706 static const uchar_t zero
= static_cast<uchar_t
>('0');
1708 while ((end
!= itr
) && (zero
== (*itr
))) ++itr
;
1710 bool return_result
= true;
1711 unsigned int digit
= 0;
1712 const std::size_t length
= static_cast<std::size_t>(std::distance(itr
,end
));
1716 exprtk_disable_fallthrough_begin
1719 #ifdef exprtk_use_lut
1721 #define exprtk_process_digit \
1722 if ((digit = details::digit_table[(int)*itr++]) < 10) \
1723 result = result * 10 + (digit); \
1726 return_result = false; \
1732 #define exprtk_process_digit \
1733 if ((digit = (*itr++ - zero)) < 10) \
1734 result = result * T(10) + digit; \
1737 return_result = false; \
1743 case 4 : exprtk_process_digit
1744 case 3 : exprtk_process_digit
1745 case 2 : exprtk_process_digit
1746 case 1 : if ((digit
= (*itr
- zero
))>= 10) { digit
= 0; return_result
= false; }
1748 #undef exprtk_process_digit
1750 exprtk_disable_fallthrough_end
1753 return_result
= false;
1755 if (length
&& return_result
)
1757 result
= result
* 10 + static_cast<T
>(digit
);
1761 result
= negative
? -result
: result
;
1762 return return_result
;
1765 template <typename Iterator
, typename T
>
1766 static inline bool parse_nan(Iterator
& itr
, const Iterator end
, T
& t
)
1768 typedef typename
std::iterator_traits
<Iterator
>::value_type type
;
1770 static const std::size_t nan_length
= 3;
1772 if (std::distance(itr
,end
) != static_cast<int>(nan_length
))
1775 if (static_cast<type
>('n') == (*itr
))
1778 (static_cast<type
>('a') != *(itr
+ 1)) ||
1779 (static_cast<type
>('n') != *(itr
+ 2))
1786 (static_cast<type
>('A') != *(itr
+ 1)) ||
1787 (static_cast<type
>('N') != *(itr
+ 2))
1793 t
= std::numeric_limits
<T
>::quiet_NaN();
1798 template <typename Iterator
, typename T
>
1799 static inline bool parse_inf(Iterator
& itr
, const Iterator end
, T
& t
, bool negative
)
1801 static const char_t inf_uc
[] = "INFINITY";
1802 static const char_t inf_lc
[] = "infinity";
1803 static const std::size_t inf_length
= 8;
1805 const std::size_t length
= static_cast<std::size_t>(std::distance(itr
,end
));
1807 if ((3 != length
) && (inf_length
!= length
))
1810 char_cptr inf_itr
= ('i' == (*itr
)) ? inf_lc
: inf_uc
;
1814 if (*inf_itr
== static_cast<char>(*itr
))
1825 t
= -std::numeric_limits
<T
>::infinity();
1827 t
= std::numeric_limits
<T
>::infinity();
1832 template <typename Iterator
, typename T
>
1833 inline bool string_to_real(Iterator
& itr_external
, const Iterator end
, T
& t
, numeric::details::real_type_tag
)
1835 if (end
== itr_external
) return false;
1837 Iterator itr
= itr_external
;
1841 const bool negative
= ('-' == (*itr
));
1843 if (negative
|| '+' == (*itr
))
1849 bool instate
= false;
1851 static const char_t zero
= static_cast<uchar_t
>('0');
1853 #define parse_digit_1(d) \
1854 if ((digit = (*itr - zero)) < 10) \
1855 { d = d * T(10) + digit; } \
1858 if (end == ++itr) break; \
1860 #define parse_digit_2(d) \
1861 if ((digit = (*itr - zero)) < 10) \
1862 { d = d * T(10) + digit; } \
1868 const Iterator curr
= itr
;
1870 while ((end
!= itr
) && (zero
== (*itr
))) ++itr
;
1876 // Note: For 'physical' superscalar architectures it
1877 // is advised that the following loop be: 4xPD1 and 1xPD2
1878 #ifdef exprtk_enable_superscalar
1887 if (curr
!= itr
) instate
= true;
1896 const Iterator curr
= ++itr
;
1902 #ifdef exprtk_enable_superscalar
1903 parse_digit_1(tmp_d
)
1904 parse_digit_1(tmp_d
)
1905 parse_digit_1(tmp_d
)
1907 parse_digit_1(tmp_d
)
1908 parse_digit_1(tmp_d
)
1909 parse_digit_2(tmp_d
)
1915 d
+= compute_pow10(tmp_d
,static_cast<int>(-std::distance(curr
,itr
)));
1918 #undef parse_digit_1
1919 #undef parse_digit_2
1924 typename
std::iterator_traits
<Iterator
>::value_type c
= (*itr
);
1926 if (('e' == c
) || ('E' == c
))
1930 if (!details::string_to_type_converter_impl_ref(++itr
, end
, exp
))
1943 if (('f' == c
) || ('F' == c
) || ('l' == c
) || ('L' == c
))
1949 else if (('I' <= (*itr
)) && ((*itr
) <= 'n'))
1951 if (('i' == (*itr
)) || ('I' == (*itr
)))
1953 return parse_inf(itr
, end
, t
, negative
);
1955 else if (('n' == (*itr
)) || ('N' == (*itr
)))
1957 return parse_nan(itr
, end
, t
);
1965 else if (('I' <= (*itr
)) && ((*itr
) <= 'n'))
1967 if (('i' == (*itr
)) || ('I' == (*itr
)))
1969 return parse_inf(itr
, end
, t
, negative
);
1971 else if (('n' == (*itr
)) || ('N' == (*itr
)))
1973 return parse_nan(itr
, end
, t
);
1984 if ((end
!= itr
) || (!instate
))
1987 d
= compute_pow10(d
,exponent
);
1989 t
= static_cast<T
>((negative
) ? -d
: d
);
1993 template <typename T
>
1994 inline bool string_to_real(const std::string
& s
, T
& t
)
1996 const typename
numeric::details::number_type
<T
>::type num_type
;
1998 char_cptr begin
= s
.data();
1999 char_cptr end
= s
.data() + s
.size();
2001 return string_to_real(begin
, end
, t
, num_type
);
2004 template <typename T
>
2008 Note: The following definitions for Type, may require tweaking
2009 based on the compiler and target architecture. The benchmark
2010 should provide enough information to make the right choice.
2013 //typedef const T Type;
2014 typedef const T
& Type
;
2016 typedef T (*qfunc_t
)(Type t0
, Type t1
, Type t2
, Type t3
);
2017 typedef T (*tfunc_t
)(Type t0
, Type t1
, Type t2
);
2018 typedef T (*bfunc_t
)(Type t0
, Type t1
);
2019 typedef T (*ufunc_t
)(Type t0
);
2022 } // namespace details
2030 e_none
= 0, e_error
= 1, e_err_symbol
= 2,
2031 e_err_number
= 3, e_err_string
= 4, e_err_sfunc
= 5,
2032 e_eof
= 6, e_number
= 7, e_symbol
= 8,
2033 e_string
= 9, e_assign
= 10, e_addass
= 11,
2034 e_subass
= 12, e_mulass
= 13, e_divass
= 14,
2035 e_modass
= 15, e_shr
= 16, e_shl
= 17,
2036 e_lte
= 18, e_ne
= 19, e_gte
= 20,
2037 e_swap
= 21, e_lt
= '<', e_gt
= '>',
2038 e_eq
= '=', e_rbracket
= ')', e_lbracket
= '(',
2039 e_rsqrbracket
= ']', e_lsqrbracket
= '[', e_rcrlbracket
= '}',
2040 e_lcrlbracket
= '{', e_comma
= ',', e_add
= '+',
2041 e_sub
= '-', e_div
= '/', e_mul
= '*',
2042 e_mod
= '%', e_pow
= '^', e_colon
= ':',
2049 position(std::numeric_limits
<std::size_t>::max())
2056 position
= std::numeric_limits
<std::size_t>::max();
2059 template <typename Iterator
>
2060 inline token
& set_operator(const token_type tt
,
2061 const Iterator begin
, const Iterator end
,
2062 const Iterator base_begin
= Iterator(0))
2065 value
.assign(begin
,end
);
2067 position
= static_cast<std::size_t>(std::distance(base_begin
,begin
));
2071 template <typename Iterator
>
2072 inline token
& set_symbol(const Iterator begin
, const Iterator end
, const Iterator base_begin
= Iterator(0))
2075 value
.assign(begin
,end
);
2077 position
= static_cast<std::size_t>(std::distance(base_begin
,begin
));
2081 template <typename Iterator
>
2082 inline token
& set_numeric(const Iterator begin
, const Iterator end
, const Iterator base_begin
= Iterator(0))
2085 value
.assign(begin
,end
);
2087 position
= static_cast<std::size_t>(std::distance(base_begin
,begin
));
2091 template <typename Iterator
>
2092 inline token
& set_string(const Iterator begin
, const Iterator end
, const Iterator base_begin
= Iterator(0))
2095 value
.assign(begin
,end
);
2097 position
= static_cast<std::size_t>(std::distance(base_begin
,begin
));
2101 inline token
& set_string(const std::string
& s
, const std::size_t p
)
2109 template <typename Iterator
>
2110 inline token
& set_error(const token_type et
,
2111 const Iterator begin
, const Iterator end
,
2112 const Iterator base_begin
= Iterator(0))
2116 (e_err_symbol
== et
) ||
2117 (e_err_number
== et
) ||
2118 (e_err_string
== et
) ||
2127 value
.assign(begin
,end
);
2130 position
= static_cast<std::size_t>(std::distance(base_begin
,begin
));
2135 static inline std::string
to_str(token_type t
)
2139 case e_none
: return "NONE";
2140 case e_error
: return "ERROR";
2141 case e_err_symbol
: return "ERROR_SYMBOL";
2142 case e_err_number
: return "ERROR_NUMBER";
2143 case e_err_string
: return "ERROR_STRING";
2144 case e_eof
: return "EOF";
2145 case e_number
: return "NUMBER";
2146 case e_symbol
: return "SYMBOL";
2147 case e_string
: return "STRING";
2148 case e_assign
: return ":=";
2149 case e_addass
: return "+=";
2150 case e_subass
: return "-=";
2151 case e_mulass
: return "*=";
2152 case e_divass
: return "/=";
2153 case e_modass
: return "%=";
2154 case e_shr
: return ">>";
2155 case e_shl
: return "<<";
2156 case e_lte
: return "<=";
2157 case e_ne
: return "!=";
2158 case e_gte
: return ">=";
2159 case e_lt
: return "<";
2160 case e_gt
: return ">";
2161 case e_eq
: return "=";
2162 case e_rbracket
: return ")";
2163 case e_lbracket
: return "(";
2164 case e_rsqrbracket
: return "]";
2165 case e_lsqrbracket
: return "[";
2166 case e_rcrlbracket
: return "}";
2167 case e_lcrlbracket
: return "{";
2168 case e_comma
: return ",";
2169 case e_add
: return "+";
2170 case e_sub
: return "-";
2171 case e_div
: return "/";
2172 case e_mul
: return "*";
2173 case e_mod
: return "%";
2174 case e_pow
: return "^";
2175 case e_colon
: return ":";
2176 case e_ternary
: return "?";
2177 case e_swap
: return "<=>";
2178 default : return "UNKNOWN";
2182 inline bool is_error() const
2185 (e_error
== type
) ||
2186 (e_err_symbol
== type
) ||
2187 (e_err_number
== type
) ||
2188 (e_err_string
== type
) ||
2189 (e_err_sfunc
== type
)
2195 std::size_t position
;
2202 typedef token token_t
;
2203 typedef std::vector
<token_t
> token_list_t
;
2204 typedef std::vector
<token_t
>::iterator token_list_itr_t
;
2205 typedef details::char_t char_t
;
2220 token_list_
.clear();
2221 token_itr_
= token_list_
.end();
2222 store_token_itr_
= token_list_
.end();
2225 inline bool process(const std::string
& str
)
2227 base_itr_
= str
.data();
2228 s_itr_
= str
.data();
2229 s_end_
= str
.data() + str
.size();
2231 eof_token_
.set_operator(token_t::e_eof
,s_end_
,s_end_
,base_itr_
);
2232 token_list_
.clear();
2234 while (!is_end(s_itr_
))
2238 if (!token_list_
.empty() && token_list_
.back().is_error())
2245 inline bool empty() const
2247 return token_list_
.empty();
2250 inline std::size_t size() const
2252 return token_list_
.size();
2257 token_itr_
= token_list_
.begin();
2258 store_token_itr_
= token_list_
.begin();
2263 store_token_itr_
= token_itr_
;
2266 inline void restore()
2268 token_itr_
= store_token_itr_
;
2271 inline token_t
& next_token()
2273 if (token_list_
.end() != token_itr_
)
2275 return *token_itr_
++;
2281 inline token_t
& peek_next_token()
2283 if (token_list_
.end() != token_itr_
)
2291 inline token_t
& operator[](const std::size_t& index
)
2293 if (index
< token_list_
.size())
2294 return token_list_
[index
];
2299 inline token_t
operator[](const std::size_t& index
) const
2301 if (index
< token_list_
.size())
2302 return token_list_
[index
];
2307 inline bool finished() const
2309 return (token_list_
.end() == token_itr_
);
2312 inline void insert_front(token_t::token_type tk_type
)
2315 !token_list_
.empty() &&
2316 (token_list_
.end() != token_itr_
)
2319 token_t t
= *token_itr_
;
2322 token_itr_
= token_list_
.insert(token_itr_
,t
);
2326 inline std::string
substr(const std::size_t& begin
, const std::size_t& end
)
2328 const details::char_cptr begin_itr
= ((base_itr_
+ begin
) < s_end_
) ? (base_itr_
+ begin
) : s_end_
;
2329 const details::char_cptr end_itr
= ((base_itr_
+ end
) < s_end_
) ? (base_itr_
+ end
) : s_end_
;
2331 return std::string(begin_itr
,end_itr
);
2334 inline std::string
remaining() const
2338 else if (token_list_
.begin() != token_itr_
)
2339 return std::string(base_itr_
+ (token_itr_
- 1)->position
, s_end_
);
2341 return std::string(base_itr_
+ token_itr_
->position
, s_end_
);
2346 inline bool is_end(details::char_cptr itr
)
2348 return (s_end_
== itr
);
2351 inline bool is_comment_start(details::char_cptr itr
)
2353 #ifndef exprtk_disable_comments
2354 const char_t c0
= *(itr
+ 0);
2355 const char_t c1
= *(itr
+ 1);
2359 else if (!is_end(itr
+ 1))
2361 if (('/' == c0
) && ('/' == c1
)) return true;
2362 if (('/' == c0
) && ('*' == c1
)) return true;
2368 inline void skip_whitespace()
2370 while (!is_end(s_itr_
) && details::is_whitespace(*s_itr_
))
2376 inline void skip_comments()
2378 #ifndef exprtk_disable_comments
2379 // The following comment styles are supported:
2385 static inline bool comment_start(const char_t c0
, const char_t c1
, int& mode
, int& incr
)
2388 if ('#' == c0
) { mode
= 1; incr
= 1; }
2391 if ('/' == c1
) { mode
= 1; incr
= 2; }
2392 else if ('*' == c1
) { mode
= 2; incr
= 2; }
2397 static inline bool comment_end(const char_t c0
, const char_t c1
, int& mode
)
2400 ((1 == mode
) && ('\n' == c0
)) ||
2401 ((2 == mode
) && ( '*' == c0
) && ('/' == c1
))
2417 else if (!test::comment_start(*s_itr_
, *(s_itr_
+ 1), mode
, increment
))
2420 details::char_cptr cmt_start
= s_itr_
;
2422 s_itr_
+= increment
;
2424 while (!is_end(s_itr_
))
2426 if ((1 == mode
) && test::comment_end(*s_itr_
, 0, mode
))
2434 if (!is_end((s_itr_
+ 1)) && test::comment_end(*s_itr_
, *(s_itr_
+ 1), mode
))
2447 t
.set_error(token::e_error
, cmt_start
, cmt_start
+ mode
, base_itr_
);
2448 token_list_
.push_back(t
);
2453 inline void scan_token()
2455 if (details::is_whitespace(*s_itr_
))
2460 else if (is_comment_start(s_itr_
))
2465 else if (details::is_operator_char(*s_itr_
))
2470 else if (details::is_letter(*s_itr_
))
2475 else if (details::is_digit((*s_itr_
)) || ('.' == (*s_itr_
)))
2480 else if ('$' == (*s_itr_
))
2482 scan_special_function();
2485 #ifndef exprtk_disable_string_capabilities
2486 else if ('\'' == (*s_itr_
))
2492 else if ('~' == (*s_itr_
))
2495 t
.set_symbol(s_itr_
, s_itr_
+ 1, base_itr_
);
2496 token_list_
.push_back(t
);
2503 t
.set_error(token::e_error
, s_itr_
, s_itr_
+ 2, base_itr_
);
2504 token_list_
.push_back(t
);
2509 inline void scan_operator()
2513 const char_t c0
= s_itr_
[0];
2515 if (!is_end(s_itr_
+ 1))
2517 const char_t c1
= s_itr_
[1];
2519 if (!is_end(s_itr_
+ 2))
2521 const char_t c2
= s_itr_
[2];
2523 if ((c0
== '<') && (c1
== '=') && (c2
== '>'))
2525 t
.set_operator(token_t::e_swap
, s_itr_
, s_itr_
+ 3, base_itr_
);
2526 token_list_
.push_back(t
);
2532 token_t::token_type ttype
= token_t::e_none
;
2534 if ((c0
== '<') && (c1
== '=')) ttype
= token_t::e_lte
;
2535 else if ((c0
== '>') && (c1
== '=')) ttype
= token_t::e_gte
;
2536 else if ((c0
== '<') && (c1
== '>')) ttype
= token_t::e_ne
;
2537 else if ((c0
== '!') && (c1
== '=')) ttype
= token_t::e_ne
;
2538 else if ((c0
== '=') && (c1
== '=')) ttype
= token_t::e_eq
;
2539 else if ((c0
== ':') && (c1
== '=')) ttype
= token_t::e_assign
;
2540 else if ((c0
== '<') && (c1
== '<')) ttype
= token_t::e_shl
;
2541 else if ((c0
== '>') && (c1
== '>')) ttype
= token_t::e_shr
;
2542 else if ((c0
== '+') && (c1
== '=')) ttype
= token_t::e_addass
;
2543 else if ((c0
== '-') && (c1
== '=')) ttype
= token_t::e_subass
;
2544 else if ((c0
== '*') && (c1
== '=')) ttype
= token_t::e_mulass
;
2545 else if ((c0
== '/') && (c1
== '=')) ttype
= token_t::e_divass
;
2546 else if ((c0
== '%') && (c1
== '=')) ttype
= token_t::e_modass
;
2548 if (token_t::e_none
!= ttype
)
2550 t
.set_operator(ttype
, s_itr_
, s_itr_
+ 2, base_itr_
);
2551 token_list_
.push_back(t
);
2558 t
.set_operator(token_t::e_lt
, s_itr_
, s_itr_
+ 1, base_itr_
);
2560 t
.set_operator(token_t::e_gt
, s_itr_
, s_itr_
+ 1, base_itr_
);
2562 t
.set_operator(token_t::e_eof
, s_itr_
, s_itr_
+ 1, base_itr_
);
2564 t
.set_symbol(s_itr_
, s_itr_
+ 1, base_itr_
);
2566 t
.set_symbol(s_itr_
, s_itr_
+ 1, base_itr_
);
2568 t
.set_operator(token_t::token_type(c0
), s_itr_
, s_itr_
+ 1, base_itr_
);
2570 token_list_
.push_back(t
);
2574 inline void scan_symbol()
2576 details::char_cptr initial_itr
= s_itr_
;
2578 while (!is_end(s_itr_
))
2580 if (!details::is_letter_or_digit(*s_itr_
) && ('_' != (*s_itr_
)))
2582 if ('.' != (*s_itr_
))
2585 Permit symbols that contain a 'dot'
2586 Allowed : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123
2587 Disallowed: .abc, abc.<white-space>, abc.<eof>, abc.<operator +,-,*,/...>
2590 (s_itr_
!= initial_itr
) &&
2591 !is_end(s_itr_
+ 1) &&
2592 !details::is_letter_or_digit(*(s_itr_
+ 1)) &&
2593 ('_' != (*(s_itr_
+ 1)))
2602 t
.set_symbol(initial_itr
,s_itr_
,base_itr_
);
2603 token_list_
.push_back(t
);
2606 inline void scan_number()
2609 Attempt to match a valid numeric value in one of the following formats:
2627 details::char_cptr initial_itr
= s_itr_
;
2628 bool dot_found
= false;
2629 bool e_found
= false;
2630 bool post_e_sign_found
= false;
2631 bool post_e_digit_found
= false;
2634 while (!is_end(s_itr_
))
2636 if ('.' == (*s_itr_
))
2640 t
.set_error(token::e_err_number
, initial_itr
, s_itr_
, base_itr_
);
2641 token_list_
.push_back(t
);
2650 else if ('e' == std::tolower(*s_itr_
))
2652 const char_t
& c
= *(s_itr_
+ 1);
2654 if (is_end(s_itr_
+ 1))
2656 t
.set_error(token::e_err_number
, initial_itr
, s_itr_
, base_itr_
);
2657 token_list_
.push_back(t
);
2664 !details::is_digit(c
)
2667 t
.set_error(token::e_err_number
, initial_itr
, s_itr_
, base_itr_
);
2668 token_list_
.push_back(t
);
2678 else if (e_found
&& details::is_sign(*s_itr_
) && !post_e_digit_found
)
2680 if (post_e_sign_found
)
2682 t
.set_error(token::e_err_number
, initial_itr
, s_itr_
, base_itr_
);
2683 token_list_
.push_back(t
);
2688 post_e_sign_found
= true;
2693 else if (e_found
&& details::is_digit(*s_itr_
))
2695 post_e_digit_found
= true;
2700 else if (('.' != (*s_itr_
)) && !details::is_digit(*s_itr_
))
2706 t
.set_numeric(initial_itr
, s_itr_
, base_itr_
);
2707 token_list_
.push_back(t
);
2712 inline void scan_special_function()
2714 details::char_cptr initial_itr
= s_itr_
;
2717 // $fdd(x,x,x) = at least 11 chars
2718 if (std::distance(s_itr_
,s_end_
) < 11)
2720 t
.set_error(token::e_err_sfunc
, initial_itr
, s_itr_
, base_itr_
);
2721 token_list_
.push_back(t
);
2727 !(('$' == *s_itr_
) &&
2728 (details::imatch ('f',*(s_itr_
+ 1))) &&
2729 (details::is_digit(*(s_itr_
+ 2))) &&
2730 (details::is_digit(*(s_itr_
+ 3))))
2733 t
.set_error(token::e_err_sfunc
, initial_itr
, s_itr_
, base_itr_
);
2734 token_list_
.push_back(t
);
2739 s_itr_
+= 4; // $fdd = 4chars
2741 t
.set_symbol(initial_itr
, s_itr_
, base_itr_
);
2742 token_list_
.push_back(t
);
2747 #ifndef exprtk_disable_string_capabilities
2748 inline void scan_string()
2750 details::char_cptr initial_itr
= s_itr_
+ 1;
2753 if (std::distance(s_itr_
,s_end_
) < 2)
2755 t
.set_error(token::e_err_string
, s_itr_
, s_end_
, base_itr_
);
2756 token_list_
.push_back(t
);
2762 bool escaped_found
= false;
2763 bool escaped
= false;
2765 while (!is_end(s_itr_
))
2767 if (!escaped
&& ('\\' == *s_itr_
))
2769 escaped_found
= true;
2777 if ('\'' == *s_itr_
)
2782 if (!is_end(s_itr_
) && ('0' == *(s_itr_
)))
2785 Note: The following 'awkward' conditional is
2786 due to various broken msvc compilers.
2788 #if defined(_MSC_VER) && (_MSC_VER == 1600)
2789 const bool within_range
= !is_end(s_itr_
+ 2) &&
2790 !is_end(s_itr_
+ 3) ;
2792 const bool within_range
= !is_end(s_itr_
+ 1) &&
2793 !is_end(s_itr_
+ 2) &&
2794 !is_end(s_itr_
+ 3) ;
2797 const bool x_seperator
= ('x' == *(s_itr_
+ 1)) ||
2798 ('X' == *(s_itr_
+ 1)) ;
2800 const bool both_digits
= details::is_hex_digit(*(s_itr_
+ 2)) &&
2801 details::is_hex_digit(*(s_itr_
+ 3)) ;
2803 if (!within_range
|| !x_seperator
|| !both_digits
)
2805 t
.set_error(token::e_err_string
, initial_itr
, s_itr_
, base_itr_
);
2806 token_list_
.push_back(t
);
2822 t
.set_error(token::e_err_string
, initial_itr
, s_itr_
, base_itr_
);
2823 token_list_
.push_back(t
);
2829 t
.set_string(initial_itr
, s_itr_
, base_itr_
);
2832 std::string
parsed_string(initial_itr
,s_itr_
);
2834 details::cleanup_escapes(parsed_string
);
2838 static_cast<std::size_t>(std::distance(base_itr_
,initial_itr
)));
2841 token_list_
.push_back(t
);
2850 token_list_t token_list_
;
2851 token_list_itr_t token_itr_
;
2852 token_list_itr_t store_token_itr_
;
2854 details::char_cptr base_itr_
;
2855 details::char_cptr s_itr_
;
2856 details::char_cptr s_end_
;
2858 friend class token_scanner
;
2859 friend class token_modifier
;
2860 friend class token_inserter
;
2861 friend class token_joiner
;
2864 class helper_interface
2868 virtual void init() { }
2869 virtual void reset() { }
2870 virtual bool result() { return true; }
2871 virtual std::size_t process(generator
&) { return 0; }
2872 virtual ~helper_interface() { }
2875 class token_scanner
: public helper_interface
2879 virtual ~token_scanner()
2882 explicit token_scanner(const std::size_t& stride
)
2887 throw std::invalid_argument("token_scanner() - Invalid stride value");
2891 inline std::size_t process(generator
& g
)
2893 if (g
.token_list_
.size() >= stride_
)
2895 for (std::size_t i
= 0; i
< (g
.token_list_
.size() - stride_
+ 1); ++i
)
2903 const token
& t0
= g
.token_list_
[i
];
2905 if (!operator()(t0
))
2914 const token
& t0
= g
.token_list_
[i
];
2915 const token
& t1
= g
.token_list_
[i
+ 1];
2917 if (!operator()(t0
, t1
))
2926 const token
& t0
= g
.token_list_
[i
];
2927 const token
& t1
= g
.token_list_
[i
+ 1];
2928 const token
& t2
= g
.token_list_
[i
+ 2];
2930 if (!operator()(t0
, t1
, t2
))
2939 const token
& t0
= g
.token_list_
[i
];
2940 const token
& t1
= g
.token_list_
[i
+ 1];
2941 const token
& t2
= g
.token_list_
[i
+ 2];
2942 const token
& t3
= g
.token_list_
[i
+ 3];
2944 if (!operator()(t0
, t1
, t2
, t3
))
2954 return (g
.token_list_
.size() - stride_
+ 1);
2957 virtual bool operator() (const token
&)
2962 virtual bool operator() (const token
&, const token
&)
2967 virtual bool operator() (const token
&, const token
&, const token
&)
2972 virtual bool operator() (const token
&, const token
&, const token
&, const token
&)
2979 const std::size_t stride_
;
2982 class token_modifier
: public helper_interface
2986 inline std::size_t process(generator
& g
)
2988 std::size_t changes
= 0;
2990 for (std::size_t i
= 0; i
< g
.token_list_
.size(); ++i
)
2992 if (modify(g
.token_list_
[i
])) changes
++;
2998 virtual bool modify(token
& t
) = 0;
3001 class token_inserter
: public helper_interface
3005 explicit token_inserter(const std::size_t& stride
)
3010 throw std::invalid_argument("token_inserter() - Invalid stride value");
3014 inline std::size_t process(generator
& g
)
3016 if (g
.token_list_
.empty())
3018 else if (g
.token_list_
.size() < stride_
)
3021 std::size_t changes
= 0;
3023 for (std::size_t i
= 0; i
< (g
.token_list_
.size() - stride_
+ 1); ++i
)
3025 int insert_index
= -1;
3030 case 1 : insert_index
= insert(g
.token_list_
[i
],t
);
3033 case 2 : insert_index
= insert(g
.token_list_
[i
], g
.token_list_
[i
+ 1], t
);
3036 case 3 : insert_index
= insert(g
.token_list_
[i
], g
.token_list_
[i
+ 1], g
.token_list_
[i
+ 2], t
);
3039 case 4 : insert_index
= insert(g
.token_list_
[i
], g
.token_list_
[i
+ 1], g
.token_list_
[i
+ 2], g
.token_list_
[i
+ 3], t
);
3042 case 5 : insert_index
= insert(g
.token_list_
[i
], g
.token_list_
[i
+ 1], g
.token_list_
[i
+ 2], g
.token_list_
[i
+ 3], g
.token_list_
[i
+ 4], t
);
3046 typedef std::iterator_traits
<generator::token_list_t::iterator
>::difference_type diff_t
;
3048 if ((insert_index
>= 0) && (insert_index
<= (static_cast<int>(stride_
) + 1)))
3050 g
.token_list_
.insert(
3051 g
.token_list_
.begin() + static_cast<diff_t
>(i
+ static_cast<std::size_t>(insert_index
)), t
);
3060 #define token_inserter_empty_body \
3065 inline virtual int insert(const token&, token&)
3066 token_inserter_empty_body
3068 inline virtual int insert(const token
&, const token
&, token
&)
3069 token_inserter_empty_body
3071 inline virtual int insert(const token
&, const token
&, const token
&, token
&)
3072 token_inserter_empty_body
3074 inline virtual int insert(const token
&, const token
&, const token
&, const token
&, token
&)
3075 token_inserter_empty_body
3077 inline virtual int insert(const token
&, const token
&, const token
&, const token
&, const token
&, token
&)
3078 token_inserter_empty_body
3080 #undef token_inserter_empty_body
3084 const std::size_t stride_
;
3087 class token_joiner
: public helper_interface
3091 explicit token_joiner(const std::size_t& stride
)
3095 inline std::size_t process(generator
& g
)
3097 if (g
.token_list_
.empty())
3102 case 2 : return process_stride_2(g
);
3103 case 3 : return process_stride_3(g
);
3108 virtual bool join(const token
&, const token
&, token
&) { return false; }
3109 virtual bool join(const token
&, const token
&, const token
&, token
&) { return false; }
3113 inline std::size_t process_stride_2(generator
& g
)
3115 typedef std::iterator_traits
<generator::token_list_t::iterator
>::difference_type diff_t
;
3117 if (g
.token_list_
.size() < 2)
3120 std::size_t changes
= 0;
3122 for (int i
= 0; i
< static_cast<int>(g
.token_list_
.size() - 1); ++i
)
3126 while (join(g
[i
], g
[i
+ 1], t
))
3128 g
.token_list_
[i
] = t
;
3130 g
.token_list_
.erase(g
.token_list_
.begin() + static_cast<diff_t
>(i
+ 1));
3134 if (static_cast<std::size_t>(i
+ 1) >= g
.token_list_
.size())
3142 inline std::size_t process_stride_3(generator
& g
)
3144 typedef std::iterator_traits
<generator::token_list_t::iterator
>::difference_type diff_t
;
3146 if (g
.token_list_
.size() < 3)
3149 std::size_t changes
= 0;
3151 for (int i
= 0; i
< static_cast<int>(g
.token_list_
.size() - 2); ++i
)
3155 while (join(g
[i
], g
[i
+ 1], g
[i
+ 2], t
))
3157 g
.token_list_
[i
] = t
;
3159 g
.token_list_
.erase(g
.token_list_
.begin() + static_cast<diff_t
>(i
+ 1),
3160 g
.token_list_
.begin() + static_cast<diff_t
>(i
+ 3));
3163 if (static_cast<std::size_t>(i
+ 2) >= g
.token_list_
.size())
3171 const std::size_t stride_
;
3177 inline void dump(lexer::generator
& generator
)
3179 for (std::size_t i
= 0; i
< generator
.size(); ++i
)
3181 lexer::token t
= generator
[i
];
3182 printf("Token[%02d] @ %03d %6s --> '%s'\n",
3183 static_cast<int>(i
),
3184 static_cast<int>(t
.position
),
3185 t
.to_str(t
.type
).c_str(),
3190 class commutative_inserter
: public lexer::token_inserter
3194 using lexer::token_inserter::insert
;
3196 commutative_inserter()
3197 : lexer::token_inserter(2)
3200 inline void ignore_symbol(const std::string
& symbol
)
3202 ignore_set_
.insert(symbol
);
3205 inline int insert(const lexer::token
& t0
, const lexer::token
& t1
, lexer::token
& new_token
)
3208 new_token
.type
= lexer::token::e_mul
;
3209 new_token
.value
= "*";
3210 new_token
.position
= t1
.position
;
3212 if (t0
.type
== lexer::token::e_symbol
)
3214 if (ignore_set_
.end() != ignore_set_
.find(t0
.value
))
3218 else if (!t0
.value
.empty() && ('$' == t0
.value
[0]))
3224 if (t1
.type
== lexer::token::e_symbol
)
3226 if (ignore_set_
.end() != ignore_set_
.find(t1
.value
))
3231 if ((t0
.type
== lexer::token::e_number
) && (t1
.type
== lexer::token::e_symbol
)) match
= true;
3232 else if ((t0
.type
== lexer::token::e_number
) && (t1
.type
== lexer::token::e_lbracket
)) match
= true;
3233 else if ((t0
.type
== lexer::token::e_number
) && (t1
.type
== lexer::token::e_lcrlbracket
)) match
= true;
3234 else if ((t0
.type
== lexer::token::e_number
) && (t1
.type
== lexer::token::e_lsqrbracket
)) match
= true;
3235 else if ((t0
.type
== lexer::token::e_symbol
) && (t1
.type
== lexer::token::e_number
)) match
= true;
3236 else if ((t0
.type
== lexer::token::e_rbracket
) && (t1
.type
== lexer::token::e_number
)) match
= true;
3237 else if ((t0
.type
== lexer::token::e_rcrlbracket
) && (t1
.type
== lexer::token::e_number
)) match
= true;
3238 else if ((t0
.type
== lexer::token::e_rsqrbracket
) && (t1
.type
== lexer::token::e_number
)) match
= true;
3239 else if ((t0
.type
== lexer::token::e_rbracket
) && (t1
.type
== lexer::token::e_symbol
)) match
= true;
3240 else if ((t0
.type
== lexer::token::e_rcrlbracket
) && (t1
.type
== lexer::token::e_symbol
)) match
= true;
3241 else if ((t0
.type
== lexer::token::e_rsqrbracket
) && (t1
.type
== lexer::token::e_symbol
)) match
= true;
3242 else if ((t0
.type
== lexer::token::e_symbol
) && (t1
.type
== lexer::token::e_symbol
)) match
= true;
3244 return (match
) ? 1 : -1;
3249 std::set
<std::string
,details::ilesscompare
> ignore_set_
;
3252 class operator_joiner
: public token_joiner
3256 explicit operator_joiner(const std::size_t& stride
)
3257 : token_joiner(stride
)
3260 inline bool join(const lexer::token
& t0
, const lexer::token
& t1
, lexer::token
& t
)
3263 if ((t0
.type
== lexer::token::e_colon
) && (t1
.type
== lexer::token::e_eq
))
3265 t
.type
= lexer::token::e_assign
;
3267 t
.position
= t0
.position
;
3272 else if ((t0
.type
== lexer::token::e_add
) && (t1
.type
== lexer::token::e_eq
))
3274 t
.type
= lexer::token::e_addass
;
3276 t
.position
= t0
.position
;
3281 else if ((t0
.type
== lexer::token::e_sub
) && (t1
.type
== lexer::token::e_eq
))
3283 t
.type
= lexer::token::e_subass
;
3285 t
.position
= t0
.position
;
3290 else if ((t0
.type
== lexer::token::e_mul
) && (t1
.type
== lexer::token::e_eq
))
3292 t
.type
= lexer::token::e_mulass
;
3294 t
.position
= t0
.position
;
3299 else if ((t0
.type
== lexer::token::e_div
) && (t1
.type
== lexer::token::e_eq
))
3301 t
.type
= lexer::token::e_divass
;
3303 t
.position
= t0
.position
;
3308 else if ((t0
.type
== lexer::token::e_mod
) && (t1
.type
== lexer::token::e_eq
))
3310 t
.type
= lexer::token::e_modass
;
3312 t
.position
= t0
.position
;
3317 else if ((t0
.type
== lexer::token::e_gt
) && (t1
.type
== lexer::token::e_eq
))
3319 t
.type
= lexer::token::e_gte
;
3321 t
.position
= t0
.position
;
3326 else if ((t0
.type
== lexer::token::e_lt
) && (t1
.type
== lexer::token::e_eq
))
3328 t
.type
= lexer::token::e_lte
;
3330 t
.position
= t0
.position
;
3335 else if ((t0
.type
== lexer::token::e_eq
) && (t1
.type
== lexer::token::e_eq
))
3337 t
.type
= lexer::token::e_eq
;
3339 t
.position
= t0
.position
;
3344 else if ((static_cast<char>(t0
.type
) == '!') && (t1
.type
== lexer::token::e_eq
))
3346 t
.type
= lexer::token::e_ne
;
3348 t
.position
= t0
.position
;
3353 else if ((t0
.type
== lexer::token::e_lt
) && (t1
.type
== lexer::token::e_gt
))
3355 t
.type
= lexer::token::e_ne
;
3357 t
.position
= t0
.position
;
3362 else if ((t0
.type
== lexer::token::e_lte
) && (t1
.type
== lexer::token::e_gt
))
3364 t
.type
= lexer::token::e_swap
;
3366 t
.position
= t0
.position
;
3371 else if ((t0
.type
== lexer::token::e_add
) && (t1
.type
== lexer::token::e_sub
))
3373 t
.type
= lexer::token::e_sub
;
3375 t
.position
= t0
.position
;
3380 else if ((t0
.type
== lexer::token::e_sub
) && (t1
.type
== lexer::token::e_add
))
3382 t
.type
= lexer::token::e_sub
;
3384 t
.position
= t0
.position
;
3389 else if ((t0
.type
== lexer::token::e_sub
) && (t1
.type
== lexer::token::e_sub
))
3392 Note: May need to reconsider this when wanting to implement
3393 pre/postfix decrement operator
3395 t
.type
= lexer::token::e_add
;
3397 t
.position
= t0
.position
;
3405 inline bool join(const lexer::token
& t0
, const lexer::token
& t1
, const lexer::token
& t2
, lexer::token
& t
)
3407 // '[ * ]' --> '[*]'
3409 (t0
.type
== lexer::token::e_lsqrbracket
) &&
3410 (t1
.type
== lexer::token::e_mul
) &&
3411 (t2
.type
== lexer::token::e_rsqrbracket
)
3414 t
.type
= lexer::token::e_symbol
;
3416 t
.position
= t0
.position
;
3425 class bracket_checker
: public lexer::token_scanner
3429 using lexer::token_scanner::operator();
3438 if (!stack_
.empty())
3441 t
.value
= stack_
.top().first
;
3442 t
.position
= stack_
.top().second
;
3452 lexer::token
error_token()
3454 return error_token_
;
3459 // Why? because msvc doesn't support swap properly.
3460 stack_
= std::stack
<std::pair
<char,std::size_t> >();
3462 error_token_
.clear();
3465 bool operator() (const lexer::token
& t
)
3469 (lexer::token::e_string
!= t
.type
) &&
3470 (lexer::token::e_symbol
!= t
.type
) &&
3471 exprtk::details::is_bracket(t
.value
[0])
3474 details::char_t c
= t
.value
[0];
3476 if (t
.type
== lexer::token::e_lbracket
) stack_
.push(std::make_pair(')',t
.position
));
3477 else if (t
.type
== lexer::token::e_lcrlbracket
) stack_
.push(std::make_pair('}',t
.position
));
3478 else if (t
.type
== lexer::token::e_lsqrbracket
) stack_
.push(std::make_pair(']',t
.position
));
3479 else if (exprtk::details::is_right_bracket(c
))
3488 else if (c
!= stack_
.top().first
)
3506 std::stack
<std::pair
<char,std::size_t> > stack_
;
3507 lexer::token error_token_
;
3510 class numeric_checker
: public lexer::token_scanner
3514 using lexer::token_scanner::operator();
3517 : token_scanner (1),
3523 return error_list_
.empty();
3528 error_list_
.clear();
3532 bool operator() (const lexer::token
& t
)
3534 if (token::e_number
== t
.type
)
3538 if (!exprtk::details::string_to_real(t
.value
,v
))
3540 error_list_
.push_back(current_index_
);
3549 std::size_t error_count() const
3551 return error_list_
.size();
3554 std::size_t error_index(const std::size_t& i
)
3556 if (i
< error_list_
.size())
3557 return error_list_
[i
];
3559 return std::numeric_limits
<std::size_t>::max();
3564 error_list_
.clear();
3569 std::size_t current_index_
;
3570 std::vector
<std::size_t> error_list_
;
3573 class symbol_replacer
: public lexer::token_modifier
3577 typedef std::map
<std::string
,std::pair
<std::string
,token::token_type
>,details::ilesscompare
> replace_map_t
;
3581 bool remove(const std::string
& target_symbol
)
3583 const replace_map_t::iterator itr
= replace_map_
.find(target_symbol
);
3585 if (replace_map_
.end() == itr
)
3588 replace_map_
.erase(itr
);
3593 bool add_replace(const std::string
& target_symbol
,
3594 const std::string
& replace_symbol
,
3595 const lexer::token::token_type token_type
= lexer::token::e_symbol
)
3597 const replace_map_t::iterator itr
= replace_map_
.find(target_symbol
);
3599 if (replace_map_
.end() != itr
)
3604 replace_map_
[target_symbol
] = std::make_pair(replace_symbol
,token_type
);
3611 replace_map_
.clear();
3616 bool modify(lexer::token
& t
)
3618 if (lexer::token::e_symbol
== t
.type
)
3620 if (replace_map_
.empty())
3623 const replace_map_t::iterator itr
= replace_map_
.find(t
.value
);
3625 if (replace_map_
.end() != itr
)
3627 t
.value
= itr
->second
.first
;
3628 t
.type
= itr
->second
.second
;
3637 replace_map_t replace_map_
;
3640 class sequence_validator
: public lexer::token_scanner
3644 typedef std::pair
<lexer::token::token_type
,lexer::token::token_type
> token_pair_t
;
3645 typedef std::set
<token_pair_t
> set_t
;
3649 using lexer::token_scanner::operator();
3651 sequence_validator()
3652 : lexer::token_scanner(2)
3654 add_invalid(lexer::token::e_number
, lexer::token::e_number
);
3655 add_invalid(lexer::token::e_string
, lexer::token::e_string
);
3656 add_invalid(lexer::token::e_number
, lexer::token::e_string
);
3657 add_invalid(lexer::token::e_string
, lexer::token::e_number
);
3659 add_invalid_set1(lexer::token::e_assign
);
3660 add_invalid_set1(lexer::token::e_shr
);
3661 add_invalid_set1(lexer::token::e_shl
);
3662 add_invalid_set1(lexer::token::e_lte
);
3663 add_invalid_set1(lexer::token::e_ne
);
3664 add_invalid_set1(lexer::token::e_gte
);
3665 add_invalid_set1(lexer::token::e_lt
);
3666 add_invalid_set1(lexer::token::e_gt
);
3667 add_invalid_set1(lexer::token::e_eq
);
3668 add_invalid_set1(lexer::token::e_comma
);
3669 add_invalid_set1(lexer::token::e_add
);
3670 add_invalid_set1(lexer::token::e_sub
);
3671 add_invalid_set1(lexer::token::e_div
);
3672 add_invalid_set1(lexer::token::e_mul
);
3673 add_invalid_set1(lexer::token::e_mod
);
3674 add_invalid_set1(lexer::token::e_pow
);
3675 add_invalid_set1(lexer::token::e_colon
);
3676 add_invalid_set1(lexer::token::e_ternary
);
3681 return error_list_
.empty();
3684 bool operator() (const lexer::token
& t0
, const lexer::token
& t1
)
3686 const set_t::value_type p
= std::make_pair(t0
.type
,t1
.type
);
3688 if (invalid_bracket_check(t0
.type
,t1
.type
))
3690 error_list_
.push_back(std::make_pair(t0
,t1
));
3692 else if (invalid_comb_
.find(p
) != invalid_comb_
.end())
3694 error_list_
.push_back(std::make_pair(t0
,t1
));
3700 std::size_t error_count() const
3702 return error_list_
.size();
3705 std::pair
<lexer::token
,lexer::token
> error(const std::size_t index
)
3707 if (index
< error_list_
.size())
3709 return error_list_
[index
];
3713 static const lexer::token error_token
;
3714 return std::make_pair(error_token
,error_token
);
3720 error_list_
.clear();
3725 void add_invalid(lexer::token::token_type base
, lexer::token::token_type t
)
3727 invalid_comb_
.insert(std::make_pair(base
,t
));
3730 void add_invalid_set1(lexer::token::token_type t
)
3732 add_invalid(t
, lexer::token::e_assign
);
3733 add_invalid(t
, lexer::token::e_shr
);
3734 add_invalid(t
, lexer::token::e_shl
);
3735 add_invalid(t
, lexer::token::e_lte
);
3736 add_invalid(t
, lexer::token::e_ne
);
3737 add_invalid(t
, lexer::token::e_gte
);
3738 add_invalid(t
, lexer::token::e_lt
);
3739 add_invalid(t
, lexer::token::e_gt
);
3740 add_invalid(t
, lexer::token::e_eq
);
3741 add_invalid(t
, lexer::token::e_comma
);
3742 add_invalid(t
, lexer::token::e_div
);
3743 add_invalid(t
, lexer::token::e_mul
);
3744 add_invalid(t
, lexer::token::e_mod
);
3745 add_invalid(t
, lexer::token::e_pow
);
3746 add_invalid(t
, lexer::token::e_colon
);
3749 bool invalid_bracket_check(lexer::token::token_type base
, lexer::token::token_type t
)
3751 if (details::is_right_bracket(static_cast<char>(base
)))
3755 case lexer::token::e_assign
: return (']' != base
);
3756 case lexer::token::e_string
: return (')' != base
);
3757 default : return false;
3760 else if (details::is_left_bracket(static_cast<char>(base
)))
3762 if (details::is_right_bracket(static_cast<char>(t
)))
3764 else if (details::is_left_bracket(static_cast<char>(t
)))
3770 case lexer::token::e_number
: return false;
3771 case lexer::token::e_symbol
: return false;
3772 case lexer::token::e_string
: return false;
3773 case lexer::token::e_add
: return false;
3774 case lexer::token::e_sub
: return false;
3775 case lexer::token::e_colon
: return false;
3776 case lexer::token::e_ternary
: return false;
3777 default : return true ;
3781 else if (details::is_right_bracket(static_cast<char>(t
)))
3785 case lexer::token::e_number
: return false;
3786 case lexer::token::e_symbol
: return false;
3787 case lexer::token::e_string
: return false;
3788 case lexer::token::e_eof
: return false;
3789 case lexer::token::e_colon
: return false;
3790 case lexer::token::e_ternary
: return false;
3791 default : return true ;
3794 else if (details::is_left_bracket(static_cast<char>(t
)))
3798 case lexer::token::e_rbracket
: return true;
3799 case lexer::token::e_rsqrbracket
: return true;
3800 case lexer::token::e_rcrlbracket
: return true;
3801 default : return false;
3808 set_t invalid_comb_
;
3809 std::vector
<std::pair
<lexer::token
,lexer::token
> > error_list_
;
3812 class sequence_validator_3tokens
: public lexer::token_scanner
3816 typedef lexer::token::token_type token_t
;
3817 typedef std::pair
<token_t
,std::pair
<token_t
,token_t
> > token_triplet_t
;
3818 typedef std::set
<token_triplet_t
> set_t
;
3822 using lexer::token_scanner::operator();
3824 sequence_validator_3tokens()
3825 : lexer::token_scanner(3)
3827 add_invalid(lexer::token::e_number
, lexer::token::e_number
, lexer::token::e_number
);
3828 add_invalid(lexer::token::e_string
, lexer::token::e_string
, lexer::token::e_string
);
3829 add_invalid(lexer::token::e_comma
, lexer::token::e_comma
, lexer::token::e_comma
);
3831 add_invalid(lexer::token::e_add
, lexer::token::e_add
, lexer::token::e_add
);
3832 add_invalid(lexer::token::e_sub
, lexer::token::e_sub
, lexer::token::e_sub
);
3833 add_invalid(lexer::token::e_div
, lexer::token::e_div
, lexer::token::e_div
);
3834 add_invalid(lexer::token::e_mul
, lexer::token::e_mul
, lexer::token::e_mul
);
3835 add_invalid(lexer::token::e_mod
, lexer::token::e_mod
, lexer::token::e_mod
);
3836 add_invalid(lexer::token::e_pow
, lexer::token::e_pow
, lexer::token::e_pow
);
3838 add_invalid(lexer::token::e_add
, lexer::token::e_sub
, lexer::token::e_add
);
3839 add_invalid(lexer::token::e_sub
, lexer::token::e_add
, lexer::token::e_sub
);
3840 add_invalid(lexer::token::e_div
, lexer::token::e_mul
, lexer::token::e_div
);
3841 add_invalid(lexer::token::e_mul
, lexer::token::e_div
, lexer::token::e_mul
);
3842 add_invalid(lexer::token::e_mod
, lexer::token::e_pow
, lexer::token::e_mod
);
3843 add_invalid(lexer::token::e_pow
, lexer::token::e_mod
, lexer::token::e_pow
);
3848 return error_list_
.empty();
3851 bool operator() (const lexer::token
& t0
, const lexer::token
& t1
, const lexer::token
& t2
)
3853 const set_t::value_type p
= std::make_pair(t0
.type
,std::make_pair(t1
.type
,t2
.type
));
3855 if (invalid_comb_
.find(p
) != invalid_comb_
.end())
3857 error_list_
.push_back(std::make_pair(t0
,t1
));
3863 std::size_t error_count() const
3865 return error_list_
.size();
3868 std::pair
<lexer::token
,lexer::token
> error(const std::size_t index
)
3870 if (index
< error_list_
.size())
3872 return error_list_
[index
];
3876 static const lexer::token error_token
;
3877 return std::make_pair(error_token
,error_token
);
3883 error_list_
.clear();
3888 void add_invalid(token_t t0
, token_t t1
, token_t t2
)
3890 invalid_comb_
.insert(std::make_pair(t0
,std::make_pair(t1
,t2
)));
3893 set_t invalid_comb_
;
3894 std::vector
<std::pair
<lexer::token
,lexer::token
> > error_list_
;
3897 struct helper_assembly
3899 inline bool register_scanner(lexer::token_scanner
* scanner
)
3901 if (token_scanner_list
.end() != std::find(token_scanner_list
.begin(),
3902 token_scanner_list
.end (),
3908 token_scanner_list
.push_back(scanner
);
3913 inline bool register_modifier(lexer::token_modifier
* modifier
)
3915 if (token_modifier_list
.end() != std::find(token_modifier_list
.begin(),
3916 token_modifier_list
.end (),
3922 token_modifier_list
.push_back(modifier
);
3927 inline bool register_joiner(lexer::token_joiner
* joiner
)
3929 if (token_joiner_list
.end() != std::find(token_joiner_list
.begin(),
3930 token_joiner_list
.end (),
3936 token_joiner_list
.push_back(joiner
);
3941 inline bool register_inserter(lexer::token_inserter
* inserter
)
3943 if (token_inserter_list
.end() != std::find(token_inserter_list
.begin(),
3944 token_inserter_list
.end (),
3950 token_inserter_list
.push_back(inserter
);
3955 inline bool run_modifiers(lexer::generator
& g
)
3957 error_token_modifier
= reinterpret_cast<lexer::token_modifier
*>(0);
3959 for (std::size_t i
= 0; i
< token_modifier_list
.size(); ++i
)
3961 lexer::token_modifier
& modifier
= (*token_modifier_list
[i
]);
3964 modifier
.process(g
);
3966 if (!modifier
.result())
3968 error_token_modifier
= token_modifier_list
[i
];
3977 inline bool run_joiners(lexer::generator
& g
)
3979 error_token_joiner
= reinterpret_cast<lexer::token_joiner
*>(0);
3981 for (std::size_t i
= 0; i
< token_joiner_list
.size(); ++i
)
3983 lexer::token_joiner
& joiner
= (*token_joiner_list
[i
]);
3988 if (!joiner
.result())
3990 error_token_joiner
= token_joiner_list
[i
];
3999 inline bool run_inserters(lexer::generator
& g
)
4001 error_token_inserter
= reinterpret_cast<lexer::token_inserter
*>(0);
4003 for (std::size_t i
= 0; i
< token_inserter_list
.size(); ++i
)
4005 lexer::token_inserter
& inserter
= (*token_inserter_list
[i
]);
4008 inserter
.process(g
);
4010 if (!inserter
.result())
4012 error_token_inserter
= token_inserter_list
[i
];
4021 inline bool run_scanners(lexer::generator
& g
)
4023 error_token_scanner
= reinterpret_cast<lexer::token_scanner
*>(0);
4025 for (std::size_t i
= 0; i
< token_scanner_list
.size(); ++i
)
4027 lexer::token_scanner
& scanner
= (*token_scanner_list
[i
]);
4032 if (!scanner
.result())
4034 error_token_scanner
= token_scanner_list
[i
];
4043 std::vector
<lexer::token_scanner
*> token_scanner_list
;
4044 std::vector
<lexer::token_modifier
*> token_modifier_list
;
4045 std::vector
<lexer::token_joiner
*> token_joiner_list
;
4046 std::vector
<lexer::token_inserter
*> token_inserter_list
;
4048 lexer::token_scanner
* error_token_scanner
;
4049 lexer::token_modifier
* error_token_modifier
;
4050 lexer::token_joiner
* error_token_joiner
;
4051 lexer::token_inserter
* error_token_inserter
;
4059 typedef token token_t
;
4060 typedef generator generator_t
;
4062 inline bool init(const std::string
& str
)
4064 if (!lexer_
.process(str
))
4076 inline generator_t
& lexer()
4081 inline const generator_t
& lexer() const
4086 inline void store_token()
4089 store_current_token_
= current_token_
;
4092 inline void restore_token()
4095 current_token_
= store_current_token_
;
4098 inline void next_token()
4100 current_token_
= lexer_
.next_token();
4103 inline const token_t
& current_token() const
4105 return current_token_
;
4108 enum token_advance_mode
4114 inline void advance_token(const token_advance_mode mode
)
4116 if (e_advance
== mode
)
4122 inline bool token_is(const token_t::token_type
& ttype
, const token_advance_mode mode
= e_advance
)
4124 if (current_token().type
!= ttype
)
4129 advance_token(mode
);
4134 inline bool token_is(const token_t::token_type
& ttype
,
4135 const std::string
& value
,
4136 const token_advance_mode mode
= e_advance
)
4139 (current_token().type
!= ttype
) ||
4140 !exprtk::details::imatch(value
,current_token().value
)
4146 advance_token(mode
);
4151 inline bool peek_token_is(const token_t::token_type
& ttype
)
4153 return (lexer_
.peek_next_token().type
== ttype
);
4156 inline bool peek_token_is(const std::string
& s
)
4158 return (exprtk::details::imatch(lexer_
.peek_next_token().value
,s
));
4164 token_t current_token_
;
4165 token_t store_current_token_
;
4169 template <typename T
>
4174 typedef T
* data_ptr_t
;
4176 vector_view(data_ptr_t data
, const std::size_t& size
)
4182 vector_view(const vector_view
<T
>& vv
)
4188 inline void rebase(data_ptr_t data
)
4192 if (!data_ref_
.empty())
4194 for (std::size_t i
= 0; i
< data_ref_
.size(); ++i
)
4196 (*data_ref_
[i
]) = data
;
4201 inline data_ptr_t
data() const
4206 inline std::size_t size() const
4211 inline const T
& operator[](const std::size_t index
) const
4213 return data_
[index
];
4216 inline T
& operator[](const std::size_t index
)
4218 return data_
[index
];
4221 void set_ref(data_ptr_t
* data_ref
)
4223 data_ref_
.push_back(data_ref
);
4228 const std::size_t size_
;
4230 std::vector
<data_ptr_t
*> data_ref_
;
4233 template <typename T
>
4234 inline vector_view
<T
> make_vector_view(T
* data
,
4235 const std::size_t size
, const std::size_t offset
= 0)
4237 return vector_view
<T
>(data
+ offset
, size
);
4240 template <typename T
>
4241 inline vector_view
<T
> make_vector_view(std::vector
<T
>& v
,
4242 const std::size_t size
, const std::size_t offset
= 0)
4244 return vector_view
<T
>(v
.data() + offset
, size
);
4247 template <typename T
> class results_context
;
4249 template <typename T
>
4275 class parameter_list
4279 parameter_list(std::vector
<type_store
>& pl
)
4280 : parameter_list_(pl
)
4283 inline bool empty() const
4285 return parameter_list_
.empty();
4288 inline std::size_t size() const
4290 return parameter_list_
.size();
4293 inline type_store
& operator[](const std::size_t& index
)
4295 return parameter_list_
[index
];
4298 inline const type_store
& operator[](const std::size_t& index
) const
4300 return parameter_list_
[index
];
4303 inline type_store
& front()
4305 return parameter_list_
[0];
4308 inline const type_store
& front() const
4310 return parameter_list_
[0];
4313 inline type_store
& back()
4315 return parameter_list_
.back();
4318 inline const type_store
& back() const
4320 return parameter_list_
.back();
4325 std::vector
<type_store
>& parameter_list_
;
4327 friend class results_context
<T
>;
4330 template <typename ViewType
>
4333 typedef type_store
<T
> type_store_t
;
4334 typedef ViewType value_t
;
4336 type_view(type_store_t
& ts
)
4338 data_(reinterpret_cast<value_t
*>(ts_
.data
))
4341 type_view(const type_store_t
& ts
)
4342 : ts_(const_cast<type_store_t
&>(ts
)),
4343 data_(reinterpret_cast<value_t
*>(ts_
.data
))
4346 inline std::size_t size() const
4351 inline value_t
& operator[](const std::size_t& i
)
4356 inline const value_t
& operator[](const std::size_t& i
) const
4361 inline const value_t
* begin() const { return data_
; }
4362 inline value_t
* begin() { return data_
; }
4364 inline const value_t
* end() const
4366 return static_cast<value_t
*>(data_
+ ts_
.size
);
4369 inline value_t
* end()
4371 return static_cast<value_t
*>(data_
+ ts_
.size
);
4378 typedef type_view
<T
> vector_view
;
4379 typedef type_view
<char> string_view
;
4383 typedef type_store
<T
> type_store_t
;
4386 scalar_view(type_store_t
& ts
)
4387 : v_(*reinterpret_cast<value_t
*>(ts
.data
))
4390 scalar_view(const type_store_t
& ts
)
4391 : v_(*reinterpret_cast<value_t
*>(const_cast<type_store_t
&>(ts
).data
))
4394 inline value_t
& operator() ()
4399 inline const value_t
& operator() () const
4404 template <typename IntType
>
4405 inline bool to_int(IntType
& i
) const
4407 if (!exprtk::details::numeric::is_integer(v_
))
4410 i
= static_cast<IntType
>(v_
);
4415 template <typename UIntType
>
4416 inline bool to_uint(UIntType
& u
) const
4420 else if (!exprtk::details::numeric::is_integer(v_
))
4423 u
= static_cast<UIntType
>(v_
);
4432 template <typename StringView
>
4433 inline std::string
to_str(const StringView
& view
)
4435 return std::string(view
.begin(),view
.size());
4438 #ifndef exprtk_disable_return_statement
4441 template <typename T
> class return_node
;
4442 template <typename T
> class return_envelope_node
;
4446 template <typename T
>
4447 class results_context
4451 typedef type_store
<T
> type_store_t
;
4454 : results_available_(false)
4457 inline std::size_t count() const
4459 if (results_available_
)
4460 return parameter_list_
.size();
4465 inline type_store_t
& operator[](const std::size_t& index
)
4467 return parameter_list_
[index
];
4470 inline const type_store_t
& operator[](const std::size_t& index
) const
4472 return parameter_list_
[index
];
4479 results_available_
= false;
4482 typedef std::vector
<type_store_t
> ts_list_t
;
4483 typedef typename
type_store_t::parameter_list parameter_list_t
;
4485 inline void assign(const parameter_list_t
& pl
)
4487 parameter_list_
= pl
.parameter_list_
;
4488 results_available_
= true;
4491 bool results_available_
;
4492 ts_list_t parameter_list_
;
4494 #ifndef exprtk_disable_return_statement
4495 friend class details::return_node
<T
>;
4496 friend class details::return_envelope_node
<T
>;
4504 e_default
, e_null
, e_add
, e_sub
,
4505 e_mul
, e_div
, e_mod
, e_pow
,
4506 e_atan2
, e_min
, e_max
, e_avg
,
4507 e_sum
, e_prod
, e_lt
, e_lte
,
4508 e_eq
, e_equal
, e_ne
, e_nequal
,
4509 e_gte
, e_gt
, e_and
, e_nand
,
4510 e_or
, e_nor
, e_xor
, e_xnor
,
4511 e_mand
, e_mor
, e_scand
, e_scor
,
4512 e_shr
, e_shl
, e_abs
, e_acos
,
4513 e_acosh
, e_asin
, e_asinh
, e_atan
,
4514 e_atanh
, e_ceil
, e_cos
, e_cosh
,
4515 e_exp
, e_expm1
, e_floor
, e_log
,
4516 e_log10
, e_log2
, e_log1p
, e_logn
,
4517 e_neg
, e_pos
, e_round
, e_roundn
,
4518 e_root
, e_sqrt
, e_sin
, e_sinc
,
4519 e_sinh
, e_sec
, e_csc
, e_tan
,
4520 e_tanh
, e_cot
, e_clamp
, e_iclamp
,
4521 e_inrange
, e_sgn
, e_r2d
, e_d2r
,
4522 e_d2g
, e_g2d
, e_hypot
, e_notl
,
4523 e_erf
, e_erfc
, e_ncdf
, e_frac
,
4524 e_trunc
, e_assign
, e_addass
, e_subass
,
4525 e_mulass
, e_divass
, e_modass
, e_in
,
4526 e_like
, e_ilike
, e_multi
, e_smulti
,
4529 // Do not add new functions/operators after this point.
4530 e_sf00
= 1000, e_sf01
= 1001, e_sf02
= 1002, e_sf03
= 1003,
4531 e_sf04
= 1004, e_sf05
= 1005, e_sf06
= 1006, e_sf07
= 1007,
4532 e_sf08
= 1008, e_sf09
= 1009, e_sf10
= 1010, e_sf11
= 1011,
4533 e_sf12
= 1012, e_sf13
= 1013, e_sf14
= 1014, e_sf15
= 1015,
4534 e_sf16
= 1016, e_sf17
= 1017, e_sf18
= 1018, e_sf19
= 1019,
4535 e_sf20
= 1020, e_sf21
= 1021, e_sf22
= 1022, e_sf23
= 1023,
4536 e_sf24
= 1024, e_sf25
= 1025, e_sf26
= 1026, e_sf27
= 1027,
4537 e_sf28
= 1028, e_sf29
= 1029, e_sf30
= 1030, e_sf31
= 1031,
4538 e_sf32
= 1032, e_sf33
= 1033, e_sf34
= 1034, e_sf35
= 1035,
4539 e_sf36
= 1036, e_sf37
= 1037, e_sf38
= 1038, e_sf39
= 1039,
4540 e_sf40
= 1040, e_sf41
= 1041, e_sf42
= 1042, e_sf43
= 1043,
4541 e_sf44
= 1044, e_sf45
= 1045, e_sf46
= 1046, e_sf47
= 1047,
4542 e_sf48
= 1048, e_sf49
= 1049, e_sf50
= 1050, e_sf51
= 1051,
4543 e_sf52
= 1052, e_sf53
= 1053, e_sf54
= 1054, e_sf55
= 1055,
4544 e_sf56
= 1056, e_sf57
= 1057, e_sf58
= 1058, e_sf59
= 1059,
4545 e_sf60
= 1060, e_sf61
= 1061, e_sf62
= 1062, e_sf63
= 1063,
4546 e_sf64
= 1064, e_sf65
= 1065, e_sf66
= 1066, e_sf67
= 1067,
4547 e_sf68
= 1068, e_sf69
= 1069, e_sf70
= 1070, e_sf71
= 1071,
4548 e_sf72
= 1072, e_sf73
= 1073, e_sf74
= 1074, e_sf75
= 1075,
4549 e_sf76
= 1076, e_sf77
= 1077, e_sf78
= 1078, e_sf79
= 1079,
4550 e_sf80
= 1080, e_sf81
= 1081, e_sf82
= 1082, e_sf83
= 1083,
4551 e_sf84
= 1084, e_sf85
= 1085, e_sf86
= 1086, e_sf87
= 1087,
4552 e_sf88
= 1088, e_sf89
= 1089, e_sf90
= 1090, e_sf91
= 1091,
4553 e_sf92
= 1092, e_sf93
= 1093, e_sf94
= 1094, e_sf95
= 1095,
4554 e_sf96
= 1096, e_sf97
= 1097, e_sf98
= 1098, e_sf99
= 1099,
4556 e_sf4ext00
= 2000, e_sf4ext01
= 2001, e_sf4ext02
= 2002, e_sf4ext03
= 2003,
4557 e_sf4ext04
= 2004, e_sf4ext05
= 2005, e_sf4ext06
= 2006, e_sf4ext07
= 2007,
4558 e_sf4ext08
= 2008, e_sf4ext09
= 2009, e_sf4ext10
= 2010, e_sf4ext11
= 2011,
4559 e_sf4ext12
= 2012, e_sf4ext13
= 2013, e_sf4ext14
= 2014, e_sf4ext15
= 2015,
4560 e_sf4ext16
= 2016, e_sf4ext17
= 2017, e_sf4ext18
= 2018, e_sf4ext19
= 2019,
4561 e_sf4ext20
= 2020, e_sf4ext21
= 2021, e_sf4ext22
= 2022, e_sf4ext23
= 2023,
4562 e_sf4ext24
= 2024, e_sf4ext25
= 2025, e_sf4ext26
= 2026, e_sf4ext27
= 2027,
4563 e_sf4ext28
= 2028, e_sf4ext29
= 2029, e_sf4ext30
= 2030, e_sf4ext31
= 2031,
4564 e_sf4ext32
= 2032, e_sf4ext33
= 2033, e_sf4ext34
= 2034, e_sf4ext35
= 2035,
4565 e_sf4ext36
= 2036, e_sf4ext37
= 2037, e_sf4ext38
= 2038, e_sf4ext39
= 2039,
4566 e_sf4ext40
= 2040, e_sf4ext41
= 2041, e_sf4ext42
= 2042, e_sf4ext43
= 2043,
4567 e_sf4ext44
= 2044, e_sf4ext45
= 2045, e_sf4ext46
= 2046, e_sf4ext47
= 2047,
4568 e_sf4ext48
= 2048, e_sf4ext49
= 2049, e_sf4ext50
= 2050, e_sf4ext51
= 2051,
4569 e_sf4ext52
= 2052, e_sf4ext53
= 2053, e_sf4ext54
= 2054, e_sf4ext55
= 2055,
4570 e_sf4ext56
= 2056, e_sf4ext57
= 2057, e_sf4ext58
= 2058, e_sf4ext59
= 2059,
4571 e_sf4ext60
= 2060, e_sf4ext61
= 2061
4574 inline std::string
to_str(const operator_type opr
)
4578 case e_add
: return "+" ;
4579 case e_sub
: return "-" ;
4580 case e_mul
: return "*" ;
4581 case e_div
: return "/" ;
4582 case e_mod
: return "%" ;
4583 case e_pow
: return "^" ;
4584 case e_assign
: return ":=" ;
4585 case e_addass
: return "+=" ;
4586 case e_subass
: return "-=" ;
4587 case e_mulass
: return "*=" ;
4588 case e_divass
: return "/=" ;
4589 case e_modass
: return "%=" ;
4590 case e_lt
: return "<" ;
4591 case e_lte
: return "<=" ;
4592 case e_eq
: return "==" ;
4593 case e_equal
: return "=" ;
4594 case e_ne
: return "!=" ;
4595 case e_nequal
: return "<>" ;
4596 case e_gte
: return ">=" ;
4597 case e_gt
: return ">" ;
4598 case e_and
: return "and" ;
4599 case e_or
: return "or" ;
4600 case e_xor
: return "xor" ;
4601 case e_nand
: return "nand";
4602 case e_nor
: return "nor" ;
4603 case e_xnor
: return "xnor";
4604 default : return "N/A" ;
4608 struct base_operation_t
4610 base_operation_t(const operator_type t
, const unsigned int& np
)
4616 unsigned int num_params
;
4619 namespace loop_unroll
4621 #ifndef exprtk_disable_superscalar_unroll
4622 const unsigned int global_loop_batch_size
= 16;
4624 const unsigned int global_loop_batch_size
= 4;
4629 details(const std::size_t& vsize
,
4630 const unsigned int loop_batch_size
= global_loop_batch_size
)
4631 : batch_size(loop_batch_size
),
4632 remainder (vsize
% batch_size
),
4633 upper_bound(static_cast<int>(vsize
- (remainder
? loop_batch_size
: 0)))
4636 unsigned int batch_size
;
4642 #ifdef exprtk_enable_debugging
4643 inline void dump_ptr(const std::string
& s
, const void* ptr
, const std::size_t size
= 0)
4646 exprtk_debug(("%s - addr: %p\n",s
.c_str(),ptr
));
4648 exprtk_debug(("%s - addr: %p size: %d\n",
4651 static_cast<unsigned int>(size
)));
4654 inline void dump_ptr(const std::string
&, const void*) {}
4655 inline void dump_ptr(const std::string
&, const void*, const std::size_t) {}
4658 template <typename T
>
4659 class vec_data_store
4663 typedef vec_data_store
<T
> type
;
4668 struct control_block
4677 control_block(const std::size_t& dsize
)
4684 control_block(const std::size_t& dsize
, data_t dptr
, bool dstrct
= false)
4693 if (data
&& destruct
&& (0 == ref_count
))
4695 dump_ptr("~control_block() data",data
);
4697 data
= reinterpret_cast<data_t
>(0);
4701 static inline control_block
* create(const std::size_t& dsize
, data_t data_ptr
= data_t(0), bool dstrct
= false)
4706 return (new control_block(dsize
));
4708 return (new control_block(dsize
, data_ptr
, dstrct
));
4711 return (new control_block
);
4714 static inline void destroy(control_block
*& cntrl_blck
)
4719 (0 != cntrl_blck
->ref_count
) &&
4720 (0 == --cntrl_blck
->ref_count
)
4730 std::size_t ref_count
;
4737 control_block(const control_block
&);
4738 control_block
& operator=(const control_block
&);
4740 inline void create_data()
4744 std::fill_n(data
,size
,T(0));
4745 dump_ptr("control_block::create_data() - data",data
,size
);
4752 : control_block_(control_block::create(0))
4755 vec_data_store(const std::size_t& size
)
4756 : control_block_(control_block::create(size
,(data_t
)(0),true))
4759 vec_data_store(const std::size_t& size
, data_t data
, bool dstrct
= false)
4760 : control_block_(control_block::create(size
, data
, dstrct
))
4763 vec_data_store(const type
& vds
)
4765 control_block_
= vds
.control_block_
;
4766 control_block_
->ref_count
++;
4771 control_block::destroy(control_block_
);
4774 type
& operator=(const type
& vds
)
4778 std::size_t final_size
= min_size(control_block_
, vds
.control_block_
);
4780 vds
.control_block_
->size
= final_size
;
4781 control_block_
->size
= final_size
;
4783 if (control_block_
->destruct
|| (0 == control_block_
->data
))
4785 control_block::destroy(control_block_
);
4787 control_block_
= vds
.control_block_
;
4788 control_block_
->ref_count
++;
4795 inline data_t
data()
4797 return control_block_
->data
;
4800 inline data_t
data() const
4802 return control_block_
->data
;
4805 inline std::size_t size()
4807 return control_block_
->size
;
4810 inline std::size_t size() const
4812 return control_block_
->size
;
4815 inline data_t
& ref()
4817 return control_block_
->data
;
4820 inline void dump() const
4822 #ifdef exprtk_enable_debugging
4823 exprtk_debug(("size: %d\taddress:%p\tdestruct:%c\n",
4826 (control_block_
->destruct
? 'T' : 'F')));
4828 for (std::size_t i
= 0; i
< size(); ++i
)
4831 exprtk_debug(("\n"));
4833 exprtk_debug(("%15.10f ",data()[i
]));
4835 exprtk_debug(("\n"));
4839 static inline void match_sizes(type
& vds0
, type
& vds1
)
4841 std::size_t size
= min_size(vds0
.control_block_
,vds1
.control_block_
);
4842 vds0
.control_block_
->size
= size
;
4843 vds1
.control_block_
->size
= size
;
4848 static inline std::size_t min_size(control_block
* cb0
, control_block
* cb1
)
4850 const std::size_t size0
= cb0
->size
;
4851 const std::size_t size1
= cb1
->size
;
4854 return std::min(size0
,size1
);
4856 return (size0
) ? size0
: size1
;
4859 control_block
* control_block_
;
4866 template <typename T
>
4867 inline T
process_impl(const operator_type operation
, const T arg
)
4871 case e_abs
: return numeric::abs (arg
);
4872 case e_acos
: return numeric::acos (arg
);
4873 case e_acosh
: return numeric::acosh(arg
);
4874 case e_asin
: return numeric::asin (arg
);
4875 case e_asinh
: return numeric::asinh(arg
);
4876 case e_atan
: return numeric::atan (arg
);
4877 case e_atanh
: return numeric::atanh(arg
);
4878 case e_ceil
: return numeric::ceil (arg
);
4879 case e_cos
: return numeric::cos (arg
);
4880 case e_cosh
: return numeric::cosh (arg
);
4881 case e_exp
: return numeric::exp (arg
);
4882 case e_expm1
: return numeric::expm1(arg
);
4883 case e_floor
: return numeric::floor(arg
);
4884 case e_log
: return numeric::log (arg
);
4885 case e_log10
: return numeric::log10(arg
);
4886 case e_log2
: return numeric::log2 (arg
);
4887 case e_log1p
: return numeric::log1p(arg
);
4888 case e_neg
: return numeric::neg (arg
);
4889 case e_pos
: return numeric::pos (arg
);
4890 case e_round
: return numeric::round(arg
);
4891 case e_sin
: return numeric::sin (arg
);
4892 case e_sinc
: return numeric::sinc (arg
);
4893 case e_sinh
: return numeric::sinh (arg
);
4894 case e_sqrt
: return numeric::sqrt (arg
);
4895 case e_tan
: return numeric::tan (arg
);
4896 case e_tanh
: return numeric::tanh (arg
);
4897 case e_cot
: return numeric::cot (arg
);
4898 case e_sec
: return numeric::sec (arg
);
4899 case e_csc
: return numeric::csc (arg
);
4900 case e_r2d
: return numeric::r2d (arg
);
4901 case e_d2r
: return numeric::d2r (arg
);
4902 case e_d2g
: return numeric::d2g (arg
);
4903 case e_g2d
: return numeric::g2d (arg
);
4904 case e_notl
: return numeric::notl (arg
);
4905 case e_sgn
: return numeric::sgn (arg
);
4906 case e_erf
: return numeric::erf (arg
);
4907 case e_erfc
: return numeric::erfc (arg
);
4908 case e_ncdf
: return numeric::ncdf (arg
);
4909 case e_frac
: return numeric::frac (arg
);
4910 case e_trunc
: return numeric::trunc(arg
);
4912 default : exprtk_debug(("numeric::details::process_impl<T> - Invalid unary operation.\n"));
4913 return std::numeric_limits
<T
>::quiet_NaN();
4917 template <typename T
>
4918 inline T
process_impl(const operator_type operation
, const T arg0
, const T arg1
)
4922 case e_add
: return (arg0
+ arg1
);
4923 case e_sub
: return (arg0
- arg1
);
4924 case e_mul
: return (arg0
* arg1
);
4925 case e_div
: return (arg0
/ arg1
);
4926 case e_mod
: return modulus
<T
>(arg0
,arg1
);
4927 case e_pow
: return pow
<T
>(arg0
,arg1
);
4928 case e_atan2
: return atan2
<T
>(arg0
,arg1
);
4929 case e_min
: return std::min
<T
>(arg0
,arg1
);
4930 case e_max
: return std::max
<T
>(arg0
,arg1
);
4931 case e_logn
: return logn
<T
>(arg0
,arg1
);
4932 case e_lt
: return (arg0
< arg1
) ? T(1) : T(0);
4933 case e_lte
: return (arg0
<= arg1
) ? T(1) : T(0);
4934 case e_eq
: return std::equal_to
<T
>()(arg0
,arg1
) ? T(1) : T(0);
4935 case e_ne
: return std::not_equal_to
<T
>()(arg0
,arg1
) ? T(1) : T(0);
4936 case e_gte
: return (arg0
>= arg1
) ? T(1) : T(0);
4937 case e_gt
: return (arg0
> arg1
) ? T(1) : T(0);
4938 case e_and
: return and_opr
<T
>(arg0
,arg1
);
4939 case e_nand
: return nand_opr
<T
>(arg0
,arg1
);
4940 case e_or
: return or_opr
<T
>(arg0
,arg1
);
4941 case e_nor
: return nor_opr
<T
>(arg0
,arg1
);
4942 case e_xor
: return xor_opr
<T
>(arg0
,arg1
);
4943 case e_xnor
: return xnor_opr
<T
>(arg0
,arg1
);
4944 case e_root
: return root
<T
>(arg0
,arg1
);
4945 case e_roundn
: return roundn
<T
>(arg0
,arg1
);
4946 case e_equal
: return equal (arg0
,arg1
);
4947 case e_nequal
: return nequal (arg0
,arg1
);
4948 case e_hypot
: return hypot
<T
>(arg0
,arg1
);
4949 case e_shr
: return shr
<T
>(arg0
,arg1
);
4950 case e_shl
: return shl
<T
>(arg0
,arg1
);
4952 default : exprtk_debug(("numeric::details::process_impl<T> - Invalid binary operation.\n"));
4953 return std::numeric_limits
<T
>::quiet_NaN();
4957 template <typename T
>
4958 inline T
process_impl(const operator_type operation
, const T arg0
, const T arg1
, int_type_tag
)
4962 case e_add
: return (arg0
+ arg1
);
4963 case e_sub
: return (arg0
- arg1
);
4964 case e_mul
: return (arg0
* arg1
);
4965 case e_div
: return (arg0
/ arg1
);
4966 case e_mod
: return arg0
% arg1
;
4967 case e_pow
: return pow
<T
>(arg0
,arg1
);
4968 case e_min
: return std::min
<T
>(arg0
,arg1
);
4969 case e_max
: return std::max
<T
>(arg0
,arg1
);
4970 case e_logn
: return logn
<T
>(arg0
,arg1
);
4971 case e_lt
: return (arg0
< arg1
) ? T(1) : T(0);
4972 case e_lte
: return (arg0
<= arg1
) ? T(1) : T(0);
4973 case e_eq
: return (arg0
== arg1
) ? T(1) : T(0);
4974 case e_ne
: return (arg0
!= arg1
) ? T(1) : T(0);
4975 case e_gte
: return (arg0
>= arg1
) ? T(1) : T(0);
4976 case e_gt
: return (arg0
> arg1
) ? T(1) : T(0);
4977 case e_and
: return ((arg0
!= T(0)) && (arg1
!= T(0))) ? T(1) : T(0);
4978 case e_nand
: return ((arg0
!= T(0)) && (arg1
!= T(0))) ? T(0) : T(1);
4979 case e_or
: return ((arg0
!= T(0)) || (arg1
!= T(0))) ? T(1) : T(0);
4980 case e_nor
: return ((arg0
!= T(0)) || (arg1
!= T(0))) ? T(0) : T(1);
4981 case e_xor
: return arg0
^ arg1
;
4982 case e_xnor
: return !(arg0
^ arg1
);
4983 case e_root
: return root
<T
>(arg0
,arg1
);
4984 case e_equal
: return arg0
== arg1
;
4985 case e_nequal
: return arg0
!= arg1
;
4986 case e_hypot
: return hypot
<T
>(arg0
,arg1
);
4987 case e_shr
: return arg0
>> arg1
;
4988 case e_shl
: return arg0
<< arg1
;
4990 default : exprtk_debug(("numeric::details::process_impl<IntType> - Invalid binary operation.\n"));
4991 return std::numeric_limits
<T
>::quiet_NaN();
4996 template <typename T
>
4997 inline T
process(const operator_type operation
, const T arg
)
4999 return exprtk::details::numeric::details::process_impl(operation
,arg
);
5002 template <typename T
>
5003 inline T
process(const operator_type operation
, const T arg0
, const T arg1
)
5005 return exprtk::details::numeric::details::process_impl(operation
, arg0
, arg1
);
5009 template <typename T
>
5010 class expression_node
5016 e_none
, e_null
, e_constant
, e_unary
,
5017 e_binary
, e_binary_ext
, e_trinary
, e_quaternary
,
5018 e_vararg
, e_conditional
, e_while
, e_repeat
,
5019 e_for
, e_switch
, e_mswitch
, e_return
,
5020 e_retenv
, e_variable
, e_stringvar
, e_stringconst
,
5021 e_stringvarrng
, e_cstringvarrng
, e_strgenrange
, e_strconcat
,
5022 e_stringvarsize
, e_strswap
, e_stringsize
, e_stringvararg
,
5023 e_function
, e_vafunction
, e_genfunction
, e_strfunction
,
5024 e_strcondition
, e_strccondition
, e_add
, e_sub
,
5025 e_mul
, e_div
, e_mod
, e_pow
,
5026 e_lt
, e_lte
, e_gt
, e_gte
,
5027 e_eq
, e_ne
, e_and
, e_nand
,
5028 e_or
, e_nor
, e_xor
, e_xnor
,
5029 e_in
, e_like
, e_ilike
, e_inranges
,
5030 e_ipow
, e_ipowinv
, e_abs
, e_acos
,
5031 e_acosh
, e_asin
, e_asinh
, e_atan
,
5032 e_atanh
, e_ceil
, e_cos
, e_cosh
,
5033 e_exp
, e_expm1
, e_floor
, e_log
,
5034 e_log10
, e_log2
, e_log1p
, e_neg
,
5035 e_pos
, e_round
, e_sin
, e_sinc
,
5036 e_sinh
, e_sqrt
, e_tan
, e_tanh
,
5037 e_cot
, e_sec
, e_csc
, e_r2d
,
5038 e_d2r
, e_d2g
, e_g2d
, e_notl
,
5039 e_sgn
, e_erf
, e_erfc
, e_ncdf
,
5040 e_frac
, e_trunc
, e_uvouv
, e_vov
,
5041 e_cov
, e_voc
, e_vob
, e_bov
,
5042 e_cob
, e_boc
, e_vovov
, e_vovoc
,
5043 e_vocov
, e_covov
, e_covoc
, e_vovovov
,
5044 e_vovovoc
, e_vovocov
, e_vocovov
, e_covovov
,
5045 e_covocov
, e_vocovoc
, e_covovoc
, e_vococov
,
5046 e_sf3ext
, e_sf4ext
, e_nulleq
, e_strass
,
5047 e_vector
, e_vecelem
, e_rbvecelem
, e_rbveccelem
,
5048 e_vecdefass
, e_vecvalass
, e_vecvecass
, e_vecopvalass
,
5049 e_vecopvecass
, e_vecfunc
, e_vecvecswap
, e_vecvecineq
,
5050 e_vecvalineq
, e_valvecineq
, e_vecvecarith
, e_vecvalarith
,
5051 e_valvecarith
, e_vecunaryop
, e_break
, e_continue
,
5055 typedef T value_type
;
5056 typedef expression_node
<T
>* expression_ptr
;
5058 virtual ~expression_node()
5061 inline virtual T
value() const
5063 return std::numeric_limits
<T
>::quiet_NaN();
5066 inline virtual expression_node
<T
>* branch(const std::size_t& index
= 0) const
5068 return reinterpret_cast<expression_ptr
>(index
* 0);
5071 inline virtual node_type
type() const
5077 template <typename T
>
5078 inline bool is_generally_string_node(const expression_node
<T
>* node
);
5080 inline bool is_true(const double v
)
5082 return std::not_equal_to
<double>()(0.0,v
);
5085 inline bool is_true(const long double v
)
5087 return std::not_equal_to
<long double>()(0.0L,v
);
5090 inline bool is_true(const float v
)
5092 return std::not_equal_to
<float>()(0.0f
,v
);
5095 template <typename T
>
5096 inline bool is_true(const std::complex<T
>& v
)
5098 return std::not_equal_to
<std::complex<T
> >()(std::complex<T
>(0),v
);
5101 template <typename T
>
5102 inline bool is_true(const expression_node
<T
>* node
)
5104 return std::not_equal_to
<T
>()(T(0),node
->value());
5107 template <typename T
>
5108 inline bool is_false(const expression_node
<T
>* node
)
5110 return std::equal_to
<T
>()(T(0),node
->value());
5113 template <typename T
>
5114 inline bool is_unary_node(const expression_node
<T
>* node
)
5116 return node
&& (details::expression_node
<T
>::e_unary
== node
->type());
5119 template <typename T
>
5120 inline bool is_neg_unary_node(const expression_node
<T
>* node
)
5122 return node
&& (details::expression_node
<T
>::e_neg
== node
->type());
5125 template <typename T
>
5126 inline bool is_binary_node(const expression_node
<T
>* node
)
5128 return node
&& (details::expression_node
<T
>::e_binary
== node
->type());
5131 template <typename T
>
5132 inline bool is_variable_node(const expression_node
<T
>* node
)
5134 return node
&& (details::expression_node
<T
>::e_variable
== node
->type());
5137 template <typename T
>
5138 inline bool is_ivariable_node(const expression_node
<T
>* node
)
5142 details::expression_node
<T
>::e_variable
== node
->type() ||
5143 details::expression_node
<T
>::e_vecelem
== node
->type() ||
5144 details::expression_node
<T
>::e_rbvecelem
== node
->type() ||
5145 details::expression_node
<T
>::e_rbveccelem
== node
->type()
5149 template <typename T
>
5150 inline bool is_vector_elem_node(const expression_node
<T
>* node
)
5152 return node
&& (details::expression_node
<T
>::e_vecelem
== node
->type());
5155 template <typename T
>
5156 inline bool is_rebasevector_elem_node(const expression_node
<T
>* node
)
5158 return node
&& (details::expression_node
<T
>::e_rbvecelem
== node
->type());
5161 template <typename T
>
5162 inline bool is_rebasevector_celem_node(const expression_node
<T
>* node
)
5164 return node
&& (details::expression_node
<T
>::e_rbveccelem
== node
->type());
5167 template <typename T
>
5168 inline bool is_vector_node(const expression_node
<T
>* node
)
5170 return node
&& (details::expression_node
<T
>::e_vector
== node
->type());
5173 template <typename T
>
5174 inline bool is_ivector_node(const expression_node
<T
>* node
)
5178 switch (node
->type())
5180 case details::expression_node
<T
>::e_vector
:
5181 case details::expression_node
<T
>::e_vecvalass
:
5182 case details::expression_node
<T
>::e_vecvecass
:
5183 case details::expression_node
<T
>::e_vecopvalass
:
5184 case details::expression_node
<T
>::e_vecopvecass
:
5185 case details::expression_node
<T
>::e_vecvecswap
:
5186 case details::expression_node
<T
>::e_vecvecarith
:
5187 case details::expression_node
<T
>::e_vecvalarith
:
5188 case details::expression_node
<T
>::e_valvecarith
:
5189 case details::expression_node
<T
>::e_vecunaryop
: return true;
5190 default : return false;
5197 template <typename T
>
5198 inline bool is_constant_node(const expression_node
<T
>* node
)
5200 return node
&& (details::expression_node
<T
>::e_constant
== node
->type());
5203 template <typename T
>
5204 inline bool is_null_node(const expression_node
<T
>* node
)
5206 return node
&& (details::expression_node
<T
>::e_null
== node
->type());
5209 template <typename T
>
5210 inline bool is_break_node(const expression_node
<T
>* node
)
5212 return node
&& (details::expression_node
<T
>::e_break
== node
->type());
5215 template <typename T
>
5216 inline bool is_continue_node(const expression_node
<T
>* node
)
5218 return node
&& (details::expression_node
<T
>::e_continue
== node
->type());
5221 template <typename T
>
5222 inline bool is_swap_node(const expression_node
<T
>* node
)
5224 return node
&& (details::expression_node
<T
>::e_swap
== node
->type());
5227 template <typename T
>
5228 inline bool is_function(const expression_node
<T
>* node
)
5230 return node
&& (details::expression_node
<T
>::e_function
== node
->type());
5233 template <typename T
>
5234 inline bool is_return_node(const expression_node
<T
>* node
)
5236 return node
&& (details::expression_node
<T
>::e_return
== node
->type());
5239 template <typename T
> class unary_node
;
5241 template <typename T
>
5242 inline bool is_negate_node(const expression_node
<T
>* node
)
5244 if (node
&& is_unary_node(node
))
5246 return (details::e_neg
== static_cast<const unary_node
<T
>*>(node
)->operation());
5252 template <typename T
>
5253 inline bool branch_deletable(expression_node
<T
>* node
)
5255 return !is_variable_node(node
) &&
5256 !is_string_node (node
) ;
5259 template <std::size_t N
, typename T
>
5260 inline bool all_nodes_valid(expression_node
<T
>* (&b
)[N
])
5262 for (std::size_t i
= 0; i
< N
; ++i
)
5264 if (0 == b
[i
]) return false;
5270 template <typename T
,
5272 template <typename
, typename
> class Sequence
>
5273 inline bool all_nodes_valid(const Sequence
<expression_node
<T
>*,Allocator
>& b
)
5275 for (std::size_t i
= 0; i
< b
.size(); ++i
)
5277 if (0 == b
[i
]) return false;
5283 template <std::size_t N
, typename T
>
5284 inline bool all_nodes_variables(expression_node
<T
>* (&b
)[N
])
5286 for (std::size_t i
= 0; i
< N
; ++i
)
5290 else if (!is_variable_node(b
[i
]))
5297 template <typename T
,
5299 template <typename
, typename
> class Sequence
>
5300 inline bool all_nodes_variables(Sequence
<expression_node
<T
>*,Allocator
>& b
)
5302 for (std::size_t i
= 0; i
< b
.size(); ++i
)
5306 else if (!is_variable_node(b
[i
]))
5313 template <typename NodeAllocator
, typename T
, std::size_t N
>
5314 inline void free_all_nodes(NodeAllocator
& node_allocator
, expression_node
<T
>* (&b
)[N
])
5316 for (std::size_t i
= 0; i
< N
; ++i
)
5318 free_node(node_allocator
,b
[i
]);
5322 template <typename NodeAllocator
,
5325 template <typename
, typename
> class Sequence
>
5326 inline void free_all_nodes(NodeAllocator
& node_allocator
, Sequence
<expression_node
<T
>*,Allocator
>& b
)
5328 for (std::size_t i
= 0; i
< b
.size(); ++i
)
5330 free_node(node_allocator
,b
[i
]);
5336 template <typename NodeAllocator
, typename T
>
5337 inline void free_node(NodeAllocator
& node_allocator
, expression_node
<T
>*& node
, const bool force_delete
= false)
5342 (is_variable_node(node
) || is_string_node(node
)) ||
5347 node_allocator
.free(node
);
5348 node
= reinterpret_cast<expression_node
<T
>*>(0);
5352 template <typename T
>
5353 inline void destroy_node(expression_node
<T
>*& node
)
5356 node
= reinterpret_cast<expression_node
<T
>*>(0);
5359 template <typename Type
>
5364 typedef Type value_type
;
5365 typedef value_type
* value_ptr
;
5366 typedef const value_ptr const_value_ptr
;
5368 class vector_holder_base
5372 virtual ~vector_holder_base() {}
5374 inline value_ptr
operator[](const std::size_t& index
) const
5376 return value_at(index
);
5379 inline std::size_t size() const
5381 return vector_size();
5384 inline value_ptr
data() const
5389 virtual inline bool rebaseable() const
5394 virtual void set_ref(value_ptr
*) {}
5398 virtual value_ptr
value_at(const std::size_t&) const = 0;
5399 virtual std::size_t vector_size() const = 0;
5402 class array_vector_impl
: public vector_holder_base
5406 array_vector_impl(const Type
* vec
, const std::size_t& vec_size
)
5413 value_ptr
value_at(const std::size_t& index
) const
5416 return const_cast<const_value_ptr
>(vec_
+ index
);
5418 return const_value_ptr(0);
5421 std::size_t vector_size() const
5428 array_vector_impl
operator=(const array_vector_impl
&);
5431 const std::size_t size_
;
5434 template <typename Allocator
,
5435 template <typename
, typename
> class Sequence
>
5436 class sequence_vector_impl
: public vector_holder_base
5440 typedef Sequence
<Type
,Allocator
> sequence_t
;
5442 sequence_vector_impl(sequence_t
& seq
)
5448 value_ptr
value_at(const std::size_t& index
) const
5450 return (index
< sequence_
.size()) ? (&sequence_
[index
]) : const_value_ptr(0);
5453 std::size_t vector_size() const
5455 return sequence_
.size();
5460 sequence_vector_impl
operator=(const sequence_vector_impl
&);
5462 sequence_t
& sequence_
;
5465 class vector_view_impl
: public vector_holder_base
5469 typedef exprtk::vector_view
<Type
> vector_view_t
;
5471 vector_view_impl(vector_view_t
& vec_view
)
5472 : vec_view_(vec_view
)
5475 void set_ref(value_ptr
* ref
)
5477 vec_view_
.set_ref(ref
);
5480 virtual inline bool rebaseable() const
5487 value_ptr
value_at(const std::size_t& index
) const
5489 return (index
< vec_view_
.size()) ? (&vec_view_
[index
]) : const_value_ptr(0);
5492 std::size_t vector_size() const
5494 return vec_view_
.size();
5499 vector_view_impl
operator=(const vector_view_impl
&);
5501 vector_view_t
& vec_view_
;
5506 typedef typename
details::vec_data_store
<Type
> vds_t
;
5508 vector_holder(Type
* vec
, const std::size_t& vec_size
)
5509 : vector_holder_base_(new(buffer
)array_vector_impl(vec
,vec_size
))
5512 vector_holder(const vds_t
& vds
)
5513 : vector_holder_base_(new(buffer
)array_vector_impl(vds
.data(),vds
.size()))
5516 template <typename Allocator
>
5517 vector_holder(std::vector
<Type
,Allocator
>& vec
)
5518 : vector_holder_base_(new(buffer
)sequence_vector_impl
<Allocator
,std::vector
>(vec
))
5521 vector_holder(exprtk::vector_view
<Type
>& vec
)
5522 : vector_holder_base_(new(buffer
)vector_view_impl(vec
))
5525 inline value_ptr
operator[](const std::size_t& index
) const
5527 return (*vector_holder_base_
)[index
];
5530 inline std::size_t size() const
5532 return vector_holder_base_
->size();
5535 inline value_ptr
data() const
5537 return vector_holder_base_
->data();
5540 void set_ref(value_ptr
* ref
)
5542 vector_holder_base_
->set_ref(ref
);
5545 bool rebaseable() const
5547 return vector_holder_base_
->rebaseable();
5552 mutable vector_holder_base
* vector_holder_base_
;
5556 template <typename T
>
5557 class null_node
: public expression_node
<T
>
5561 inline T
value() const
5563 return std::numeric_limits
<T
>::quiet_NaN();
5566 inline typename expression_node
<T
>::node_type
type() const
5568 return expression_node
<T
>::e_null
;
5572 template <typename T
>
5573 class null_eq_node
: public expression_node
<T
>
5577 typedef expression_node
<T
>* expression_ptr
;
5579 null_eq_node(expression_ptr brnch
, const bool equality
= true)
5581 branch_deletable_(branch_deletable(branch_
)),
5587 if (branch_
&& branch_deletable_
)
5589 destroy_node(branch_
);
5593 inline T
value() const
5595 const T v
= branch_
->value();
5596 const bool result
= details::numeric::is_nan(v
);
5599 return (equality_
) ? T(1) : T(0);
5601 return (equality_
) ? T(0) : T(1);
5604 inline typename expression_node
<T
>::node_type
type() const
5606 return expression_node
<T
>::e_nulleq
;
5609 inline operator_type
operation() const
5611 return details::e_eq
;
5614 inline expression_node
<T
>* branch(const std::size_t&) const
5621 expression_ptr branch_
;
5622 const bool branch_deletable_
;
5626 template <typename T
>
5627 class literal_node
: public expression_node
<T
>
5631 explicit literal_node(const T
& v
)
5635 inline T
value() const
5640 inline typename expression_node
<T
>::node_type
type() const
5642 return expression_node
<T
>::e_constant
;
5645 inline expression_node
<T
>* branch(const std::size_t&) const
5647 return reinterpret_cast<expression_node
<T
>*>(0);
5652 literal_node(literal_node
<T
>&) {}
5653 literal_node
<T
>& operator=(literal_node
<T
>&) { return (*this); }
5658 template <typename T
>
5661 template <typename T
>
5662 struct range_data_type
;
5664 template <typename T
>
5665 class range_interface
5669 typedef range_pack
<T
> range_t
;
5671 virtual ~range_interface()
5674 virtual range_t
& range_ref() = 0;
5676 virtual const range_t
& range_ref() const = 0;
5679 #ifndef exprtk_disable_string_capabilities
5680 template <typename T
>
5681 class string_base_node
5685 typedef range_data_type
<T
> range_data_type_t
;
5687 virtual ~string_base_node()
5690 virtual std::string
str () const = 0;
5692 virtual char_cptr
base() const = 0;
5694 virtual std::size_t size() const = 0;
5697 template <typename T
>
5698 class string_literal_node
: public expression_node
<T
>,
5699 public string_base_node
<T
>,
5700 public range_interface
<T
>
5704 typedef range_pack
<T
> range_t
;
5706 explicit string_literal_node(const std::string
& v
)
5709 rp_
.n0_c
= std::make_pair
<bool,std::size_t>(true,0);
5710 rp_
.n1_c
= std::make_pair
<bool,std::size_t>(true,v
.size() - 1);
5711 rp_
.cache
.first
= rp_
.n0_c
.second
;
5712 rp_
.cache
.second
= rp_
.n1_c
.second
;
5715 inline T
value() const
5717 return std::numeric_limits
<T
>::quiet_NaN();
5720 inline typename expression_node
<T
>::node_type
type() const
5722 return expression_node
<T
>::e_stringconst
;
5725 inline expression_node
<T
>* branch(const std::size_t&) const
5727 return reinterpret_cast<expression_node
<T
>*>(0);
5730 std::string
str() const
5735 char_cptr
base() const
5737 return value_
.data();
5740 std::size_t size() const
5742 return value_
.size();
5745 range_t
& range_ref()
5750 const range_t
& range_ref() const
5757 string_literal_node(const string_literal_node
<T
>&);
5758 string_literal_node
<T
>& operator=(const string_literal_node
<T
>&);
5760 const std::string value_
;
5765 template <typename T
>
5766 class unary_node
: public expression_node
<T
>
5770 typedef expression_node
<T
>* expression_ptr
;
5772 unary_node(const operator_type
& opr
,
5773 expression_ptr brnch
)
5776 branch_deletable_(branch_deletable(branch_
))
5781 if (branch_
&& branch_deletable_
)
5783 destroy_node(branch_
);
5787 inline T
value() const
5789 const T arg
= branch_
->value();
5791 return numeric::process
<T
>(operation_
,arg
);
5794 inline typename expression_node
<T
>::node_type
type() const
5796 return expression_node
<T
>::e_unary
;
5799 inline operator_type
operation() const
5804 inline expression_node
<T
>* branch(const std::size_t&) const
5809 inline void release()
5811 branch_deletable_
= false;
5816 operator_type operation_
;
5817 expression_ptr branch_
;
5818 bool branch_deletable_
;
5821 template <typename T
, std::size_t D
, bool B
>
5822 struct construct_branch_pair
5824 template <std::size_t N
>
5825 static inline void process(std::pair
<expression_node
<T
>*,bool> (&)[N
], expression_node
<T
>*)
5829 template <typename T
, std::size_t D
>
5830 struct construct_branch_pair
<T
,D
,true>
5832 template <std::size_t N
>
5833 static inline void process(std::pair
<expression_node
<T
>*,bool> (&branch
)[N
], expression_node
<T
>* b
)
5837 branch
[D
] = std::make_pair(b
,branch_deletable(b
));
5842 template <std::size_t N
, typename T
>
5843 inline void init_branches(std::pair
<expression_node
<T
>*,bool> (&branch
)[N
],
5844 expression_node
<T
>* b0
,
5845 expression_node
<T
>* b1
= reinterpret_cast<expression_node
<T
>*>(0),
5846 expression_node
<T
>* b2
= reinterpret_cast<expression_node
<T
>*>(0),
5847 expression_node
<T
>* b3
= reinterpret_cast<expression_node
<T
>*>(0),
5848 expression_node
<T
>* b4
= reinterpret_cast<expression_node
<T
>*>(0),
5849 expression_node
<T
>* b5
= reinterpret_cast<expression_node
<T
>*>(0),
5850 expression_node
<T
>* b6
= reinterpret_cast<expression_node
<T
>*>(0),
5851 expression_node
<T
>* b7
= reinterpret_cast<expression_node
<T
>*>(0),
5852 expression_node
<T
>* b8
= reinterpret_cast<expression_node
<T
>*>(0),
5853 expression_node
<T
>* b9
= reinterpret_cast<expression_node
<T
>*>(0))
5855 construct_branch_pair
<T
,0,(N
> 0)>::process(branch
,b0
);
5856 construct_branch_pair
<T
,1,(N
> 1)>::process(branch
,b1
);
5857 construct_branch_pair
<T
,2,(N
> 2)>::process(branch
,b2
);
5858 construct_branch_pair
<T
,3,(N
> 3)>::process(branch
,b3
);
5859 construct_branch_pair
<T
,4,(N
> 4)>::process(branch
,b4
);
5860 construct_branch_pair
<T
,5,(N
> 5)>::process(branch
,b5
);
5861 construct_branch_pair
<T
,6,(N
> 6)>::process(branch
,b6
);
5862 construct_branch_pair
<T
,7,(N
> 7)>::process(branch
,b7
);
5863 construct_branch_pair
<T
,8,(N
> 8)>::process(branch
,b8
);
5864 construct_branch_pair
<T
,9,(N
> 9)>::process(branch
,b9
);
5867 struct cleanup_branches
5869 template <typename T
, std::size_t N
>
5870 static inline void execute(std::pair
<expression_node
<T
>*,bool> (&branch
)[N
])
5872 for (std::size_t i
= 0; i
< N
; ++i
)
5874 if (branch
[i
].first
&& branch
[i
].second
)
5876 destroy_node(branch
[i
].first
);
5881 template <typename T
,
5883 template <typename
, typename
> class Sequence
>
5884 static inline void execute(Sequence
<std::pair
<expression_node
<T
>*,bool>,Allocator
>& branch
)
5886 for (std::size_t i
= 0; i
< branch
.size(); ++i
)
5888 if (branch
[i
].first
&& branch
[i
].second
)
5890 destroy_node(branch
[i
].first
);
5896 template <typename T
>
5897 class binary_node
: public expression_node
<T
>
5901 typedef expression_node
<T
>* expression_ptr
;
5902 typedef std::pair
<expression_ptr
,bool> branch_t
;
5904 binary_node(const operator_type
& opr
,
5905 expression_ptr branch0
,
5906 expression_ptr branch1
)
5909 init_branches
<2>(branch_
, branch0
, branch1
);
5914 cleanup_branches::execute
<T
,2>(branch_
);
5917 inline T
value() const
5919 const T arg0
= branch_
[0].first
->value();
5920 const T arg1
= branch_
[1].first
->value();
5922 return numeric::process
<T
>(operation_
,arg0
,arg1
);
5925 inline typename expression_node
<T
>::node_type
type() const
5927 return expression_node
<T
>::e_binary
;
5930 inline operator_type
operation()
5935 inline expression_node
<T
>* branch(const std::size_t& index
= 0) const
5938 return branch_
[0].first
;
5939 else if (1 == index
)
5940 return branch_
[1].first
;
5942 return reinterpret_cast<expression_ptr
>(0);
5947 operator_type operation_
;
5948 branch_t branch_
[2];
5951 template <typename T
, typename Operation
>
5952 class binary_ext_node
: public expression_node
<T
>
5956 typedef expression_node
<T
>* expression_ptr
;
5957 typedef std::pair
<expression_ptr
,bool> branch_t
;
5959 binary_ext_node(expression_ptr branch0
, expression_ptr branch1
)
5961 init_branches
<2>(branch_
, branch0
, branch1
);
5966 cleanup_branches::execute
<T
,2>(branch_
);
5969 inline T
value() const
5971 const T arg0
= branch_
[0].first
->value();
5972 const T arg1
= branch_
[1].first
->value();
5974 return Operation::process(arg0
,arg1
);
5977 inline typename expression_node
<T
>::node_type
type() const
5979 return expression_node
<T
>::e_binary_ext
;
5982 inline operator_type
operation()
5984 return Operation::operation();
5987 inline expression_node
<T
>* branch(const std::size_t& index
= 0) const
5990 return branch_
[0].first
;
5991 else if (1 == index
)
5992 return branch_
[1].first
;
5994 return reinterpret_cast<expression_ptr
>(0);
5999 branch_t branch_
[2];
6002 template <typename T
>
6003 class trinary_node
: public expression_node
<T
>
6007 typedef expression_node
<T
>* expression_ptr
;
6008 typedef std::pair
<expression_ptr
,bool> branch_t
;
6010 trinary_node(const operator_type
& opr
,
6011 expression_ptr branch0
,
6012 expression_ptr branch1
,
6013 expression_ptr branch2
)
6016 init_branches
<3>(branch_
, branch0
, branch1
, branch2
);
6021 cleanup_branches::execute
<T
,3>(branch_
);
6024 inline T
value() const
6026 const T arg0
= branch_
[0].first
->value();
6027 const T arg1
= branch_
[1].first
->value();
6028 const T arg2
= branch_
[2].first
->value();
6032 case e_inrange
: return (arg1
< arg0
) ? T(0) : ((arg1
> arg2
) ? T(0) : T(1));
6034 case e_clamp
: return (arg1
< arg0
) ? arg0
: (arg1
> arg2
? arg2
: arg1
);
6036 case e_iclamp
: if ((arg1
<= arg0
) || (arg1
>= arg2
))
6039 return ((T(2) * arg1
<= (arg2
+ arg0
)) ? arg0
: arg2
);
6041 default : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n"));
6042 return std::numeric_limits
<T
>::quiet_NaN();
6046 inline typename expression_node
<T
>::node_type
type() const
6048 return expression_node
<T
>::e_trinary
;
6053 operator_type operation_
;
6054 branch_t branch_
[3];
6057 template <typename T
>
6058 class quaternary_node
: public expression_node
<T
>
6062 typedef expression_node
<T
>* expression_ptr
;
6063 typedef std::pair
<expression_ptr
,bool> branch_t
;
6065 quaternary_node(const operator_type
& opr
,
6066 expression_ptr branch0
,
6067 expression_ptr branch1
,
6068 expression_ptr branch2
,
6069 expression_ptr branch3
)
6072 init_branches
<4>(branch_
, branch0
, branch1
, branch2
, branch3
);
6077 cleanup_branches::execute
<T
,4>(branch_
);
6080 inline T
value() const
6082 return std::numeric_limits
<T
>::quiet_NaN();
6085 inline typename expression_node
<T
>::node_type
type() const
6087 return expression_node
<T
>::e_quaternary
;
6092 operator_type operation_
;
6093 branch_t branch_
[4];
6096 template <typename T
>
6097 class conditional_node
: public expression_node
<T
>
6101 typedef expression_node
<T
>* expression_ptr
;
6103 conditional_node(expression_ptr test
,
6104 expression_ptr consequent
,
6105 expression_ptr alternative
)
6107 consequent_(consequent
),
6108 alternative_(alternative
),
6109 test_deletable_(branch_deletable(test_
)),
6110 consequent_deletable_(branch_deletable(consequent_
)),
6111 alternative_deletable_(branch_deletable(alternative_
))
6116 if (test_
&& test_deletable_
)
6118 destroy_node(test_
);
6121 if (consequent_
&& consequent_deletable_
)
6123 destroy_node(consequent_
);
6126 if (alternative_
&& alternative_deletable_
)
6128 destroy_node(alternative_
);
6132 inline T
value() const
6135 return consequent_
->value();
6137 return alternative_
->value();
6140 inline typename expression_node
<T
>::node_type
type() const
6142 return expression_node
<T
>::e_conditional
;
6147 expression_ptr test_
;
6148 expression_ptr consequent_
;
6149 expression_ptr alternative_
;
6150 const bool test_deletable_
;
6151 const bool consequent_deletable_
;
6152 const bool alternative_deletable_
;
6155 template <typename T
>
6156 class cons_conditional_node
: public expression_node
<T
>
6160 // Consequent only conditional statement node
6161 typedef expression_node
<T
>* expression_ptr
;
6163 cons_conditional_node(expression_ptr test
,
6164 expression_ptr consequent
)
6166 consequent_(consequent
),
6167 test_deletable_(branch_deletable(test_
)),
6168 consequent_deletable_(branch_deletable(consequent_
))
6171 ~cons_conditional_node()
6173 if (test_
&& test_deletable_
)
6175 destroy_node(test_
);
6178 if (consequent_
&& consequent_deletable_
)
6180 destroy_node(consequent_
);
6184 inline T
value() const
6187 return consequent_
->value();
6189 return std::numeric_limits
<T
>::quiet_NaN();
6192 inline typename expression_node
<T
>::node_type
type() const
6194 return expression_node
<T
>::e_conditional
;
6199 expression_ptr test_
;
6200 expression_ptr consequent_
;
6201 const bool test_deletable_
;
6202 const bool consequent_deletable_
;
6205 #ifndef exprtk_disable_break_continue
6206 template <typename T
>
6207 class break_exception
6211 break_exception(const T
& v
)
6218 class continue_exception
6221 template <typename T
>
6222 class break_node
: public expression_node
<T
>
6226 typedef expression_node
<T
>* expression_ptr
;
6228 break_node(expression_ptr ret
= expression_ptr(0))
6230 return_deletable_(branch_deletable(return_
))
6235 if (return_deletable_
)
6237 destroy_node(return_
);
6241 inline T
value() const
6243 throw break_exception
<T
>(return_
? return_
->value() : std::numeric_limits
<T
>::quiet_NaN());
6245 return std::numeric_limits
<T
>::quiet_NaN();
6249 inline typename expression_node
<T
>::node_type
type() const
6251 return expression_node
<T
>::e_break
;
6256 expression_ptr return_
;
6257 const bool return_deletable_
;
6260 template <typename T
>
6261 class continue_node
: public expression_node
<T
>
6265 inline T
value() const
6267 throw continue_exception();
6269 return std::numeric_limits
<T
>::quiet_NaN();
6273 inline typename expression_node
<T
>::node_type
type() const
6275 return expression_node
<T
>::e_break
;
6280 template <typename T
>
6281 class while_loop_node
: public expression_node
<T
>
6285 typedef expression_node
<T
>* expression_ptr
;
6287 while_loop_node(expression_ptr condition
, expression_ptr loop_body
)
6288 : condition_(condition
),
6289 loop_body_(loop_body
),
6290 condition_deletable_(branch_deletable(condition_
)),
6291 loop_body_deletable_(branch_deletable(loop_body_
))
6296 if (condition_
&& condition_deletable_
)
6298 destroy_node(condition_
);
6301 if (loop_body_
&& loop_body_deletable_
)
6303 destroy_node(loop_body_
);
6307 inline T
value() const
6311 while (is_true(condition_
))
6313 result
= loop_body_
->value();
6319 inline typename expression_node
<T
>::node_type
type() const
6321 return expression_node
<T
>::e_while
;
6326 expression_ptr condition_
;
6327 expression_ptr loop_body_
;
6328 const bool condition_deletable_
;
6329 const bool loop_body_deletable_
;
6332 template <typename T
>
6333 class repeat_until_loop_node
: public expression_node
<T
>
6337 typedef expression_node
<T
>* expression_ptr
;
6339 repeat_until_loop_node(expression_ptr condition
, expression_ptr loop_body
)
6340 : condition_(condition
),
6341 loop_body_(loop_body
),
6342 condition_deletable_(branch_deletable(condition_
)),
6343 loop_body_deletable_(branch_deletable(loop_body_
))
6346 ~repeat_until_loop_node()
6348 if (condition_
&& condition_deletable_
)
6350 destroy_node(condition_
);
6353 if (loop_body_
&& loop_body_deletable_
)
6355 destroy_node(loop_body_
);
6359 inline T
value() const
6365 result
= loop_body_
->value();
6367 while (is_false(condition_
));
6372 inline typename expression_node
<T
>::node_type
type() const
6374 return expression_node
<T
>::e_repeat
;
6379 expression_ptr condition_
;
6380 expression_ptr loop_body_
;
6381 const bool condition_deletable_
;
6382 const bool loop_body_deletable_
;
6385 template <typename T
>
6386 class for_loop_node
: public expression_node
<T
>
6390 typedef expression_node
<T
>* expression_ptr
;
6392 for_loop_node(expression_ptr initialiser
,
6393 expression_ptr condition
,
6394 expression_ptr incrementor
,
6395 expression_ptr loop_body
)
6396 : initialiser_(initialiser
),
6397 condition_ (condition
),
6398 incrementor_(incrementor
),
6399 loop_body_ (loop_body
),
6400 initialiser_deletable_(branch_deletable(initialiser_
)),
6401 condition_deletable_ (branch_deletable(condition_
)),
6402 incrementor_deletable_(branch_deletable(incrementor_
)),
6403 loop_body_deletable_ (branch_deletable(loop_body_
))
6408 if (initialiser_
&& initialiser_deletable_
)
6410 destroy_node(initialiser_
);
6413 if (condition_
&& condition_deletable_
)
6415 destroy_node(condition_
);
6418 if (incrementor_
&& incrementor_deletable_
)
6420 destroy_node(incrementor_
);
6423 if (loop_body_
&& loop_body_deletable_
)
6425 destroy_node(loop_body_
);
6429 inline T
value() const
6434 initialiser_
->value();
6438 while (is_true(condition_
))
6440 result
= loop_body_
->value();
6441 incrementor_
->value();
6446 while (is_true(condition_
))
6448 result
= loop_body_
->value();
6455 inline typename expression_node
<T
>::node_type
type() const
6457 return expression_node
<T
>::e_for
;
6462 expression_ptr initialiser_
;
6463 expression_ptr condition_
;
6464 expression_ptr incrementor_
;
6465 expression_ptr loop_body_
;
6466 const bool initialiser_deletable_
;
6467 const bool condition_deletable_
;
6468 const bool incrementor_deletable_
;
6469 const bool loop_body_deletable_
;
6472 #ifndef exprtk_disable_break_continue
6473 template <typename T
>
6474 class while_loop_bc_node
: public expression_node
<T
>
6478 typedef expression_node
<T
>* expression_ptr
;
6480 while_loop_bc_node(expression_ptr condition
, expression_ptr loop_body
)
6481 : condition_(condition
),
6482 loop_body_(loop_body
),
6483 condition_deletable_(branch_deletable(condition_
)),
6484 loop_body_deletable_(branch_deletable(loop_body_
))
6487 ~while_loop_bc_node()
6489 if (condition_
&& condition_deletable_
)
6491 destroy_node(condition_
);
6494 if (loop_body_
&& loop_body_deletable_
)
6496 destroy_node(loop_body_
);
6500 inline T
value() const
6504 while (is_true(condition_
))
6508 result
= loop_body_
->value();
6510 catch(const break_exception
<T
>& e
)
6514 catch(const continue_exception
&)
6521 inline typename expression_node
<T
>::node_type
type() const
6523 return expression_node
<T
>::e_while
;
6528 expression_ptr condition_
;
6529 expression_ptr loop_body_
;
6530 const bool condition_deletable_
;
6531 const bool loop_body_deletable_
;
6534 template <typename T
>
6535 class repeat_until_loop_bc_node
: public expression_node
<T
>
6539 typedef expression_node
<T
>* expression_ptr
;
6541 repeat_until_loop_bc_node(expression_ptr condition
, expression_ptr loop_body
)
6542 : condition_(condition
),
6543 loop_body_(loop_body
),
6544 condition_deletable_(branch_deletable(condition_
)),
6545 loop_body_deletable_(branch_deletable(loop_body_
))
6548 ~repeat_until_loop_bc_node()
6550 if (condition_
&& condition_deletable_
)
6552 destroy_node(condition_
);
6555 if (loop_body_
&& loop_body_deletable_
)
6557 destroy_node(loop_body_
);
6561 inline T
value() const
6569 result
= loop_body_
->value();
6571 catch(const break_exception
<T
>& e
)
6575 catch(const continue_exception
&)
6578 while (is_false(condition_
));
6583 inline typename expression_node
<T
>::node_type
type() const
6585 return expression_node
<T
>::e_repeat
;
6590 expression_ptr condition_
;
6591 expression_ptr loop_body_
;
6592 const bool condition_deletable_
;
6593 const bool loop_body_deletable_
;
6596 template <typename T
>
6597 class for_loop_bc_node
: public expression_node
<T
>
6601 typedef expression_node
<T
>* expression_ptr
;
6603 for_loop_bc_node(expression_ptr initialiser
,
6604 expression_ptr condition
,
6605 expression_ptr incrementor
,
6606 expression_ptr loop_body
)
6607 : initialiser_(initialiser
),
6608 condition_ (condition
),
6609 incrementor_(incrementor
),
6610 loop_body_ (loop_body
),
6611 initialiser_deletable_(branch_deletable(initialiser_
)),
6612 condition_deletable_ (branch_deletable(condition_
)),
6613 incrementor_deletable_(branch_deletable(incrementor_
)),
6614 loop_body_deletable_ (branch_deletable(loop_body_
))
6619 if (initialiser_
&& initialiser_deletable_
)
6621 destroy_node(initialiser_
);
6624 if (condition_
&& condition_deletable_
)
6626 destroy_node(condition_
);
6629 if (incrementor_
&& incrementor_deletable_
)
6631 destroy_node(incrementor_
);
6634 if (loop_body_
&& loop_body_deletable_
)
6636 destroy_node(loop_body_
);
6640 inline T
value() const
6645 initialiser_
->value();
6649 while (is_true(condition_
))
6653 result
= loop_body_
->value();
6655 catch(const break_exception
<T
>& e
)
6659 catch(const continue_exception
&)
6662 incrementor_
->value();
6667 while (is_true(condition_
))
6671 result
= loop_body_
->value();
6673 catch(const break_exception
<T
>& e
)
6677 catch(const continue_exception
&)
6685 inline typename expression_node
<T
>::node_type
type() const
6687 return expression_node
<T
>::e_for
;
6692 expression_ptr initialiser_
;
6693 expression_ptr condition_
;
6694 expression_ptr incrementor_
;
6695 expression_ptr loop_body_
;
6696 const bool initialiser_deletable_
;
6697 const bool condition_deletable_
;
6698 const bool incrementor_deletable_
;
6699 const bool loop_body_deletable_
;
6703 template <typename T
>
6704 class switch_node
: public expression_node
<T
>
6708 typedef expression_node
<T
>* expression_ptr
;
6710 template <typename Allocator
,
6711 template <typename
, typename
> class Sequence
>
6712 explicit switch_node(const Sequence
<expression_ptr
,Allocator
>& arg_list
)
6714 if (1 != (arg_list
.size() & 1))
6717 arg_list_
.resize(arg_list
.size());
6718 delete_branch_
.resize(arg_list
.size());
6720 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
6724 arg_list_
[i
] = arg_list
[i
];
6725 delete_branch_
[i
] = static_cast<unsigned char>(branch_deletable(arg_list_
[i
]) ? 1 : 0);
6730 delete_branch_
.clear();
6738 for (std::size_t i
= 0; i
< arg_list_
.size(); ++i
)
6740 if (arg_list_
[i
] && delete_branch_
[i
])
6742 destroy_node(arg_list_
[i
]);
6747 inline T
value() const
6749 if (!arg_list_
.empty())
6751 const std::size_t upper_bound
= (arg_list_
.size() - 1);
6753 for (std::size_t i
= 0; i
< upper_bound
; i
+= 2)
6755 expression_ptr condition
= arg_list_
[i
];
6756 expression_ptr consequent
= arg_list_
[i
+ 1];
6758 if (is_true(condition
))
6760 return consequent
->value();
6764 return arg_list_
[upper_bound
]->value();
6767 return std::numeric_limits
<T
>::quiet_NaN();
6770 inline typename expression_node
<T
>::node_type
type() const
6772 return expression_node
<T
>::e_switch
;
6777 std::vector
<expression_ptr
> arg_list_
;
6778 std::vector
<unsigned char> delete_branch_
;
6781 template <typename T
, typename Switch_N
>
6782 class switch_n_node
: public switch_node
<T
>
6786 typedef expression_node
<T
>* expression_ptr
;
6788 template <typename Allocator
,
6789 template <typename
, typename
> class Sequence
>
6790 explicit switch_n_node(const Sequence
<expression_ptr
,Allocator
>& arg_list
)
6791 : switch_node
<T
>(arg_list
)
6794 inline T
value() const
6796 return Switch_N::process(switch_node
<T
>::arg_list_
);
6800 template <typename T
>
6801 class multi_switch_node
: public expression_node
<T
>
6805 typedef expression_node
<T
>* expression_ptr
;
6807 template <typename Allocator
,
6808 template <typename
, typename
> class Sequence
>
6809 explicit multi_switch_node(const Sequence
<expression_ptr
,Allocator
>& arg_list
)
6811 if (0 != (arg_list
.size() & 1))
6814 arg_list_
.resize(arg_list
.size());
6815 delete_branch_
.resize(arg_list
.size());
6817 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
6821 arg_list_
[i
] = arg_list
[i
];
6822 delete_branch_
[i
] = static_cast<unsigned char>(branch_deletable(arg_list_
[i
]) ? 1 : 0);
6827 delete_branch_
.clear();
6833 ~multi_switch_node()
6835 for (std::size_t i
= 0; i
< arg_list_
.size(); ++i
)
6837 if (arg_list_
[i
] && delete_branch_
[i
])
6839 destroy_node(arg_list_
[i
]);
6844 inline T
value() const
6848 if (arg_list_
.empty())
6850 return std::numeric_limits
<T
>::quiet_NaN();
6853 const std::size_t upper_bound
= (arg_list_
.size() - 1);
6855 for (std::size_t i
= 0; i
< upper_bound
; i
+= 2)
6857 expression_ptr condition
= arg_list_
[i
];
6858 expression_ptr consequent
= arg_list_
[i
+ 1];
6860 if (is_true(condition
))
6862 result
= consequent
->value();
6869 inline typename expression_node
<T
>::node_type
type() const
6871 return expression_node
<T
>::e_mswitch
;
6876 std::vector
<expression_ptr
> arg_list_
;
6877 std::vector
<unsigned char> delete_branch_
;
6880 template <typename T
>
6885 virtual ~ivariable()
6888 virtual T
& ref() = 0;
6889 virtual const T
& ref() const = 0;
6892 template <typename T
>
6893 class variable_node
: public expression_node
<T
>,
6894 public ivariable
<T
>
6898 static T null_value
;
6900 explicit variable_node()
6901 : value_(&null_value
)
6904 explicit variable_node(T
& v
)
6908 inline bool operator <(const variable_node
<T
>& v
) const
6913 inline T
value() const
6923 inline const T
& ref() const
6928 inline typename expression_node
<T
>::node_type
type() const
6930 return expression_node
<T
>::e_variable
;
6938 template <typename T
>
6939 T variable_node
<T
>::null_value
= T(std::numeric_limits
<T
>::quiet_NaN());
6941 template <typename T
>
6944 typedef expression_node
<T
>* expression_node_ptr
;
6945 typedef std::pair
<std::size_t,std::size_t> cached_range_t
;
6948 : n0_e (std::make_pair(false,expression_node_ptr(0))),
6949 n1_e (std::make_pair(false,expression_node_ptr(0))),
6950 n0_c (std::make_pair(false,0)),
6951 n1_c (std::make_pair(false,0)),
6952 cache(std::make_pair(0,0))
6957 n0_e
= std::make_pair(false,expression_node_ptr(0));
6958 n1_e
= std::make_pair(false,expression_node_ptr(0));
6959 n0_c
= std::make_pair(false,0);
6960 n1_c
= std::make_pair(false,0);
6961 cache
= std::make_pair(0,0);
6966 if (n0_e
.first
&& n0_e
.second
)
6971 !is_variable_node(n0_e
.second
) &&
6972 !is_string_node (n0_e
.second
)
6975 destroy_node(n0_e
.second
);
6979 if (n1_e
.first
&& n1_e
.second
)
6984 !is_variable_node(n1_e
.second
) &&
6985 !is_string_node (n1_e
.second
)
6988 destroy_node(n1_e
.second
);
6995 return ( n0_c
.first
&& n1_c
.first
) &&
6996 (!n0_e
.first
&& !n1_e
.first
);
7001 return ( n0_e
.first
&& n1_e
.first
) &&
7002 (!n0_c
.first
&& !n1_c
.first
);
7005 bool operator() (std::size_t& r0
, std::size_t& r1
,
7006 const std::size_t& size
= std::numeric_limits
<std::size_t>::max()) const
7010 else if (n0_e
.first
)
7012 const T r0_value
= n0_e
.second
->value();
7017 r0
= static_cast<std::size_t>(details::numeric::to_int64(r0_value
));
7024 else if (n1_e
.first
)
7026 const T r1_value
= n1_e
.second
->value();
7031 r1
= static_cast<std::size_t>(details::numeric::to_int64(r1_value
));
7037 (std::numeric_limits
<std::size_t>::max() != size
) &&
7038 (std::numeric_limits
<std::size_t>::max() == r1
)
7050 inline std::size_t const_size() const
7052 return (n1_c
.second
- n0_c
.second
+ 1);
7055 inline std::size_t cache_size() const
7057 return (cache
.second
- cache
.first
+ 1);
7060 std::pair
<bool,expression_node_ptr
> n0_e
;
7061 std::pair
<bool,expression_node_ptr
> n1_e
;
7062 std::pair
<bool,std::size_t > n0_c
;
7063 std::pair
<bool,std::size_t > n1_c
;
7064 mutable cached_range_t cache
;
7067 template <typename T
>
7068 class string_base_node
;
7070 template <typename T
>
7071 struct range_data_type
7073 typedef range_pack
<T
> range_t
;
7074 typedef string_base_node
<T
>* strbase_ptr_t
;
7087 std::size_t type_size
;
7088 strbase_ptr_t str_node
;
7091 template <typename T
> class vector_node
;
7093 template <typename T
>
7094 class vector_interface
7098 typedef vector_node
<T
>* vector_node_ptr
;
7099 typedef vec_data_store
<T
> vds_t
;
7101 virtual ~vector_interface()
7104 virtual std::size_t size () const = 0;
7106 virtual vector_node_ptr
vec() const = 0;
7108 virtual vector_node_ptr
vec() = 0;
7110 virtual vds_t
& vds () = 0;
7112 virtual const vds_t
& vds () const = 0;
7114 virtual bool side_effect () const { return false; }
7117 template <typename T
>
7118 class vector_node
: public expression_node
<T
>,
7119 public vector_interface
<T
>
7123 typedef expression_node
<T
>* expression_ptr
;
7124 typedef vector_holder
<T
> vector_holder_t
;
7125 typedef vector_node
<T
>* vector_node_ptr
;
7126 typedef vec_data_store
<T
> vds_t
;
7128 explicit vector_node(vector_holder_t
* vh
)
7129 : vector_holder_(vh
),
7130 vds_((*vector_holder_
).size(),(*vector_holder_
)[0])
7132 vector_holder_
->set_ref(&vds_
.ref());
7135 vector_node(const vds_t
& vds
, vector_holder_t
* vh
)
7136 : vector_holder_(vh
),
7140 inline T
value() const
7142 return vds().data()[0];
7145 vector_node_ptr
vec() const
7147 return const_cast<vector_node_ptr
>(this);
7150 vector_node_ptr
vec()
7155 inline typename expression_node
<T
>::node_type
type() const
7157 return expression_node
<T
>::e_vector
;
7160 std::size_t size() const
7162 return vds().size();
7170 const vds_t
& vds() const
7175 inline vector_holder_t
& vec_holder()
7177 return (*vector_holder_
);
7182 vector_holder_t
* vector_holder_
;
7186 template <typename T
>
7187 class vector_elem_node
: public expression_node
<T
>,
7188 public ivariable
<T
>
7192 typedef expression_node
<T
>* expression_ptr
;
7193 typedef vector_holder
<T
> vector_holder_t
;
7194 typedef vector_holder_t
* vector_holder_ptr
;
7196 vector_elem_node(expression_ptr index
, vector_holder_ptr vec_holder
)
7198 vec_holder_(vec_holder
),
7199 vector_base_((*vec_holder
)[0]),
7200 index_deletable_(branch_deletable(index_
))
7205 if (index_
&& index_deletable_
)
7207 destroy_node(index_
);
7211 inline T
value() const
7213 return *(vector_base_
+ static_cast<std::size_t>(details::numeric::to_int64(index_
->value())));
7218 return *(vector_base_
+ static_cast<std::size_t>(details::numeric::to_int64(index_
->value())));
7221 inline const T
& ref() const
7223 return *(vector_base_
+ static_cast<std::size_t>(details::numeric::to_int64(index_
->value())));
7226 inline typename expression_node
<T
>::node_type
type() const
7228 return expression_node
<T
>::e_vecelem
;
7231 inline vector_holder_t
& vec_holder()
7233 return (*vec_holder_
);
7238 expression_ptr index_
;
7239 vector_holder_ptr vec_holder_
;
7241 const bool index_deletable_
;
7244 template <typename T
>
7245 class rebasevector_elem_node
: public expression_node
<T
>,
7246 public ivariable
<T
>
7250 typedef expression_node
<T
>* expression_ptr
;
7251 typedef vector_holder
<T
> vector_holder_t
;
7252 typedef vector_holder_t
* vector_holder_ptr
;
7253 typedef vec_data_store
<T
> vds_t
;
7255 rebasevector_elem_node(expression_ptr index
, vector_holder_ptr vec_holder
)
7257 index_deletable_(branch_deletable(index_
)),
7258 vector_holder_(vec_holder
),
7259 vds_((*vector_holder_
).size(),(*vector_holder_
)[0])
7261 vector_holder_
->set_ref(&vds_
.ref());
7264 ~rebasevector_elem_node()
7266 if (index_
&& index_deletable_
)
7268 destroy_node(index_
);
7272 inline T
value() const
7274 return *(vds_
.data() + static_cast<std::size_t>(details::numeric::to_int64(index_
->value())));
7279 return *(vds_
.data() + static_cast<std::size_t>(details::numeric::to_int64(index_
->value())));
7282 inline const T
& ref() const
7284 return *(vds_
.data() + static_cast<std::size_t>(details::numeric::to_int64(index_
->value())));
7287 inline typename expression_node
<T
>::node_type
type() const
7289 return expression_node
<T
>::e_rbvecelem
;
7292 inline vector_holder_t
& vec_holder()
7294 return (*vector_holder_
);
7299 expression_ptr index_
;
7300 const bool index_deletable_
;
7301 vector_holder_ptr vector_holder_
;
7305 template <typename T
>
7306 class rebasevector_celem_node
: public expression_node
<T
>,
7307 public ivariable
<T
>
7311 typedef expression_node
<T
>* expression_ptr
;
7312 typedef vector_holder
<T
> vector_holder_t
;
7313 typedef vector_holder_t
* vector_holder_ptr
;
7314 typedef vec_data_store
<T
> vds_t
;
7316 rebasevector_celem_node(const std::size_t index
, vector_holder_ptr vec_holder
)
7318 vector_holder_(vec_holder
),
7319 vds_((*vector_holder_
).size(),(*vector_holder_
)[0])
7321 vector_holder_
->set_ref(&vds_
.ref());
7324 inline T
value() const
7326 return *(vds_
.data() + index_
);
7331 return *(vds_
.data() + index_
);
7334 inline const T
& ref() const
7336 return *(vds_
.data() + index_
);
7339 inline typename expression_node
<T
>::node_type
type() const
7341 return expression_node
<T
>::e_rbveccelem
;
7344 inline vector_holder_t
& vec_holder()
7346 return (*vector_holder_
);
7351 const std::size_t index_
;
7352 vector_holder_ptr vector_holder_
;
7356 template <typename T
>
7357 class vector_assignment_node
: public expression_node
<T
>
7361 typedef expression_node
<T
>* expression_ptr
;
7363 vector_assignment_node(T
* vector_base
,
7364 const std::size_t& size
,
7365 const std::vector
<expression_ptr
>& initialiser_list
,
7366 const bool single_value_initialse
)
7367 : vector_base_(vector_base
),
7368 initialiser_list_(initialiser_list
),
7370 single_value_initialse_(single_value_initialse
)
7373 ~vector_assignment_node()
7375 for (std::size_t i
= 0; i
< initialiser_list_
.size(); ++i
)
7377 if (branch_deletable(initialiser_list_
[i
]))
7379 destroy_node(initialiser_list_
[i
]);
7384 inline T
value() const
7386 if (single_value_initialse_
)
7388 for (std::size_t i
= 0; i
< size_
; ++i
)
7390 *(vector_base_
+ i
) = initialiser_list_
[0]->value();
7395 std::size_t il_size
= initialiser_list_
.size();
7397 for (std::size_t i
= 0; i
< il_size
; ++i
)
7399 *(vector_base_
+ i
) = initialiser_list_
[i
]->value();
7402 if (il_size
< size_
)
7404 for (std::size_t i
= il_size
; i
< size_
; ++i
)
7406 *(vector_base_
+ i
) = T(0);
7411 return *(vector_base_
);
7414 inline typename expression_node
<T
>::node_type
type() const
7416 return expression_node
<T
>::e_vecdefass
;
7421 vector_assignment_node
<T
>& operator=(const vector_assignment_node
<T
>&);
7423 mutable T
* vector_base_
;
7424 std::vector
<expression_ptr
> initialiser_list_
;
7425 const std::size_t size_
;
7426 const bool single_value_initialse_
;
7429 template <typename T
>
7430 class swap_node
: public expression_node
<T
>
7434 typedef expression_node
<T
>* expression_ptr
;
7435 typedef variable_node
<T
>* variable_node_ptr
;
7437 swap_node(variable_node_ptr var0
, variable_node_ptr var1
)
7442 inline T
value() const
7444 std::swap(var0_
->ref(),var1_
->ref());
7445 return var1_
->ref();
7448 inline typename expression_node
<T
>::node_type
type() const
7450 return expression_node
<T
>::e_swap
;
7455 variable_node_ptr var0_
;
7456 variable_node_ptr var1_
;
7459 template <typename T
>
7460 class swap_generic_node
: public binary_node
<T
>
7464 typedef expression_node
<T
>* expression_ptr
;
7465 typedef ivariable
<T
>* ivariable_ptr
;
7467 swap_generic_node(expression_ptr var0
, expression_ptr var1
)
7468 : binary_node
<T
>(details::e_swap
, var0
, var1
),
7469 var0_(dynamic_cast<ivariable_ptr
>(var0
)),
7470 var1_(dynamic_cast<ivariable_ptr
>(var1
))
7473 inline T
value() const
7475 std::swap(var0_
->ref(),var1_
->ref());
7476 return var1_
->ref();
7479 inline typename expression_node
<T
>::node_type
type() const
7481 return expression_node
<T
>::e_swap
;
7486 ivariable_ptr var0_
;
7487 ivariable_ptr var1_
;
7490 template <typename T
>
7491 class swap_vecvec_node
: public binary_node
<T
>,
7492 public vector_interface
<T
>
7496 typedef expression_node
<T
>* expression_ptr
;
7497 typedef vector_node
<T
>* vector_node_ptr
;
7498 typedef vec_data_store
<T
> vds_t
;
7500 swap_vecvec_node(expression_ptr branch0
,
7501 expression_ptr branch1
)
7502 : binary_node
<T
>(details::e_swap
, branch0
, branch1
),
7506 initialised_ (false)
7508 if (is_ivector_node(binary_node
<T
>::branch_
[0].first
))
7510 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
7512 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[0].first
)))
7514 vec0_node_ptr_
= vi
->vec();
7519 if (is_ivector_node(binary_node
<T
>::branch_
[1].first
))
7521 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
7523 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[1].first
)))
7525 vec1_node_ptr_
= vi
->vec();
7529 if (vec0_node_ptr_
&& vec1_node_ptr_
)
7531 vec_size_
= std::min(vec0_node_ptr_
->vds().size(),
7532 vec1_node_ptr_
->vds().size());
7534 initialised_
= true;
7538 inline T
value() const
7542 binary_node
<T
>::branch_
[0].first
->value();
7543 binary_node
<T
>::branch_
[1].first
->value();
7545 T
* vec0
= vec0_node_ptr_
->vds().data();
7546 T
* vec1
= vec1_node_ptr_
->vds().data();
7548 for (std::size_t i
= 0; i
< vec_size_
; ++i
)
7550 std::swap(vec0
[i
],vec1
[i
]);
7553 return vec1_node_ptr_
->value();
7556 return std::numeric_limits
<T
>::quiet_NaN();
7559 vector_node_ptr
vec() const
7561 return vec0_node_ptr_
;
7564 vector_node_ptr
vec()
7566 return vec0_node_ptr_
;
7569 inline typename expression_node
<T
>::node_type
type() const
7571 return expression_node
<T
>::e_vecvecswap
;
7574 std::size_t size() const
7584 const vds_t
& vds() const
7591 vector_node
<T
>* vec0_node_ptr_
;
7592 vector_node
<T
>* vec1_node_ptr_
;
7593 std::size_t vec_size_
;
7598 #ifndef exprtk_disable_string_capabilities
7599 template <typename T
>
7600 class stringvar_node
: public expression_node
<T
>,
7601 public string_base_node
<T
>,
7602 public range_interface
<T
>
7606 typedef range_pack
<T
> range_t
;
7608 static std::string null_value
;
7610 explicit stringvar_node()
7611 : value_(&null_value
)
7614 explicit stringvar_node(std::string
& v
)
7617 rp_
.n0_c
= std::make_pair
<bool,std::size_t>(true,0);
7618 rp_
.n1_c
= std::make_pair
<bool,std::size_t>(true,v
.size() - 1);
7619 rp_
.cache
.first
= rp_
.n0_c
.second
;
7620 rp_
.cache
.second
= rp_
.n1_c
.second
;
7623 inline bool operator <(const stringvar_node
<T
>& v
) const
7628 inline T
value() const
7630 rp_
.n1_c
.second
= (*value_
).size() - 1;
7631 rp_
.cache
.second
= rp_
.n1_c
.second
;
7633 return std::numeric_limits
<T
>::quiet_NaN();
7636 std::string
str() const
7641 char_cptr
base() const
7643 return &(*value_
)[0];
7646 std::size_t size() const
7648 return ref().size();
7656 const std::string
& ref() const
7661 range_t
& range_ref()
7666 const range_t
& range_ref() const
7671 inline typename expression_node
<T
>::node_type
type() const
7673 return expression_node
<T
>::e_stringvar
;
7678 std::string
* value_
;
7679 mutable range_t rp_
;
7682 template <typename T
>
7683 std::string stringvar_node
<T
>::null_value
= std::string("");
7685 template <typename T
>
7686 class string_range_node
: public expression_node
<T
>,
7687 public string_base_node
<T
>,
7688 public range_interface
<T
>
7692 typedef range_pack
<T
> range_t
;
7694 static std::string null_value
;
7696 explicit string_range_node(std::string
& v
, const range_t
& rp
)
7701 virtual ~string_range_node()
7706 inline bool operator <(const string_range_node
<T
>& v
) const
7711 inline T
value() const
7713 return std::numeric_limits
<T
>::quiet_NaN();
7716 inline std::string
str() const
7721 char_cptr
base() const
7723 return &(*value_
)[0];
7726 std::size_t size() const
7728 return ref().size();
7731 inline range_t
range() const
7736 inline virtual std::string
& ref()
7741 inline virtual const std::string
& ref() const
7746 inline range_t
& range_ref()
7751 inline const range_t
& range_ref() const
7756 inline typename expression_node
<T
>::node_type
type() const
7758 return expression_node
<T
>::e_stringvarrng
;
7763 std::string
* value_
;
7767 template <typename T
>
7768 std::string string_range_node
<T
>::null_value
= std::string("");
7770 template <typename T
>
7771 class const_string_range_node
: public expression_node
<T
>,
7772 public string_base_node
<T
>,
7773 public range_interface
<T
>
7777 typedef range_pack
<T
> range_t
;
7779 explicit const_string_range_node(const std::string
& v
, const range_t
& rp
)
7784 ~const_string_range_node()
7789 inline T
value() const
7791 return std::numeric_limits
<T
>::quiet_NaN();
7794 std::string
str() const
7799 char_cptr
base() const
7801 return value_
.data();
7804 std::size_t size() const
7806 return value_
.size();
7809 range_t
range() const
7814 range_t
& range_ref()
7819 const range_t
& range_ref() const
7824 inline typename expression_node
<T
>::node_type
type() const
7826 return expression_node
<T
>::e_cstringvarrng
;
7831 const_string_range_node
<T
>& operator=(const const_string_range_node
<T
>&);
7833 const std::string value_
;
7837 template <typename T
>
7838 class generic_string_range_node
: public expression_node
<T
>,
7839 public string_base_node
<T
>,
7840 public range_interface
<T
>
7844 typedef expression_node
<T
>* expression_ptr
;
7845 typedef stringvar_node
<T
>* strvar_node_ptr
;
7846 typedef string_base_node
<T
>* str_base_ptr
;
7847 typedef range_pack
<T
> range_t
;
7848 typedef range_t
* range_ptr
;
7849 typedef range_interface
<T
> irange_t
;
7850 typedef irange_t
* irange_ptr
;
7852 generic_string_range_node(expression_ptr str_branch
, const range_t
& brange
)
7853 : initialised_(false),
7854 branch_(str_branch
),
7855 branch_deletable_(branch_deletable(branch_
)),
7860 range_
.n0_c
= std::make_pair
<bool,std::size_t>(true,0);
7861 range_
.n1_c
= std::make_pair
<bool,std::size_t>(true,0);
7862 range_
.cache
.first
= range_
.n0_c
.second
;
7863 range_
.cache
.second
= range_
.n1_c
.second
;
7865 if (is_generally_string_node(branch_
))
7867 str_base_ptr_
= dynamic_cast<str_base_ptr
>(branch_
);
7869 if (0 == str_base_ptr_
)
7872 str_range_ptr_
= dynamic_cast<irange_ptr
>(branch_
);
7874 if (0 == str_range_ptr_
)
7878 initialised_
= (str_base_ptr_
&& str_range_ptr_
);
7881 ~generic_string_range_node()
7885 if (branch_
&& branch_deletable_
)
7887 destroy_node(branch_
);
7891 inline T
value() const
7897 std::size_t str_r0
= 0;
7898 std::size_t str_r1
= 0;
7903 range_t
& range
= str_range_ptr_
->range_ref();
7905 const std::size_t base_str_size
= str_base_ptr_
->size();
7908 range (str_r0
, str_r1
, base_str_size
) &&
7909 base_range_( r0
, r1
, base_str_size
)
7912 const std::size_t size
= (r1
- r0
) + 1;
7914 range_
.n1_c
.second
= size
- 1;
7915 range_
.cache
.second
= range_
.n1_c
.second
;
7917 value_
.assign(str_base_ptr_
->base() + str_r0
+ r0
, size
);
7921 return std::numeric_limits
<T
>::quiet_NaN();
7924 std::string
str() const
7929 char_cptr
base() const
7934 std::size_t size() const
7936 return value_
.size();
7939 range_t
& range_ref()
7944 const range_t
& range_ref() const
7949 inline typename expression_node
<T
>::node_type
type() const
7951 return expression_node
<T
>::e_strgenrange
;
7957 expression_ptr branch_
;
7958 const bool branch_deletable_
;
7959 str_base_ptr str_base_ptr_
;
7960 irange_ptr str_range_ptr_
;
7961 mutable range_t base_range_
;
7962 mutable range_t range_
;
7963 mutable std::string value_
;
7966 template <typename T
>
7967 class string_concat_node
: public binary_node
<T
>,
7968 public string_base_node
<T
>,
7969 public range_interface
<T
>
7973 typedef expression_node
<T
>* expression_ptr
;
7974 typedef string_base_node
<T
>* str_base_ptr
;
7975 typedef range_pack
<T
> range_t
;
7976 typedef range_t
* range_ptr
;
7977 typedef range_interface
<T
> irange_t
;
7978 typedef irange_t
* irange_ptr
;
7980 string_concat_node(const operator_type
& opr
,
7981 expression_ptr branch0
,
7982 expression_ptr branch1
)
7983 : binary_node
<T
>(opr
, branch0
, branch1
),
7984 initialised_(false),
7990 range_
.n0_c
= std::make_pair
<bool,std::size_t>(true,0);
7991 range_
.n1_c
= std::make_pair
<bool,std::size_t>(true,0);
7993 range_
.cache
.first
= range_
.n0_c
.second
;
7994 range_
.cache
.second
= range_
.n1_c
.second
;
7996 if (is_generally_string_node(binary_node
<T
>::branch_
[0].first
))
7998 str0_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[0].first
);
8000 if (0 == str0_base_ptr_
)
8003 str0_range_ptr_
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[0].first
);
8005 if (0 == str0_range_ptr_
)
8009 if (is_generally_string_node(binary_node
<T
>::branch_
[1].first
))
8011 str1_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[1].first
);
8013 if (0 == str1_base_ptr_
)
8016 str1_range_ptr_
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[1].first
);
8018 if (0 == str1_range_ptr_
)
8022 initialised_
= str0_base_ptr_
&&
8028 inline T
value() const
8032 binary_node
<T
>::branch_
[0].first
->value();
8033 binary_node
<T
>::branch_
[1].first
->value();
8035 std::size_t str0_r0
= 0;
8036 std::size_t str0_r1
= 0;
8038 std::size_t str1_r0
= 0;
8039 std::size_t str1_r1
= 0;
8041 range_t
& range0
= str0_range_ptr_
->range_ref();
8042 range_t
& range1
= str1_range_ptr_
->range_ref();
8045 range0(str0_r0
, str0_r1
, str0_base_ptr_
->size()) &&
8046 range1(str1_r0
, str1_r1
, str1_base_ptr_
->size())
8049 const std::size_t size0
= (str0_r1
- str0_r0
) + 1;
8050 const std::size_t size1
= (str1_r1
- str1_r0
) + 1;
8052 value_
.assign(str0_base_ptr_
->base() + str0_r0
, size0
);
8053 value_
.append(str1_base_ptr_
->base() + str1_r0
, size1
);
8055 range_
.n1_c
.second
= value_
.size() - 1;
8056 range_
.cache
.second
= range_
.n1_c
.second
;
8060 return std::numeric_limits
<T
>::quiet_NaN();
8063 std::string
str() const
8068 char_cptr
base() const
8073 std::size_t size() const
8075 return value_
.size();
8078 range_t
& range_ref()
8083 const range_t
& range_ref() const
8088 inline typename expression_node
<T
>::node_type
type() const
8090 return expression_node
<T
>::e_strconcat
;
8096 str_base_ptr str0_base_ptr_
;
8097 str_base_ptr str1_base_ptr_
;
8098 irange_ptr str0_range_ptr_
;
8099 irange_ptr str1_range_ptr_
;
8100 mutable range_t range_
;
8101 mutable std::string value_
;
8104 template <typename T
>
8105 class swap_string_node
: public binary_node
<T
>,
8106 public string_base_node
<T
>,
8107 public range_interface
<T
>
8111 typedef expression_node
<T
>* expression_ptr
;
8112 typedef stringvar_node
<T
>* strvar_node_ptr
;
8113 typedef string_base_node
<T
>* str_base_ptr
;
8114 typedef range_pack
<T
> range_t
;
8115 typedef range_t
* range_ptr
;
8116 typedef range_interface
<T
> irange_t
;
8117 typedef irange_t
* irange_ptr
;
8119 swap_string_node(expression_ptr branch0
, expression_ptr branch1
)
8120 : binary_node
<T
>(details::e_swap
, branch0
, branch1
),
8121 initialised_(false),
8125 if (is_string_node(binary_node
<T
>::branch_
[0].first
))
8127 str0_node_ptr_
= static_cast<strvar_node_ptr
>(binary_node
<T
>::branch_
[0].first
);
8130 if (is_string_node(binary_node
<T
>::branch_
[1].first
))
8132 str1_node_ptr_
= static_cast<strvar_node_ptr
>(binary_node
<T
>::branch_
[1].first
);
8135 initialised_
= (str0_node_ptr_
&& str1_node_ptr_
);
8138 inline T
value() const
8142 binary_node
<T
>::branch_
[0].first
->value();
8143 binary_node
<T
>::branch_
[1].first
->value();
8145 std::swap(str0_node_ptr_
->ref(), str1_node_ptr_
->ref());
8148 return std::numeric_limits
<T
>::quiet_NaN();
8151 std::string
str() const
8153 return str0_node_ptr_
->str();
8156 char_cptr
base() const
8158 return str0_node_ptr_
->base();
8161 std::size_t size() const
8163 return str0_node_ptr_
->size();
8166 range_t
& range_ref()
8168 return str0_node_ptr_
->range_ref();
8171 const range_t
& range_ref() const
8173 return str0_node_ptr_
->range_ref();
8176 inline typename expression_node
<T
>::node_type
type() const
8178 return expression_node
<T
>::e_strswap
;
8184 strvar_node_ptr str0_node_ptr_
;
8185 strvar_node_ptr str1_node_ptr_
;
8188 template <typename T
>
8189 class swap_genstrings_node
: public binary_node
<T
>
8193 typedef expression_node
<T
>* expression_ptr
;
8194 typedef string_base_node
<T
>* str_base_ptr
;
8195 typedef range_pack
<T
> range_t
;
8196 typedef range_t
* range_ptr
;
8197 typedef range_interface
<T
> irange_t
;
8198 typedef irange_t
* irange_ptr
;
8200 swap_genstrings_node(expression_ptr branch0
,
8201 expression_ptr branch1
)
8202 : binary_node
<T
>(details::e_default
, branch0
, branch1
),
8209 if (is_generally_string_node(binary_node
<T
>::branch_
[0].first
))
8211 str0_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[0].first
);
8213 if (0 == str0_base_ptr_
)
8216 irange_ptr range
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[0].first
);
8221 str0_range_ptr_
= &(range
->range_ref());
8224 if (is_generally_string_node(binary_node
<T
>::branch_
[1].first
))
8226 str1_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[1].first
);
8228 if (0 == str1_base_ptr_
)
8231 irange_ptr range
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[1].first
);
8236 str1_range_ptr_
= &(range
->range_ref());
8239 initialised_
= str0_base_ptr_
&&
8245 inline T
value() const
8249 binary_node
<T
>::branch_
[0].first
->value();
8250 binary_node
<T
>::branch_
[1].first
->value();
8252 std::size_t str0_r0
= 0;
8253 std::size_t str0_r1
= 0;
8255 std::size_t str1_r0
= 0;
8256 std::size_t str1_r1
= 0;
8258 range_t
& range0
= (*str0_range_ptr_
);
8259 range_t
& range1
= (*str1_range_ptr_
);
8262 range0(str0_r0
, str0_r1
, str0_base_ptr_
->size()) &&
8263 range1(str1_r0
, str1_r1
, str1_base_ptr_
->size())
8266 const std::size_t size0
= range0
.cache_size();
8267 const std::size_t size1
= range1
.cache_size();
8268 const std::size_t max_size
= std::min(size0
,size1
);
8270 char_ptr s0
= const_cast<char_ptr
>(str0_base_ptr_
->base() + str0_r0
);
8271 char_ptr s1
= const_cast<char_ptr
>(str1_base_ptr_
->base() + str1_r0
);
8273 loop_unroll::details
lud(max_size
);
8274 char_cptr upper_bound
= s0
+ lud
.upper_bound
;
8276 while (s0
< upper_bound
)
8278 #define exprtk_loop(N) \
8279 std::swap(s0[N], s1[N]); \
8281 exprtk_loop( 0) exprtk_loop( 1)
8282 exprtk_loop( 2) exprtk_loop( 3)
8283 #ifndef exprtk_disable_superscalar_unroll
8284 exprtk_loop( 4) exprtk_loop( 5)
8285 exprtk_loop( 6) exprtk_loop( 7)
8286 exprtk_loop( 8) exprtk_loop( 9)
8287 exprtk_loop(10) exprtk_loop(11)
8288 exprtk_loop(12) exprtk_loop(13)
8289 exprtk_loop(14) exprtk_loop(15)
8292 s0
+= lud
.batch_size
;
8293 s1
+= lud
.batch_size
;
8298 exprtk_disable_fallthrough_begin
8299 switch (lud
.remainder
)
8301 #define case_stmt(N) \
8302 case N : { std::swap(s0[i], s1[i]); ++i; } \
8304 #ifndef exprtk_disable_superscalar_unroll
8305 case_stmt(15) case_stmt(14)
8306 case_stmt(13) case_stmt(12)
8307 case_stmt(11) case_stmt(10)
8308 case_stmt( 9) case_stmt( 8)
8309 case_stmt( 7) case_stmt( 6)
8310 case_stmt( 5) case_stmt( 4)
8312 case_stmt( 3) case_stmt( 2)
8315 exprtk_disable_fallthrough_end
8322 return std::numeric_limits
<T
>::quiet_NaN();
8325 inline typename expression_node
<T
>::node_type
type() const
8327 return expression_node
<T
>::e_strswap
;
8332 swap_genstrings_node(swap_genstrings_node
<T
>&);
8333 swap_genstrings_node
<T
>& operator=(swap_genstrings_node
<T
>&);
8335 str_base_ptr str0_base_ptr_
;
8336 str_base_ptr str1_base_ptr_
;
8337 range_ptr str0_range_ptr_
;
8338 range_ptr str1_range_ptr_
;
8342 template <typename T
>
8343 class stringvar_size_node
: public expression_node
<T
>
8347 static std::string null_value
;
8349 explicit stringvar_size_node()
8350 : value_(&null_value
)
8353 explicit stringvar_size_node(std::string
& v
)
8357 inline T
value() const
8359 return T((*value_
).size());
8362 inline typename expression_node
<T
>::node_type
type() const
8364 return expression_node
<T
>::e_stringvarsize
;
8369 std::string
* value_
;
8372 template <typename T
>
8373 std::string stringvar_size_node
<T
>::null_value
= std::string("");
8375 template <typename T
>
8376 class string_size_node
: public expression_node
<T
>
8380 typedef expression_node
<T
>* expression_ptr
;
8381 typedef string_base_node
<T
>* str_base_ptr
;
8383 explicit string_size_node(expression_ptr brnch
)
8385 branch_deletable_(branch_deletable(branch_
)),
8388 if (is_generally_string_node(branch_
))
8390 str_base_ptr_
= dynamic_cast<str_base_ptr
>(branch_
);
8392 if (0 == str_base_ptr_
)
8399 if (branch_
&& branch_deletable_
)
8401 destroy_node(branch_
);
8405 inline T
value() const
8407 T result
= std::numeric_limits
<T
>::quiet_NaN();
8412 result
= T(str_base_ptr_
->size());
8418 inline typename expression_node
<T
>::node_type
type() const
8420 return expression_node
<T
>::e_stringsize
;
8425 expression_ptr branch_
;
8426 const bool branch_deletable_
;
8427 str_base_ptr str_base_ptr_
;
8430 struct asn_assignment
8432 static inline void execute(std::string
& s
, char_cptr data
, const std::size_t size
)
8433 { s
.assign(data
,size
); }
8436 struct asn_addassignment
8438 static inline void execute(std::string
& s
, char_cptr data
, const std::size_t size
)
8439 { s
.append(data
,size
); }
8442 template <typename T
, typename AssignmentProcess
= asn_assignment
>
8443 class assignment_string_node
: public binary_node
<T
>,
8444 public string_base_node
<T
>,
8445 public range_interface
<T
>
8449 typedef expression_node
<T
>* expression_ptr
;
8450 typedef stringvar_node
<T
>* strvar_node_ptr
;
8451 typedef string_base_node
<T
>* str_base_ptr
;
8452 typedef range_pack
<T
> range_t
;
8453 typedef range_t
* range_ptr
;
8454 typedef range_interface
<T
> irange_t
;
8455 typedef irange_t
* irange_ptr
;
8457 assignment_string_node(const operator_type
& opr
,
8458 expression_ptr branch0
,
8459 expression_ptr branch1
)
8460 : binary_node
<T
>(opr
, branch0
, branch1
),
8461 initialised_(false),
8467 if (is_string_node(binary_node
<T
>::branch_
[0].first
))
8469 str0_node_ptr_
= static_cast<strvar_node_ptr
>(binary_node
<T
>::branch_
[0].first
);
8471 str0_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[0].first
);
8474 if (is_generally_string_node(binary_node
<T
>::branch_
[1].first
))
8476 str1_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[1].first
);
8478 if (0 == str1_base_ptr_
)
8481 irange_ptr range
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[1].first
);
8486 str1_range_ptr_
= &(range
->range_ref());
8489 initialised_
= str0_base_ptr_
&&
8495 inline T
value() const
8499 binary_node
<T
>::branch_
[1].first
->value();
8504 range_t
& range
= (*str1_range_ptr_
);
8506 if (range(r0
, r1
, str1_base_ptr_
->size()))
8508 AssignmentProcess::execute(str0_node_ptr_
->ref(),
8509 str1_base_ptr_
->base() + r0
,
8512 binary_node
<T
>::branch_
[0].first
->value();
8516 return std::numeric_limits
<T
>::quiet_NaN();
8519 std::string
str() const
8521 return str0_node_ptr_
->str();
8524 char_cptr
base() const
8526 return str0_node_ptr_
->base();
8529 std::size_t size() const
8531 return str0_node_ptr_
->size();
8534 range_t
& range_ref()
8536 return str0_node_ptr_
->range_ref();
8539 const range_t
& range_ref() const
8541 return str0_node_ptr_
->range_ref();
8544 inline typename expression_node
<T
>::node_type
type() const
8546 return expression_node
<T
>::e_strass
;
8552 str_base_ptr str0_base_ptr_
;
8553 str_base_ptr str1_base_ptr_
;
8554 strvar_node_ptr str0_node_ptr_
;
8555 range_ptr str1_range_ptr_
;
8558 template <typename T
, typename AssignmentProcess
= asn_assignment
>
8559 class assignment_string_range_node
: public binary_node
<T
>,
8560 public string_base_node
<T
>,
8561 public range_interface
<T
>
8565 typedef expression_node
<T
>* expression_ptr
;
8566 typedef stringvar_node
<T
>* strvar_node_ptr
;
8567 typedef string_base_node
<T
>* str_base_ptr
;
8568 typedef range_pack
<T
> range_t
;
8569 typedef range_t
* range_ptr
;
8570 typedef range_interface
<T
> irange_t
;
8571 typedef irange_t
* irange_ptr
;
8573 assignment_string_range_node(const operator_type
& opr
,
8574 expression_ptr branch0
,
8575 expression_ptr branch1
)
8576 : binary_node
<T
>(opr
, branch0
, branch1
),
8577 initialised_(false),
8584 if (is_string_range_node(binary_node
<T
>::branch_
[0].first
))
8586 str0_node_ptr_
= static_cast<strvar_node_ptr
>(binary_node
<T
>::branch_
[0].first
);
8588 str0_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[0].first
);
8590 irange_ptr range
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[0].first
);
8595 str0_range_ptr_
= &(range
->range_ref());
8598 if (is_generally_string_node(binary_node
<T
>::branch_
[1].first
))
8600 str1_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[1].first
);
8602 if (0 == str1_base_ptr_
)
8605 irange_ptr range
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[1].first
);
8610 str1_range_ptr_
= &(range
->range_ref());
8613 initialised_
= str0_base_ptr_
&&
8620 inline T
value() const
8624 binary_node
<T
>::branch_
[0].first
->value();
8625 binary_node
<T
>::branch_
[1].first
->value();
8627 std::size_t s0_r0
= 0;
8628 std::size_t s0_r1
= 0;
8630 std::size_t s1_r0
= 0;
8631 std::size_t s1_r1
= 0;
8633 range_t
& range0
= (*str0_range_ptr_
);
8634 range_t
& range1
= (*str1_range_ptr_
);
8637 range0(s0_r0
, s0_r1
, str0_base_ptr_
->size()) &&
8638 range1(s1_r0
, s1_r1
, str1_base_ptr_
->size())
8641 std::size_t size
= std::min((s0_r1
- s0_r0
), (s1_r1
- s1_r0
)) + 1;
8643 std::copy(str1_base_ptr_
->base() + s1_r0
,
8644 str1_base_ptr_
->base() + s1_r0
+ size
,
8645 const_cast<char_ptr
>(base() + s0_r0
));
8649 return std::numeric_limits
<T
>::quiet_NaN();
8652 std::string
str() const
8654 return str0_node_ptr_
->str();
8657 char_cptr
base() const
8659 return str0_node_ptr_
->base();
8662 std::size_t size() const
8664 return str0_node_ptr_
->size();
8667 range_t
& range_ref()
8669 return str0_node_ptr_
->range_ref();
8672 const range_t
& range_ref() const
8674 return str0_node_ptr_
->range_ref();
8677 inline typename expression_node
<T
>::node_type
type() const
8679 return expression_node
<T
>::e_strass
;
8685 str_base_ptr str0_base_ptr_
;
8686 str_base_ptr str1_base_ptr_
;
8687 strvar_node_ptr str0_node_ptr_
;
8688 range_ptr str0_range_ptr_
;
8689 range_ptr str1_range_ptr_
;
8692 template <typename T
>
8693 class conditional_string_node
: public trinary_node
<T
>,
8694 public string_base_node
<T
>,
8695 public range_interface
<T
>
8699 typedef expression_node
<T
>* expression_ptr
;
8700 typedef string_base_node
<T
>* str_base_ptr
;
8701 typedef range_pack
<T
> range_t
;
8702 typedef range_t
* range_ptr
;
8703 typedef range_interface
<T
> irange_t
;
8704 typedef irange_t
* irange_ptr
;
8706 conditional_string_node(expression_ptr test
,
8707 expression_ptr consequent
,
8708 expression_ptr alternative
)
8709 : trinary_node
<T
>(details::e_default
,consequent
,alternative
,test
),
8710 initialised_(false),
8716 consequent_ (consequent
),
8717 alternative_(alternative
)
8719 range_
.n0_c
= std::make_pair
<bool,std::size_t>(true,0);
8720 range_
.n1_c
= std::make_pair
<bool,std::size_t>(true,0);
8722 range_
.cache
.first
= range_
.n0_c
.second
;
8723 range_
.cache
.second
= range_
.n1_c
.second
;
8725 if (is_generally_string_node(trinary_node
<T
>::branch_
[0].first
))
8727 str0_base_ptr_
= dynamic_cast<str_base_ptr
>(trinary_node
<T
>::branch_
[0].first
);
8729 if (0 == str0_base_ptr_
)
8732 str0_range_ptr_
= dynamic_cast<irange_ptr
>(trinary_node
<T
>::branch_
[0].first
);
8734 if (0 == str0_range_ptr_
)
8738 if (is_generally_string_node(trinary_node
<T
>::branch_
[1].first
))
8740 str1_base_ptr_
= dynamic_cast<str_base_ptr
>(trinary_node
<T
>::branch_
[1].first
);
8742 if (0 == str1_base_ptr_
)
8745 str1_range_ptr_
= dynamic_cast<irange_ptr
>(trinary_node
<T
>::branch_
[1].first
);
8747 if (0 == str1_range_ptr_
)
8751 initialised_
= str0_base_ptr_
&&
8758 inline T
value() const
8767 consequent_
->value();
8769 range_t
& range
= str0_range_ptr_
->range_ref();
8771 if (range(r0
, r1
, str0_base_ptr_
->size()))
8773 const std::size_t size
= (r1
- r0
) + 1;
8775 value_
.assign(str0_base_ptr_
->base() + r0
, size
);
8777 range_
.n1_c
.second
= value_
.size() - 1;
8778 range_
.cache
.second
= range_
.n1_c
.second
;
8785 alternative_
->value();
8787 range_t
& range
= str1_range_ptr_
->range_ref();
8789 if (range(r0
, r1
, str1_base_ptr_
->size()))
8791 const std::size_t size
= (r1
- r0
) + 1;
8793 value_
.assign(str1_base_ptr_
->base() + r0
, size
);
8795 range_
.n1_c
.second
= value_
.size() - 1;
8796 range_
.cache
.second
= range_
.n1_c
.second
;
8803 return std::numeric_limits
<T
>::quiet_NaN();
8806 std::string
str() const
8811 char_cptr
base() const
8816 std::size_t size() const
8818 return value_
.size();
8821 range_t
& range_ref()
8826 const range_t
& range_ref() const
8831 inline typename expression_node
<T
>::node_type
type() const
8833 return expression_node
<T
>::e_strcondition
;
8839 str_base_ptr str0_base_ptr_
;
8840 str_base_ptr str1_base_ptr_
;
8841 irange_ptr str0_range_ptr_
;
8842 irange_ptr str1_range_ptr_
;
8843 mutable range_t range_
;
8844 mutable std::string value_
;
8846 expression_ptr test_
;
8847 expression_ptr consequent_
;
8848 expression_ptr alternative_
;
8851 template <typename T
>
8852 class cons_conditional_str_node
: public binary_node
<T
>,
8853 public string_base_node
<T
>,
8854 public range_interface
<T
>
8858 typedef expression_node
<T
>* expression_ptr
;
8859 typedef string_base_node
<T
>* str_base_ptr
;
8860 typedef range_pack
<T
> range_t
;
8861 typedef range_t
* range_ptr
;
8862 typedef range_interface
<T
> irange_t
;
8863 typedef irange_t
* irange_ptr
;
8865 cons_conditional_str_node(expression_ptr test
,
8866 expression_ptr consequent
)
8867 : binary_node
<T
>(details::e_default
, consequent
, test
),
8868 initialised_(false),
8872 consequent_(consequent
)
8874 range_
.n0_c
= std::make_pair
<bool,std::size_t>(true,0);
8875 range_
.n1_c
= std::make_pair
<bool,std::size_t>(true,0);
8877 range_
.cache
.first
= range_
.n0_c
.second
;
8878 range_
.cache
.second
= range_
.n1_c
.second
;
8880 if (is_generally_string_node(binary_node
<T
>::branch_
[0].first
))
8882 str0_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[0].first
);
8884 if (0 == str0_base_ptr_
)
8887 str0_range_ptr_
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[0].first
);
8889 if (0 == str0_range_ptr_
)
8893 initialised_
= str0_base_ptr_
&& str0_range_ptr_
;
8896 inline T
value() const
8902 consequent_
->value();
8904 range_t
& range
= str0_range_ptr_
->range_ref();
8909 if (range(r0
, r1
, str0_base_ptr_
->size()))
8911 const std::size_t size
= (r1
- r0
) + 1;
8913 value_
.assign(str0_base_ptr_
->base() + r0
, size
);
8915 range_
.n1_c
.second
= value_
.size() - 1;
8916 range_
.cache
.second
= range_
.n1_c
.second
;
8923 return std::numeric_limits
<T
>::quiet_NaN();
8926 std::string
str() const
8931 char_cptr
base() const
8936 std::size_t size() const
8938 return value_
.size();
8941 range_t
& range_ref()
8946 const range_t
& range_ref() const
8951 inline typename expression_node
<T
>::node_type
type() const
8953 return expression_node
<T
>::e_strccondition
;
8959 str_base_ptr str0_base_ptr_
;
8960 irange_ptr str0_range_ptr_
;
8961 mutable range_t range_
;
8962 mutable std::string value_
;
8964 expression_ptr test_
;
8965 expression_ptr consequent_
;
8968 template <typename T
, typename VarArgFunction
>
8969 class str_vararg_node
: public expression_node
<T
>,
8970 public string_base_node
<T
>,
8971 public range_interface
<T
>
8975 typedef expression_node
<T
>* expression_ptr
;
8976 typedef string_base_node
<T
>* str_base_ptr
;
8977 typedef range_pack
<T
> range_t
;
8978 typedef range_t
* range_ptr
;
8979 typedef range_interface
<T
> irange_t
;
8980 typedef irange_t
* irange_ptr
;
8982 template <typename Allocator
,
8983 template <typename
, typename
> class Sequence
>
8984 explicit str_vararg_node(const Sequence
<expression_ptr
,Allocator
>& arg_list
)
8985 : final_node_(arg_list
.back()),
8986 final_deletable_(branch_deletable(final_node_
)),
8987 initialised_(false),
8991 if (0 == final_node_
)
8993 else if (!is_generally_string_node(final_node_
))
8996 str_base_ptr_
= dynamic_cast<str_base_ptr
>(final_node_
);
8998 if (0 == str_base_ptr_
)
9001 str_range_ptr_
= dynamic_cast<irange_ptr
>(final_node_
);
9003 if (0 == str_range_ptr_
)
9006 initialised_
= str_base_ptr_
&& str_range_ptr_
;
9008 if (arg_list
.size() > 1)
9010 const std::size_t arg_list_size
= arg_list
.size() - 1;
9012 arg_list_
.resize(arg_list_size
);
9013 delete_branch_
.resize(arg_list_size
);
9015 for (std::size_t i
= 0; i
< arg_list_size
; ++i
)
9019 arg_list_
[i
] = arg_list
[i
];
9020 delete_branch_
[i
] = static_cast<unsigned char>(branch_deletable(arg_list_
[i
]) ? 1 : 0);
9025 delete_branch_
.clear();
9034 if (final_node_
&& final_deletable_
)
9036 destroy_node(final_node_
);
9039 for (std::size_t i
= 0; i
< arg_list_
.size(); ++i
)
9041 if (arg_list_
[i
] && delete_branch_
[i
])
9043 destroy_node(arg_list_
[i
]);
9048 inline T
value() const
9050 if (!arg_list_
.empty())
9052 VarArgFunction::process(arg_list_
);
9055 final_node_
->value();
9057 return std::numeric_limits
<T
>::quiet_NaN();
9060 std::string
str() const
9062 return str_base_ptr_
->str();
9065 char_cptr
base() const
9067 return str_base_ptr_
->base();
9070 std::size_t size() const
9072 return str_base_ptr_
->size();
9075 range_t
& range_ref()
9077 return str_range_ptr_
->range_ref();
9080 const range_t
& range_ref() const
9082 return str_range_ptr_
->range_ref();
9085 inline typename expression_node
<T
>::node_type
type() const
9087 return expression_node
<T
>::e_stringvararg
;
9092 expression_ptr final_node_
;
9093 bool final_deletable_
;
9095 str_base_ptr str_base_ptr_
;
9096 irange_ptr str_range_ptr_
;
9097 std::vector
<expression_ptr
> arg_list_
;
9098 std::vector
<unsigned char> delete_branch_
;
9102 template <typename T
, std::size_t N
>
9103 inline T
axn(T a
, T x
)
9106 return a
* exprtk::details::numeric::fast_exp
<T
,N
>::result(x
);
9109 template <typename T
, std::size_t N
>
9110 inline T
axnb(T a
, T x
, T b
)
9113 return a
* exprtk::details::numeric::fast_exp
<T
,N
>::result(x
) + b
;
9116 template <typename T
>
9119 typedef typename
details::functor_t
<T
>::Type Type
;
9120 typedef typename
details::functor_t
<T
> functor_t
;
9121 typedef typename
functor_t::qfunc_t quaternary_functor_t
;
9122 typedef typename
functor_t::tfunc_t trinary_functor_t
;
9123 typedef typename
functor_t::bfunc_t binary_functor_t
;
9124 typedef typename
functor_t::ufunc_t unary_functor_t
;
9127 #define define_sfop3(NN,OP0,OP1) \
9128 template <typename T> \
9129 struct sf##NN##_op : public sf_base<T> \
9131 typedef typename sf_base<T>::Type const Type; \
9132 static inline T process(Type x, Type y, Type z) \
9136 static inline std::string id() \
9142 define_sfop3(00,(x + y) / z ,"(t+t)/t")
9143 define_sfop3(01,(x
+ y
) * z
,"(t+t)*t")
9144 define_sfop3(02,(x
+ y
) - z
,"(t+t)-t")
9145 define_sfop3(03,(x
+ y
) + z
,"(t+t)+t")
9146 define_sfop3(04,(x
- y
) + z
,"(t-t)+t")
9147 define_sfop3(05,(x
- y
) / z
,"(t-t)/t")
9148 define_sfop3(06,(x
- y
) * z
,"(t-t)*t")
9149 define_sfop3(07,(x
* y
) + z
,"(t*t)+t")
9150 define_sfop3(08,(x
* y
) - z
,"(t*t)-t")
9151 define_sfop3(09,(x
* y
) / z
,"(t*t)/t")
9152 define_sfop3(10,(x
* y
) * z
,"(t*t)*t")
9153 define_sfop3(11,(x
/ y
) + z
,"(t/t)+t")
9154 define_sfop3(12,(x
/ y
) - z
,"(t/t)-t")
9155 define_sfop3(13,(x
/ y
) / z
,"(t/t)/t")
9156 define_sfop3(14,(x
/ y
) * z
,"(t/t)*t")
9157 define_sfop3(15,x
/ (y
+ z
) ,"t/(t+t)")
9158 define_sfop3(16,x
/ (y
- z
) ,"t/(t-t)")
9159 define_sfop3(17,x
/ (y
* z
) ,"t/(t*t)")
9160 define_sfop3(18,x
/ (y
/ z
) ,"t/(t/t)")
9161 define_sfop3(19,x
* (y
+ z
) ,"t*(t+t)")
9162 define_sfop3(20,x
* (y
- z
) ,"t*(t-t)")
9163 define_sfop3(21,x
* (y
* z
) ,"t*(t*t)")
9164 define_sfop3(22,x
* (y
/ z
) ,"t*(t/t)")
9165 define_sfop3(23,x
- (y
+ z
) ,"t-(t+t)")
9166 define_sfop3(24,x
- (y
- z
) ,"t-(t-t)")
9167 define_sfop3(25,x
- (y
/ z
) ,"t-(t/t)")
9168 define_sfop3(26,x
- (y
* z
) ,"t-(t*t)")
9169 define_sfop3(27,x
+ (y
* z
) ,"t+(t*t)")
9170 define_sfop3(28,x
+ (y
/ z
) ,"t+(t/t)")
9171 define_sfop3(29,x
+ (y
+ z
) ,"t+(t+t)")
9172 define_sfop3(30,x
+ (y
- z
) ,"t+(t-t)")
9173 define_sfop3(31,(axnb
<T
,2>(x
,y
,z
))," ")
9174 define_sfop3(32,(axnb
<T
,3>(x
,y
,z
))," ")
9175 define_sfop3(33,(axnb
<T
,4>(x
,y
,z
))," ")
9176 define_sfop3(34,(axnb
<T
,5>(x
,y
,z
))," ")
9177 define_sfop3(35,(axnb
<T
,6>(x
,y
,z
))," ")
9178 define_sfop3(36,(axnb
<T
,7>(x
,y
,z
))," ")
9179 define_sfop3(37,(axnb
<T
,8>(x
,y
,z
))," ")
9180 define_sfop3(38,(axnb
<T
,9>(x
,y
,z
))," ")
9181 define_sfop3(39,x
* numeric::log(y
) + z
,"")
9182 define_sfop3(40,x
* numeric::log(y
) - z
,"")
9183 define_sfop3(41,x
* numeric::log10(y
) + z
,"")
9184 define_sfop3(42,x
* numeric::log10(y
) - z
,"")
9185 define_sfop3(43,x
* numeric::sin(y
) + z
,"")
9186 define_sfop3(44,x
* numeric::sin(y
) - z
,"")
9187 define_sfop3(45,x
* numeric::cos(y
) + z
,"")
9188 define_sfop3(46,x
* numeric::cos(y
) - z
,"")
9189 define_sfop3(47,details::is_true(x
) ? y
: z
,"")
9191 #define define_sfop4(NN,OP0,OP1) \
9192 template <typename T> \
9193 struct sf##NN##_op : public sf_base<T> \
9195 typedef typename sf_base<T>::Type const Type; \
9196 static inline T process(Type x, Type y, Type z, Type w) \
9200 static inline std::string id() { return OP1; } \
9203 define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)")
9204 define_sfop4(49,(x
+ ((y
+ z
) * w
)),"t+((t+t)*t)")
9205 define_sfop4(50,(x
+ ((y
- z
) / w
)),"t+((t-t)/t)")
9206 define_sfop4(51,(x
+ ((y
- z
) * w
)),"t+((t-t)*t)")
9207 define_sfop4(52,(x
+ ((y
* z
) / w
)),"t+((t*t)/t)")
9208 define_sfop4(53,(x
+ ((y
* z
) * w
)),"t+((t*t)*t)")
9209 define_sfop4(54,(x
+ ((y
/ z
) + w
)),"t+((t/t)+t)")
9210 define_sfop4(55,(x
+ ((y
/ z
) / w
)),"t+((t/t)/t)")
9211 define_sfop4(56,(x
+ ((y
/ z
) * w
)),"t+((t/t)*t)")
9212 define_sfop4(57,(x
- ((y
+ z
) / w
)),"t-((t+t)/t)")
9213 define_sfop4(58,(x
- ((y
+ z
) * w
)),"t-((t+t)*t)")
9214 define_sfop4(59,(x
- ((y
- z
) / w
)),"t-((t-t)/t)")
9215 define_sfop4(60,(x
- ((y
- z
) * w
)),"t-((t-t)*t)")
9216 define_sfop4(61,(x
- ((y
* z
) / w
)),"t-((t*t)/t)")
9217 define_sfop4(62,(x
- ((y
* z
) * w
)),"t-((t*t)*t)")
9218 define_sfop4(63,(x
- ((y
/ z
) / w
)),"t-((t/t)/t)")
9219 define_sfop4(64,(x
- ((y
/ z
) * w
)),"t-((t/t)*t)")
9220 define_sfop4(65,(((x
+ y
) * z
) - w
),"((t+t)*t)-t")
9221 define_sfop4(66,(((x
- y
) * z
) - w
),"((t-t)*t)-t")
9222 define_sfop4(67,(((x
* y
) * z
) - w
),"((t*t)*t)-t")
9223 define_sfop4(68,(((x
/ y
) * z
) - w
),"((t/t)*t)-t")
9224 define_sfop4(69,(((x
+ y
) / z
) - w
),"((t+t)/t)-t")
9225 define_sfop4(70,(((x
- y
) / z
) - w
),"((t-t)/t)-t")
9226 define_sfop4(71,(((x
* y
) / z
) - w
),"((t*t)/t)-t")
9227 define_sfop4(72,(((x
/ y
) / z
) - w
),"((t/t)/t)-t")
9228 define_sfop4(73,((x
* y
) + (z
* w
)),"(t*t)+(t*t)")
9229 define_sfop4(74,((x
* y
) - (z
* w
)),"(t*t)-(t*t)")
9230 define_sfop4(75,((x
* y
) + (z
/ w
)),"(t*t)+(t/t)")
9231 define_sfop4(76,((x
* y
) - (z
/ w
)),"(t*t)-(t/t)")
9232 define_sfop4(77,((x
/ y
) + (z
/ w
)),"(t/t)+(t/t)")
9233 define_sfop4(78,((x
/ y
) - (z
/ w
)),"(t/t)-(t/t)")
9234 define_sfop4(79,((x
/ y
) - (z
* w
)),"(t/t)-(t*t)")
9235 define_sfop4(80,(x
/ (y
+ (z
* w
))),"t/(t+(t*t))")
9236 define_sfop4(81,(x
/ (y
- (z
* w
))),"t/(t-(t*t))")
9237 define_sfop4(82,(x
* (y
+ (z
* w
))),"t*(t+(t*t))")
9238 define_sfop4(83,(x
* (y
- (z
* w
))),"t*(t-(t*t))")
9240 define_sfop4(84,(axn
<T
,2>(x
,y
) + axn
<T
,2>(z
,w
)),"")
9241 define_sfop4(85,(axn
<T
,3>(x
,y
) + axn
<T
,3>(z
,w
)),"")
9242 define_sfop4(86,(axn
<T
,4>(x
,y
) + axn
<T
,4>(z
,w
)),"")
9243 define_sfop4(87,(axn
<T
,5>(x
,y
) + axn
<T
,5>(z
,w
)),"")
9244 define_sfop4(88,(axn
<T
,6>(x
,y
) + axn
<T
,6>(z
,w
)),"")
9245 define_sfop4(89,(axn
<T
,7>(x
,y
) + axn
<T
,7>(z
,w
)),"")
9246 define_sfop4(90,(axn
<T
,8>(x
,y
) + axn
<T
,8>(z
,w
)),"")
9247 define_sfop4(91,(axn
<T
,9>(x
,y
) + axn
<T
,9>(z
,w
)),"")
9248 define_sfop4(92,((details::is_true(x
) && details::is_true(y
)) ? z
: w
),"")
9249 define_sfop4(93,((details::is_true(x
) || details::is_true(y
)) ? z
: w
),"")
9250 define_sfop4(94,((x
< y
) ? z
: w
),"")
9251 define_sfop4(95,((x
<= y
) ? z
: w
),"")
9252 define_sfop4(96,((x
> y
) ? z
: w
),"")
9253 define_sfop4(97,((x
>= y
) ? z
: w
),"")
9254 define_sfop4(98,(details::is_true(numeric::equal(x
,y
)) ? z
: w
),"")
9255 define_sfop4(99,(x
* numeric::sin(y
) + z
* numeric::cos(w
)),"")
9257 define_sfop4(ext00
,((x
+ y
) - (z
* w
)),"(t+t)-(t*t)")
9258 define_sfop4(ext01
,((x
+ y
) - (z
/ w
)),"(t+t)-(t/t)")
9259 define_sfop4(ext02
,((x
+ y
) + (z
* w
)),"(t+t)+(t*t)")
9260 define_sfop4(ext03
,((x
+ y
) + (z
/ w
)),"(t+t)+(t/t)")
9261 define_sfop4(ext04
,((x
- y
) + (z
* w
)),"(t-t)+(t*t)")
9262 define_sfop4(ext05
,((x
- y
) + (z
/ w
)),"(t-t)+(t/t)")
9263 define_sfop4(ext06
,((x
- y
) - (z
* w
)),"(t-t)-(t*t)")
9264 define_sfop4(ext07
,((x
- y
) - (z
/ w
)),"(t-t)-(t/t)")
9265 define_sfop4(ext08
,((x
+ y
) - (z
- w
)),"(t+t)-(t-t)")
9266 define_sfop4(ext09
,((x
+ y
) + (z
- w
)),"(t+t)+(t-t)")
9267 define_sfop4(ext10
,((x
+ y
) + (z
+ w
)),"(t+t)+(t+t)")
9268 define_sfop4(ext11
,((x
+ y
) * (z
- w
)),"(t+t)*(t-t)")
9269 define_sfop4(ext12
,((x
+ y
) / (z
- w
)),"(t+t)/(t-t)")
9270 define_sfop4(ext13
,((x
- y
) - (z
+ w
)),"(t-t)-(t+t)")
9271 define_sfop4(ext14
,((x
- y
) + (z
+ w
)),"(t-t)+(t+t)")
9272 define_sfop4(ext15
,((x
- y
) * (z
+ w
)),"(t-t)*(t+t)")
9273 define_sfop4(ext16
,((x
- y
) / (z
+ w
)),"(t-t)/(t+t)")
9274 define_sfop4(ext17
,((x
* y
) - (z
+ w
)),"(t*t)-(t+t)")
9275 define_sfop4(ext18
,((x
/ y
) - (z
+ w
)),"(t/t)-(t+t)")
9276 define_sfop4(ext19
,((x
* y
) + (z
+ w
)),"(t*t)+(t+t)")
9277 define_sfop4(ext20
,((x
/ y
) + (z
+ w
)),"(t/t)+(t+t)")
9278 define_sfop4(ext21
,((x
* y
) + (z
- w
)),"(t*t)+(t-t)")
9279 define_sfop4(ext22
,((x
/ y
) + (z
- w
)),"(t/t)+(t-t)")
9280 define_sfop4(ext23
,((x
* y
) - (z
- w
)),"(t*t)-(t-t)")
9281 define_sfop4(ext24
,((x
/ y
) - (z
- w
)),"(t/t)-(t-t)")
9282 define_sfop4(ext25
,((x
+ y
) * (z
* w
)),"(t+t)*(t*t)")
9283 define_sfop4(ext26
,((x
+ y
) * (z
/ w
)),"(t+t)*(t/t)")
9284 define_sfop4(ext27
,((x
+ y
) / (z
* w
)),"(t+t)/(t*t)")
9285 define_sfop4(ext28
,((x
+ y
) / (z
/ w
)),"(t+t)/(t/t)")
9286 define_sfop4(ext29
,((x
- y
) / (z
* w
)),"(t-t)/(t*t)")
9287 define_sfop4(ext30
,((x
- y
) / (z
/ w
)),"(t-t)/(t/t)")
9288 define_sfop4(ext31
,((x
- y
) * (z
* w
)),"(t-t)*(t*t)")
9289 define_sfop4(ext32
,((x
- y
) * (z
/ w
)),"(t-t)*(t/t)")
9290 define_sfop4(ext33
,((x
* y
) * (z
+ w
)),"(t*t)*(t+t)")
9291 define_sfop4(ext34
,((x
/ y
) * (z
+ w
)),"(t/t)*(t+t)")
9292 define_sfop4(ext35
,((x
* y
) / (z
+ w
)),"(t*t)/(t+t)")
9293 define_sfop4(ext36
,((x
/ y
) / (z
+ w
)),"(t/t)/(t+t)")
9294 define_sfop4(ext37
,((x
* y
) / (z
- w
)),"(t*t)/(t-t)")
9295 define_sfop4(ext38
,((x
/ y
) / (z
- w
)),"(t/t)/(t-t)")
9296 define_sfop4(ext39
,((x
* y
) * (z
- w
)),"(t*t)*(t-t)")
9297 define_sfop4(ext40
,((x
* y
) / (z
* w
)),"(t*t)/(t*t)")
9298 define_sfop4(ext41
,((x
/ y
) * (z
/ w
)),"(t/t)*(t/t)")
9299 define_sfop4(ext42
,((x
/ y
) * (z
- w
)),"(t/t)*(t-t)")
9300 define_sfop4(ext43
,((x
* y
) * (z
* w
)),"(t*t)*(t*t)")
9301 define_sfop4(ext44
,(x
+ (y
* (z
/ w
))),"t+(t*(t/t))")
9302 define_sfop4(ext45
,(x
- (y
* (z
/ w
))),"t-(t*(t/t))")
9303 define_sfop4(ext46
,(x
+ (y
/ (z
* w
))),"t+(t/(t*t))")
9304 define_sfop4(ext47
,(x
- (y
/ (z
* w
))),"t-(t/(t*t))")
9305 define_sfop4(ext48
,(((x
- y
) - z
) * w
),"((t-t)-t)*t")
9306 define_sfop4(ext49
,(((x
- y
) - z
) / w
),"((t-t)-t)/t")
9307 define_sfop4(ext50
,(((x
- y
) + z
) * w
),"((t-t)+t)*t")
9308 define_sfop4(ext51
,(((x
- y
) + z
) / w
),"((t-t)+t)/t")
9309 define_sfop4(ext52
,((x
+ (y
- z
)) * w
),"(t+(t-t))*t")
9310 define_sfop4(ext53
,((x
+ (y
- z
)) / w
),"(t+(t-t))/t")
9311 define_sfop4(ext54
,((x
+ y
) / (z
+ w
)),"(t+t)/(t+t)")
9312 define_sfop4(ext55
,((x
- y
) / (z
- w
)),"(t-t)/(t-t)")
9313 define_sfop4(ext56
,((x
+ y
) * (z
+ w
)),"(t+t)*(t+t)")
9314 define_sfop4(ext57
,((x
- y
) * (z
- w
)),"(t-t)*(t-t)")
9315 define_sfop4(ext58
,((x
- y
) + (z
- w
)),"(t-t)+(t-t)")
9316 define_sfop4(ext59
,((x
- y
) - (z
- w
)),"(t-t)-(t-t)")
9317 define_sfop4(ext60
,((x
/ y
) + (z
* w
)),"(t/t)+(t*t)")
9318 define_sfop4(ext61
,(((x
* y
) * z
) / w
),"((t*t)*t)/t")
9323 template <typename T
, typename SpecialFunction
>
9324 class sf3_node
: public trinary_node
<T
>
9328 typedef expression_node
<T
>* expression_ptr
;
9330 sf3_node(const operator_type
& opr
,
9331 expression_ptr branch0
,
9332 expression_ptr branch1
,
9333 expression_ptr branch2
)
9334 : trinary_node
<T
>(opr
, branch0
, branch1
, branch2
)
9337 inline T
value() const
9339 const T x
= trinary_node
<T
>::branch_
[0].first
->value();
9340 const T y
= trinary_node
<T
>::branch_
[1].first
->value();
9341 const T z
= trinary_node
<T
>::branch_
[2].first
->value();
9343 return SpecialFunction::process(x
, y
, z
);
9347 template <typename T
, typename SpecialFunction
>
9348 class sf4_node
: public quaternary_node
<T
>
9352 typedef expression_node
<T
>* expression_ptr
;
9354 sf4_node(const operator_type
& opr
,
9355 expression_ptr branch0
,
9356 expression_ptr branch1
,
9357 expression_ptr branch2
,
9358 expression_ptr branch3
)
9359 : quaternary_node
<T
>(opr
, branch0
, branch1
, branch2
, branch3
)
9362 inline T
value() const
9364 const T x
= quaternary_node
<T
>::branch_
[0].first
->value();
9365 const T y
= quaternary_node
<T
>::branch_
[1].first
->value();
9366 const T z
= quaternary_node
<T
>::branch_
[2].first
->value();
9367 const T w
= quaternary_node
<T
>::branch_
[3].first
->value();
9369 return SpecialFunction::process(x
, y
, z
, w
);
9373 template <typename T
, typename SpecialFunction
>
9374 class sf3_var_node
: public expression_node
<T
>
9378 typedef expression_node
<T
>* expression_ptr
;
9380 sf3_var_node(const T
& v0
, const T
& v1
, const T
& v2
)
9386 inline T
value() const
9388 return SpecialFunction::process(v0_
, v1_
, v2_
);
9391 inline typename expression_node
<T
>::node_type
type() const
9393 return expression_node
<T
>::e_trinary
;
9398 sf3_var_node(sf3_var_node
<T
,SpecialFunction
>&);
9399 sf3_var_node
<T
,SpecialFunction
>& operator=(sf3_var_node
<T
,SpecialFunction
>&);
9406 template <typename T
, typename SpecialFunction
>
9407 class sf4_var_node
: public expression_node
<T
>
9411 typedef expression_node
<T
>* expression_ptr
;
9413 sf4_var_node(const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
)
9420 inline T
value() const
9422 return SpecialFunction::process(v0_
, v1_
, v2_
, v3_
);
9425 inline typename expression_node
<T
>::node_type
type() const
9427 return expression_node
<T
>::e_trinary
;
9432 sf4_var_node(sf4_var_node
<T
,SpecialFunction
>&);
9433 sf4_var_node
<T
,SpecialFunction
>& operator=(sf4_var_node
<T
,SpecialFunction
>&);
9441 template <typename T
, typename VarArgFunction
>
9442 class vararg_node
: public expression_node
<T
>
9446 typedef expression_node
<T
>* expression_ptr
;
9448 template <typename Allocator
,
9449 template <typename
, typename
> class Sequence
>
9450 explicit vararg_node(const Sequence
<expression_ptr
,Allocator
>& arg_list
)
9452 arg_list_
.resize(arg_list
.size());
9453 delete_branch_
.resize(arg_list
.size());
9455 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
9459 arg_list_
[i
] = arg_list
[i
];
9460 delete_branch_
[i
] = static_cast<unsigned char>(branch_deletable(arg_list_
[i
]) ? 1 : 0);
9465 delete_branch_
.clear();
9473 for (std::size_t i
= 0; i
< arg_list_
.size(); ++i
)
9475 if (arg_list_
[i
] && delete_branch_
[i
])
9477 destroy_node(arg_list_
[i
]);
9482 inline T
value() const
9484 return VarArgFunction::process(arg_list_
);
9487 inline typename expression_node
<T
>::node_type
type() const
9489 return expression_node
<T
>::e_vararg
;
9494 std::vector
<expression_ptr
> arg_list_
;
9495 std::vector
<unsigned char> delete_branch_
;
9498 template <typename T
, typename VarArgFunction
>
9499 class vararg_varnode
: public expression_node
<T
>
9503 typedef expression_node
<T
>* expression_ptr
;
9505 template <typename Allocator
,
9506 template <typename
, typename
> class Sequence
>
9507 explicit vararg_varnode(const Sequence
<expression_ptr
,Allocator
>& arg_list
)
9509 arg_list_
.resize(arg_list
.size());
9511 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
9513 if (arg_list
[i
] && is_variable_node(arg_list
[i
]))
9515 variable_node
<T
>* var_node_ptr
= static_cast<variable_node
<T
>*>(arg_list
[i
]);
9516 arg_list_
[i
] = (&var_node_ptr
->ref());
9526 inline T
value() const
9528 if (!arg_list_
.empty())
9529 return VarArgFunction::process(arg_list_
);
9531 return std::numeric_limits
<T
>::quiet_NaN();
9534 inline typename expression_node
<T
>::node_type
type() const
9536 return expression_node
<T
>::e_vararg
;
9541 std::vector
<const T
*> arg_list_
;
9544 template <typename T
, typename VecFunction
>
9545 class vectorize_node
: public expression_node
<T
>
9549 typedef expression_node
<T
>* expression_ptr
;
9551 explicit vectorize_node(const expression_ptr v
)
9554 v_deletable_(branch_deletable(v_
))
9556 if (is_ivector_node(v
))
9558 ivec_ptr_
= dynamic_cast<vector_interface
<T
>*>(v
);
9566 if (v_
&& v_deletable_
)
9572 inline T
value() const
9577 return VecFunction::process(ivec_ptr_
);
9580 return std::numeric_limits
<T
>::quiet_NaN();
9583 inline typename expression_node
<T
>::node_type
type() const
9585 return expression_node
<T
>::e_vecfunc
;
9590 vector_interface
<T
>* ivec_ptr_
;
9592 const bool v_deletable_
;
9595 template <typename T
>
9596 class assignment_node
: public binary_node
<T
>
9600 typedef expression_node
<T
>* expression_ptr
;
9602 assignment_node(const operator_type
& opr
,
9603 expression_ptr branch0
,
9604 expression_ptr branch1
)
9605 : binary_node
<T
>(opr
, branch0
, branch1
),
9608 if (is_variable_node(binary_node
<T
>::branch_
[0].first
))
9610 var_node_ptr_
= static_cast<variable_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
9614 inline T
value() const
9618 T
& result
= var_node_ptr_
->ref();
9620 result
= binary_node
<T
>::branch_
[1].first
->value();
9625 return std::numeric_limits
<T
>::quiet_NaN();
9630 variable_node
<T
>* var_node_ptr_
;
9633 template <typename T
>
9634 class assignment_vec_elem_node
: public binary_node
<T
>
9638 typedef expression_node
<T
>* expression_ptr
;
9640 assignment_vec_elem_node(const operator_type
& opr
,
9641 expression_ptr branch0
,
9642 expression_ptr branch1
)
9643 : binary_node
<T
>(opr
, branch0
, branch1
),
9646 if (is_vector_elem_node(binary_node
<T
>::branch_
[0].first
))
9648 vec_node_ptr_
= static_cast<vector_elem_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
9652 inline T
value() const
9656 T
& result
= vec_node_ptr_
->ref();
9658 result
= binary_node
<T
>::branch_
[1].first
->value();
9663 return std::numeric_limits
<T
>::quiet_NaN();
9668 vector_elem_node
<T
>* vec_node_ptr_
;
9671 template <typename T
>
9672 class assignment_rebasevec_elem_node
: public binary_node
<T
>
9676 typedef expression_node
<T
>* expression_ptr
;
9678 assignment_rebasevec_elem_node(const operator_type
& opr
,
9679 expression_ptr branch0
,
9680 expression_ptr branch1
)
9681 : binary_node
<T
>(opr
, branch0
, branch1
),
9684 if (is_rebasevector_elem_node(binary_node
<T
>::branch_
[0].first
))
9686 rbvec_node_ptr_
= static_cast<rebasevector_elem_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
9690 inline T
value() const
9692 if (rbvec_node_ptr_
)
9694 T
& result
= rbvec_node_ptr_
->ref();
9696 result
= binary_node
<T
>::branch_
[1].first
->value();
9701 return std::numeric_limits
<T
>::quiet_NaN();
9706 rebasevector_elem_node
<T
>* rbvec_node_ptr_
;
9709 template <typename T
>
9710 class assignment_rebasevec_celem_node
: public binary_node
<T
>
9714 typedef expression_node
<T
>* expression_ptr
;
9716 assignment_rebasevec_celem_node(const operator_type
& opr
,
9717 expression_ptr branch0
,
9718 expression_ptr branch1
)
9719 : binary_node
<T
>(opr
, branch0
, branch1
),
9722 if (is_rebasevector_celem_node(binary_node
<T
>::branch_
[0].first
))
9724 rbvec_node_ptr_
= static_cast<rebasevector_celem_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
9728 inline T
value() const
9730 if (rbvec_node_ptr_
)
9732 T
& result
= rbvec_node_ptr_
->ref();
9734 result
= binary_node
<T
>::branch_
[1].first
->value();
9739 return std::numeric_limits
<T
>::quiet_NaN();
9744 rebasevector_celem_node
<T
>* rbvec_node_ptr_
;
9747 template <typename T
>
9748 class assignment_vec_node
: public binary_node
<T
>,
9749 public vector_interface
<T
>
9753 typedef expression_node
<T
>* expression_ptr
;
9754 typedef vector_node
<T
>* vector_node_ptr
;
9755 typedef vec_data_store
<T
> vds_t
;
9757 assignment_vec_node(const operator_type
& opr
,
9758 expression_ptr branch0
,
9759 expression_ptr branch1
)
9760 : binary_node
<T
>(opr
, branch0
, branch1
),
9763 if (is_vector_node(binary_node
<T
>::branch_
[0].first
))
9765 vec_node_ptr_
= static_cast<vector_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
9766 vds() = vec_node_ptr_
->vds();
9770 inline T
value() const
9774 const T v
= binary_node
<T
>::branch_
[1].first
->value();
9776 T
* vec
= vds().data();
9778 loop_unroll::details
lud(size());
9779 const T
* upper_bound
= vec
+ lud
.upper_bound
;
9781 while (vec
< upper_bound
)
9783 #define exprtk_loop(N) \
9786 exprtk_loop( 0) exprtk_loop( 1)
9787 exprtk_loop( 2) exprtk_loop( 3)
9788 #ifndef exprtk_disable_superscalar_unroll
9789 exprtk_loop( 4) exprtk_loop( 5)
9790 exprtk_loop( 6) exprtk_loop( 7)
9791 exprtk_loop( 8) exprtk_loop( 9)
9792 exprtk_loop(10) exprtk_loop(11)
9793 exprtk_loop(12) exprtk_loop(13)
9794 exprtk_loop(14) exprtk_loop(15)
9797 vec
+= lud
.batch_size
;
9800 exprtk_disable_fallthrough_begin
9801 switch (lud
.remainder
)
9803 #define case_stmt(N) \
9804 case N : *vec++ = v; \
9806 #ifndef exprtk_disable_superscalar_unroll
9807 case_stmt(15) case_stmt(14)
9808 case_stmt(13) case_stmt(12)
9809 case_stmt(11) case_stmt(10)
9810 case_stmt( 9) case_stmt( 8)
9811 case_stmt( 7) case_stmt( 6)
9812 case_stmt( 5) case_stmt( 4)
9814 case_stmt( 3) case_stmt( 2)
9817 exprtk_disable_fallthrough_end
9822 return vec_node_ptr_
->value();
9825 return std::numeric_limits
<T
>::quiet_NaN();
9828 vector_node_ptr
vec() const
9830 return vec_node_ptr_
;
9833 vector_node_ptr
vec()
9835 return vec_node_ptr_
;
9838 inline typename expression_node
<T
>::node_type
type() const
9840 return expression_node
<T
>::e_vecvalass
;
9843 std::size_t size() const
9845 return vds().size();
9853 const vds_t
& vds() const
9860 vector_node
<T
>* vec_node_ptr_
;
9864 template <typename T
>
9865 class assignment_vecvec_node
: public binary_node
<T
>,
9866 public vector_interface
<T
>
9870 typedef expression_node
<T
>* expression_ptr
;
9871 typedef vector_node
<T
>* vector_node_ptr
;
9872 typedef vec_data_store
<T
> vds_t
;
9874 assignment_vecvec_node(const operator_type
& opr
,
9875 expression_ptr branch0
,
9876 expression_ptr branch1
)
9877 : binary_node
<T
>(opr
, branch0
, branch1
),
9880 initialised_(false),
9883 if (is_vector_node(binary_node
<T
>::branch_
[0].first
))
9885 vec0_node_ptr_
= static_cast<vector_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
9886 vds() = vec0_node_ptr_
->vds();
9889 if (is_vector_node(binary_node
<T
>::branch_
[1].first
))
9891 vec1_node_ptr_
= static_cast<vector_node
<T
>*>(binary_node
<T
>::branch_
[1].first
);
9892 vds_t::match_sizes(vds(),vec1_node_ptr_
->vds());
9894 else if (is_ivector_node(binary_node
<T
>::branch_
[1].first
))
9896 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
9898 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[1].first
)))
9900 vec1_node_ptr_
= vi
->vec();
9902 if (!vi
->side_effect())
9905 src_is_ivec_
= true;
9908 vds_t::match_sizes(vds(),vi
->vds());
9912 initialised_
= (vec0_node_ptr_
&& vec1_node_ptr_
);
9915 inline T
value() const
9919 binary_node
<T
>::branch_
[1].first
->value();
9922 return vec0_node_ptr_
->value();
9924 T
* vec0
= vec0_node_ptr_
->vds().data();
9925 T
* vec1
= vec1_node_ptr_
->vds().data();
9927 loop_unroll::details
lud(size());
9928 const T
* upper_bound
= vec0
+ lud
.upper_bound
;
9930 while (vec0
< upper_bound
)
9932 #define exprtk_loop(N) \
9933 vec0[N] = vec1[N]; \
9935 exprtk_loop( 0) exprtk_loop( 1)
9936 exprtk_loop( 2) exprtk_loop( 3)
9937 #ifndef exprtk_disable_superscalar_unroll
9938 exprtk_loop( 4) exprtk_loop( 5)
9939 exprtk_loop( 6) exprtk_loop( 7)
9940 exprtk_loop( 8) exprtk_loop( 9)
9941 exprtk_loop(10) exprtk_loop(11)
9942 exprtk_loop(12) exprtk_loop(13)
9943 exprtk_loop(14) exprtk_loop(15)
9946 vec0
+= lud
.batch_size
;
9947 vec1
+= lud
.batch_size
;
9950 exprtk_disable_fallthrough_begin
9951 switch (lud
.remainder
)
9953 #define case_stmt(N) \
9954 case N : *vec0++ = *vec1++; \
9956 #ifndef exprtk_disable_superscalar_unroll
9957 case_stmt(15) case_stmt(14)
9958 case_stmt(13) case_stmt(12)
9959 case_stmt(11) case_stmt(10)
9960 case_stmt( 9) case_stmt( 8)
9961 case_stmt( 7) case_stmt( 6)
9962 case_stmt( 5) case_stmt( 4)
9964 case_stmt( 3) case_stmt( 2)
9967 exprtk_disable_fallthrough_end
9972 return vec0_node_ptr_
->value();
9975 return std::numeric_limits
<T
>::quiet_NaN();
9978 vector_node_ptr
vec() const
9980 return vec0_node_ptr_
;
9983 vector_node_ptr
vec()
9985 return vec0_node_ptr_
;
9988 inline typename expression_node
<T
>::node_type
type() const
9990 return expression_node
<T
>::e_vecvecass
;
9993 std::size_t size() const
9995 return vds().size();
10003 const vds_t
& vds() const
10010 vector_node
<T
>* vec0_node_ptr_
;
10011 vector_node
<T
>* vec1_node_ptr_
;
10017 template <typename T
, typename Operation
>
10018 class assignment_op_node
: public binary_node
<T
>
10022 typedef expression_node
<T
>* expression_ptr
;
10024 assignment_op_node(const operator_type
& opr
,
10025 expression_ptr branch0
,
10026 expression_ptr branch1
)
10027 : binary_node
<T
>(opr
, branch0
, branch1
),
10030 if (is_variable_node(binary_node
<T
>::branch_
[0].first
))
10032 var_node_ptr_
= static_cast<variable_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
10036 inline T
value() const
10040 T
& v
= var_node_ptr_
->ref();
10041 v
= Operation::process(v
,binary_node
<T
>::branch_
[1].first
->value());
10046 return std::numeric_limits
<T
>::quiet_NaN();
10051 variable_node
<T
>* var_node_ptr_
;
10054 template <typename T
, typename Operation
>
10055 class assignment_vec_elem_op_node
: public binary_node
<T
>
10059 typedef expression_node
<T
>* expression_ptr
;
10061 assignment_vec_elem_op_node(const operator_type
& opr
,
10062 expression_ptr branch0
,
10063 expression_ptr branch1
)
10064 : binary_node
<T
>(opr
, branch0
, branch1
),
10067 if (is_vector_elem_node(binary_node
<T
>::branch_
[0].first
))
10069 vec_node_ptr_
= static_cast<vector_elem_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
10073 inline T
value() const
10077 T
& v
= vec_node_ptr_
->ref();
10078 v
= Operation::process(v
,binary_node
<T
>::branch_
[1].first
->value());
10083 return std::numeric_limits
<T
>::quiet_NaN();
10088 vector_elem_node
<T
>* vec_node_ptr_
;
10091 template <typename T
, typename Operation
>
10092 class assignment_rebasevec_elem_op_node
: public binary_node
<T
>
10096 typedef expression_node
<T
>* expression_ptr
;
10098 assignment_rebasevec_elem_op_node(const operator_type
& opr
,
10099 expression_ptr branch0
,
10100 expression_ptr branch1
)
10101 : binary_node
<T
>(opr
, branch0
, branch1
),
10104 if (is_rebasevector_elem_node(binary_node
<T
>::branch_
[0].first
))
10106 rbvec_node_ptr_
= static_cast<rebasevector_elem_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
10110 inline T
value() const
10112 if (rbvec_node_ptr_
)
10114 T
& v
= rbvec_node_ptr_
->ref();
10115 v
= Operation::process(v
,binary_node
<T
>::branch_
[1].first
->value());
10120 return std::numeric_limits
<T
>::quiet_NaN();
10125 rebasevector_elem_node
<T
>* rbvec_node_ptr_
;
10128 template <typename T
, typename Operation
>
10129 class assignment_rebasevec_celem_op_node
: public binary_node
<T
>
10133 typedef expression_node
<T
>* expression_ptr
;
10135 assignment_rebasevec_celem_op_node(const operator_type
& opr
,
10136 expression_ptr branch0
,
10137 expression_ptr branch1
)
10138 : binary_node
<T
>(opr
, branch0
, branch1
),
10141 if (is_rebasevector_celem_node(binary_node
<T
>::branch_
[0].first
))
10143 rbvec_node_ptr_
= static_cast<rebasevector_celem_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
10147 inline T
value() const
10149 if (rbvec_node_ptr_
)
10151 T
& v
= rbvec_node_ptr_
->ref();
10152 v
= Operation::process(v
,binary_node
<T
>::branch_
[1].first
->value());
10157 return std::numeric_limits
<T
>::quiet_NaN();
10162 rebasevector_celem_node
<T
>* rbvec_node_ptr_
;
10165 template <typename T
, typename Operation
>
10166 class assignment_vec_op_node
: public binary_node
<T
>,
10167 public vector_interface
<T
>
10171 typedef expression_node
<T
>* expression_ptr
;
10172 typedef vector_node
<T
>* vector_node_ptr
;
10173 typedef vec_data_store
<T
> vds_t
;
10175 assignment_vec_op_node(const operator_type
& opr
,
10176 expression_ptr branch0
,
10177 expression_ptr branch1
)
10178 : binary_node
<T
>(opr
, branch0
, branch1
),
10181 if (is_vector_node(binary_node
<T
>::branch_
[0].first
))
10183 vec_node_ptr_
= static_cast<vector_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
10184 vds() = vec_node_ptr_
->vds();
10188 inline T
value() const
10192 const T v
= binary_node
<T
>::branch_
[1].first
->value();
10194 T
* vec
= vds().data();
10196 loop_unroll::details
lud(size());
10197 const T
* upper_bound
= vec
+ lud
.upper_bound
;
10199 while (vec
< upper_bound
)
10201 #define exprtk_loop(N) \
10202 Operation::assign(vec[N],v); \
10204 exprtk_loop( 0) exprtk_loop( 1)
10205 exprtk_loop( 2) exprtk_loop( 3)
10206 #ifndef exprtk_disable_superscalar_unroll
10207 exprtk_loop( 4) exprtk_loop( 5)
10208 exprtk_loop( 6) exprtk_loop( 7)
10209 exprtk_loop( 8) exprtk_loop( 9)
10210 exprtk_loop(10) exprtk_loop(11)
10211 exprtk_loop(12) exprtk_loop(13)
10212 exprtk_loop(14) exprtk_loop(15)
10215 vec
+= lud
.batch_size
;
10218 exprtk_disable_fallthrough_begin
10219 switch (lud
.remainder
)
10221 #define case_stmt(N) \
10222 case N : Operation::assign(*vec++,v); \
10224 #ifndef exprtk_disable_superscalar_unroll
10225 case_stmt(15) case_stmt(14)
10226 case_stmt(13) case_stmt(12)
10227 case_stmt(11) case_stmt(10)
10228 case_stmt( 9) case_stmt( 8)
10229 case_stmt( 7) case_stmt( 6)
10230 case_stmt( 5) case_stmt( 4)
10232 case_stmt( 3) case_stmt( 2)
10235 exprtk_disable_fallthrough_end
10241 return vec_node_ptr_
->value();
10244 return std::numeric_limits
<T
>::quiet_NaN();
10247 vector_node_ptr
vec() const
10249 return vec_node_ptr_
;
10252 vector_node_ptr
vec()
10254 return vec_node_ptr_
;
10257 inline typename expression_node
<T
>::node_type
type() const
10259 return expression_node
<T
>::e_vecopvalass
;
10262 std::size_t size() const
10264 return vds().size();
10272 const vds_t
& vds() const
10277 bool side_effect() const
10284 vector_node
<T
>* vec_node_ptr_
;
10288 template <typename T
, typename Operation
>
10289 class assignment_vecvec_op_node
: public binary_node
<T
>,
10290 public vector_interface
<T
>
10294 typedef expression_node
<T
>* expression_ptr
;
10295 typedef vector_node
<T
>* vector_node_ptr
;
10296 typedef vec_data_store
<T
> vds_t
;
10298 assignment_vecvec_op_node(const operator_type
& opr
,
10299 expression_ptr branch0
,
10300 expression_ptr branch1
)
10301 : binary_node
<T
>(opr
, branch0
, branch1
),
10304 initialised_(false)
10306 if (is_vector_node(binary_node
<T
>::branch_
[0].first
))
10308 vec0_node_ptr_
= static_cast<vector_node
<T
>*>(binary_node
<T
>::branch_
[0].first
);
10309 vds() = vec0_node_ptr_
->vds();
10312 if (is_vector_node(binary_node
<T
>::branch_
[1].first
))
10314 vec1_node_ptr_
= static_cast<vector_node
<T
>*>(binary_node
<T
>::branch_
[1].first
);
10315 vec1_node_ptr_
->vds() = vds();
10317 else if (is_ivector_node(binary_node
<T
>::branch_
[1].first
))
10319 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
10321 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[1].first
)))
10323 vec1_node_ptr_
= vi
->vec();
10324 vec1_node_ptr_
->vds() = vds();
10327 vds_t::match_sizes(vds(),vec1_node_ptr_
->vds());
10330 initialised_
= (vec0_node_ptr_
&& vec1_node_ptr_
);
10333 inline T
value() const
10337 binary_node
<T
>::branch_
[0].first
->value();
10338 binary_node
<T
>::branch_
[1].first
->value();
10340 T
* vec0
= vec0_node_ptr_
->vds().data();
10341 const T
* vec1
= vec1_node_ptr_
->vds().data();
10343 loop_unroll::details
lud(size());
10344 const T
* upper_bound
= vec0
+ lud
.upper_bound
;
10346 while (vec0
< upper_bound
)
10348 #define exprtk_loop(N) \
10349 vec0[N] = Operation::process(vec0[N], vec1[N]); \
10351 exprtk_loop( 0) exprtk_loop( 1)
10352 exprtk_loop( 2) exprtk_loop( 3)
10353 #ifndef exprtk_disable_superscalar_unroll
10354 exprtk_loop( 4) exprtk_loop( 5)
10355 exprtk_loop( 6) exprtk_loop( 7)
10356 exprtk_loop( 8) exprtk_loop( 9)
10357 exprtk_loop(10) exprtk_loop(11)
10358 exprtk_loop(12) exprtk_loop(13)
10359 exprtk_loop(14) exprtk_loop(15)
10362 vec0
+= lud
.batch_size
;
10363 vec1
+= lud
.batch_size
;
10368 exprtk_disable_fallthrough_begin
10369 switch (lud
.remainder
)
10371 #define case_stmt(N) \
10372 case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
10374 #ifndef exprtk_disable_superscalar_unroll
10375 case_stmt(15) case_stmt(14)
10376 case_stmt(13) case_stmt(12)
10377 case_stmt(11) case_stmt(10)
10378 case_stmt( 9) case_stmt( 8)
10379 case_stmt( 7) case_stmt( 6)
10380 case_stmt( 5) case_stmt( 4)
10382 case_stmt( 3) case_stmt( 2)
10385 exprtk_disable_fallthrough_end
10390 return vec0_node_ptr_
->value();
10393 return std::numeric_limits
<T
>::quiet_NaN();
10396 vector_node_ptr
vec() const
10398 return vec0_node_ptr_
;
10401 vector_node_ptr
vec()
10403 return vec0_node_ptr_
;
10406 inline typename expression_node
<T
>::node_type
type() const
10408 return expression_node
<T
>::e_vecopvecass
;
10411 std::size_t size() const
10413 return vds().size();
10421 const vds_t
& vds() const
10426 bool side_effect() const
10433 vector_node
<T
>* vec0_node_ptr_
;
10434 vector_node
<T
>* vec1_node_ptr_
;
10439 template <typename T
, typename Operation
>
10440 class vec_binop_vecvec_node
: public binary_node
<T
>,
10441 public vector_interface
<T
>
10445 typedef expression_node
<T
>* expression_ptr
;
10446 typedef vector_node
<T
>* vector_node_ptr
;
10447 typedef vector_holder
<T
>* vector_holder_ptr
;
10448 typedef vec_data_store
<T
> vds_t
;
10450 vec_binop_vecvec_node(const operator_type
& opr
,
10451 expression_ptr branch0
,
10452 expression_ptr branch1
)
10453 : binary_node
<T
>(opr
, branch0
, branch1
),
10458 initialised_(false)
10460 bool v0_is_ivec
= false;
10461 bool v1_is_ivec
= false;
10463 if (is_vector_node(binary_node
<T
>::branch_
[0].first
))
10465 vec0_node_ptr_
= static_cast<vector_node_ptr
>(binary_node
<T
>::branch_
[0].first
);
10467 else if (is_ivector_node(binary_node
<T
>::branch_
[0].first
))
10469 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
10471 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[0].first
)))
10473 vec0_node_ptr_
= vi
->vec();
10478 if (is_vector_node(binary_node
<T
>::branch_
[1].first
))
10480 vec1_node_ptr_
= static_cast<vector_node_ptr
>(binary_node
<T
>::branch_
[1].first
);
10482 else if (is_ivector_node(binary_node
<T
>::branch_
[1].first
))
10484 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
10486 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[1].first
)))
10488 vec1_node_ptr_
= vi
->vec();
10493 if (vec0_node_ptr_
&& vec1_node_ptr_
)
10495 vector_holder
<T
>& vec0
= vec0_node_ptr_
->vec_holder();
10496 vector_holder
<T
>& vec1
= vec1_node_ptr_
->vec_holder();
10498 if (v0_is_ivec
&& (vec0
.size() <= vec1
.size()))
10499 vds_
= vds_t(vec0_node_ptr_
->vds());
10500 else if (v1_is_ivec
&& (vec1
.size() <= vec0
.size()))
10501 vds_
= vds_t(vec1_node_ptr_
->vds());
10503 vds_
= vds_t(std::min(vec0
.size(),vec1
.size()));
10505 temp_
= new vector_holder
<T
>(vds().data(),vds().size());
10506 temp_vec_node_
= new vector_node
<T
> (vds(),temp_
);
10508 initialised_
= true;
10512 ~vec_binop_vecvec_node()
10515 delete temp_vec_node_
;
10518 inline T
value() const
10522 binary_node
<T
>::branch_
[0].first
->value();
10523 binary_node
<T
>::branch_
[1].first
->value();
10525 const T
* vec0
= vec0_node_ptr_
->vds().data();
10526 const T
* vec1
= vec1_node_ptr_
->vds().data();
10527 T
* vec2
= vds().data();
10529 loop_unroll::details
lud(size());
10530 const T
* upper_bound
= vec2
+ lud
.upper_bound
;
10532 while (vec2
< upper_bound
)
10534 #define exprtk_loop(N) \
10535 vec2[N] = Operation::process(vec0[N], vec1[N]); \
10537 exprtk_loop( 0) exprtk_loop( 1)
10538 exprtk_loop( 2) exprtk_loop( 3)
10539 #ifndef exprtk_disable_superscalar_unroll
10540 exprtk_loop( 4) exprtk_loop( 5)
10541 exprtk_loop( 6) exprtk_loop( 7)
10542 exprtk_loop( 8) exprtk_loop( 9)
10543 exprtk_loop(10) exprtk_loop(11)
10544 exprtk_loop(12) exprtk_loop(13)
10545 exprtk_loop(14) exprtk_loop(15)
10548 vec0
+= lud
.batch_size
;
10549 vec1
+= lud
.batch_size
;
10550 vec2
+= lud
.batch_size
;
10555 exprtk_disable_fallthrough_begin
10556 switch (lud
.remainder
)
10558 #define case_stmt(N) \
10559 case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
10561 #ifndef exprtk_disable_superscalar_unroll
10562 case_stmt(15) case_stmt(14)
10563 case_stmt(13) case_stmt(12)
10564 case_stmt(11) case_stmt(10)
10565 case_stmt( 9) case_stmt( 8)
10566 case_stmt( 7) case_stmt( 6)
10567 case_stmt( 5) case_stmt( 4)
10569 case_stmt( 3) case_stmt( 2)
10572 exprtk_disable_fallthrough_end
10577 return (vds().data())[0];
10580 return std::numeric_limits
<T
>::quiet_NaN();
10583 vector_node_ptr
vec() const
10585 return temp_vec_node_
;
10588 vector_node_ptr
vec()
10590 return temp_vec_node_
;
10593 inline typename expression_node
<T
>::node_type
type() const
10595 return expression_node
<T
>::e_vecvecarith
;
10598 std::size_t size() const
10600 return vds_
.size();
10608 const vds_t
& vds() const
10615 vector_node_ptr vec0_node_ptr_
;
10616 vector_node_ptr vec1_node_ptr_
;
10617 vector_holder_ptr temp_
;
10618 vector_node_ptr temp_vec_node_
;
10623 template <typename T
, typename Operation
>
10624 class vec_binop_vecval_node
: public binary_node
<T
>,
10625 public vector_interface
<T
>
10629 typedef expression_node
<T
>* expression_ptr
;
10630 typedef vector_node
<T
>* vector_node_ptr
;
10631 typedef vector_holder
<T
>* vector_holder_ptr
;
10632 typedef vec_data_store
<T
> vds_t
;
10634 vec_binop_vecval_node(const operator_type
& opr
,
10635 expression_ptr branch0
,
10636 expression_ptr branch1
)
10637 : binary_node
<T
>(opr
, branch0
, branch1
),
10642 bool v0_is_ivec
= false;
10644 if (is_vector_node(binary_node
<T
>::branch_
[0].first
))
10646 vec0_node_ptr_
= static_cast<vector_node_ptr
>(binary_node
<T
>::branch_
[0].first
);
10648 else if (is_ivector_node(binary_node
<T
>::branch_
[0].first
))
10650 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
10652 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[0].first
)))
10654 vec0_node_ptr_
= vi
->vec();
10659 if (vec0_node_ptr_
)
10662 vds() = vec0_node_ptr_
->vds();
10664 vds() = vds_t(vec0_node_ptr_
->size());
10666 temp_
= new vector_holder
<T
>(vds());
10667 temp_vec_node_
= new vector_node
<T
> (vds(),temp_
);
10671 ~vec_binop_vecval_node()
10674 delete temp_vec_node_
;
10677 inline T
value() const
10679 if (vec0_node_ptr_
)
10681 binary_node
<T
>::branch_
[0].first
->value();
10682 const T v
= binary_node
<T
>::branch_
[1].first
->value();
10684 const T
* vec0
= vec0_node_ptr_
->vds().data();
10685 T
* vec1
= vds().data();
10687 loop_unroll::details
lud(size());
10688 const T
* upper_bound
= vec0
+ lud
.upper_bound
;
10690 while (vec0
< upper_bound
)
10692 #define exprtk_loop(N) \
10693 vec1[N] = Operation::process(vec0[N], v); \
10695 exprtk_loop( 0) exprtk_loop( 1)
10696 exprtk_loop( 2) exprtk_loop( 3)
10697 #ifndef exprtk_disable_superscalar_unroll
10698 exprtk_loop( 4) exprtk_loop( 5)
10699 exprtk_loop( 6) exprtk_loop( 7)
10700 exprtk_loop( 8) exprtk_loop( 9)
10701 exprtk_loop(10) exprtk_loop(11)
10702 exprtk_loop(12) exprtk_loop(13)
10703 exprtk_loop(14) exprtk_loop(15)
10706 vec0
+= lud
.batch_size
;
10707 vec1
+= lud
.batch_size
;
10712 exprtk_disable_fallthrough_begin
10713 switch (lud
.remainder
)
10715 #define case_stmt(N) \
10716 case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
10718 #ifndef exprtk_disable_superscalar_unroll
10719 case_stmt(15) case_stmt(14)
10720 case_stmt(13) case_stmt(12)
10721 case_stmt(11) case_stmt(10)
10722 case_stmt( 9) case_stmt( 8)
10723 case_stmt( 7) case_stmt( 6)
10724 case_stmt( 5) case_stmt( 4)
10726 case_stmt( 3) case_stmt( 2)
10729 exprtk_disable_fallthrough_end
10734 return (vds().data())[0];
10737 return std::numeric_limits
<T
>::quiet_NaN();
10740 vector_node_ptr
vec() const
10742 return temp_vec_node_
;
10745 vector_node_ptr
vec()
10747 return temp_vec_node_
;
10750 inline typename expression_node
<T
>::node_type
type() const
10752 return expression_node
<T
>::e_vecvalarith
;
10755 std::size_t size() const
10757 return vds().size();
10765 const vds_t
& vds() const
10772 vector_node_ptr vec0_node_ptr_
;
10773 vector_holder_ptr temp_
;
10774 vector_node_ptr temp_vec_node_
;
10778 template <typename T
, typename Operation
>
10779 class vec_binop_valvec_node
: public binary_node
<T
>,
10780 public vector_interface
<T
>
10784 typedef expression_node
<T
>* expression_ptr
;
10785 typedef vector_node
<T
>* vector_node_ptr
;
10786 typedef vector_holder
<T
>* vector_holder_ptr
;
10787 typedef vec_data_store
<T
> vds_t
;
10789 vec_binop_valvec_node(const operator_type
& opr
,
10790 expression_ptr branch0
,
10791 expression_ptr branch1
)
10792 : binary_node
<T
>(opr
, branch0
, branch1
),
10797 bool v1_is_ivec
= false;
10799 if (is_vector_node(binary_node
<T
>::branch_
[1].first
))
10801 vec1_node_ptr_
= static_cast<vector_node_ptr
>(binary_node
<T
>::branch_
[1].first
);
10803 else if (is_ivector_node(binary_node
<T
>::branch_
[1].first
))
10805 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
10807 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(binary_node
<T
>::branch_
[1].first
)))
10809 vec1_node_ptr_
= vi
->vec();
10814 if (vec1_node_ptr_
)
10817 vds() = vec1_node_ptr_
->vds();
10819 vds() = vds_t(vec1_node_ptr_
->size());
10821 temp_
= new vector_holder
<T
>(vds());
10822 temp_vec_node_
= new vector_node
<T
> (vds(),temp_
);
10826 ~vec_binop_valvec_node()
10829 delete temp_vec_node_
;
10832 inline T
value() const
10834 if (vec1_node_ptr_
)
10836 const T v
= binary_node
<T
>::branch_
[0].first
->value();
10837 binary_node
<T
>::branch_
[1].first
->value();
10839 T
* vec0
= vds().data();
10840 const T
* vec1
= vec1_node_ptr_
->vds().data();
10842 loop_unroll::details
lud(size());
10843 const T
* upper_bound
= vec0
+ lud
.upper_bound
;
10845 while (vec0
< upper_bound
)
10847 #define exprtk_loop(N) \
10848 vec0[N] = Operation::process(v, vec1[N]); \
10850 exprtk_loop( 0) exprtk_loop( 1)
10851 exprtk_loop( 2) exprtk_loop( 3)
10852 #ifndef exprtk_disable_superscalar_unroll
10853 exprtk_loop( 4) exprtk_loop( 5)
10854 exprtk_loop( 6) exprtk_loop( 7)
10855 exprtk_loop( 8) exprtk_loop( 9)
10856 exprtk_loop(10) exprtk_loop(11)
10857 exprtk_loop(12) exprtk_loop(13)
10858 exprtk_loop(14) exprtk_loop(15)
10861 vec0
+= lud
.batch_size
;
10862 vec1
+= lud
.batch_size
;
10867 exprtk_disable_fallthrough_begin
10868 switch (lud
.remainder
)
10870 #define case_stmt(N) \
10871 case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
10873 #ifndef exprtk_disable_superscalar_unroll
10874 case_stmt(15) case_stmt(14)
10875 case_stmt(13) case_stmt(12)
10876 case_stmt(11) case_stmt(10)
10877 case_stmt( 9) case_stmt( 8)
10878 case_stmt( 7) case_stmt( 6)
10879 case_stmt( 5) case_stmt( 4)
10881 case_stmt( 3) case_stmt( 2)
10884 exprtk_disable_fallthrough_end
10889 return (vds().data())[0];
10892 return std::numeric_limits
<T
>::quiet_NaN();
10895 vector_node_ptr
vec() const
10897 return temp_vec_node_
;
10900 vector_node_ptr
vec()
10902 return temp_vec_node_
;
10905 inline typename expression_node
<T
>::node_type
type() const
10907 return expression_node
<T
>::e_vecvalarith
;
10910 std::size_t size() const
10912 return vds().size();
10920 const vds_t
& vds() const
10927 vector_node_ptr vec1_node_ptr_
;
10928 vector_holder_ptr temp_
;
10929 vector_node_ptr temp_vec_node_
;
10933 template <typename T
, typename Operation
>
10934 class unary_vector_node
: public unary_node
<T
>,
10935 public vector_interface
<T
>
10939 typedef expression_node
<T
>* expression_ptr
;
10940 typedef vector_node
<T
>* vector_node_ptr
;
10941 typedef vector_holder
<T
>* vector_holder_ptr
;
10942 typedef vec_data_store
<T
> vds_t
;
10944 unary_vector_node(const operator_type
& opr
, expression_ptr branch0
)
10945 : unary_node
<T
>(opr
, branch0
),
10950 bool vec0_is_ivec
= false;
10952 if (is_vector_node(unary_node
<T
>::branch_
))
10954 vec0_node_ptr_
= static_cast<vector_node_ptr
>(unary_node
<T
>::branch_
);
10956 else if (is_ivector_node(unary_node
<T
>::branch_
))
10958 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
10960 if (0 != (vi
= dynamic_cast<vector_interface
<T
>*>(unary_node
<T
>::branch_
)))
10962 vec0_node_ptr_
= vi
->vec();
10963 vec0_is_ivec
= true;
10967 if (vec0_node_ptr_
)
10970 vds_
= vec0_node_ptr_
->vds();
10972 vds_
= vds_t(vec0_node_ptr_
->size());
10974 temp_
= new vector_holder
<T
>(vds());
10975 temp_vec_node_
= new vector_node
<T
> (vds(),temp_
);
10979 ~unary_vector_node()
10982 delete temp_vec_node_
;
10985 inline T
value() const
10987 unary_node
<T
>::branch_
->value();
10989 if (vec0_node_ptr_
)
10991 const T
* vec0
= vec0_node_ptr_
->vds().data();
10992 T
* vec1
= vds().data();
10994 loop_unroll::details
lud(size());
10995 const T
* upper_bound
= vec0
+ lud
.upper_bound
;
10997 while (vec0
< upper_bound
)
10999 #define exprtk_loop(N) \
11000 vec1[N] = Operation::process(vec0[N]); \
11002 exprtk_loop( 0) exprtk_loop( 1)
11003 exprtk_loop( 2) exprtk_loop( 3)
11004 #ifndef exprtk_disable_superscalar_unroll
11005 exprtk_loop( 4) exprtk_loop( 5)
11006 exprtk_loop( 6) exprtk_loop( 7)
11007 exprtk_loop( 8) exprtk_loop( 9)
11008 exprtk_loop(10) exprtk_loop(11)
11009 exprtk_loop(12) exprtk_loop(13)
11010 exprtk_loop(14) exprtk_loop(15)
11013 vec0
+= lud
.batch_size
;
11014 vec1
+= lud
.batch_size
;
11019 exprtk_disable_fallthrough_begin
11020 switch (lud
.remainder
)
11022 #define case_stmt(N) \
11023 case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
11025 #ifndef exprtk_disable_superscalar_unroll
11026 case_stmt(15) case_stmt(14)
11027 case_stmt(13) case_stmt(12)
11028 case_stmt(11) case_stmt(10)
11029 case_stmt( 9) case_stmt( 8)
11030 case_stmt( 7) case_stmt( 6)
11031 case_stmt( 5) case_stmt( 4)
11033 case_stmt( 3) case_stmt( 2)
11036 exprtk_disable_fallthrough_end
11041 return (vds().data())[0];
11044 return std::numeric_limits
<T
>::quiet_NaN();
11047 vector_node_ptr
vec() const
11049 return temp_vec_node_
;
11052 vector_node_ptr
vec()
11054 return temp_vec_node_
;
11057 inline typename expression_node
<T
>::node_type
type() const
11059 return expression_node
<T
>::e_vecunaryop
;
11062 std::size_t size() const
11064 return vds().size();
11072 const vds_t
& vds() const
11079 vector_node_ptr vec0_node_ptr_
;
11080 vector_holder_ptr temp_
;
11081 vector_node_ptr temp_vec_node_
;
11085 template <typename T
>
11086 class scand_node
: public binary_node
<T
>
11090 typedef expression_node
<T
>* expression_ptr
;
11092 scand_node(const operator_type
& opr
,
11093 expression_ptr branch0
,
11094 expression_ptr branch1
)
11095 : binary_node
<T
>(opr
, branch0
, branch1
)
11098 inline T
value() const
11101 std::not_equal_to
<T
>()
11102 (T(0),binary_node
<T
>::branch_
[0].first
->value()) &&
11103 std::not_equal_to
<T
>()
11104 (T(0),binary_node
<T
>::branch_
[1].first
->value())
11109 template <typename T
>
11110 class scor_node
: public binary_node
<T
>
11114 typedef expression_node
<T
>* expression_ptr
;
11116 scor_node(const operator_type
& opr
,
11117 expression_ptr branch0
,
11118 expression_ptr branch1
)
11119 : binary_node
<T
>(opr
, branch0
, branch1
)
11122 inline T
value() const
11125 std::not_equal_to
<T
>()
11126 (T(0),binary_node
<T
>::branch_
[0].first
->value()) ||
11127 std::not_equal_to
<T
>()
11128 (T(0),binary_node
<T
>::branch_
[1].first
->value())
11133 template <typename T
, typename IFunction
, std::size_t N
>
11134 class function_N_node
: public expression_node
<T
>
11138 // Function of N paramters.
11139 typedef expression_node
<T
>* expression_ptr
;
11140 typedef std::pair
<expression_ptr
,bool> branch_t
;
11141 typedef IFunction ifunction
;
11143 explicit function_N_node(ifunction
* func
)
11144 : function_((N
== func
->param_count
) ? func
: reinterpret_cast<ifunction
*>(0)),
11145 parameter_count_(func
->param_count
)
11150 cleanup_branches::execute
<T
,N
>(branch_
);
11153 template <std::size_t NumBranches
>
11154 bool init_branches(expression_ptr (&b
)[NumBranches
])
11156 // Needed for incompetent and broken msvc compiler versions
11158 #pragma warning(push)
11159 #pragma warning(disable: 4127)
11161 if (N
!= NumBranches
)
11165 for (std::size_t i
= 0; i
< NumBranches
; ++i
)
11168 branch_
[i
] = std::make_pair(b
[i
],branch_deletable(b
[i
]));
11175 #pragma warning(pop)
11179 inline bool operator <(const function_N_node
<T
,IFunction
,N
>& fn
) const
11181 return this < (&fn
);
11184 inline T
value() const
11186 // Needed for incompetent and broken msvc compiler versions
11188 #pragma warning(push)
11189 #pragma warning(disable: 4127)
11191 if ((0 == function_
) || (0 == N
))
11192 return std::numeric_limits
<T
>::quiet_NaN();
11196 evaluate_branches
<T
,N
>::execute(v
,branch_
);
11197 return invoke
<T
,N
>::execute(*function_
,v
);
11200 #pragma warning(pop)
11204 template <typename T_
, std::size_t BranchCount
>
11205 struct evaluate_branches
11207 static inline void execute(T_ (&v
)[BranchCount
], const branch_t (&b
)[BranchCount
])
11209 for (std::size_t i
= 0; i
< BranchCount
; ++i
)
11211 v
[i
] = b
[i
].first
->value();
11216 template <typename T_
>
11217 struct evaluate_branches
<T_
,5>
11219 static inline void execute(T_ (&v
)[5], const branch_t (&b
)[5])
11221 v
[0] = b
[0].first
->value();
11222 v
[1] = b
[1].first
->value();
11223 v
[2] = b
[2].first
->value();
11224 v
[3] = b
[3].first
->value();
11225 v
[4] = b
[4].first
->value();
11229 template <typename T_
>
11230 struct evaluate_branches
<T_
,4>
11232 static inline void execute(T_ (&v
)[4], const branch_t (&b
)[4])
11234 v
[0] = b
[0].first
->value();
11235 v
[1] = b
[1].first
->value();
11236 v
[2] = b
[2].first
->value();
11237 v
[3] = b
[3].first
->value();
11241 template <typename T_
>
11242 struct evaluate_branches
<T_
,3>
11244 static inline void execute(T_ (&v
)[3], const branch_t (&b
)[3])
11246 v
[0] = b
[0].first
->value();
11247 v
[1] = b
[1].first
->value();
11248 v
[2] = b
[2].first
->value();
11252 template <typename T_
>
11253 struct evaluate_branches
<T_
,2>
11255 static inline void execute(T_ (&v
)[2], const branch_t (&b
)[2])
11257 v
[0] = b
[0].first
->value();
11258 v
[1] = b
[1].first
->value();
11262 template <typename T_
>
11263 struct evaluate_branches
<T_
,1>
11265 static inline void execute(T_ (&v
)[1], const branch_t (&b
)[1])
11267 v
[0] = b
[0].first
->value();
11271 template <typename T_
, std::size_t ParamCount
>
11272 struct invoke
{ static inline T
execute(ifunction
&, branch_t (&)[ParamCount
]) { return std::numeric_limits
<T_
>::quiet_NaN(); } };
11274 template <typename T_
>
11275 struct invoke
<T_
,20>
11277 static inline T_
execute(ifunction
& f
, T_ (&v
)[20])
11278 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12],v
[13],v
[14],v
[15],v
[16],v
[17],v
[18],v
[19]); }
11281 template <typename T_
>
11282 struct invoke
<T_
,19>
11284 static inline T_
execute(ifunction
& f
, T_ (&v
)[19])
11285 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12],v
[13],v
[14],v
[15],v
[16],v
[17],v
[18]); }
11288 template <typename T_
>
11289 struct invoke
<T_
,18>
11291 static inline T_
execute(ifunction
& f
, T_ (&v
)[18])
11292 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12],v
[13],v
[14],v
[15],v
[16],v
[17]); }
11295 template <typename T_
>
11296 struct invoke
<T_
,17>
11298 static inline T_
execute(ifunction
& f
, T_ (&v
)[17])
11299 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12],v
[13],v
[14],v
[15],v
[16]); }
11302 template <typename T_
>
11303 struct invoke
<T_
,16>
11305 static inline T_
execute(ifunction
& f
, T_ (&v
)[16])
11306 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12],v
[13],v
[14],v
[15]); }
11309 template <typename T_
>
11310 struct invoke
<T_
,15>
11312 static inline T_
execute(ifunction
& f
, T_ (&v
)[15])
11313 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12],v
[13],v
[14]); }
11316 template <typename T_
>
11317 struct invoke
<T_
,14>
11319 static inline T_
execute(ifunction
& f
, T_ (&v
)[14])
11320 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12],v
[13]); }
11323 template <typename T_
>
11324 struct invoke
<T_
,13>
11326 static inline T_
execute(ifunction
& f
, T_ (&v
)[13])
11327 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11],v
[12]); }
11330 template <typename T_
>
11331 struct invoke
<T_
,12>
11333 static inline T_
execute(ifunction
& f
, T_ (&v
)[12])
11334 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10],v
[11]); }
11337 template <typename T_
>
11338 struct invoke
<T_
,11>
11340 static inline T_
execute(ifunction
& f
, T_ (&v
)[11])
11341 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9],v
[10]); }
11344 template <typename T_
>
11345 struct invoke
<T_
,10>
11347 static inline T_
execute(ifunction
& f
, T_ (&v
)[10])
11348 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8],v
[9]); }
11351 template <typename T_
>
11352 struct invoke
<T_
,9>
11354 static inline T_
execute(ifunction
& f
, T_ (&v
)[9])
11355 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7],v
[8]); }
11358 template <typename T_
>
11359 struct invoke
<T_
,8>
11361 static inline T_
execute(ifunction
& f
, T_ (&v
)[8])
11362 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6],v
[7]); }
11365 template <typename T_
>
11366 struct invoke
<T_
,7>
11368 static inline T_
execute(ifunction
& f
, T_ (&v
)[7])
11369 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5],v
[6]); }
11372 template <typename T_
>
11373 struct invoke
<T_
,6>
11375 static inline T_
execute(ifunction
& f
, T_ (&v
)[6])
11376 { return f(v
[0],v
[1],v
[2],v
[3],v
[4],v
[5]); }
11379 template <typename T_
>
11380 struct invoke
<T_
,5>
11382 static inline T_
execute(ifunction
& f
, T_ (&v
)[5])
11383 { return f(v
[0],v
[1],v
[2],v
[3],v
[4]); }
11386 template <typename T_
>
11387 struct invoke
<T_
,4>
11389 static inline T_
execute(ifunction
& f
, T_ (&v
)[4])
11390 { return f(v
[0],v
[1],v
[2],v
[3]); }
11393 template <typename T_
>
11394 struct invoke
<T_
,3>
11396 static inline T_
execute(ifunction
& f
, T_ (&v
)[3])
11397 { return f(v
[0],v
[1],v
[2]); }
11400 template <typename T_
>
11401 struct invoke
<T_
,2>
11403 static inline T_
execute(ifunction
& f
, T_ (&v
)[2])
11404 { return f(v
[0],v
[1]); }
11407 template <typename T_
>
11408 struct invoke
<T_
,1>
11410 static inline T_
execute(ifunction
& f
, T_ (&v
)[1])
11411 { return f(v
[0]); }
11414 inline typename expression_node
<T
>::node_type
type() const
11416 return expression_node
<T
>::e_function
;
11421 ifunction
* function_
;
11422 std::size_t parameter_count_
;
11423 branch_t branch_
[N
];
11426 template <typename T
, typename IFunction
>
11427 class function_N_node
<T
,IFunction
,0> : public expression_node
<T
>
11431 typedef expression_node
<T
>* expression_ptr
;
11432 typedef IFunction ifunction
;
11434 explicit function_N_node(ifunction
* func
)
11435 : function_((0 == func
->param_count
) ? func
: reinterpret_cast<ifunction
*>(0))
11438 inline bool operator <(const function_N_node
<T
,IFunction
,0>& fn
) const
11440 return this < (&fn
);
11443 inline T
value() const
11446 return (*function_
)();
11448 return std::numeric_limits
<T
>::quiet_NaN();
11451 inline typename expression_node
<T
>::node_type
type() const
11453 return expression_node
<T
>::e_function
;
11458 ifunction
* function_
;
11461 template <typename T
, typename VarArgFunction
>
11462 class vararg_function_node
: public expression_node
<T
>
11466 typedef expression_node
<T
>* expression_ptr
;
11468 vararg_function_node(VarArgFunction
* func
,
11469 const std::vector
<expression_ptr
>& arg_list
)
11471 arg_list_(arg_list
)
11473 value_list_
.resize(arg_list
.size(),std::numeric_limits
<T
>::quiet_NaN());
11476 ~vararg_function_node()
11478 for (std::size_t i
= 0; i
< arg_list_
.size(); ++i
)
11480 if (arg_list_
[i
] && !details::is_variable_node(arg_list_
[i
]))
11482 destroy_node(arg_list_
[i
]);
11487 inline bool operator <(const vararg_function_node
<T
,VarArgFunction
>& fn
) const
11489 return this < (&fn
);
11492 inline T
value() const
11496 populate_value_list();
11497 return (*function_
)(value_list_
);
11500 return std::numeric_limits
<T
>::quiet_NaN();
11503 inline typename expression_node
<T
>::node_type
type() const
11505 return expression_node
<T
>::e_vafunction
;
11510 inline void populate_value_list() const
11512 for (std::size_t i
= 0; i
< arg_list_
.size(); ++i
)
11514 value_list_
[i
] = arg_list_
[i
]->value();
11518 VarArgFunction
* function_
;
11519 std::vector
<expression_ptr
> arg_list_
;
11520 mutable std::vector
<T
> value_list_
;
11523 template <typename T
, typename GenericFunction
>
11524 class generic_function_node
: public expression_node
<T
>
11528 typedef type_store
<T
> type_store_t
;
11529 typedef expression_node
<T
>* expression_ptr
;
11530 typedef variable_node
<T
> variable_node_t
;
11531 typedef vector_node
<T
> vector_node_t
;
11532 typedef variable_node_t
* variable_node_ptr_t
;
11533 typedef vector_node_t
* vector_node_ptr_t
;
11534 typedef range_interface
<T
> range_interface_t
;
11535 typedef range_data_type
<T
> range_data_type_t
;
11536 typedef range_pack
<T
> range_t
;
11537 typedef std::pair
<expression_ptr
,bool> branch_t
;
11538 typedef std::pair
<void*,std::size_t> void_t
;
11539 typedef std::vector
<T
> tmp_vs_t
;
11540 typedef std::vector
<type_store_t
> typestore_list_t
;
11541 typedef std::vector
<range_data_type_t
> range_list_t
;
11543 generic_function_node(const std::vector
<expression_ptr
>& arg_list
,
11544 GenericFunction
* func
= (GenericFunction
*)(0))
11546 arg_list_(arg_list
)
11549 virtual ~generic_function_node()
11551 cleanup_branches::execute(branch_
);
11554 virtual bool init_branches()
11556 expr_as_vec1_store_
.resize(arg_list_
.size(),T(0) );
11557 typestore_list_
.resize(arg_list_
.size(),type_store_t() );
11558 range_list_
.resize(arg_list_
.size(),range_data_type_t());
11559 branch_
.resize(arg_list_
.size(),branch_t((expression_ptr
)0,false));
11561 for (std::size_t i
= 0; i
< arg_list_
.size(); ++i
)
11563 type_store_t
& ts
= typestore_list_
[i
];
11565 if (0 == arg_list_
[i
])
11567 else if (is_ivector_node(arg_list_
[i
]))
11569 vector_interface
<T
>* vi
= reinterpret_cast<vector_interface
<T
>*>(0);
11571 if (0 == (vi
= dynamic_cast<vector_interface
<T
>*>(arg_list_
[i
])))
11574 ts
.size
= vi
->size();
11575 ts
.data
= vi
->vds().data();
11576 ts
.type
= type_store_t::e_vector
;
11577 vi
->vec()->vec_holder().set_ref(&ts
.vec_data
);
11579 #ifndef exprtk_disable_string_capabilities
11580 else if (is_generally_string_node(arg_list_
[i
]))
11582 string_base_node
<T
>* sbn
= reinterpret_cast<string_base_node
<T
>*>(0);
11584 if (0 == (sbn
= dynamic_cast<string_base_node
<T
>*>(arg_list_
[i
])))
11587 ts
.size
= sbn
->size();
11588 ts
.data
= reinterpret_cast<void*>(const_cast<char_ptr
>(sbn
->base()));
11589 ts
.type
= type_store_t::e_string
;
11591 range_list_
[i
].data
= ts
.data
;
11592 range_list_
[i
].size
= ts
.size
;
11593 range_list_
[i
].type_size
= sizeof(char);
11594 range_list_
[i
].str_node
= sbn
;
11596 range_interface_t
* ri
= reinterpret_cast<range_interface_t
*>(0);
11598 if (0 == (ri
= dynamic_cast<range_interface_t
*>(arg_list_
[i
])))
11601 range_t
& rp
= ri
->range_ref();
11604 rp
.const_range() &&
11605 is_const_string_range_node(arg_list_
[i
])
11608 ts
.size
= rp
.const_size();
11609 ts
.data
= static_cast<char_ptr
>(ts
.data
) + rp
.n0_c
.second
;
11610 range_list_
[i
].range
= reinterpret_cast<range_t
*>(0);
11613 range_list_
[i
].range
= &(ri
->range_ref());
11616 else if (is_variable_node(arg_list_
[i
]))
11618 variable_node_ptr_t var
= variable_node_ptr_t(0);
11620 if (0 == (var
= dynamic_cast<variable_node_ptr_t
>(arg_list_
[i
])))
11624 ts
.data
= &var
->ref();
11625 ts
.type
= type_store_t::e_scalar
;
11630 ts
.data
= reinterpret_cast<void*>(&expr_as_vec1_store_
[i
]);
11631 ts
.type
= type_store_t::e_scalar
;
11634 branch_
[i
] = std::make_pair(arg_list_
[i
],branch_deletable(arg_list_
[i
]));
11640 inline bool operator <(const generic_function_node
<T
,GenericFunction
>& fn
) const
11642 return this < (&fn
);
11645 inline T
value() const
11649 if (populate_value_list())
11651 typedef typename
GenericFunction::parameter_list_t parameter_list_t
;
11653 return (*function_
)(parameter_list_t(typestore_list_
));
11657 return std::numeric_limits
<T
>::quiet_NaN();
11660 inline typename expression_node
<T
>::node_type
type() const
11662 return expression_node
<T
>::e_genfunction
;
11667 inline virtual bool populate_value_list() const
11669 for (std::size_t i
= 0; i
< branch_
.size(); ++i
)
11671 expr_as_vec1_store_
[i
] = branch_
[i
].first
->value();
11674 for (std::size_t i
= 0; i
< branch_
.size(); ++i
)
11676 range_data_type_t
& rdt
= range_list_
[i
];
11680 range_t
& rp
= (*rdt
.range
);
11681 std::size_t r0
= 0;
11682 std::size_t r1
= 0;
11684 if (rp(r0
,r1
,rdt
.size
))
11686 type_store_t
& ts
= typestore_list_
[i
];
11688 ts
.size
= rp
.cache_size();
11689 #ifndef exprtk_disable_string_capabilities
11690 if (ts
.type
== type_store_t::e_string
)
11691 ts
.data
= const_cast<char_ptr
>(rdt
.str_node
->base()) + rp
.cache
.first
;
11694 ts
.data
= static_cast<char_ptr
>(rdt
.data
) + (rp
.cache
.first
* rdt
.type_size
);
11704 GenericFunction
* function_
;
11705 mutable typestore_list_t typestore_list_
;
11709 std::vector
<expression_ptr
> arg_list_
;
11710 std::vector
<branch_t
> branch_
;
11711 mutable tmp_vs_t expr_as_vec1_store_
;
11712 mutable range_list_t range_list_
;
11715 #ifndef exprtk_disable_string_capabilities
11716 template <typename T
, typename StringFunction
>
11717 class string_function_node
: public generic_function_node
<T
,StringFunction
>,
11718 public string_base_node
<T
>,
11719 public range_interface
<T
>
11723 typedef generic_function_node
<T
,StringFunction
> gen_function_t
;
11724 typedef range_pack
<T
> range_t
;
11726 string_function_node(StringFunction
* func
,
11727 const std::vector
<typename
gen_function_t::expression_ptr
>& arg_list
)
11728 : gen_function_t(arg_list
,func
)
11730 range_
.n0_c
= std::make_pair
<bool,std::size_t>(true,0);
11731 range_
.n1_c
= std::make_pair
<bool,std::size_t>(true,0);
11732 range_
.cache
.first
= range_
.n0_c
.second
;
11733 range_
.cache
.second
= range_
.n1_c
.second
;
11736 inline bool operator <(const string_function_node
<T
,StringFunction
>& fn
) const
11738 return this < (&fn
);
11741 inline T
value() const
11743 if (gen_function_t::function_
)
11745 if (gen_function_t::populate_value_list())
11747 typedef typename
StringFunction::parameter_list_t parameter_list_t
;
11749 const T result
= (*gen_function_t::function_
)
11752 parameter_list_t(gen_function_t::typestore_list_
)
11755 range_
.n1_c
.second
= ret_string_
.size() - 1;
11756 range_
.cache
.second
= range_
.n1_c
.second
;
11762 return std::numeric_limits
<T
>::quiet_NaN();
11765 inline typename expression_node
<T
>::node_type
type() const
11767 return expression_node
<T
>::e_strfunction
;
11770 std::string
str() const
11772 return ret_string_
;
11775 char_cptr
base() const
11777 return &ret_string_
[0];
11780 std::size_t size() const
11782 return ret_string_
.size();
11785 range_t
& range_ref()
11790 const range_t
& range_ref() const
11797 mutable range_t range_
;
11798 mutable std::string ret_string_
;
11802 template <typename T
, typename GenericFunction
>
11803 class multimode_genfunction_node
: public generic_function_node
<T
,GenericFunction
>
11807 typedef generic_function_node
<T
,GenericFunction
> gen_function_t
;
11808 typedef range_pack
<T
> range_t
;
11810 multimode_genfunction_node(GenericFunction
* func
,
11811 const std::size_t& param_seq_index
,
11812 const std::vector
<typename
gen_function_t::expression_ptr
>& arg_list
)
11813 : gen_function_t(arg_list
,func
),
11814 param_seq_index_(param_seq_index
)
11817 inline T
value() const
11819 if (gen_function_t::function_
)
11821 if (gen_function_t::populate_value_list())
11823 typedef typename
GenericFunction::parameter_list_t parameter_list_t
;
11825 return (*gen_function_t::function_
)
11828 parameter_list_t(gen_function_t::typestore_list_
)
11833 return std::numeric_limits
<T
>::quiet_NaN();
11836 inline typename expression_node
<T
>::node_type
type() const
11838 return expression_node
<T
>::e_genfunction
;
11843 std::size_t param_seq_index_
;
11846 #ifndef exprtk_disable_string_capabilities
11847 template <typename T
, typename StringFunction
>
11848 class multimode_strfunction_node
: public string_function_node
<T
,StringFunction
>
11852 typedef string_function_node
<T
,StringFunction
> str_function_t
;
11853 typedef range_pack
<T
> range_t
;
11855 multimode_strfunction_node(StringFunction
* func
,
11856 const std::size_t& param_seq_index
,
11857 const std::vector
<typename
str_function_t::expression_ptr
>& arg_list
)
11858 : str_function_t(func
,arg_list
),
11859 param_seq_index_(param_seq_index
)
11862 inline T
value() const
11864 if (str_function_t::function_
)
11866 if (str_function_t::populate_value_list())
11868 typedef typename
StringFunction::parameter_list_t parameter_list_t
;
11870 const T result
= (*str_function_t::function_
)
11873 str_function_t::ret_string_
,
11874 parameter_list_t(str_function_t::typestore_list_
)
11877 str_function_t::range_
.n1_c
.second
= str_function_t::ret_string_
.size() - 1;
11878 str_function_t::range_
.cache
.second
= str_function_t::range_
.n1_c
.second
;
11884 return std::numeric_limits
<T
>::quiet_NaN();
11887 inline typename expression_node
<T
>::node_type
type() const
11889 return expression_node
<T
>::e_strfunction
;
11894 const std::size_t param_seq_index_
;
11898 class return_exception
11901 template <typename T
>
11902 class null_igenfunc
11906 virtual ~null_igenfunc()
11909 typedef type_store
<T
> generic_type
;
11910 typedef typename
generic_type::parameter_list parameter_list_t
;
11912 inline virtual T
operator() (parameter_list_t
)
11914 return std::numeric_limits
<T
>::quiet_NaN();
11918 #ifndef exprtk_disable_return_statement
11919 template <typename T
>
11920 class return_node
: public generic_function_node
<T
,null_igenfunc
<T
> >
11924 typedef null_igenfunc
<T
> igeneric_function_t
;
11925 typedef igeneric_function_t
* igeneric_function_ptr
;
11926 typedef generic_function_node
<T
,igeneric_function_t
> gen_function_t
;
11927 typedef results_context
<T
> results_context_t
;
11929 return_node(const std::vector
<typename
gen_function_t::expression_ptr
>& arg_list
,
11930 results_context_t
& rc
)
11931 : gen_function_t (arg_list
),
11932 results_context_(&rc
)
11935 inline T
value() const
11938 (0 != results_context_
) &&
11939 gen_function_t::populate_value_list()
11942 typedef typename type_store
<T
>::parameter_list parameter_list_t
;
11945 assign(parameter_list_t(gen_function_t::typestore_list_
));
11947 throw return_exception();
11950 return std::numeric_limits
<T
>::quiet_NaN();
11953 inline typename expression_node
<T
>::node_type
type() const
11955 return expression_node
<T
>::e_return
;
11960 results_context_t
* results_context_
;
11963 template <typename T
>
11964 class return_envelope_node
: public expression_node
<T
>
11968 typedef expression_node
<T
>* expression_ptr
;
11969 typedef results_context
<T
> results_context_t
;
11971 return_envelope_node(expression_ptr body
, results_context_t
& rc
)
11972 : results_context_(&rc
),
11973 return_invoked_ (false),
11975 body_deletable_ (branch_deletable(body_
))
11978 ~return_envelope_node()
11980 if (body_
&& body_deletable_
)
11982 destroy_node(body_
);
11986 inline T
value() const
11990 return_invoked_
= false;
11991 results_context_
->clear();
11993 return body_
->value();
11995 catch(const return_exception
&)
11997 return_invoked_
= true;
11998 return std::numeric_limits
<T
>::quiet_NaN();
12002 inline typename expression_node
<T
>::node_type
type() const
12004 return expression_node
<T
>::e_retenv
;
12007 inline bool* retinvk_ptr()
12009 return &return_invoked_
;
12014 results_context_t
* results_context_
;
12015 mutable bool return_invoked_
;
12016 expression_ptr body_
;
12017 const bool body_deletable_
;
12021 #define exprtk_define_unary_op(OpName) \
12022 template <typename T> \
12023 struct OpName##_op \
12025 typedef typename functor_t<T>::Type Type; \
12026 typedef typename expression_node<T>::node_type node_t; \
12028 static inline T process(Type v) \
12030 return numeric:: OpName (v); \
12033 static inline node_t type() \
12035 return expression_node<T>::e_##OpName; \
12038 static inline details::operator_type operation() \
12040 return details::e_##OpName; \
12044 exprtk_define_unary_op(abs )
12045 exprtk_define_unary_op(acos
)
12046 exprtk_define_unary_op(acosh
)
12047 exprtk_define_unary_op(asin
)
12048 exprtk_define_unary_op(asinh
)
12049 exprtk_define_unary_op(atan
)
12050 exprtk_define_unary_op(atanh
)
12051 exprtk_define_unary_op(ceil
)
12052 exprtk_define_unary_op(cos
)
12053 exprtk_define_unary_op(cosh
)
12054 exprtk_define_unary_op(cot
)
12055 exprtk_define_unary_op(csc
)
12056 exprtk_define_unary_op(d2g
)
12057 exprtk_define_unary_op(d2r
)
12058 exprtk_define_unary_op(erf
)
12059 exprtk_define_unary_op(erfc
)
12060 exprtk_define_unary_op(exp
)
12061 exprtk_define_unary_op(expm1
)
12062 exprtk_define_unary_op(floor
)
12063 exprtk_define_unary_op(frac
)
12064 exprtk_define_unary_op(g2d
)
12065 exprtk_define_unary_op(log
)
12066 exprtk_define_unary_op(log10
)
12067 exprtk_define_unary_op(log2
)
12068 exprtk_define_unary_op(log1p
)
12069 exprtk_define_unary_op(ncdf
)
12070 exprtk_define_unary_op(neg
)
12071 exprtk_define_unary_op(notl
)
12072 exprtk_define_unary_op(pos
)
12073 exprtk_define_unary_op(r2d
)
12074 exprtk_define_unary_op(round
)
12075 exprtk_define_unary_op(sec
)
12076 exprtk_define_unary_op(sgn
)
12077 exprtk_define_unary_op(sin
)
12078 exprtk_define_unary_op(sinc
)
12079 exprtk_define_unary_op(sinh
)
12080 exprtk_define_unary_op(sqrt
)
12081 exprtk_define_unary_op(tan
)
12082 exprtk_define_unary_op(tanh
)
12083 exprtk_define_unary_op(trunc
)
12084 #undef exprtk_define_unary_op
12086 template <typename T
>
12089 typedef typename
details::functor_t
<T
>::Type Type
;
12090 typedef typename
details::functor_t
<T
>::RefType RefType
;
12091 typedef typename
details::functor_t
<T
> functor_t
;
12092 typedef typename
functor_t::qfunc_t quaternary_functor_t
;
12093 typedef typename
functor_t::tfunc_t trinary_functor_t
;
12094 typedef typename
functor_t::bfunc_t binary_functor_t
;
12095 typedef typename
functor_t::ufunc_t unary_functor_t
;
12098 template <typename T
>
12099 struct add_op
: public opr_base
<T
>
12101 typedef typename opr_base
<T
>::Type Type
;
12102 typedef typename opr_base
<T
>::RefType RefType
;
12104 static inline T
process(Type t1
, Type t2
) { return t1
+ t2
; }
12105 static inline T
process(Type t1
, Type t2
, Type t3
) { return t1
+ t2
+ t3
; }
12106 static inline void assign(RefType t1
, Type t2
) { t1
+= t2
; }
12107 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_add
; }
12108 static inline details::operator_type
operation() { return details::e_add
; }
12111 template <typename T
>
12112 struct mul_op
: public opr_base
<T
>
12114 typedef typename opr_base
<T
>::Type Type
;
12115 typedef typename opr_base
<T
>::RefType RefType
;
12117 static inline T
process(Type t1
, Type t2
) { return t1
* t2
; }
12118 static inline T
process(Type t1
, Type t2
, Type t3
) { return t1
* t2
* t3
; }
12119 static inline void assign(RefType t1
, Type t2
) { t1
*= t2
; }
12120 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_mul
; }
12121 static inline details::operator_type
operation() { return details::e_mul
; }
12124 template <typename T
>
12125 struct sub_op
: public opr_base
<T
>
12127 typedef typename opr_base
<T
>::Type Type
;
12128 typedef typename opr_base
<T
>::RefType RefType
;
12130 static inline T
process(Type t1
, Type t2
) { return t1
- t2
; }
12131 static inline T
process(Type t1
, Type t2
, Type t3
) { return t1
- t2
- t3
; }
12132 static inline void assign(RefType t1
, Type t2
) { t1
-= t2
; }
12133 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_sub
; }
12134 static inline details::operator_type
operation() { return details::e_sub
; }
12137 template <typename T
>
12138 struct div_op
: public opr_base
<T
>
12140 typedef typename opr_base
<T
>::Type Type
;
12141 typedef typename opr_base
<T
>::RefType RefType
;
12143 static inline T
process(Type t1
, Type t2
) { return t1
/ t2
; }
12144 static inline T
process(Type t1
, Type t2
, Type t3
) { return t1
/ t2
/ t3
; }
12145 static inline void assign(RefType t1
, Type t2
) { t1
/= t2
; }
12146 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_div
; }
12147 static inline details::operator_type
operation() { return details::e_div
; }
12150 template <typename T
>
12151 struct mod_op
: public opr_base
<T
>
12153 typedef typename opr_base
<T
>::Type Type
;
12154 typedef typename opr_base
<T
>::RefType RefType
;
12156 static inline T
process(Type t1
, Type t2
) { return numeric::modulus
<T
>(t1
,t2
); }
12157 static inline void assign(RefType t1
, Type t2
) { t1
= numeric::modulus
<T
>(t1
,t2
); }
12158 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_mod
; }
12159 static inline details::operator_type
operation() { return details::e_mod
; }
12162 template <typename T
>
12163 struct pow_op
: public opr_base
<T
>
12165 typedef typename opr_base
<T
>::Type Type
;
12166 typedef typename opr_base
<T
>::RefType RefType
;
12168 static inline T
process(Type t1
, Type t2
) { return numeric::pow
<T
>(t1
,t2
); }
12169 static inline void assign(RefType t1
, Type t2
) { t1
= numeric::pow
<T
>(t1
,t2
); }
12170 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_pow
; }
12171 static inline details::operator_type
operation() { return details::e_pow
; }
12174 template <typename T
>
12175 struct lt_op
: public opr_base
<T
>
12177 typedef typename opr_base
<T
>::Type Type
;
12179 static inline T
process(Type t1
, Type t2
) { return ((t1
< t2
) ? T(1) : T(0)); }
12180 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((t1
< t2
) ? T(1) : T(0)); }
12181 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_lt
; }
12182 static inline details::operator_type
operation() { return details::e_lt
; }
12185 template <typename T
>
12186 struct lte_op
: public opr_base
<T
>
12188 typedef typename opr_base
<T
>::Type Type
;
12190 static inline T
process(Type t1
, Type t2
) { return ((t1
<= t2
) ? T(1) : T(0)); }
12191 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((t1
<= t2
) ? T(1) : T(0)); }
12192 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_lte
; }
12193 static inline details::operator_type
operation() { return details::e_lte
; }
12196 template <typename T
>
12197 struct gt_op
: public opr_base
<T
>
12199 typedef typename opr_base
<T
>::Type Type
;
12201 static inline T
process(Type t1
, Type t2
) { return ((t1
> t2
) ? T(1) : T(0)); }
12202 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((t1
> t2
) ? T(1) : T(0)); }
12203 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_gt
; }
12204 static inline details::operator_type
operation() { return details::e_gt
; }
12207 template <typename T
>
12208 struct gte_op
: public opr_base
<T
>
12210 typedef typename opr_base
<T
>::Type Type
;
12212 static inline T
process(Type t1
, Type t2
) { return ((t1
>= t2
) ? T(1) : T(0)); }
12213 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((t1
>= t2
) ? T(1) : T(0)); }
12214 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_gte
; }
12215 static inline details::operator_type
operation() { return details::e_gte
; }
12218 template <typename T
>
12219 struct eq_op
: public opr_base
<T
>
12221 typedef typename opr_base
<T
>::Type Type
;
12222 static inline T
process(Type t1
, Type t2
) { return (std::equal_to
<T
>()(t1
,t2
) ? T(1) : T(0)); }
12223 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((t1
== t2
) ? T(1) : T(0)); }
12224 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_eq
; }
12225 static inline details::operator_type
operation() { return details::e_eq
; }
12228 template <typename T
>
12229 struct equal_op
: public opr_base
<T
>
12231 typedef typename opr_base
<T
>::Type Type
;
12233 static inline T
process(Type t1
, Type t2
) { return numeric::equal(t1
,t2
); }
12234 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((t1
== t2
) ? T(1) : T(0)); }
12235 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_eq
; }
12236 static inline details::operator_type
operation() { return details::e_equal
; }
12239 template <typename T
>
12240 struct ne_op
: public opr_base
<T
>
12242 typedef typename opr_base
<T
>::Type Type
;
12244 static inline T
process(Type t1
, Type t2
) { return (std::not_equal_to
<T
>()(t1
,t2
) ? T(1) : T(0)); }
12245 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((t1
!= t2
) ? T(1) : T(0)); }
12246 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_ne
; }
12247 static inline details::operator_type
operation() { return details::e_ne
; }
12250 template <typename T
>
12251 struct and_op
: public opr_base
<T
>
12253 typedef typename opr_base
<T
>::Type Type
;
12255 static inline T
process(Type t1
, Type t2
) { return (details::is_true(t1
) && details::is_true(t2
)) ? T(1) : T(0); }
12256 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_and
; }
12257 static inline details::operator_type
operation() { return details::e_and
; }
12260 template <typename T
>
12261 struct nand_op
: public opr_base
<T
>
12263 typedef typename opr_base
<T
>::Type Type
;
12265 static inline T
process(Type t1
, Type t2
) { return (details::is_true(t1
) && details::is_true(t2
)) ? T(0) : T(1); }
12266 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_nand
; }
12267 static inline details::operator_type
operation() { return details::e_nand
; }
12270 template <typename T
>
12271 struct or_op
: public opr_base
<T
>
12273 typedef typename opr_base
<T
>::Type Type
;
12275 static inline T
process(Type t1
, Type t2
) { return (details::is_true(t1
) || details::is_true(t2
)) ? T(1) : T(0); }
12276 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_or
; }
12277 static inline details::operator_type
operation() { return details::e_or
; }
12280 template <typename T
>
12281 struct nor_op
: public opr_base
<T
>
12283 typedef typename opr_base
<T
>::Type Type
;
12285 static inline T
process(Type t1
, Type t2
) { return (details::is_true(t1
) || details::is_true(t2
)) ? T(0) : T(1); }
12286 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_nor
; }
12287 static inline details::operator_type
operation() { return details::e_nor
; }
12290 template <typename T
>
12291 struct xor_op
: public opr_base
<T
>
12293 typedef typename opr_base
<T
>::Type Type
;
12295 static inline T
process(Type t1
, Type t2
) { return numeric::xor_opr
<T
>(t1
,t2
); }
12296 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_nor
; }
12297 static inline details::operator_type
operation() { return details::e_xor
; }
12300 template <typename T
>
12301 struct xnor_op
: public opr_base
<T
>
12303 typedef typename opr_base
<T
>::Type Type
;
12305 static inline T
process(Type t1
, Type t2
) { return numeric::xnor_opr
<T
>(t1
,t2
); }
12306 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_nor
; }
12307 static inline details::operator_type
operation() { return details::e_xnor
; }
12310 template <typename T
>
12311 struct in_op
: public opr_base
<T
>
12313 typedef typename opr_base
<T
>::Type Type
;
12315 static inline T
process(const T
&, const T
&) { return std::numeric_limits
<T
>::quiet_NaN(); }
12316 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return ((std::string::npos
!= t2
.find(t1
)) ? T(1) : T(0)); }
12317 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_in
; }
12318 static inline details::operator_type
operation() { return details::e_in
; }
12321 template <typename T
>
12322 struct like_op
: public opr_base
<T
>
12324 typedef typename opr_base
<T
>::Type Type
;
12326 static inline T
process(const T
&, const T
&) { return std::numeric_limits
<T
>::quiet_NaN(); }
12327 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return (details::wc_match(t2
,t1
) ? T(1) : T(0)); }
12328 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_like
; }
12329 static inline details::operator_type
operation() { return details::e_like
; }
12332 template <typename T
>
12333 struct ilike_op
: public opr_base
<T
>
12335 typedef typename opr_base
<T
>::Type Type
;
12337 static inline T
process(const T
&, const T
&) { return std::numeric_limits
<T
>::quiet_NaN(); }
12338 static inline T
process(const std::string
& t1
, const std::string
& t2
) { return (details::wc_imatch(t2
,t1
) ? T(1) : T(0)); }
12339 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_ilike
; }
12340 static inline details::operator_type
operation() { return details::e_ilike
; }
12343 template <typename T
>
12344 struct inrange_op
: public opr_base
<T
>
12346 typedef typename opr_base
<T
>::Type Type
;
12348 static inline T
process(const T
& t0
, const T
& t1
, const T
& t2
) { return ((t0
<= t1
) && (t1
<= t2
)) ? T(1) : T(0); }
12349 static inline T
process(const std::string
& t0
, const std::string
& t1
, const std::string
& t2
)
12351 return ((t0
<= t1
) && (t1
<= t2
)) ? T(1) : T(0);
12353 static inline typename expression_node
<T
>::node_type
type() { return expression_node
<T
>::e_inranges
; }
12354 static inline details::operator_type
operation() { return details::e_inrange
; }
12357 template <typename T
>
12358 inline T
value(details::expression_node
<T
>* n
)
12363 template <typename T
>
12364 inline T
value(T
* t
)
12369 template <typename T
>
12370 struct vararg_add_op
: public opr_base
<T
>
12372 typedef typename opr_base
<T
>::Type Type
;
12374 template <typename Type
,
12375 typename Allocator
,
12376 template <typename
, typename
> class Sequence
>
12377 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12379 switch (arg_list
.size())
12381 case 0 : return T(0);
12382 case 1 : return process_1(arg_list
);
12383 case 2 : return process_2(arg_list
);
12384 case 3 : return process_3(arg_list
);
12385 case 4 : return process_4(arg_list
);
12386 case 5 : return process_5(arg_list
);
12391 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
12393 result
+= value(arg_list
[i
]);
12401 template <typename Sequence
>
12402 static inline T
process_1(const Sequence
& arg_list
)
12404 return value(arg_list
[0]);
12407 template <typename Sequence
>
12408 static inline T
process_2(const Sequence
& arg_list
)
12410 return value(arg_list
[0]) + value(arg_list
[1]);
12413 template <typename Sequence
>
12414 static inline T
process_3(const Sequence
& arg_list
)
12416 return value(arg_list
[0]) + value(arg_list
[1]) +
12417 value(arg_list
[2]) ;
12420 template <typename Sequence
>
12421 static inline T
process_4(const Sequence
& arg_list
)
12423 return value(arg_list
[0]) + value(arg_list
[1]) +
12424 value(arg_list
[2]) + value(arg_list
[3]) ;
12427 template <typename Sequence
>
12428 static inline T
process_5(const Sequence
& arg_list
)
12430 return value(arg_list
[0]) + value(arg_list
[1]) +
12431 value(arg_list
[2]) + value(arg_list
[3]) +
12432 value(arg_list
[4]) ;
12436 template <typename T
>
12437 struct vararg_mul_op
: public opr_base
<T
>
12439 typedef typename opr_base
<T
>::Type Type
;
12441 template <typename Type
,
12442 typename Allocator
,
12443 template <typename
, typename
> class Sequence
>
12444 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12446 switch (arg_list
.size())
12448 case 0 : return T(0);
12449 case 1 : return process_1(arg_list
);
12450 case 2 : return process_2(arg_list
);
12451 case 3 : return process_3(arg_list
);
12452 case 4 : return process_4(arg_list
);
12453 case 5 : return process_5(arg_list
);
12456 T result
= T(value(arg_list
[0]));
12458 for (std::size_t i
= 1; i
< arg_list
.size(); ++i
)
12460 result
*= value(arg_list
[i
]);
12468 template <typename Sequence
>
12469 static inline T
process_1(const Sequence
& arg_list
)
12471 return value(arg_list
[0]);
12474 template <typename Sequence
>
12475 static inline T
process_2(const Sequence
& arg_list
)
12477 return value(arg_list
[0]) * value(arg_list
[1]);
12480 template <typename Sequence
>
12481 static inline T
process_3(const Sequence
& arg_list
)
12483 return value(arg_list
[0]) * value(arg_list
[1]) *
12484 value(arg_list
[2]) ;
12487 template <typename Sequence
>
12488 static inline T
process_4(const Sequence
& arg_list
)
12490 return value(arg_list
[0]) * value(arg_list
[1]) *
12491 value(arg_list
[2]) * value(arg_list
[3]) ;
12494 template <typename Sequence
>
12495 static inline T
process_5(const Sequence
& arg_list
)
12497 return value(arg_list
[0]) * value(arg_list
[1]) *
12498 value(arg_list
[2]) * value(arg_list
[3]) *
12499 value(arg_list
[4]) ;
12503 template <typename T
>
12504 struct vararg_avg_op
: public opr_base
<T
>
12506 typedef typename opr_base
<T
>::Type Type
;
12508 template <typename Type
,
12509 typename Allocator
,
12510 template <typename
, typename
> class Sequence
>
12511 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12513 switch (arg_list
.size())
12515 case 0 : return T(0);
12516 case 1 : return process_1(arg_list
);
12517 case 2 : return process_2(arg_list
);
12518 case 3 : return process_3(arg_list
);
12519 case 4 : return process_4(arg_list
);
12520 case 5 : return process_5(arg_list
);
12521 default : return vararg_add_op
<T
>::process(arg_list
) / arg_list
.size();
12525 template <typename Sequence
>
12526 static inline T
process_1(const Sequence
& arg_list
)
12528 return value(arg_list
[0]);
12531 template <typename Sequence
>
12532 static inline T
process_2(const Sequence
& arg_list
)
12534 return (value(arg_list
[0]) + value(arg_list
[1])) / T(2);
12537 template <typename Sequence
>
12538 static inline T
process_3(const Sequence
& arg_list
)
12540 return (value(arg_list
[0]) + value(arg_list
[1]) + value(arg_list
[2])) / T(3);
12543 template <typename Sequence
>
12544 static inline T
process_4(const Sequence
& arg_list
)
12546 return (value(arg_list
[0]) + value(arg_list
[1]) +
12547 value(arg_list
[2]) + value(arg_list
[3])) / T(4);
12550 template <typename Sequence
>
12551 static inline T
process_5(const Sequence
& arg_list
)
12553 return (value(arg_list
[0]) + value(arg_list
[1]) +
12554 value(arg_list
[2]) + value(arg_list
[3]) +
12555 value(arg_list
[4])) / T(5);
12559 template <typename T
>
12560 struct vararg_min_op
: public opr_base
<T
>
12562 typedef typename opr_base
<T
>::Type Type
;
12564 template <typename Type
,
12565 typename Allocator
,
12566 template <typename
, typename
> class Sequence
>
12567 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12569 switch (arg_list
.size())
12571 case 0 : return T(0);
12572 case 1 : return process_1(arg_list
);
12573 case 2 : return process_2(arg_list
);
12574 case 3 : return process_3(arg_list
);
12575 case 4 : return process_4(arg_list
);
12576 case 5 : return process_5(arg_list
);
12579 T result
= T(value(arg_list
[0]));
12581 for (std::size_t i
= 1; i
< arg_list
.size(); ++i
)
12583 const T v
= value(arg_list
[i
]);
12594 template <typename Sequence
>
12595 static inline T
process_1(const Sequence
& arg_list
)
12597 return value(arg_list
[0]);
12600 template <typename Sequence
>
12601 static inline T
process_2(const Sequence
& arg_list
)
12603 return std::min
<T
>(value(arg_list
[0]),value(arg_list
[1]));
12606 template <typename Sequence
>
12607 static inline T
process_3(const Sequence
& arg_list
)
12609 return std::min
<T
>(std::min
<T
>(value(arg_list
[0]),value(arg_list
[1])),value(arg_list
[2]));
12612 template <typename Sequence
>
12613 static inline T
process_4(const Sequence
& arg_list
)
12615 return std::min
<T
>(
12616 std::min
<T
>(value(arg_list
[0]), value(arg_list
[1])),
12617 std::min
<T
>(value(arg_list
[2]), value(arg_list
[3])));
12620 template <typename Sequence
>
12621 static inline T
process_5(const Sequence
& arg_list
)
12623 return std::min
<T
>(
12624 std::min
<T
>(std::min
<T
>(value(arg_list
[0]), value(arg_list
[1])),
12625 std::min
<T
>(value(arg_list
[2]), value(arg_list
[3]))),
12626 value(arg_list
[4]));
12630 template <typename T
>
12631 struct vararg_max_op
: public opr_base
<T
>
12633 typedef typename opr_base
<T
>::Type Type
;
12635 template <typename Type
,
12636 typename Allocator
,
12637 template <typename
, typename
> class Sequence
>
12638 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12640 switch (arg_list
.size())
12642 case 0 : return T(0);
12643 case 1 : return process_1(arg_list
);
12644 case 2 : return process_2(arg_list
);
12645 case 3 : return process_3(arg_list
);
12646 case 4 : return process_4(arg_list
);
12647 case 5 : return process_5(arg_list
);
12650 T result
= T(value(arg_list
[0]));
12652 for (std::size_t i
= 1; i
< arg_list
.size(); ++i
)
12654 const T v
= value(arg_list
[i
]);
12665 template <typename Sequence
>
12666 static inline T
process_1(const Sequence
& arg_list
)
12668 return value(arg_list
[0]);
12671 template <typename Sequence
>
12672 static inline T
process_2(const Sequence
& arg_list
)
12674 return std::max
<T
>(value(arg_list
[0]),value(arg_list
[1]));
12677 template <typename Sequence
>
12678 static inline T
process_3(const Sequence
& arg_list
)
12680 return std::max
<T
>(std::max
<T
>(value(arg_list
[0]),value(arg_list
[1])),value(arg_list
[2]));
12683 template <typename Sequence
>
12684 static inline T
process_4(const Sequence
& arg_list
)
12686 return std::max
<T
>(
12687 std::max
<T
>(value(arg_list
[0]), value(arg_list
[1])),
12688 std::max
<T
>(value(arg_list
[2]), value(arg_list
[3])));
12691 template <typename Sequence
>
12692 static inline T
process_5(const Sequence
& arg_list
)
12694 return std::max
<T
>(
12695 std::max
<T
>(std::max
<T
>(value(arg_list
[0]), value(arg_list
[1])),
12696 std::max
<T
>(value(arg_list
[2]), value(arg_list
[3]))),
12697 value(arg_list
[4]));
12701 template <typename T
>
12702 struct vararg_mand_op
: public opr_base
<T
>
12704 typedef typename opr_base
<T
>::Type Type
;
12706 template <typename Type
,
12707 typename Allocator
,
12708 template <typename
, typename
> class Sequence
>
12709 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12711 switch (arg_list
.size())
12713 case 1 : return process_1(arg_list
);
12714 case 2 : return process_2(arg_list
);
12715 case 3 : return process_3(arg_list
);
12716 case 4 : return process_4(arg_list
);
12717 case 5 : return process_5(arg_list
);
12720 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
12722 if (std::equal_to
<T
>()(T(0), value(arg_list
[i
])))
12731 template <typename Sequence
>
12732 static inline T
process_1(const Sequence
& arg_list
)
12734 return std::not_equal_to
<T
>()
12735 (T(0), value(arg_list
[0])) ? T(1) : T(0);
12738 template <typename Sequence
>
12739 static inline T
process_2(const Sequence
& arg_list
)
12742 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) &&
12743 std::not_equal_to
<T
>()(T(0), value(arg_list
[1]))
12747 template <typename Sequence
>
12748 static inline T
process_3(const Sequence
& arg_list
)
12751 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) &&
12752 std::not_equal_to
<T
>()(T(0), value(arg_list
[1])) &&
12753 std::not_equal_to
<T
>()(T(0), value(arg_list
[2]))
12757 template <typename Sequence
>
12758 static inline T
process_4(const Sequence
& arg_list
)
12761 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) &&
12762 std::not_equal_to
<T
>()(T(0), value(arg_list
[1])) &&
12763 std::not_equal_to
<T
>()(T(0), value(arg_list
[2])) &&
12764 std::not_equal_to
<T
>()(T(0), value(arg_list
[3]))
12768 template <typename Sequence
>
12769 static inline T
process_5(const Sequence
& arg_list
)
12772 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) &&
12773 std::not_equal_to
<T
>()(T(0), value(arg_list
[1])) &&
12774 std::not_equal_to
<T
>()(T(0), value(arg_list
[2])) &&
12775 std::not_equal_to
<T
>()(T(0), value(arg_list
[3])) &&
12776 std::not_equal_to
<T
>()(T(0), value(arg_list
[4]))
12781 template <typename T
>
12782 struct vararg_mor_op
: public opr_base
<T
>
12784 typedef typename opr_base
<T
>::Type Type
;
12786 template <typename Type
,
12787 typename Allocator
,
12788 template <typename
, typename
> class Sequence
>
12789 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12791 switch (arg_list
.size())
12793 case 1 : return process_1(arg_list
);
12794 case 2 : return process_2(arg_list
);
12795 case 3 : return process_3(arg_list
);
12796 case 4 : return process_4(arg_list
);
12797 case 5 : return process_5(arg_list
);
12800 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
12802 if (std::not_equal_to
<T
>()(T(0), value(arg_list
[i
])))
12811 template <typename Sequence
>
12812 static inline T
process_1(const Sequence
& arg_list
)
12814 return std::not_equal_to
<T
>()
12815 (T(0), value(arg_list
[0])) ? T(1) : T(0);
12818 template <typename Sequence
>
12819 static inline T
process_2(const Sequence
& arg_list
)
12822 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) ||
12823 std::not_equal_to
<T
>()(T(0), value(arg_list
[1]))
12827 template <typename Sequence
>
12828 static inline T
process_3(const Sequence
& arg_list
)
12831 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) ||
12832 std::not_equal_to
<T
>()(T(0), value(arg_list
[1])) ||
12833 std::not_equal_to
<T
>()(T(0), value(arg_list
[2]))
12837 template <typename Sequence
>
12838 static inline T
process_4(const Sequence
& arg_list
)
12841 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) ||
12842 std::not_equal_to
<T
>()(T(0), value(arg_list
[1])) ||
12843 std::not_equal_to
<T
>()(T(0), value(arg_list
[2])) ||
12844 std::not_equal_to
<T
>()(T(0), value(arg_list
[3]))
12848 template <typename Sequence
>
12849 static inline T
process_5(const Sequence
& arg_list
)
12852 std::not_equal_to
<T
>()(T(0), value(arg_list
[0])) ||
12853 std::not_equal_to
<T
>()(T(0), value(arg_list
[1])) ||
12854 std::not_equal_to
<T
>()(T(0), value(arg_list
[2])) ||
12855 std::not_equal_to
<T
>()(T(0), value(arg_list
[3])) ||
12856 std::not_equal_to
<T
>()(T(0), value(arg_list
[4]))
12861 template <typename T
>
12862 struct vararg_multi_op
: public opr_base
<T
>
12864 typedef typename opr_base
<T
>::Type Type
;
12866 template <typename Type
,
12867 typename Allocator
,
12868 template <typename
, typename
> class Sequence
>
12869 static inline T
process(const Sequence
<Type
,Allocator
>& arg_list
)
12871 switch (arg_list
.size())
12873 case 0 : return std::numeric_limits
<T
>::quiet_NaN();
12874 case 1 : return process_1(arg_list
);
12875 case 2 : return process_2(arg_list
);
12876 case 3 : return process_3(arg_list
);
12877 case 4 : return process_4(arg_list
);
12878 case 5 : return process_5(arg_list
);
12879 case 6 : return process_6(arg_list
);
12880 case 7 : return process_7(arg_list
);
12881 case 8 : return process_8(arg_list
);
12884 for (std::size_t i
= 0; i
< (arg_list
.size() - 1); ++i
)
12886 value(arg_list
[i
]);
12889 return value(arg_list
.back());
12894 template <typename Sequence
>
12895 static inline T
process_1(const Sequence
& arg_list
)
12897 return value(arg_list
[0]);
12900 template <typename Sequence
>
12901 static inline T
process_2(const Sequence
& arg_list
)
12903 value(arg_list
[0]);
12904 return value(arg_list
[1]);
12907 template <typename Sequence
>
12908 static inline T
process_3(const Sequence
& arg_list
)
12910 value(arg_list
[0]);
12911 value(arg_list
[1]);
12912 return value(arg_list
[2]);
12915 template <typename Sequence
>
12916 static inline T
process_4(const Sequence
& arg_list
)
12918 value(arg_list
[0]);
12919 value(arg_list
[1]);
12920 value(arg_list
[2]);
12921 return value(arg_list
[3]);
12924 template <typename Sequence
>
12925 static inline T
process_5(const Sequence
& arg_list
)
12927 value(arg_list
[0]);
12928 value(arg_list
[1]);
12929 value(arg_list
[2]);
12930 value(arg_list
[3]);
12931 return value(arg_list
[4]);
12934 template <typename Sequence
>
12935 static inline T
process_6(const Sequence
& arg_list
)
12937 value(arg_list
[0]);
12938 value(arg_list
[1]);
12939 value(arg_list
[2]);
12940 value(arg_list
[3]);
12941 value(arg_list
[4]);
12942 return value(arg_list
[5]);
12945 template <typename Sequence
>
12946 static inline T
process_7(const Sequence
& arg_list
)
12948 value(arg_list
[0]);
12949 value(arg_list
[1]);
12950 value(arg_list
[2]);
12951 value(arg_list
[3]);
12952 value(arg_list
[4]);
12953 value(arg_list
[5]);
12954 return value(arg_list
[6]);
12957 template <typename Sequence
>
12958 static inline T
process_8(const Sequence
& arg_list
)
12960 value(arg_list
[0]);
12961 value(arg_list
[1]);
12962 value(arg_list
[2]);
12963 value(arg_list
[3]);
12964 value(arg_list
[4]);
12965 value(arg_list
[5]);
12966 value(arg_list
[6]);
12967 return value(arg_list
[7]);
12971 template <typename T
>
12974 typedef vector_interface
<T
>* ivector_ptr
;
12976 static inline T
process(const ivector_ptr v
)
12978 const T
* vec
= v
->vec()->vds().data();
12979 const std::size_t vec_size
= v
->vec()->vds().size();
12981 loop_unroll::details
lud(vec_size
);
12983 if (vec_size
<= static_cast<std::size_t>(lud
.batch_size
))
12988 exprtk_disable_fallthrough_begin
12991 #define case_stmt(N) \
12992 case N : result += vec[i++]; \
12994 #ifndef exprtk_disable_superscalar_unroll
12995 case_stmt(16) case_stmt(15)
12996 case_stmt(14) case_stmt(13)
12997 case_stmt(12) case_stmt(11)
12998 case_stmt(10) case_stmt( 9)
12999 case_stmt( 8) case_stmt( 7)
13000 case_stmt( 6) case_stmt( 5)
13002 case_stmt( 4) case_stmt( 3)
13003 case_stmt( 2) case_stmt( 1)
13005 exprtk_disable_fallthrough_end
13013 T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0),
13014 T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0)
13017 const T
* upper_bound
= vec
+ lud
.upper_bound
;
13019 while (vec
< upper_bound
)
13021 #define exprtk_loop(N) \
13024 exprtk_loop( 0) exprtk_loop( 1)
13025 exprtk_loop( 2) exprtk_loop( 3)
13026 #ifndef exprtk_disable_superscalar_unroll
13027 exprtk_loop( 4) exprtk_loop( 5)
13028 exprtk_loop( 6) exprtk_loop( 7)
13029 exprtk_loop( 8) exprtk_loop( 9)
13030 exprtk_loop(10) exprtk_loop(11)
13031 exprtk_loop(12) exprtk_loop(13)
13032 exprtk_loop(14) exprtk_loop(15)
13035 vec
+= lud
.batch_size
;
13040 exprtk_disable_fallthrough_begin
13041 switch (lud
.remainder
)
13043 #define case_stmt(N) \
13044 case N : r[0] += vec[i++]; \
13046 #ifndef exprtk_disable_superscalar_unroll
13047 case_stmt(15) case_stmt(14)
13048 case_stmt(13) case_stmt(12)
13049 case_stmt(11) case_stmt(10)
13050 case_stmt( 9) case_stmt( 8)
13051 case_stmt( 7) case_stmt( 6)
13052 case_stmt( 5) case_stmt( 4)
13054 case_stmt( 3) case_stmt( 2)
13057 exprtk_disable_fallthrough_end
13062 return (r
[ 0] + r
[ 1] + r
[ 2] + r
[ 3])
13063 #ifndef exprtk_disable_superscalar_unroll
13064 + (r
[ 4] + r
[ 5] + r
[ 6] + r
[ 7])
13065 + (r
[ 8] + r
[ 9] + r
[10] + r
[11])
13066 + (r
[12] + r
[13] + r
[14] + r
[15])
13072 template <typename T
>
13075 typedef vector_interface
<T
>* ivector_ptr
;
13077 static inline T
process(const ivector_ptr v
)
13079 const T
* vec
= v
->vec()->vds().data();
13080 const std::size_t vec_size
= v
->vec()->vds().size();
13082 loop_unroll::details
lud(vec_size
);
13084 if (vec_size
<= static_cast<std::size_t>(lud
.batch_size
))
13089 exprtk_disable_fallthrough_begin
13092 #define case_stmt(N) \
13093 case N : result *= vec[i++]; \
13095 #ifndef exprtk_disable_superscalar_unroll
13096 case_stmt(16) case_stmt(15)
13097 case_stmt(14) case_stmt(13)
13098 case_stmt(12) case_stmt(11)
13099 case_stmt(10) case_stmt( 9)
13100 case_stmt( 8) case_stmt( 7)
13101 case_stmt( 6) case_stmt( 5)
13103 case_stmt( 4) case_stmt( 3)
13104 case_stmt( 2) case_stmt( 1)
13106 exprtk_disable_fallthrough_end
13114 T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1),
13115 T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1)
13118 const T
* upper_bound
= vec
+ lud
.upper_bound
;
13120 while (vec
< upper_bound
)
13122 #define exprtk_loop(N) \
13125 exprtk_loop( 0) exprtk_loop( 1)
13126 exprtk_loop( 2) exprtk_loop( 3)
13127 #ifndef exprtk_disable_superscalar_unroll
13128 exprtk_loop( 4) exprtk_loop( 5)
13129 exprtk_loop( 6) exprtk_loop( 7)
13130 exprtk_loop( 8) exprtk_loop( 9)
13131 exprtk_loop(10) exprtk_loop(11)
13132 exprtk_loop(12) exprtk_loop(13)
13133 exprtk_loop(14) exprtk_loop(15)
13136 vec
+= lud
.batch_size
;
13141 exprtk_disable_fallthrough_begin
13142 switch (lud
.remainder
)
13144 #define case_stmt(N) \
13145 case N : r[0] *= vec[i++]; \
13147 #ifndef exprtk_disable_superscalar_unroll
13148 case_stmt(15) case_stmt(14)
13149 case_stmt(13) case_stmt(12)
13150 case_stmt(11) case_stmt(10)
13151 case_stmt( 9) case_stmt( 8)
13152 case_stmt( 7) case_stmt( 6)
13153 case_stmt( 5) case_stmt( 4)
13155 case_stmt( 3) case_stmt( 2)
13158 exprtk_disable_fallthrough_end
13163 return (r
[ 0] * r
[ 1] * r
[ 2] * r
[ 3])
13164 #ifndef exprtk_disable_superscalar_unroll
13165 + (r
[ 4] * r
[ 5] * r
[ 6] * r
[ 7])
13166 + (r
[ 8] * r
[ 9] * r
[10] * r
[11])
13167 + (r
[12] * r
[13] * r
[14] * r
[15])
13173 template <typename T
>
13176 typedef vector_interface
<T
>* ivector_ptr
;
13178 static inline T
process(const ivector_ptr v
)
13180 const std::size_t vec_size
= v
->vec()->vds().size();
13182 return vec_add_op
<T
>::process(v
) / vec_size
;
13186 template <typename T
>
13189 typedef vector_interface
<T
>* ivector_ptr
;
13191 static inline T
process(const ivector_ptr v
)
13193 const T
* vec
= v
->vec()->vds().data();
13194 const std::size_t vec_size
= v
->vec()->vds().size();
13198 for (std::size_t i
= 1; i
< vec_size
; ++i
)
13210 template <typename T
>
13213 typedef vector_interface
<T
>* ivector_ptr
;
13215 static inline T
process(const ivector_ptr v
)
13217 const T
* vec
= v
->vec()->vds().data();
13218 const std::size_t vec_size
= v
->vec()->vds().size();
13222 for (std::size_t i
= 1; i
< vec_size
; ++i
)
13234 template <typename T
>
13235 class vov_base_node
: public expression_node
<T
>
13239 virtual ~vov_base_node()
13242 inline virtual operator_type
operation() const
13244 return details::e_default
;
13247 virtual const T
& v0() const = 0;
13249 virtual const T
& v1() const = 0;
13252 template <typename T
>
13253 class cov_base_node
: public expression_node
<T
>
13257 virtual ~cov_base_node()
13260 inline virtual operator_type
operation() const
13262 return details::e_default
;
13265 virtual const T
c() const = 0;
13267 virtual const T
& v() const = 0;
13270 template <typename T
>
13271 class voc_base_node
: public expression_node
<T
>
13275 virtual ~voc_base_node()
13278 inline virtual operator_type
operation() const
13280 return details::e_default
;
13283 virtual const T
c() const = 0;
13285 virtual const T
& v() const = 0;
13288 template <typename T
>
13289 class vob_base_node
: public expression_node
<T
>
13293 virtual ~vob_base_node()
13296 virtual const T
& v() const = 0;
13299 template <typename T
>
13300 class bov_base_node
: public expression_node
<T
>
13304 virtual ~bov_base_node()
13307 virtual const T
& v() const = 0;
13310 template <typename T
>
13311 class cob_base_node
: public expression_node
<T
>
13315 virtual ~cob_base_node()
13318 inline virtual operator_type
operation() const
13320 return details::e_default
;
13323 virtual const T
c() const = 0;
13325 virtual void set_c(const T
) = 0;
13327 virtual expression_node
<T
>* move_branch(const std::size_t& index
) = 0;
13330 template <typename T
>
13331 class boc_base_node
: public expression_node
<T
>
13335 virtual ~boc_base_node()
13338 inline virtual operator_type
operation() const
13340 return details::e_default
;
13343 virtual const T
c() const = 0;
13345 virtual void set_c(const T
) = 0;
13347 virtual expression_node
<T
>* move_branch(const std::size_t& index
) = 0;
13350 template <typename T
>
13351 class uv_base_node
: public expression_node
<T
>
13355 virtual ~uv_base_node()
13358 inline virtual operator_type
operation() const
13360 return details::e_default
;
13363 virtual const T
& v() const = 0;
13366 template <typename T
>
13367 class sos_base_node
: public expression_node
<T
>
13371 virtual ~sos_base_node()
13374 inline virtual operator_type
operation() const
13376 return details::e_default
;
13380 template <typename T
>
13381 class sosos_base_node
: public expression_node
<T
>
13385 virtual ~sosos_base_node()
13388 inline virtual operator_type
operation() const
13390 return details::e_default
;
13394 template <typename T
>
13395 class T0oT1oT2_base_node
: public expression_node
<T
>
13399 virtual ~T0oT1oT2_base_node()
13402 virtual std::string
type_id() const = 0;
13405 template <typename T
>
13406 class T0oT1oT2oT3_base_node
: public expression_node
<T
>
13410 virtual ~T0oT1oT2oT3_base_node()
13413 virtual std::string
type_id() const = 0;
13416 template <typename T
, typename Operation
>
13417 class unary_variable_node
: public uv_base_node
<T
>
13421 typedef expression_node
<T
>* expression_ptr
;
13422 typedef Operation operation_t
;
13424 explicit unary_variable_node(const T
& var
)
13428 inline T
value() const
13430 return Operation::process(v_
);
13433 inline typename expression_node
<T
>::node_type
type() const
13435 return Operation::type();
13438 inline operator_type
operation() const
13440 return Operation::operation();
13443 inline const T
& v() const
13450 unary_variable_node(unary_variable_node
<T
,Operation
>&);
13451 unary_variable_node
<T
,Operation
>& operator=(unary_variable_node
<T
,Operation
>&);
13456 template <typename T
>
13457 class uvouv_node
: public expression_node
<T
>
13461 // UOpr1(v0) Op UOpr2(v1)
13463 typedef expression_node
<T
>* expression_ptr
;
13464 typedef typename
details::functor_t
<T
> functor_t
;
13465 typedef typename
functor_t::bfunc_t bfunc_t
;
13466 typedef typename
functor_t::ufunc_t ufunc_t
;
13468 explicit uvouv_node(const T
& var0
,const T
& var1
,
13469 ufunc_t uf0
, ufunc_t uf1
, bfunc_t bf
)
13477 inline T
value() const
13479 return f_(u0_(v0_
),u1_(v1_
));
13482 inline typename expression_node
<T
>::node_type
type() const
13484 return expression_node
<T
>::e_uvouv
;
13487 inline operator_type
operation() const
13489 return details::e_default
;
13492 inline const T
& v0()
13497 inline const T
& v1()
13502 inline ufunc_t
u0()
13507 inline ufunc_t
u1()
13519 uvouv_node(uvouv_node
<T
>&);
13520 uvouv_node
<T
>& operator=(uvouv_node
<T
>&);
13529 template <typename T
, typename Operation
>
13530 class unary_branch_node
: public expression_node
<T
>
13534 typedef expression_node
<T
>* expression_ptr
;
13535 typedef Operation operation_t
;
13537 explicit unary_branch_node(expression_ptr brnch
)
13539 branch_deletable_(branch_deletable(branch_
))
13542 ~unary_branch_node()
13544 if (branch_
&& branch_deletable_
)
13546 destroy_node(branch_
);
13550 inline T
value() const
13552 return Operation::process(branch_
->value());
13555 inline typename expression_node
<T
>::node_type
type() const
13557 return Operation::type();
13560 inline operator_type
operation() const
13562 return Operation::operation();
13565 inline expression_node
<T
>* branch(const std::size_t&) const
13570 inline void release()
13572 branch_deletable_
= false;
13577 unary_branch_node(unary_branch_node
<T
,Operation
>&);
13578 unary_branch_node
<T
,Operation
>& operator=(unary_branch_node
<T
,Operation
>&);
13580 expression_ptr branch_
;
13581 bool branch_deletable_
;
13584 template <typename T
> struct is_const
{ enum {result
= 0}; };
13585 template <typename T
> struct is_const
<const T
> { enum {result
= 1}; };
13586 template <typename T
> struct is_const_ref
{ enum {result
= 0}; };
13587 template <typename T
> struct is_const_ref
<const T
&> { enum {result
= 1}; };
13588 template <typename T
> struct is_ref
{ enum {result
= 0}; };
13589 template <typename T
> struct is_ref
<T
&> { enum {result
= 1}; };
13590 template <typename T
> struct is_ref
<const T
&> { enum {result
= 0}; };
13592 template <std::size_t State
>
13593 struct param_to_str
{ static std::string
result() { static const std::string
r("v"); return r
; } };
13596 struct param_to_str
<0> { static std::string
result() { static const std::string
r("c"); return r
; } };
13598 #define exprtk_crtype(Type) \
13599 param_to_str<is_const_ref< Type >::result>::result() \
13601 template <typename T>
13602 struct T0oT1oT2process
13604 typedef typename
details::functor_t
<T
> functor_t
;
13605 typedef typename
functor_t::bfunc_t bfunc_t
;
13609 static inline T
process(const T
& t0
, const T
& t1
, const T
& t2
, const bfunc_t bf0
, const bfunc_t bf1
)
13611 // (T0 o0 T1) o1 T2
13612 return bf1(bf0(t0
,t1
),t2
);
13615 template <typename T0
, typename T1
, typename T2
>
13616 static inline std::string
id()
13618 static const std::string result
= "(" + exprtk_crtype(T0
) + "o" +
13619 exprtk_crtype(T1
) + ")o(" +
13620 exprtk_crtype(T2
) + ")" ;
13627 static inline T
process(const T
& t0
, const T
& t1
, const T
& t2
, const bfunc_t bf0
, const bfunc_t bf1
)
13629 // T0 o0 (T1 o1 T2)
13630 return bf0(t0
,bf1(t1
,t2
));
13633 template <typename T0
, typename T1
, typename T2
>
13634 static inline std::string
id()
13636 static const std::string result
= "(" + exprtk_crtype(T0
) + ")o(" +
13637 exprtk_crtype(T1
) + "o" +
13638 exprtk_crtype(T2
) + ")" ;
13644 template <typename T
>
13645 struct T0oT1oT20T3process
13647 typedef typename
details::functor_t
<T
> functor_t
;
13648 typedef typename
functor_t::bfunc_t bfunc_t
;
13652 static inline T
process(const T
& t0
, const T
& t1
,
13653 const T
& t2
, const T
& t3
,
13654 const bfunc_t bf0
, const bfunc_t bf1
, const bfunc_t bf2
)
13656 // (T0 o0 T1) o1 (T2 o2 T3)
13657 return bf1(bf0(t0
,t1
),bf2(t2
,t3
));
13660 template <typename T0
, typename T1
, typename T2
, typename T3
>
13661 static inline std::string
id()
13663 static const std::string result
= "(" + exprtk_crtype(T0
) + "o" +
13664 exprtk_crtype(T1
) + ")o" +
13665 "(" + exprtk_crtype(T2
) + "o" +
13666 exprtk_crtype(T3
) + ")" ;
13673 static inline T
process(const T
& t0
, const T
& t1
,
13674 const T
& t2
, const T
& t3
,
13675 const bfunc_t bf0
, const bfunc_t bf1
, const bfunc_t bf2
)
13677 // (T0 o0 (T1 o1 (T2 o2 T3))
13678 return bf0(t0
,bf1(t1
,bf2(t2
,t3
)));
13680 template <typename T0
, typename T1
, typename T2
, typename T3
>
13681 static inline std::string
id()
13683 static const std::string result
= "(" + exprtk_crtype(T0
) + ")o((" +
13684 exprtk_crtype(T1
) + ")o(" +
13685 exprtk_crtype(T2
) + "o" +
13686 exprtk_crtype(T3
) + "))" ;
13693 static inline T
process(const T
& t0
, const T
& t1
,
13694 const T
& t2
, const T
& t3
,
13695 const bfunc_t bf0
, const bfunc_t bf1
, const bfunc_t bf2
)
13697 // (T0 o0 ((T1 o1 T2) o2 T3)
13698 return bf0(t0
,bf2(bf1(t1
,t2
),t3
));
13701 template <typename T0
, typename T1
, typename T2
, typename T3
>
13702 static inline std::string
id()
13704 static const std::string result
= "(" + exprtk_crtype(T0
) + ")o((" +
13705 exprtk_crtype(T1
) + "o" +
13706 exprtk_crtype(T2
) + ")o(" +
13707 exprtk_crtype(T3
) + "))" ;
13714 static inline T
process(const T
& t0
, const T
& t1
,
13715 const T
& t2
, const T
& t3
,
13716 const bfunc_t bf0
, const bfunc_t bf1
, const bfunc_t bf2
)
13718 // (((T0 o0 T1) o1 T2) o2 T3)
13719 return bf2(bf1(bf0(t0
,t1
),t2
),t3
);
13722 template <typename T0
, typename T1
, typename T2
, typename T3
>
13723 static inline std::string
id()
13725 static const std::string result
= "((" + exprtk_crtype(T0
) + "o" +
13726 exprtk_crtype(T1
) + ")o(" +
13727 exprtk_crtype(T2
) + "))o(" +
13728 exprtk_crtype(T3
) + ")";
13735 static inline T
process(const T
& t0
, const T
& t1
,
13736 const T
& t2
, const T
& t3
,
13737 const bfunc_t bf0
, const bfunc_t bf1
, const bfunc_t bf2
)
13739 // ((T0 o0 (T1 o1 T2)) o2 T3
13740 return bf2(bf0(t0
,bf1(t1
,t2
)),t3
);
13743 template <typename T0
, typename T1
, typename T2
, typename T3
>
13744 static inline std::string
id()
13746 static const std::string result
= "((" + exprtk_crtype(T0
) + ")o(" +
13747 exprtk_crtype(T1
) + "o" +
13748 exprtk_crtype(T2
) + "))o(" +
13749 exprtk_crtype(T3
) + ")" ;
13755 #undef exprtk_crtype
13757 template <typename T
, typename T0
, typename T1
>
13758 struct nodetype_T0oT1
{ static const typename expression_node
<T
>::node_type result
; };
13759 template <typename T
, typename T0
, typename T1
>
13760 const typename expression_node
<T
>::node_type nodetype_T0oT1
<T
,T0
,T1
>::result
= expression_node
<T
>::e_none
;
13762 #define synthesis_node_type_define(T0_,T1_,v_) \
13763 template <typename T, typename T0, typename T1> \
13764 struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
13765 template <typename T, typename T0, typename T1> \
13766 const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
13768 synthesis_node_type_define(const T0&, const T1&, e_vov)
13769 synthesis_node_type_define(const T0
&, const T1
, e_voc
)
13770 synthesis_node_type_define(const T0
, const T1
&, e_cov
)
13771 synthesis_node_type_define( T0
&, T1
&, e_none
)
13772 synthesis_node_type_define(const T0
, const T1
, e_none
)
13773 synthesis_node_type_define( T0
&, const T1
, e_none
)
13774 synthesis_node_type_define(const T0
, T1
&, e_none
)
13775 synthesis_node_type_define(const T0
&, T1
&, e_none
)
13776 synthesis_node_type_define( T0
&, const T1
&, e_none
)
13777 #undef synthesis_node_type_define
13779 template <typename T
, typename T0
, typename T1
, typename T2
>
13780 struct nodetype_T0oT1oT2
{ static const typename expression_node
<T
>::node_type result
; };
13781 template <typename T
, typename T0
, typename T1
, typename T2
>
13782 const typename expression_node
<T
>::node_type nodetype_T0oT1oT2
<T
,T0
,T1
,T2
>::result
= expression_node
<T
>::e_none
;
13784 #define synthesis_node_type_define(T0_,T1_,T2_,v_) \
13785 template <typename T, typename T0, typename T1, typename T2> \
13786 struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
13787 template <typename T, typename T0, typename T1, typename T2> \
13788 const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
13790 synthesis_node_type_define(const T0&, const T1&, const T2&, e_vovov)
13791 synthesis_node_type_define(const T0
&, const T1
&, const T2
, e_vovoc
)
13792 synthesis_node_type_define(const T0
&, const T1
, const T2
&, e_vocov
)
13793 synthesis_node_type_define(const T0
, const T1
&, const T2
&, e_covov
)
13794 synthesis_node_type_define(const T0
, const T1
&, const T2
, e_covoc
)
13795 synthesis_node_type_define(const T0
, const T1
, const T2
, e_none
)
13796 synthesis_node_type_define(const T0
, const T1
, const T2
&, e_none
)
13797 synthesis_node_type_define(const T0
&, const T1
, const T2
, e_none
)
13798 synthesis_node_type_define( T0
&, T1
&, T2
&, e_none
)
13799 #undef synthesis_node_type_define
13801 template <typename T
, typename T0
, typename T1
, typename T2
, typename T3
>
13802 struct nodetype_T0oT1oT2oT3
{ static const typename expression_node
<T
>::node_type result
; };
13803 template <typename T
, typename T0
, typename T1
, typename T2
, typename T3
>
13804 const typename expression_node
<T
>::node_type nodetype_T0oT1oT2oT3
<T
,T0
,T1
,T2
,T3
>::result
= expression_node
<T
>::e_none
;
13806 #define synthesis_node_type_define(T0_,T1_,T2_,T3_,v_) \
13807 template <typename T, typename T0, typename T1, typename T2, typename T3> \
13808 struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
13809 template <typename T, typename T0, typename T1, typename T2, typename T3> \
13810 const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
13812 synthesis_node_type_define(const T0&, const T1&, const T2&, const T3&, e_vovovov)
13813 synthesis_node_type_define(const T0
&, const T1
&, const T2
&, const T3
, e_vovovoc
)
13814 synthesis_node_type_define(const T0
&, const T1
&, const T2
, const T3
&, e_vovocov
)
13815 synthesis_node_type_define(const T0
&, const T1
, const T2
&, const T3
&, e_vocovov
)
13816 synthesis_node_type_define(const T0
, const T1
&, const T2
&, const T3
&, e_covovov
)
13817 synthesis_node_type_define(const T0
, const T1
&, const T2
, const T3
&, e_covocov
)
13818 synthesis_node_type_define(const T0
&, const T1
, const T2
&, const T3
, e_vocovoc
)
13819 synthesis_node_type_define(const T0
, const T1
&, const T2
&, const T3
, e_covovoc
)
13820 synthesis_node_type_define(const T0
&, const T1
, const T2
, const T3
&, e_vococov
)
13821 synthesis_node_type_define(const T0
, const T1
, const T2
, const T3
, e_none
)
13822 synthesis_node_type_define(const T0
, const T1
, const T2
, const T3
&, e_none
)
13823 synthesis_node_type_define(const T0
, const T1
, const T2
&, const T3
, e_none
)
13824 synthesis_node_type_define(const T0
, const T1
&, const T2
, const T3
, e_none
)
13825 synthesis_node_type_define(const T0
&, const T1
, const T2
, const T3
, e_none
)
13826 synthesis_node_type_define(const T0
, const T1
, const T2
&, const T3
&, e_none
)
13827 synthesis_node_type_define(const T0
&, const T1
&, const T2
, const T3
, e_none
)
13828 #undef synthesis_node_type_define
13830 template <typename T
, typename T0
, typename T1
>
13831 class T0oT1
: public expression_node
<T
>
13835 typedef typename
details::functor_t
<T
> functor_t
;
13836 typedef typename
functor_t::bfunc_t bfunc_t
;
13837 typedef T value_type
;
13838 typedef T0oT1
<T
,T0
,T1
> node_type
;
13840 T0oT1(T0 p0
, T1 p1
, const bfunc_t p2
)
13846 inline typename expression_node
<T
>::node_type
type() const
13848 static const typename expression_node
<T
>::node_type result
= nodetype_T0oT1
<T
,T0
,T1
>::result
;
13852 inline operator_type
operation() const
13857 inline T
value() const
13859 return f_(t0_
,t1_
);
13862 inline T0
t0() const
13867 inline T1
t1() const
13872 inline bfunc_t
f() const
13877 template <typename Allocator
>
13878 static inline expression_node
<T
>* allocate(Allocator
& allocator
,
13883 .template allocate_type
<node_type
, T0
, T1
, bfunc_t
&>
13889 T0oT1(T0oT1
<T
,T0
,T1
>&) {}
13890 T0oT1
<T
,T0
,T1
>& operator=(T0oT1
<T
,T0
,T1
>&) { return (*this); }
13897 template <typename T
, typename T0
, typename T1
, typename T2
, typename ProcessMode
>
13898 class T0oT1oT2
: public T0oT1oT2_base_node
<T
>
13902 typedef typename
details::functor_t
<T
> functor_t
;
13903 typedef typename
functor_t::bfunc_t bfunc_t
;
13904 typedef T value_type
;
13905 typedef T0oT1oT2
<T
,T0
,T1
,T2
,ProcessMode
> node_type
;
13906 typedef ProcessMode process_mode_t
;
13908 T0oT1oT2(T0 p0
, T1 p1
, T2 p2
, const bfunc_t p3
, const bfunc_t p4
)
13916 inline typename expression_node
<T
>::node_type
type() const
13918 static const typename expression_node
<T
>::node_type result
= nodetype_T0oT1oT2
<T
,T0
,T1
,T2
>::result
;
13922 inline operator_type
operation() const
13927 inline T
value() const
13929 return ProcessMode::process(t0_
, t1_
, t2_
, f0_
, f1_
);
13932 inline T0
t0() const
13937 inline T1
t1() const
13942 inline T2
t2() const
13957 std::string
type_id() const
13962 static inline std::string
id()
13964 return process_mode_t::template id
<T0
,T1
,T2
>();
13967 template <typename Allocator
>
13968 static inline expression_node
<T
>* allocate(Allocator
& allocator
, T0 p0
, T1 p1
, T2 p2
, bfunc_t p3
, bfunc_t p4
)
13971 .template allocate_type
<node_type
, T0
, T1
, T2
, bfunc_t
, bfunc_t
>
13972 (p0
, p1
, p2
, p3
, p4
);
13977 T0oT1oT2(node_type
&) {}
13978 node_type
& operator=(node_type
&) { return (*this); }
13987 template <typename T
, typename T0_
, typename T1_
, typename T2_
, typename T3_
, typename ProcessMode
>
13988 class T0oT1oT2oT3
: public T0oT1oT2oT3_base_node
<T
>
13992 typedef typename
details::functor_t
<T
> functor_t
;
13993 typedef typename
functor_t::bfunc_t bfunc_t
;
13994 typedef T value_type
;
13999 typedef T0oT1oT2oT3
<T
,T0
,T1
,T2
,T3
,ProcessMode
> node_type
;
14000 typedef ProcessMode process_mode_t
;
14002 T0oT1oT2oT3(T0 p0
, T1 p1
, T2 p2
, T3 p3
, bfunc_t p4
, bfunc_t p5
, bfunc_t p6
)
14012 inline T
value() const
14014 return ProcessMode::process(t0_
, t1_
, t2_
, t3_
, f0_
, f1_
, f2_
);
14017 inline T0
t0() const
14022 inline T1
t1() const
14027 inline T2
t2() const
14032 inline T3
t3() const
14037 inline bfunc_t
f0() const
14042 inline bfunc_t
f1() const
14047 inline bfunc_t
f2() const
14052 inline std::string
type_id() const
14057 static inline std::string
id()
14059 return process_mode_t::template id
<T0
, T1
, T2
, T3
>();
14062 template <typename Allocator
>
14063 static inline expression_node
<T
>* allocate(Allocator
& allocator
,
14064 T0 p0
, T1 p1
, T2 p2
, T3 p3
,
14065 bfunc_t p4
, bfunc_t p5
, bfunc_t p6
)
14068 .template allocate_type
<node_type
, T0
, T1
, T2
, T3
, bfunc_t
, bfunc_t
>
14069 (p0
, p1
, p2
, p3
, p4
, p5
, p6
);
14074 T0oT1oT2oT3(node_type
&) {}
14075 node_type
& operator=(node_type
&) { return (*this); }
14086 template <typename T
, typename T0
, typename T1
, typename T2
>
14087 class T0oT1oT2_sf3
: public T0oT1oT2_base_node
<T
>
14091 typedef typename
details::functor_t
<T
> functor_t
;
14092 typedef typename
functor_t::tfunc_t tfunc_t
;
14093 typedef T value_type
;
14094 typedef T0oT1oT2_sf3
<T
,T0
,T1
,T2
> node_type
;
14096 T0oT1oT2_sf3(T0 p0
, T1 p1
, T2 p2
, const tfunc_t p3
)
14103 inline typename expression_node
<T
>::node_type
type() const
14105 static const typename expression_node
<T
>::node_type result
= nodetype_T0oT1oT2
<T
,T0
,T1
,T2
>::result
;
14109 inline operator_type
operation() const
14114 inline T
value() const
14116 return f_(t0_
, t1_
, t2_
);
14119 inline T0
t0() const
14124 inline T1
t1() const
14129 inline T2
t2() const
14139 std::string
type_id() const
14144 static inline std::string
id()
14149 template <typename Allocator
>
14150 static inline expression_node
<T
>* allocate(Allocator
& allocator
, T0 p0
, T1 p1
, T2 p2
, tfunc_t p3
)
14153 .template allocate_type
<node_type
, T0
, T1
, T2
, tfunc_t
>
14159 T0oT1oT2_sf3(node_type
&) {}
14160 node_type
& operator=(node_type
&) { return (*this); }
14168 template <typename T
, typename T0
, typename T1
, typename T2
>
14169 class sf3ext_type_node
: public T0oT1oT2_base_node
<T
>
14173 virtual ~sf3ext_type_node()
14176 virtual T0
t0() const = 0;
14178 virtual T1
t1() const = 0;
14180 virtual T2
t2() const = 0;
14183 template <typename T
, typename T0
, typename T1
, typename T2
, typename SF3Operation
>
14184 class T0oT1oT2_sf3ext
: public sf3ext_type_node
<T
,T0
,T1
,T2
>
14188 typedef typename
details::functor_t
<T
> functor_t
;
14189 typedef typename
functor_t::tfunc_t tfunc_t
;
14190 typedef T value_type
;
14191 typedef T0oT1oT2_sf3ext
<T
,T0
,T1
,T2
,SF3Operation
> node_type
;
14193 T0oT1oT2_sf3ext(T0 p0
, T1 p1
, T2 p2
)
14199 inline typename expression_node
<T
>::node_type
type() const
14201 static const typename expression_node
<T
>::node_type result
= nodetype_T0oT1oT2
<T
,T0
,T1
,T2
>::result
;
14205 inline operator_type
operation() const
14210 inline T
value() const
14212 return SF3Operation::process(t0_
, t1_
, t2_
);
14230 std::string
type_id() const
14235 static inline std::string
id()
14237 return SF3Operation::id();
14240 template <typename Allocator
>
14241 static inline expression_node
<T
>* allocate(Allocator
& allocator
, T0 p0
, T1 p1
, T2 p2
)
14244 .template allocate_type
<node_type
, T0
, T1
, T2
>
14250 T0oT1oT2_sf3ext(node_type
&) {}
14251 node_type
& operator=(node_type
&) { return (*this); }
14258 template <typename T
>
14259 inline bool is_sf3ext_node(const expression_node
<T
>* n
)
14263 case expression_node
<T
>::e_vovov
: return true;
14264 case expression_node
<T
>::e_vovoc
: return true;
14265 case expression_node
<T
>::e_vocov
: return true;
14266 case expression_node
<T
>::e_covov
: return true;
14267 case expression_node
<T
>::e_covoc
: return true;
14268 default : return false;
14272 template <typename T
, typename T0
, typename T1
, typename T2
, typename T3
>
14273 class T0oT1oT2oT3_sf4
: public T0oT1oT2_base_node
<T
>
14277 typedef typename
details::functor_t
<T
> functor_t
;
14278 typedef typename
functor_t::qfunc_t qfunc_t
;
14279 typedef T value_type
;
14280 typedef T0oT1oT2oT3_sf4
<T
,T0
,T1
,T2
,T3
> node_type
;
14282 T0oT1oT2oT3_sf4(T0 p0
, T1 p1
, T2 p2
, T3 p3
, const qfunc_t p4
)
14290 inline typename expression_node
<T
>::node_type
type() const
14292 static const typename expression_node
<T
>::node_type result
= nodetype_T0oT1oT2oT3
<T
,T0
,T1
,T2
,T3
>::result
;
14296 inline operator_type
operation() const
14301 inline T
value() const
14303 return f_(t0_
, t1_
, t2_
, t3_
);
14306 inline T0
t0() const
14311 inline T1
t1() const
14316 inline T2
t2() const
14321 inline T3
t3() const
14331 std::string
type_id() const
14336 static inline std::string
id()
14341 template <typename Allocator
>
14342 static inline expression_node
<T
>* allocate(Allocator
& allocator
, T0 p0
, T1 p1
, T2 p2
, T3 p3
, qfunc_t p4
)
14345 .template allocate_type
<node_type
, T0
, T1
, T2
, T3
, qfunc_t
>
14346 (p0
, p1
, p2
, p3
, p4
);
14351 T0oT1oT2oT3_sf4(node_type
&) {}
14352 node_type
& operator=(node_type
&) { return (*this); }
14361 template <typename T
, typename T0
, typename T1
, typename T2
, typename T3
, typename SF4Operation
>
14362 class T0oT1oT2oT3_sf4ext
: public T0oT1oT2oT3_base_node
<T
>
14366 typedef typename
details::functor_t
<T
> functor_t
;
14367 typedef typename
functor_t::tfunc_t tfunc_t
;
14368 typedef T value_type
;
14369 typedef T0oT1oT2oT3_sf4ext
<T
,T0
,T1
,T2
,T3
,SF4Operation
> node_type
;
14371 T0oT1oT2oT3_sf4ext(T0 p0
, T1 p1
, T2 p2
, T3 p3
)
14378 inline typename expression_node
<T
>::node_type
type() const
14380 static const typename expression_node
<T
>::node_type result
= nodetype_T0oT1oT2oT3
<T
,T0
,T1
,T2
,T3
>::result
;
14384 inline operator_type
operation() const
14389 inline T
value() const
14391 return SF4Operation::process(t0_
, t1_
, t2_
, t3_
);
14394 inline T0
t0() const
14399 inline T1
t1() const
14404 inline T2
t2() const
14409 inline T3
t3() const
14414 std::string
type_id() const
14419 static inline std::string
id()
14421 return SF4Operation::id();
14424 template <typename Allocator
>
14425 static inline expression_node
<T
>* allocate(Allocator
& allocator
, T0 p0
, T1 p1
, T2 p2
, T3 p3
)
14428 .template allocate_type
<node_type
, T0
, T1
, T2
, T3
>
14434 T0oT1oT2oT3_sf4ext(node_type
&) {}
14435 node_type
& operator=(node_type
&) { return (*this); }
14443 template <typename T
>
14444 inline bool is_sf4ext_node(const expression_node
<T
>* n
)
14448 case expression_node
<T
>::e_vovovov
: return true;
14449 case expression_node
<T
>::e_vovovoc
: return true;
14450 case expression_node
<T
>::e_vovocov
: return true;
14451 case expression_node
<T
>::e_vocovov
: return true;
14452 case expression_node
<T
>::e_covovov
: return true;
14453 case expression_node
<T
>::e_covocov
: return true;
14454 case expression_node
<T
>::e_vocovoc
: return true;
14455 case expression_node
<T
>::e_covovoc
: return true;
14456 case expression_node
<T
>::e_vococov
: return true;
14457 default : return false;
14461 template <typename T
, typename T0
, typename T1
>
14462 struct T0oT1_define
14464 typedef details::T0oT1
<T
, T0
, T1
> type0
;
14467 template <typename T
, typename T0
, typename T1
, typename T2
>
14468 struct T0oT1oT2_define
14470 typedef details::T0oT1oT2
<T
, T0
, T1
, T2
, typename T0oT1oT2process
<T
>::mode0
> type0
;
14471 typedef details::T0oT1oT2
<T
, T0
, T1
, T2
, typename T0oT1oT2process
<T
>::mode1
> type1
;
14472 typedef details::T0oT1oT2_sf3
<T
, T0
, T1
, T2
> sf3_type
;
14473 typedef details::sf3ext_type_node
<T
, T0
, T1
, T2
> sf3_type_node
;
14476 template <typename T
, typename T0
, typename T1
, typename T2
, typename T3
>
14477 struct T0oT1oT2oT3_define
14479 typedef details::T0oT1oT2oT3
<T
, T0
, T1
, T2
, T3
, typename T0oT1oT20T3process
<T
>::mode0
> type0
;
14480 typedef details::T0oT1oT2oT3
<T
, T0
, T1
, T2
, T3
, typename T0oT1oT20T3process
<T
>::mode1
> type1
;
14481 typedef details::T0oT1oT2oT3
<T
, T0
, T1
, T2
, T3
, typename T0oT1oT20T3process
<T
>::mode2
> type2
;
14482 typedef details::T0oT1oT2oT3
<T
, T0
, T1
, T2
, T3
, typename T0oT1oT20T3process
<T
>::mode3
> type3
;
14483 typedef details::T0oT1oT2oT3
<T
, T0
, T1
, T2
, T3
, typename T0oT1oT20T3process
<T
>::mode4
> type4
;
14484 typedef details::T0oT1oT2oT3_sf4
<T
, T0
, T1
, T2
, T3
> sf4_type
;
14487 template <typename T
, typename Operation
>
14488 class vov_node
: public vov_base_node
<T
>
14492 typedef expression_node
<T
>* expression_ptr
;
14493 typedef Operation operation_t
;
14495 // variable op variable node
14496 explicit vov_node(const T
& var0
, const T
& var1
)
14501 inline T
value() const
14503 return Operation::process(v0_
,v1_
);
14506 inline typename expression_node
<T
>::node_type
type() const
14508 return Operation::type();
14511 inline operator_type
operation() const
14513 return Operation::operation();
14516 inline const T
& v0() const
14521 inline const T
& v1() const
14533 vov_node(vov_node
<T
,Operation
>&);
14534 vov_node
<T
,Operation
>& operator=(vov_node
<T
,Operation
>&);
14537 template <typename T
, typename Operation
>
14538 class cov_node
: public cov_base_node
<T
>
14542 typedef expression_node
<T
>* expression_ptr
;
14543 typedef Operation operation_t
;
14545 // constant op variable node
14546 explicit cov_node(const T
& const_var
, const T
& var
)
14551 inline T
value() const
14553 return Operation::process(c_
,v_
);
14556 inline typename expression_node
<T
>::node_type
type() const
14558 return Operation::type();
14561 inline operator_type
operation() const
14563 return Operation::operation();
14566 inline const T
c() const
14571 inline const T
& v() const
14583 cov_node(const cov_node
<T
,Operation
>&);
14584 cov_node
<T
,Operation
>& operator=(const cov_node
<T
,Operation
>&);
14587 template <typename T
, typename Operation
>
14588 class voc_node
: public voc_base_node
<T
>
14592 typedef expression_node
<T
>* expression_ptr
;
14593 typedef Operation operation_t
;
14595 // variable op constant node
14596 explicit voc_node(const T
& var
, const T
& const_var
)
14601 inline T
value() const
14603 return Operation::process(v_
,c_
);
14606 inline operator_type
operation() const
14608 return Operation::operation();
14611 inline const T
c() const
14616 inline const T
& v() const
14628 voc_node(const voc_node
<T
,Operation
>&);
14629 voc_node
<T
,Operation
>& operator=(const voc_node
<T
,Operation
>&);
14632 template <typename T
, typename Operation
>
14633 class vob_node
: public vob_base_node
<T
>
14637 typedef expression_node
<T
>* expression_ptr
;
14638 typedef std::pair
<expression_ptr
,bool> branch_t
;
14639 typedef Operation operation_t
;
14641 // variable op constant node
14642 explicit vob_node(const T
& var
, const expression_ptr brnch
)
14645 init_branches
<1>(branch_
,brnch
);
14650 cleanup_branches::execute
<T
,1>(branch_
);
14653 inline T
value() const
14655 return Operation::process(v_
,branch_
[0].first
->value());
14658 inline operator_type
operation() const
14660 return Operation::operation();
14663 inline const T
& v() const
14668 inline expression_node
<T
>* branch(const std::size_t&) const
14670 return branch_
[0].first
;
14675 vob_node(const vob_node
<T
,Operation
>&);
14676 vob_node
<T
,Operation
>& operator=(const vob_node
<T
,Operation
>&);
14679 branch_t branch_
[1];
14682 template <typename T
, typename Operation
>
14683 class bov_node
: public bov_base_node
<T
>
14687 typedef expression_node
<T
>* expression_ptr
;
14688 typedef std::pair
<expression_ptr
,bool> branch_t
;
14689 typedef Operation operation_t
;
14691 // variable op constant node
14692 explicit bov_node(const expression_ptr brnch
, const T
& var
)
14695 init_branches
<1>(branch_
,brnch
);
14700 cleanup_branches::execute
<T
,1>(branch_
);
14703 inline T
value() const
14705 return Operation::process(branch_
[0].first
->value(),v_
);
14708 inline operator_type
operation() const
14710 return Operation::operation();
14713 inline const T
& v() const
14718 inline expression_node
<T
>* branch(const std::size_t&) const
14720 return branch_
[0].first
;
14725 bov_node(const bov_node
<T
,Operation
>&);
14726 bov_node
<T
,Operation
>& operator=(const bov_node
<T
,Operation
>&);
14729 branch_t branch_
[1];
14732 template <typename T
, typename Operation
>
14733 class cob_node
: public cob_base_node
<T
>
14737 typedef expression_node
<T
>* expression_ptr
;
14738 typedef std::pair
<expression_ptr
,bool> branch_t
;
14739 typedef Operation operation_t
;
14741 // variable op constant node
14742 explicit cob_node(const T const_var
, const expression_ptr brnch
)
14745 init_branches
<1>(branch_
,brnch
);
14750 cleanup_branches::execute
<T
,1>(branch_
);
14753 inline T
value() const
14755 return Operation::process(c_
,branch_
[0].first
->value());
14758 inline operator_type
operation() const
14760 return Operation::operation();
14763 inline const T
c() const
14768 inline void set_c(const T new_c
)
14770 (*const_cast<T
*>(&c_
)) = new_c
;
14773 inline expression_node
<T
>* branch(const std::size_t&) const
14775 return branch_
[0].first
;
14778 inline expression_node
<T
>* move_branch(const std::size_t&)
14780 branch_
[0].second
= false;
14781 return branch_
[0].first
;
14786 cob_node(const cob_node
<T
,Operation
>&);
14787 cob_node
<T
,Operation
>& operator=(const cob_node
<T
,Operation
>&);
14790 branch_t branch_
[1];
14793 template <typename T
, typename Operation
>
14794 class boc_node
: public boc_base_node
<T
>
14798 typedef expression_node
<T
>* expression_ptr
;
14799 typedef std::pair
<expression_ptr
,bool> branch_t
;
14800 typedef Operation operation_t
;
14802 // variable op constant node
14803 explicit boc_node(const expression_ptr brnch
, const T const_var
)
14806 init_branches
<1>(branch_
,brnch
);
14811 cleanup_branches::execute
<T
,1>(branch_
);
14814 inline T
value() const
14816 return Operation::process(branch_
[0].first
->value(),c_
);
14819 inline operator_type
operation() const
14821 return Operation::operation();
14824 inline const T
c() const
14829 inline void set_c(const T new_c
)
14831 (*const_cast<T
*>(&c_
)) = new_c
;
14834 inline expression_node
<T
>* branch(const std::size_t&) const
14836 return branch_
[0].first
;
14839 inline expression_node
<T
>* move_branch(const std::size_t&)
14841 branch_
[0].second
= false;
14842 return branch_
[0].first
;
14847 boc_node(const boc_node
<T
,Operation
>&);
14848 boc_node
<T
,Operation
>& operator=(const boc_node
<T
,Operation
>&);
14851 branch_t branch_
[1];
14854 #ifndef exprtk_disable_string_capabilities
14855 template <typename T
, typename SType0
, typename SType1
, typename Operation
>
14856 class sos_node
: public sos_base_node
<T
>
14860 typedef expression_node
<T
>* expression_ptr
;
14861 typedef Operation operation_t
;
14863 // string op string node
14864 explicit sos_node(SType0 p0
, SType1 p1
)
14869 inline T
value() const
14871 return Operation::process(s0_
,s1_
);
14874 inline typename expression_node
<T
>::node_type
type() const
14876 return Operation::type();
14879 inline operator_type
operation() const
14881 return Operation::operation();
14884 inline std::string
& s0()
14889 inline std::string
& s1()
14901 sos_node(sos_node
<T
,SType0
,SType1
,Operation
>&);
14902 sos_node
<T
,SType0
,SType1
,Operation
>& operator=(sos_node
<T
,SType0
,SType1
,Operation
>&);
14905 template <typename T
, typename SType0
, typename SType1
, typename RangePack
, typename Operation
>
14906 class str_xrox_node
: public sos_base_node
<T
>
14910 typedef expression_node
<T
>* expression_ptr
;
14911 typedef Operation operation_t
;
14913 // string-range op string node
14914 explicit str_xrox_node(SType0 p0
, SType1 p1
, RangePack rp0
)
14925 inline T
value() const
14927 std::size_t r0
= 0;
14928 std::size_t r1
= 0;
14930 if (rp0_(r0
, r1
, s0_
.size()))
14931 return Operation::process(s0_
.substr(r0
, (r1
- r0
) + 1), s1_
);
14936 inline typename expression_node
<T
>::node_type
type() const
14938 return Operation::type();
14941 inline operator_type
operation() const
14943 return Operation::operation();
14946 inline std::string
& s0()
14951 inline std::string
& s1()
14964 str_xrox_node(str_xrox_node
<T
,SType0
,SType1
,RangePack
,Operation
>&);
14965 str_xrox_node
<T
,SType0
,SType1
,RangePack
,Operation
>& operator=(str_xrox_node
<T
,SType0
,SType1
,RangePack
,Operation
>&);
14968 template <typename T
, typename SType0
, typename SType1
, typename RangePack
, typename Operation
>
14969 class str_xoxr_node
: public sos_base_node
<T
>
14973 typedef expression_node
<T
>* expression_ptr
;
14974 typedef Operation operation_t
;
14976 // string op string range node
14977 explicit str_xoxr_node(SType0 p0
, SType1 p1
, RangePack rp1
)
14988 inline T
value() const
14990 std::size_t r0
= 0;
14991 std::size_t r1
= 0;
14993 if (rp1_(r0
, r1
, s1_
.size()))
14994 return Operation::process(s0_
, s1_
.substr(r0
, (r1
- r0
) + 1));
14999 inline typename expression_node
<T
>::node_type
type() const
15001 return Operation::type();
15004 inline operator_type
operation() const
15006 return Operation::operation();
15009 inline std::string
& s0()
15014 inline std::string
& s1()
15027 str_xoxr_node(str_xoxr_node
<T
,SType0
,SType1
,RangePack
,Operation
>&);
15028 str_xoxr_node
<T
,SType0
,SType1
,RangePack
,Operation
>& operator=(str_xoxr_node
<T
,SType0
,SType1
,RangePack
,Operation
>&);
15031 template <typename T
, typename SType0
, typename SType1
, typename RangePack
, typename Operation
>
15032 class str_xroxr_node
: public sos_base_node
<T
>
15036 typedef expression_node
<T
>* expression_ptr
;
15037 typedef Operation operation_t
;
15039 // string-range op string-range node
15040 explicit str_xroxr_node(SType0 p0
, SType1 p1
, RangePack rp0
, RangePack rp1
)
15053 inline T
value() const
15055 std::size_t r0_0
= 0;
15056 std::size_t r0_1
= 0;
15057 std::size_t r1_0
= 0;
15058 std::size_t r1_1
= 0;
15061 rp0_(r0_0
, r1_0
, s0_
.size()) &&
15062 rp1_(r0_1
, r1_1
, s1_
.size())
15065 return Operation::process(
15066 s0_
.substr(r0_0
, (r1_0
- r0_0
) + 1),
15067 s1_
.substr(r0_1
, (r1_1
- r0_1
) + 1)
15074 inline typename expression_node
<T
>::node_type
type() const
15076 return Operation::type();
15079 inline operator_type
operation() const
15081 return Operation::operation();
15084 inline std::string
& s0()
15089 inline std::string
& s1()
15103 str_xroxr_node(str_xroxr_node
<T
,SType0
,SType1
,RangePack
,Operation
>&);
15104 str_xroxr_node
<T
,SType0
,SType1
,RangePack
,Operation
>& operator=(str_xroxr_node
<T
,SType0
,SType1
,RangePack
,Operation
>&);
15107 template <typename T
, typename Operation
>
15108 class str_sogens_node
: public binary_node
<T
>
15112 typedef expression_node
<T
>* expression_ptr
;
15113 typedef string_base_node
<T
>* str_base_ptr
;
15114 typedef range_pack
<T
> range_t
;
15115 typedef range_t
* range_ptr
;
15116 typedef range_interface
<T
> irange_t
;
15117 typedef irange_t
* irange_ptr
;
15119 str_sogens_node(const operator_type
& opr
,
15120 expression_ptr branch0
,
15121 expression_ptr branch1
)
15122 : binary_node
<T
>(opr
, branch0
, branch1
),
15123 str0_base_ptr_ (0),
15124 str1_base_ptr_ (0),
15125 str0_range_ptr_(0),
15128 if (is_generally_string_node(binary_node
<T
>::branch_
[0].first
))
15130 str0_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[0].first
);
15132 if (0 == str0_base_ptr_
)
15135 irange_ptr range
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[0].first
);
15140 str0_range_ptr_
= &(range
->range_ref());
15143 if (is_generally_string_node(binary_node
<T
>::branch_
[1].first
))
15145 str1_base_ptr_
= dynamic_cast<str_base_ptr
>(binary_node
<T
>::branch_
[1].first
);
15147 if (0 == str1_base_ptr_
)
15150 irange_ptr range
= dynamic_cast<irange_ptr
>(binary_node
<T
>::branch_
[1].first
);
15155 str1_range_ptr_
= &(range
->range_ref());
15159 inline T
value() const
15168 binary_node
<T
>::branch_
[0].first
->value();
15169 binary_node
<T
>::branch_
[1].first
->value();
15171 std::size_t str0_r0
= 0;
15172 std::size_t str0_r1
= 0;
15174 std::size_t str1_r0
= 0;
15175 std::size_t str1_r1
= 0;
15177 range_t
& range0
= (*str0_range_ptr_
);
15178 range_t
& range1
= (*str1_range_ptr_
);
15181 range0(str0_r0
, str0_r1
, str0_base_ptr_
->size()) &&
15182 range1(str1_r0
, str1_r1
, str1_base_ptr_
->size())
15185 return Operation::process(
15186 str0_base_ptr_
->str().substr(str0_r0
,(str0_r1
- str0_r0
) + 1),
15187 str1_base_ptr_
->str().substr(str1_r0
,(str1_r1
- str1_r0
) + 1)
15192 return std::numeric_limits
<T
>::quiet_NaN();
15195 inline typename expression_node
<T
>::node_type
type() const
15197 return Operation::type();
15200 inline operator_type
operation() const
15202 return Operation::operation();
15207 str_sogens_node(str_sogens_node
<T
,Operation
>&);
15208 str_sogens_node
<T
,Operation
>& operator=(str_sogens_node
<T
,Operation
>&);
15210 str_base_ptr str0_base_ptr_
;
15211 str_base_ptr str1_base_ptr_
;
15212 range_ptr str0_range_ptr_
;
15213 range_ptr str1_range_ptr_
;
15216 template <typename T
, typename SType0
, typename SType1
, typename SType2
, typename Operation
>
15217 class sosos_node
: public sosos_base_node
<T
>
15221 typedef expression_node
<T
>* expression_ptr
;
15222 typedef Operation operation_t
;
15224 // variable op variable node
15225 explicit sosos_node(SType0 p0
, SType1 p1
, SType2 p2
)
15231 inline T
value() const
15233 return Operation::process(s0_
,s1_
,s2_
);
15236 inline typename expression_node
<T
>::node_type
type() const
15238 return Operation::type();
15241 inline operator_type
operation() const
15243 return Operation::operation();
15246 inline std::string
& s0()
15251 inline std::string
& s1()
15256 inline std::string
& s2()
15269 sosos_node(sosos_node
<T
,SType0
,SType1
,SType2
,Operation
>&);
15270 sosos_node
<T
,SType0
,SType1
,SType2
,Operation
>& operator=(sosos_node
<T
,SType0
,SType1
,SType2
,Operation
>&);
15274 template <typename T
, typename PowOp
>
15275 class ipow_node
: public expression_node
<T
>
15279 typedef expression_node
<T
>* expression_ptr
;
15280 typedef PowOp operation_t
;
15282 explicit ipow_node(const T
& v
)
15286 inline T
value() const
15288 return PowOp::result(v_
);
15291 inline typename expression_node
<T
>::node_type
type() const
15293 return expression_node
<T
>::e_ipow
;
15298 ipow_node(const ipow_node
<T
,PowOp
>&);
15299 ipow_node
<T
,PowOp
>& operator=(const ipow_node
<T
,PowOp
>&);
15304 template <typename T
, typename PowOp
>
15305 class bipow_node
: public expression_node
<T
>
15309 typedef expression_node
<T
>* expression_ptr
;
15310 typedef std::pair
<expression_ptr
, bool> branch_t
;
15311 typedef PowOp operation_t
;
15313 explicit bipow_node(expression_ptr brnch
)
15315 init_branches
<1>(branch_
, brnch
);
15320 cleanup_branches::execute
<T
,1>(branch_
);
15323 inline T
value() const
15325 return PowOp::result(branch_
[0].first
->value());
15328 inline typename expression_node
<T
>::node_type
type() const
15330 return expression_node
<T
>::e_ipow
;
15335 bipow_node(const bipow_node
<T
,PowOp
>&);
15336 bipow_node
<T
,PowOp
>& operator=(const bipow_node
<T
,PowOp
>&);
15338 branch_t branch_
[1];
15341 template <typename T
, typename PowOp
>
15342 class ipowinv_node
: public expression_node
<T
>
15346 typedef expression_node
<T
>* expression_ptr
;
15347 typedef PowOp operation_t
;
15349 explicit ipowinv_node(const T
& v
)
15353 inline T
value() const
15355 return (T(1) / PowOp::result(v_
));
15358 inline typename expression_node
<T
>::node_type
type() const
15360 return expression_node
<T
>::e_ipowinv
;
15365 ipowinv_node(const ipowinv_node
<T
,PowOp
>&);
15366 ipowinv_node
<T
,PowOp
>& operator=(const ipowinv_node
<T
,PowOp
>&);
15371 template <typename T
, typename PowOp
>
15372 class bipowninv_node
: public expression_node
<T
>
15376 typedef expression_node
<T
>* expression_ptr
;
15377 typedef std::pair
<expression_ptr
, bool> branch_t
;
15378 typedef PowOp operation_t
;
15380 explicit bipowninv_node(expression_ptr brnch
)
15382 init_branches
<1>(branch_
, brnch
);
15387 cleanup_branches::execute
<T
,1>(branch_
);
15390 inline T
value() const
15392 return (T(1) / PowOp::result(branch_
[0].first
->value()));
15395 inline typename expression_node
<T
>::node_type
type() const
15397 return expression_node
<T
>::e_ipowinv
;
15402 bipowninv_node(const bipowninv_node
<T
,PowOp
>&);
15403 bipowninv_node
<T
,PowOp
>& operator=(const bipowninv_node
<T
,PowOp
>&);
15405 branch_t branch_
[1];
15408 template <typename T
>
15409 inline bool is_vov_node(const expression_node
<T
>* node
)
15411 return (0 != dynamic_cast<const vov_base_node
<T
>*>(node
));
15414 template <typename T
>
15415 inline bool is_cov_node(const expression_node
<T
>* node
)
15417 return (0 != dynamic_cast<const cov_base_node
<T
>*>(node
));
15420 template <typename T
>
15421 inline bool is_voc_node(const expression_node
<T
>* node
)
15423 return (0 != dynamic_cast<const voc_base_node
<T
>*>(node
));
15426 template <typename T
>
15427 inline bool is_cob_node(const expression_node
<T
>* node
)
15429 return (0 != dynamic_cast<const cob_base_node
<T
>*>(node
));
15432 template <typename T
>
15433 inline bool is_boc_node(const expression_node
<T
>* node
)
15435 return (0 != dynamic_cast<const boc_base_node
<T
>*>(node
));
15438 template <typename T
>
15439 inline bool is_t0ot1ot2_node(const expression_node
<T
>* node
)
15441 return (0 != dynamic_cast<const T0oT1oT2_base_node
<T
>*>(node
));
15444 template <typename T
>
15445 inline bool is_t0ot1ot2ot3_node(const expression_node
<T
>* node
)
15447 return (0 != dynamic_cast<const T0oT1oT2oT3_base_node
<T
>*>(node
));
15450 template <typename T
>
15451 inline bool is_uv_node(const expression_node
<T
>* node
)
15453 return (0 != dynamic_cast<const uv_base_node
<T
>*>(node
));
15456 template <typename T
>
15457 inline bool is_string_node(const expression_node
<T
>* node
)
15459 return node
&& (expression_node
<T
>::e_stringvar
== node
->type());
15462 template <typename T
>
15463 inline bool is_string_range_node(const expression_node
<T
>* node
)
15465 return node
&& (expression_node
<T
>::e_stringvarrng
== node
->type());
15468 template <typename T
>
15469 inline bool is_const_string_node(const expression_node
<T
>* node
)
15471 return node
&& (expression_node
<T
>::e_stringconst
== node
->type());
15474 template <typename T
>
15475 inline bool is_const_string_range_node(const expression_node
<T
>* node
)
15477 return node
&& (expression_node
<T
>::e_cstringvarrng
== node
->type());
15480 template <typename T
>
15481 inline bool is_string_assignment_node(const expression_node
<T
>* node
)
15483 return node
&& (expression_node
<T
>::e_strass
== node
->type());
15486 template <typename T
>
15487 inline bool is_string_concat_node(const expression_node
<T
>* node
)
15489 return node
&& (expression_node
<T
>::e_strconcat
== node
->type());
15492 template <typename T
>
15493 inline bool is_string_function_node(const expression_node
<T
>* node
)
15495 return node
&& (expression_node
<T
>::e_strfunction
== node
->type());
15498 template <typename T
>
15499 inline bool is_string_condition_node(const expression_node
<T
>* node
)
15501 return node
&& (expression_node
<T
>::e_strcondition
== node
->type());
15504 template <typename T
>
15505 inline bool is_string_ccondition_node(const expression_node
<T
>* node
)
15507 return node
&& (expression_node
<T
>::e_strccondition
== node
->type());
15510 template <typename T
>
15511 inline bool is_string_vararg_node(const expression_node
<T
>* node
)
15513 return node
&& (expression_node
<T
>::e_stringvararg
== node
->type());
15516 template <typename T
>
15517 inline bool is_genricstring_range_node(const expression_node
<T
>* node
)
15519 return node
&& (expression_node
<T
>::e_strgenrange
== node
->type());
15522 template <typename T
>
15523 inline bool is_generally_string_node(const expression_node
<T
>* node
)
15527 switch (node
->type())
15529 case expression_node
<T
>::e_stringvar
:
15530 case expression_node
<T
>::e_stringconst
:
15531 case expression_node
<T
>::e_stringvarrng
:
15532 case expression_node
<T
>::e_cstringvarrng
:
15533 case expression_node
<T
>::e_strgenrange
:
15534 case expression_node
<T
>::e_strass
:
15535 case expression_node
<T
>::e_strconcat
:
15536 case expression_node
<T
>::e_strfunction
:
15537 case expression_node
<T
>::e_strcondition
:
15538 case expression_node
<T
>::e_strccondition
:
15539 case expression_node
<T
>::e_stringvararg
: return true;
15540 default : return false;
15547 class node_allocator
15551 template <typename ResultNode
, typename OpType
, typename ExprNode
>
15552 inline expression_node
<typename
ResultNode::value_type
>* allocate(OpType
& operation
, ExprNode (&branch
)[1])
15554 return allocate
<ResultNode
>(operation
, branch
[0]);
15557 template <typename ResultNode
, typename OpType
, typename ExprNode
>
15558 inline expression_node
<typename
ResultNode::value_type
>* allocate(OpType
& operation
, ExprNode (&branch
)[2])
15560 return allocate
<ResultNode
>(operation
, branch
[0], branch
[1]);
15563 template <typename ResultNode
, typename OpType
, typename ExprNode
>
15564 inline expression_node
<typename
ResultNode::value_type
>* allocate(OpType
& operation
, ExprNode (&branch
)[3])
15566 return allocate
<ResultNode
>(operation
, branch
[0], branch
[1], branch
[2]);
15569 template <typename ResultNode
, typename OpType
, typename ExprNode
>
15570 inline expression_node
<typename
ResultNode::value_type
>* allocate(OpType
& operation
, ExprNode (&branch
)[4])
15572 return allocate
<ResultNode
>(operation
, branch
[0], branch
[1], branch
[2], branch
[3]);
15575 template <typename ResultNode
, typename OpType
, typename ExprNode
>
15576 inline expression_node
<typename
ResultNode::value_type
>* allocate(OpType
& operation
, ExprNode (&branch
)[5])
15578 return allocate
<ResultNode
>(operation
, branch
[0],branch
[1], branch
[2], branch
[3], branch
[4]);
15581 template <typename ResultNode
, typename OpType
, typename ExprNode
>
15582 inline expression_node
<typename
ResultNode::value_type
>* allocate(OpType
& operation
, ExprNode (&branch
)[6])
15584 return allocate
<ResultNode
>(operation
, branch
[0], branch
[1], branch
[2], branch
[3], branch
[4], branch
[5]);
15587 template <typename node_type
>
15588 inline expression_node
<typename
node_type::value_type
>* allocate() const
15590 return (new node_type());
15593 template <typename node_type
,
15595 typename Allocator
,
15596 template <typename
, typename
> class Sequence
>
15597 inline expression_node
<typename
node_type::value_type
>* allocate(const Sequence
<Type
,Allocator
>& seq
) const
15599 return (new node_type(seq
));
15602 template <typename node_type
, typename T1
>
15603 inline expression_node
<typename
node_type::value_type
>* allocate(T1
& t1
) const
15605 return (new node_type(t1
));
15608 template <typename node_type
, typename T1
>
15609 inline expression_node
<typename
node_type::value_type
>* allocate_c(const T1
& t1
) const
15611 return (new node_type(t1
));
15614 template <typename node_type
,
15615 typename T1
, typename T2
>
15616 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
) const
15618 return (new node_type(t1
, t2
));
15621 template <typename node_type
,
15622 typename T1
, typename T2
>
15623 inline expression_node
<typename
node_type::value_type
>* allocate_cr(const T1
& t1
, T2
& t2
) const
15625 return (new node_type(t1
, t2
));
15628 template <typename node_type
,
15629 typename T1
, typename T2
>
15630 inline expression_node
<typename
node_type::value_type
>* allocate_rc(T1
& t1
, const T2
& t2
) const
15632 return (new node_type(t1
, t2
));
15635 template <typename node_type
,
15636 typename T1
, typename T2
>
15637 inline expression_node
<typename
node_type::value_type
>* allocate_rr(T1
& t1
, T2
& t2
) const
15639 return (new node_type(t1
, t2
));
15642 template <typename node_type
,
15643 typename T1
, typename T2
>
15644 inline expression_node
<typename
node_type::value_type
>* allocate_tt(T1 t1
, T2 t2
) const
15646 return (new node_type(t1
, t2
));
15649 template <typename node_type
,
15650 typename T1
, typename T2
, typename T3
>
15651 inline expression_node
<typename
node_type::value_type
>* allocate_ttt(T1 t1
, T2 t2
, T3 t3
) const
15653 return (new node_type(t1
, t2
, t3
));
15656 template <typename node_type
,
15657 typename T1
, typename T2
, typename T3
, typename T4
>
15658 inline expression_node
<typename
node_type::value_type
>* allocate_tttt(T1 t1
, T2 t2
, T3 t3
, T4 t4
) const
15660 return (new node_type(t1
, t2
, t3
, t4
));
15663 template <typename node_type
,
15664 typename T1
, typename T2
, typename T3
>
15665 inline expression_node
<typename
node_type::value_type
>* allocate_rrr(T1
& t1
, T2
& t2
, T3
& t3
) const
15667 return (new node_type(t1
, t2
, t3
));
15670 template <typename node_type
,
15671 typename T1
, typename T2
, typename T3
, typename T4
>
15672 inline expression_node
<typename
node_type::value_type
>* allocate_rrrr(T1
& t1
, T2
& t2
, T3
& t3
, T4
& t4
) const
15674 return (new node_type(t1
, t2
, t3
, t4
));
15677 template <typename node_type
,
15678 typename T1
, typename T2
, typename T3
, typename T4
, typename T5
>
15679 inline expression_node
<typename
node_type::value_type
>* allocate_rrrrr(T1
& t1
, T2
& t2
, T3
& t3
, T4
& t4
, T5
& t5
) const
15681 return (new node_type(t1
, t2
, t3
, t4
, t5
));
15684 template <typename node_type
,
15685 typename T1
, typename T2
, typename T3
>
15686 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15687 const T3
& t3
) const
15689 return (new node_type(t1
, t2
, t3
));
15692 template <typename node_type
,
15693 typename T1
, typename T2
,
15694 typename T3
, typename T4
>
15695 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15696 const T3
& t3
, const T4
& t4
) const
15698 return (new node_type(t1
, t2
, t3
, t4
));
15701 template <typename node_type
,
15702 typename T1
, typename T2
,
15703 typename T3
, typename T4
, typename T5
>
15704 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15705 const T3
& t3
, const T4
& t4
,
15706 const T5
& t5
) const
15708 return (new node_type(t1
, t2
, t3
, t4
, t5
));
15711 template <typename node_type
,
15712 typename T1
, typename T2
,
15713 typename T3
, typename T4
, typename T5
, typename T6
>
15714 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15715 const T3
& t3
, const T4
& t4
,
15716 const T5
& t5
, const T6
& t6
) const
15718 return (new node_type(t1
, t2
, t3
, t4
, t5
, t6
));
15721 template <typename node_type
,
15722 typename T1
, typename T2
,
15723 typename T3
, typename T4
,
15724 typename T5
, typename T6
, typename T7
>
15725 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15726 const T3
& t3
, const T4
& t4
,
15727 const T5
& t5
, const T6
& t6
,
15728 const T7
& t7
) const
15730 return (new node_type(t1
, t2
, t3
, t4
, t5
, t6
, t7
));
15733 template <typename node_type
,
15734 typename T1
, typename T2
,
15735 typename T3
, typename T4
,
15736 typename T5
, typename T6
,
15737 typename T7
, typename T8
>
15738 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15739 const T3
& t3
, const T4
& t4
,
15740 const T5
& t5
, const T6
& t6
,
15741 const T7
& t7
, const T8
& t8
) const
15743 return (new node_type(t1
, t2
, t3
, t4
, t5
, t6
, t7
, t8
));
15746 template <typename node_type
,
15747 typename T1
, typename T2
,
15748 typename T3
, typename T4
,
15749 typename T5
, typename T6
,
15750 typename T7
, typename T8
, typename T9
>
15751 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15752 const T3
& t3
, const T4
& t4
,
15753 const T5
& t5
, const T6
& t6
,
15754 const T7
& t7
, const T8
& t8
,
15755 const T9
& t9
) const
15757 return (new node_type(t1
, t2
, t3
, t4
, t5
, t6
, t7
, t8
, t9
));
15760 template <typename node_type
,
15761 typename T1
, typename T2
,
15762 typename T3
, typename T4
,
15763 typename T5
, typename T6
,
15764 typename T7
, typename T8
,
15765 typename T9
, typename T10
>
15766 inline expression_node
<typename
node_type::value_type
>* allocate(const T1
& t1
, const T2
& t2
,
15767 const T3
& t3
, const T4
& t4
,
15768 const T5
& t5
, const T6
& t6
,
15769 const T7
& t7
, const T8
& t8
,
15770 const T9
& t9
, const T10
& t10
) const
15772 return (new node_type(t1
, t2
, t3
, t4
, t5
, t6
, t7
, t8
, t9
, t10
));
15775 template <typename node_type
,
15776 typename T1
, typename T2
, typename T3
>
15777 inline expression_node
<typename
node_type::value_type
>* allocate_type(T1 t1
, T2 t2
, T3 t3
) const
15779 return (new node_type(t1
, t2
, t3
));
15782 template <typename node_type
,
15783 typename T1
, typename T2
,
15784 typename T3
, typename T4
>
15785 inline expression_node
<typename
node_type::value_type
>* allocate_type(T1 t1
, T2 t2
,
15786 T3 t3
, T4 t4
) const
15788 return (new node_type(t1
, t2
, t3
, t4
));
15791 template <typename node_type
,
15792 typename T1
, typename T2
,
15793 typename T3
, typename T4
,
15795 inline expression_node
<typename
node_type::value_type
>* allocate_type(T1 t1
, T2 t2
,
15799 return (new node_type(t1
, t2
, t3
, t4
, t5
));
15802 template <typename node_type
,
15803 typename T1
, typename T2
,
15804 typename T3
, typename T4
,
15805 typename T5
, typename T6
>
15806 inline expression_node
<typename
node_type::value_type
>* allocate_type(T1 t1
, T2 t2
,
15808 T5 t5
, T6 t6
) const
15810 return (new node_type(t1
, t2
, t3
, t4
, t5
, t6
));
15813 template <typename node_type
,
15814 typename T1
, typename T2
,
15815 typename T3
, typename T4
,
15816 typename T5
, typename T6
, typename T7
>
15817 inline expression_node
<typename
node_type::value_type
>* allocate_type(T1 t1
, T2 t2
,
15822 return (new node_type(t1
, t2
, t3
, t4
, t5
, t6
, t7
));
15825 template <typename T
>
15826 void inline free(expression_node
<T
>*& e
) const
15833 inline void load_operations_map(std::multimap
<std::string
,details::base_operation_t
,details::ilesscompare
>& m
)
15835 #define register_op(Symbol,Type,Args) \
15836 m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
15838 register_op( "abs", e_abs , 1)
15839 register_op( "acos", e_acos
, 1)
15840 register_op( "acosh", e_acosh
, 1)
15841 register_op( "asin", e_asin
, 1)
15842 register_op( "asinh", e_asinh
, 1)
15843 register_op( "atan", e_atan
, 1)
15844 register_op( "atanh", e_atanh
, 1)
15845 register_op( "ceil", e_ceil
, 1)
15846 register_op( "cos", e_cos
, 1)
15847 register_op( "cosh", e_cosh
, 1)
15848 register_op( "exp", e_exp
, 1)
15849 register_op( "expm1", e_expm1
, 1)
15850 register_op( "floor", e_floor
, 1)
15851 register_op( "log", e_log
, 1)
15852 register_op( "log10", e_log10
, 1)
15853 register_op( "log2", e_log2
, 1)
15854 register_op( "log1p", e_log1p
, 1)
15855 register_op( "round", e_round
, 1)
15856 register_op( "sin", e_sin
, 1)
15857 register_op( "sinc", e_sinc
, 1)
15858 register_op( "sinh", e_sinh
, 1)
15859 register_op( "sec", e_sec
, 1)
15860 register_op( "csc", e_csc
, 1)
15861 register_op( "sqrt", e_sqrt
, 1)
15862 register_op( "tan", e_tan
, 1)
15863 register_op( "tanh", e_tanh
, 1)
15864 register_op( "cot", e_cot
, 1)
15865 register_op( "rad2deg", e_r2d
, 1)
15866 register_op( "deg2rad", e_d2r
, 1)
15867 register_op( "deg2grad", e_d2g
, 1)
15868 register_op( "grad2deg", e_g2d
, 1)
15869 register_op( "sgn", e_sgn
, 1)
15870 register_op( "not", e_notl
, 1)
15871 register_op( "erf", e_erf
, 1)
15872 register_op( "erfc", e_erfc
, 1)
15873 register_op( "ncdf", e_ncdf
, 1)
15874 register_op( "frac", e_frac
, 1)
15875 register_op( "trunc", e_trunc
, 1)
15876 register_op( "atan2", e_atan2
, 2)
15877 register_op( "mod", e_mod
, 2)
15878 register_op( "logn", e_logn
, 2)
15879 register_op( "pow", e_pow
, 2)
15880 register_op( "root", e_root
, 2)
15881 register_op( "roundn", e_roundn
, 2)
15882 register_op( "equal", e_equal
, 2)
15883 register_op("not_equal", e_nequal
, 2)
15884 register_op( "hypot", e_hypot
, 2)
15885 register_op( "shr", e_shr
, 2)
15886 register_op( "shl", e_shl
, 2)
15887 register_op( "clamp", e_clamp
, 3)
15888 register_op( "iclamp", e_iclamp
, 3)
15889 register_op( "inrange", e_inrange
, 3)
15893 } // namespace details
15895 class function_traits
15900 : allow_zero_parameters_(false),
15901 has_side_effects_(true),
15903 max_num_args_(std::numeric_limits
<std::size_t>::max())
15906 inline bool& allow_zero_parameters()
15908 return allow_zero_parameters_
;
15911 inline bool& has_side_effects()
15913 return has_side_effects_
;
15916 std::size_t& min_num_args()
15918 return min_num_args_
;
15921 std::size_t& max_num_args()
15923 return max_num_args_
;
15928 bool allow_zero_parameters_
;
15929 bool has_side_effects_
;
15930 std::size_t min_num_args_
;
15931 std::size_t max_num_args_
;
15934 template <typename FunctionType
>
15935 void enable_zero_parameters(FunctionType
& func
)
15937 func
.allow_zero_parameters() = true;
15939 if (0 != func
.min_num_args())
15941 func
.min_num_args() = 0;
15945 template <typename FunctionType
>
15946 void disable_zero_parameters(FunctionType
& func
)
15948 func
.allow_zero_parameters() = false;
15951 template <typename FunctionType
>
15952 void enable_has_side_effects(FunctionType
& func
)
15954 func
.has_side_effects() = true;
15957 template <typename FunctionType
>
15958 void disable_has_side_effects(FunctionType
& func
)
15960 func
.has_side_effects() = false;
15963 template <typename FunctionType
>
15964 void set_min_num_args(FunctionType
& func
, const std::size_t& num_args
)
15966 func
.min_num_args() = num_args
;
15968 if ((0 != func
.min_num_args()) && func
.allow_zero_parameters())
15969 func
.allow_zero_parameters() = false;
15972 template <typename FunctionType
>
15973 void set_max_num_args(FunctionType
& func
, const std::size_t& num_args
)
15975 func
.max_num_args() = num_args
;
15978 template <typename T
>
15979 class ifunction
: public function_traits
15983 explicit ifunction(const std::size_t& pc
)
15987 virtual ~ifunction()
15990 #define empty_method_body \
15992 return std::numeric_limits<T>::quiet_NaN(); \
15995 inline virtual T operator() ()
15998 inline virtual T
operator() (const T
&)
16001 inline virtual T
operator() (const T
&,const T
&)
16004 inline virtual T
operator() (const T
&, const T
&, const T
&)
16007 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&)
16010 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&)
16013 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16016 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16019 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16022 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16025 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16028 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16032 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16033 const T
&, const T
&)
16036 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16037 const T
&, const T
&, const T
&)
16040 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16041 const T
&, const T
&, const T
&, const T
&)
16044 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16045 const T
&, const T
&, const T
&, const T
&, const T
&)
16048 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16049 const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16052 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16053 const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16056 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16057 const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16060 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16061 const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16064 inline virtual T
operator() (const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&,
16065 const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&, const T
&)
16068 #undef empty_method_body
16070 std::size_t param_count
;
16073 template <typename T
>
16074 class ivararg_function
: public function_traits
16078 virtual ~ivararg_function()
16081 inline virtual T
operator() (const std::vector
<T
>&)
16083 exprtk_debug(("ivararg_function::operator() - Operator has not been overridden.\n"));
16084 return std::numeric_limits
<T
>::quiet_NaN();
16088 template <typename T
>
16089 class igeneric_function
: public function_traits
16097 e_rtrn_overload
= 2
16101 typedef type_store
<T
> generic_type
;
16102 typedef typename
generic_type::parameter_list parameter_list_t
;
16104 igeneric_function(const std::string
& param_seq
= "", const return_type rtr_type
= e_rtrn_scalar
)
16105 : parameter_sequence(param_seq
),
16106 rtrn_type(rtr_type
)
16109 virtual ~igeneric_function()
16112 #define igeneric_function_empty_body(N) \
16114 exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. ["#N"]\n")); \
16115 return std::numeric_limits<T>::quiet_NaN(); \
16118 // f(i_0,i_1,....,i_N) --> Scalar
16119 inline virtual T
operator() (parameter_list_t
)
16120 igeneric_function_empty_body(1)
16122 // f(i_0,i_1,....,i_N) --> String
16123 inline virtual T
operator() (std::string
&, parameter_list_t
)
16124 igeneric_function_empty_body(2)
16126 // f(psi,i_0,i_1,....,i_N) --> Scalar
16127 inline virtual T
operator() (const std::size_t&, parameter_list_t
)
16128 igeneric_function_empty_body(3)
16130 // f(psi,i_0,i_1,....,i_N) --> String
16131 inline virtual T
operator() (const std::size_t&, std::string
&, parameter_list_t
)
16132 igeneric_function_empty_body(4)
16134 std::string parameter_sequence
;
16135 return_type rtrn_type
;
16138 template <typename T
> class parser
;
16139 template <typename T
> class expression_helper
;
16141 template <typename T
>
16146 typedef T (*ff00_functor
)();
16147 typedef T (*ff01_functor
)(T
);
16148 typedef T (*ff02_functor
)(T
, T
);
16149 typedef T (*ff03_functor
)(T
, T
, T
);
16150 typedef T (*ff04_functor
)(T
, T
, T
, T
);
16151 typedef T (*ff05_functor
)(T
, T
, T
, T
, T
);
16152 typedef T (*ff06_functor
)(T
, T
, T
, T
, T
, T
);
16153 typedef T (*ff07_functor
)(T
, T
, T
, T
, T
, T
, T
);
16154 typedef T (*ff08_functor
)(T
, T
, T
, T
, T
, T
, T
, T
);
16155 typedef T (*ff09_functor
)(T
, T
, T
, T
, T
, T
, T
, T
, T
);
16156 typedef T (*ff10_functor
)(T
, T
, T
, T
, T
, T
, T
, T
, T
, T
);
16157 typedef T (*ff11_functor
)(T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
);
16158 typedef T (*ff12_functor
)(T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
);
16159 typedef T (*ff13_functor
)(T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
);
16160 typedef T (*ff14_functor
)(T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
);
16161 typedef T (*ff15_functor
)(T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
, T
);
16165 struct freefunc00
: public exprtk::ifunction
<T
>
16167 using exprtk::ifunction
<T
>::operator();
16169 explicit freefunc00(ff00_functor ff
) : exprtk::ifunction
<T
>(0), f(ff
) {}
16170 inline T
operator() ()
16175 struct freefunc01
: public exprtk::ifunction
<T
>
16177 using exprtk::ifunction
<T
>::operator();
16179 explicit freefunc01(ff01_functor ff
) : exprtk::ifunction
<T
>(1), f(ff
) {}
16180 inline T
operator() (const T
& v0
)
16185 struct freefunc02
: public exprtk::ifunction
<T
>
16187 using exprtk::ifunction
<T
>::operator();
16189 explicit freefunc02(ff02_functor ff
) : exprtk::ifunction
<T
>(2), f(ff
) {}
16190 inline T
operator() (const T
& v0
, const T
& v1
)
16191 { return f(v0
, v1
); }
16195 struct freefunc03
: public exprtk::ifunction
<T
>
16197 using exprtk::ifunction
<T
>::operator();
16199 explicit freefunc03(ff03_functor ff
) : exprtk::ifunction
<T
>(3), f(ff
) {}
16200 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
)
16201 { return f(v0
, v1
, v2
); }
16205 struct freefunc04
: public exprtk::ifunction
<T
>
16207 using exprtk::ifunction
<T
>::operator();
16209 explicit freefunc04(ff04_functor ff
) : exprtk::ifunction
<T
>(4), f(ff
) {}
16210 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
)
16211 { return f(v0
, v1
, v2
, v3
); }
16215 struct freefunc05
: public exprtk::ifunction
<T
>
16217 using exprtk::ifunction
<T
>::operator();
16219 explicit freefunc05(ff05_functor ff
) : exprtk::ifunction
<T
>(5), f(ff
) {}
16220 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
)
16221 { return f(v0
, v1
, v2
, v3
, v4
); }
16225 struct freefunc06
: public exprtk::ifunction
<T
>
16227 using exprtk::ifunction
<T
>::operator();
16229 explicit freefunc06(ff06_functor ff
) : exprtk::ifunction
<T
>(6), f(ff
) {}
16230 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
, const T
& v5
)
16231 { return f(v0
, v1
, v2
, v3
, v4
, v5
); }
16235 struct freefunc07
: public exprtk::ifunction
<T
>
16237 using exprtk::ifunction
<T
>::operator();
16239 explicit freefunc07(ff07_functor ff
) : exprtk::ifunction
<T
>(7), f(ff
) {}
16240 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
,
16241 const T
& v5
, const T
& v6
)
16242 { return f(v0
, v1
, v2
, v3
, v4
, v5
, v6
); }
16246 struct freefunc08
: public exprtk::ifunction
<T
>
16248 using exprtk::ifunction
<T
>::operator();
16250 explicit freefunc08(ff08_functor ff
) : exprtk::ifunction
<T
>(8), f(ff
) {}
16251 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
,
16252 const T
& v5
, const T
& v6
, const T
& v7
)
16253 { return f(v0
, v1
, v2
, v3
, v4
, v5
, v6
, v7
); }
16257 struct freefunc09
: public exprtk::ifunction
<T
>
16259 using exprtk::ifunction
<T
>::operator();
16261 explicit freefunc09(ff09_functor ff
) : exprtk::ifunction
<T
>(9), f(ff
) {}
16262 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
,
16263 const T
& v5
, const T
& v6
, const T
& v7
, const T
& v8
)
16264 { return f(v0
, v1
, v2
, v3
, v4
, v5
, v6
, v7
, v8
); }
16268 struct freefunc10
: public exprtk::ifunction
<T
>
16270 using exprtk::ifunction
<T
>::operator();
16272 explicit freefunc10(ff10_functor ff
) : exprtk::ifunction
<T
>(10), f(ff
) {}
16273 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
,
16274 const T
& v5
, const T
& v6
, const T
& v7
, const T
& v8
, const T
& v9
)
16275 { return f(v0
, v1
, v2
, v3
, v4
, v5
, v6
, v7
, v8
, v9
); }
16279 struct freefunc11
: public exprtk::ifunction
<T
>
16281 using exprtk::ifunction
<T
>::operator();
16283 explicit freefunc11(ff11_functor ff
) : exprtk::ifunction
<T
>(11), f(ff
) {}
16284 inline T
operator() (const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
,
16285 const T
& v5
, const T
& v6
, const T
& v7
, const T
& v8
, const T
& v9
, const T
& v10
)
16286 { return f(v0
, v1
, v2
, v3
, v4
, v5
, v6
, v7
, v8
, v9
, v10
); }
16290 struct freefunc12
: public exprtk::ifunction
<T
>
16292 using exprtk::ifunction
<T
>::operator();
16294 explicit freefunc12(ff12_functor ff
) : exprtk::ifunction
<T
>(12), f(ff
) {}
16295 inline T
operator() (const T
& v00
, const T
& v01
, const T
& v02
, const T
& v03
, const T
& v04
,
16296 const T
& v05
, const T
& v06
, const T
& v07
, const T
& v08
, const T
& v09
,
16297 const T
& v10
, const T
& v11
)
16298 { return f(v00
, v01
, v02
, v03
, v04
, v05
, v06
, v07
, v08
, v09
, v10
, v11
); }
16302 struct freefunc13
: public exprtk::ifunction
<T
>
16304 using exprtk::ifunction
<T
>::operator();
16306 explicit freefunc13(ff13_functor ff
) : exprtk::ifunction
<T
>(13), f(ff
) {}
16307 inline T
operator() (const T
& v00
, const T
& v01
, const T
& v02
, const T
& v03
, const T
& v04
,
16308 const T
& v05
, const T
& v06
, const T
& v07
, const T
& v08
, const T
& v09
,
16309 const T
& v10
, const T
& v11
, const T
& v12
)
16310 { return f(v00
, v01
, v02
, v03
, v04
, v05
, v06
, v07
, v08
, v09
, v10
, v11
, v12
); }
16314 struct freefunc14
: public exprtk::ifunction
<T
>
16316 using exprtk::ifunction
<T
>::operator();
16318 explicit freefunc14(ff14_functor ff
) : exprtk::ifunction
<T
>(14), f(ff
) {}
16319 inline T
operator() (const T
& v00
, const T
& v01
, const T
& v02
, const T
& v03
, const T
& v04
,
16320 const T
& v05
, const T
& v06
, const T
& v07
, const T
& v08
, const T
& v09
,
16321 const T
& v10
, const T
& v11
, const T
& v12
, const T
& v13
)
16322 { return f(v00
, v01
, v02
, v03
, v04
, v05
, v06
, v07
, v08
, v09
, v10
, v11
, v12
, v13
); }
16326 struct freefunc15
: public exprtk::ifunction
<T
>
16328 using exprtk::ifunction
<T
>::operator();
16330 explicit freefunc15(ff15_functor ff
) : exprtk::ifunction
<T
>(15), f(ff
) {}
16331 inline T
operator() (const T
& v00
, const T
& v01
, const T
& v02
, const T
& v03
, const T
& v04
,
16332 const T
& v05
, const T
& v06
, const T
& v07
, const T
& v08
, const T
& v09
,
16333 const T
& v10
, const T
& v11
, const T
& v12
, const T
& v13
, const T
& v14
)
16334 { return f(v00
, v01
, v02
, v03
, v04
, v05
, v06
, v07
, v08
, v09
, v10
, v11
, v12
, v13
, v14
); }
16338 template <typename Type
, typename RawType
>
16341 typedef details::expression_node
<T
>* expression_ptr
;
16342 typedef typename
details::variable_node
<T
> variable_node_t
;
16343 typedef ifunction
<T
> ifunction_t
;
16344 typedef ivararg_function
<T
> ivararg_function_t
;
16345 typedef igeneric_function
<T
> igeneric_function_t
;
16346 typedef details::vector_holder
<T
> vector_t
;
16347 #ifndef exprtk_disable_string_capabilities
16348 typedef typename
details::stringvar_node
<T
> stringvar_node_t
;
16351 typedef Type type_t
;
16352 typedef type_t
* type_ptr
;
16353 typedef std::pair
<bool,type_ptr
> type_pair_t
;
16354 typedef std::map
<std::string
,type_pair_t
,details::ilesscompare
> type_map_t
;
16355 typedef typename
type_map_t::iterator tm_itr_t
;
16356 typedef typename
type_map_t::const_iterator tm_const_itr_t
;
16358 enum { lut_size
= 256 };
16367 inline bool symbol_exists(const std::string
& symbol_name
) const
16369 if (symbol_name
.empty())
16371 else if (map
.end() != map
.find(symbol_name
))
16377 template <typename PtrType
>
16378 inline std::string
entity_name(const PtrType
& ptr
) const
16381 return std::string();
16383 tm_const_itr_t itr
= map
.begin();
16385 while (map
.end() != itr
)
16387 if (itr
->second
.second
== ptr
)
16395 return std::string();
16398 inline bool is_constant(const std::string
& symbol_name
) const
16400 if (symbol_name
.empty())
16404 const tm_const_itr_t itr
= map
.find(symbol_name
);
16406 if (map
.end() == itr
)
16409 return (*itr
).second
.first
;
16413 template <typename Tie
, typename RType
>
16414 inline bool add_impl(const std::string
& symbol_name
, RType t
, const bool is_const
)
16416 if (symbol_name
.size() > 1)
16418 for (std::size_t i
= 0; i
< details::reserved_symbols_size
; ++i
)
16420 if (details::imatch(symbol_name
, details::reserved_symbols
[i
]))
16427 const tm_itr_t itr
= map
.find(symbol_name
);
16429 if (map
.end() == itr
)
16431 map
[symbol_name
] = Tie::make(t
,is_const
);
16440 static inline std::pair
<bool,vector_t
*> make(std::pair
<T
*,std::size_t> v
, const bool is_const
= false)
16442 return std::make_pair(is_const
, new vector_t(v
.first
, v
.second
));
16448 template <typename Allocator
>
16449 static inline std::pair
<bool,vector_t
*> make(std::vector
<T
,Allocator
>& v
, const bool is_const
= false)
16451 return std::make_pair(is_const
, new vector_t(v
));
16457 static inline std::pair
<bool,vector_t
*> make(exprtk::vector_view
<T
>& v
, const bool is_const
= false)
16459 return std::make_pair(is_const
, new vector_t(v
));
16465 template <typename Allocator
>
16466 static inline std::pair
<bool,vector_t
*> make(std::deque
<T
,Allocator
>& v
, const bool is_const
= false)
16468 return std::make_pair(is_const
, new vector_t(v
));
16472 template <std::size_t v_size
>
16473 inline bool add(const std::string
& symbol_name
, T (&v
)[v_size
], const bool is_const
= false)
16475 return add_impl
<tie_array
,std::pair
<T
*,std::size_t> >
16476 (symbol_name
, std::make_pair(v
,v_size
), is_const
);
16479 inline bool add(const std::string
& symbol_name
, T
* v
, const std::size_t v_size
, const bool is_const
= false)
16481 return add_impl
<tie_array
,std::pair
<T
*,std::size_t> >
16482 (symbol_name
, std::make_pair(v
,v_size
), is_const
);
16485 template <typename Allocator
>
16486 inline bool add(const std::string
& symbol_name
, std::vector
<T
,Allocator
>& v
, const bool is_const
= false)
16488 return add_impl
<tie_stdvec
,std::vector
<T
,Allocator
>&>
16489 (symbol_name
, v
, is_const
);
16492 inline bool add(const std::string
& symbol_name
, exprtk::vector_view
<T
>& v
, const bool is_const
= false)
16494 return add_impl
<tie_vecview
,exprtk::vector_view
<T
>&>
16495 (symbol_name
, v
, is_const
);
16498 template <typename Allocator
>
16499 inline bool add(const std::string
& symbol_name
, std::deque
<T
,Allocator
>& v
, const bool is_const
= false)
16501 return add_impl
<tie_stddeq
,std::deque
<T
,Allocator
>&>
16502 (symbol_name
, v
, is_const
);
16505 inline bool add(const std::string
& symbol_name
, RawType
& t
, const bool is_const
= false)
16509 static inline std::pair
<bool,variable_node_t
*> make(T
& t
,const bool is_const
= false)
16511 return std::make_pair(is_const
, new variable_node_t(t
));
16514 #ifndef exprtk_disable_string_capabilities
16515 static inline std::pair
<bool,stringvar_node_t
*> make(std::string
& t
,const bool is_const
= false)
16517 return std::make_pair(is_const
, new stringvar_node_t(t
));
16521 static inline std::pair
<bool,function_t
*> make(function_t
& t
, const bool is_constant
= false)
16523 return std::make_pair(is_constant
,&t
);
16526 static inline std::pair
<bool,vararg_function_t
*> make(vararg_function_t
& t
, const bool is_const
= false)
16528 return std::make_pair(is_const
,&t
);
16531 static inline std::pair
<bool,generic_function_t
*> make(generic_function_t
& t
, const bool is_constant
= false)
16533 return std::make_pair(is_constant
,&t
);
16537 const tm_itr_t itr
= map
.find(symbol_name
);
16539 if (map
.end() == itr
)
16541 map
[symbol_name
] = tie::make(t
,is_const
);
16548 inline type_ptr
get(const std::string
& symbol_name
) const
16550 const tm_const_itr_t itr
= map
.find(symbol_name
);
16552 if (map
.end() == itr
)
16553 return reinterpret_cast<type_ptr
>(0);
16555 return itr
->second
.second
;
16558 template <typename TType
, typename TRawType
, typename PtrType
>
16561 static inline bool test(const PtrType
, const void*)
16567 template <typename TType
, typename TRawType
>
16568 struct ptr_match
<TType
,TRawType
,variable_node_t
*>
16570 static inline bool test(const variable_node_t
* p
, const void* ptr
)
16572 exprtk_debug(("ptr_match::test() - %p <--> %p\n",(void*)(&(p
->ref())),ptr
));
16573 return (&(p
->ref()) == ptr
);
16577 inline type_ptr
get_from_varptr(const void* ptr
) const
16579 tm_const_itr_t itr
= map
.begin();
16581 while (map
.end() != itr
)
16583 type_ptr ret_ptr
= itr
->second
.second
;
16585 if (ptr_match
<Type
,RawType
,type_ptr
>::test(ret_ptr
,ptr
))
16593 return type_ptr(0);
16596 inline bool remove(const std::string
& symbol_name
, const bool delete_node
= true)
16598 const tm_itr_t itr
= map
.find(symbol_name
);
16600 if (map
.end() != itr
)
16604 static inline void process(std::pair
<bool,variable_node_t
*>& n
) { delete n
.second
; }
16605 static inline void process(std::pair
<bool,vector_t
*>& n
) { delete n
.second
; }
16606 #ifndef exprtk_disable_string_capabilities
16607 static inline void process(std::pair
<bool,stringvar_node_t
*>& n
) { delete n
.second
; }
16609 static inline void process(std::pair
<bool,function_t
*>&) { }
16614 deleter::process((*itr
).second
);
16626 inline RawType
& type_ref(const std::string
& symbol_name
)
16630 static inline double set(double) { return (0.0); }
16631 static inline double set(long double) { return (0.0); }
16632 static inline float set(float) { return (0.0f
); }
16633 static inline std::string
set(std::string
) { return std::string(""); }
16636 static RawType null_type
= init_type::set(RawType());
16638 const tm_const_itr_t itr
= map
.find(symbol_name
);
16640 if (map
.end() == itr
)
16643 return itr
->second
.second
->ref();
16646 inline void clear(const bool delete_node
= true)
16650 static inline void process(std::pair
<bool,variable_node_t
*>& n
) { delete n
.second
; }
16651 static inline void process(std::pair
<bool,vector_t
*>& n
) { delete n
.second
; }
16652 static inline void process(std::pair
<bool,function_t
*>&) { }
16653 #ifndef exprtk_disable_string_capabilities
16654 static inline void process(std::pair
<bool,stringvar_node_t
*>& n
) { delete n
.second
; }
16662 tm_itr_t itr
= map
.begin();
16663 tm_itr_t end
= map
.end ();
16667 deleter::process((*itr
).second
);
16678 template <typename Allocator
,
16679 template <typename
, typename
> class Sequence
>
16680 inline std::size_t get_list(Sequence
<std::pair
<std::string
,RawType
>,Allocator
>& list
) const
16682 std::size_t count
= 0;
16686 tm_const_itr_t itr
= map
.begin();
16687 tm_const_itr_t end
= map
.end ();
16691 list
.push_back(std::make_pair((*itr
).first
,itr
->second
.second
->ref()));
16700 template <typename Allocator
,
16701 template <typename
, typename
> class Sequence
>
16702 inline std::size_t get_list(Sequence
<std::string
,Allocator
>& vlist
) const
16704 std::size_t count
= 0;
16708 tm_const_itr_t itr
= map
.begin();
16709 tm_const_itr_t end
= map
.end ();
16713 vlist
.push_back((*itr
).first
);
16723 typedef details::expression_node
<T
>* expression_ptr
;
16724 typedef typename
details::variable_node
<T
> variable_t
;
16725 typedef typename
details::vector_holder
<T
> vector_holder_t
;
16726 typedef variable_t
* variable_ptr
;
16727 #ifndef exprtk_disable_string_capabilities
16728 typedef typename
details::stringvar_node
<T
> stringvar_t
;
16729 typedef stringvar_t
* stringvar_ptr
;
16731 typedef ifunction
<T
> function_t
;
16732 typedef ivararg_function
<T
> vararg_function_t
;
16733 typedef igeneric_function
<T
> generic_function_t
;
16734 typedef function_t
* function_ptr
;
16735 typedef vararg_function_t
* vararg_function_ptr
;
16736 typedef generic_function_t
* generic_function_ptr
;
16738 static const std::size_t lut_size
= 256;
16740 // Symbol Table Holder
16741 struct control_block
16745 type_store
<typename
details::variable_node
<T
>,T
> variable_store
;
16746 #ifndef exprtk_disable_string_capabilities
16747 type_store
<typename
details::stringvar_node
<T
>,std::string
> stringvar_store
;
16749 type_store
<ifunction
<T
>,ifunction
<T
> > function_store
;
16750 type_store
<ivararg_function
<T
>,ivararg_function
<T
> > vararg_function_store
;
16751 type_store
<igeneric_function
<T
>,igeneric_function
<T
> > generic_function_store
;
16752 type_store
<igeneric_function
<T
>,igeneric_function
<T
> > string_function_store
;
16753 type_store
<igeneric_function
<T
>,igeneric_function
<T
> > overload_function_store
;
16754 type_store
<vector_holder_t
,vector_holder_t
> vector_store
;
16758 for (std::size_t i
= 0; i
< details::reserved_words_size
; ++i
)
16760 reserved_symbol_table_
.insert(details::reserved_words
[i
]);
16763 for (std::size_t i
= 0; i
< details::reserved_symbols_size
; ++i
)
16765 reserved_symbol_table_
.insert(details::reserved_symbols
[i
]);
16771 for (std::size_t i
= 0; i
< free_function_list_
.size(); ++i
)
16773 delete free_function_list_
[i
];
16777 inline bool is_reserved_symbol(const std::string
& symbol
) const
16779 return (reserved_symbol_table_
.end() != reserved_symbol_table_
.find(symbol
));
16782 static inline st_data
* create()
16784 return (new st_data
);
16787 static inline void destroy(st_data
*& sd
)
16790 sd
= reinterpret_cast<st_data
*>(0);
16793 std::list
<T
> local_symbol_list_
;
16794 std::list
<std::string
> local_stringvar_list_
;
16795 std::set
<std::string
> reserved_symbol_table_
;
16796 std::vector
<ifunction
<T
>*> free_function_list_
;
16801 data_(st_data::create())
16804 explicit control_block(st_data
* data
)
16811 if (data_
&& (0 == ref_count
))
16813 st_data::destroy(data_
);
16817 static inline control_block
* create()
16819 return (new control_block
);
16822 template <typename SymTab
>
16823 static inline void destroy(control_block
*& cntrl_blck
, SymTab
* sym_tab
)
16828 (0 != cntrl_blck
->ref_count
) &&
16829 (0 == --cntrl_blck
->ref_count
)
16842 std::size_t ref_count
;
16849 : control_block_(control_block::create())
16856 control_block::destroy(control_block_
,this);
16859 symbol_table(const symbol_table
<T
>& st
)
16861 control_block_
= st
.control_block_
;
16862 control_block_
->ref_count
++;
16865 inline symbol_table
<T
>& operator=(const symbol_table
<T
>& st
)
16869 control_block::destroy(control_block_
,reinterpret_cast<symbol_table
<T
>*>(0));
16871 control_block_
= st
.control_block_
;
16872 control_block_
->ref_count
++;
16878 inline bool operator==(const symbol_table
<T
>& st
) const
16880 return (this == &st
) || (control_block_
== st
.control_block_
);
16883 inline void clear_variables(const bool delete_node
= true)
16885 local_data().variable_store
.clear(delete_node
);
16888 inline void clear_functions()
16890 local_data().function_store
.clear();
16893 inline void clear_strings()
16895 #ifndef exprtk_disable_string_capabilities
16896 local_data().stringvar_store
.clear();
16900 inline void clear_vectors()
16902 local_data().vector_store
.clear();
16905 inline void clear_local_constants()
16907 local_data().local_symbol_list_
.clear();
16910 inline void clear()
16912 if (!valid()) return;
16913 clear_variables ();
16914 clear_functions ();
16917 clear_local_constants();
16920 inline std::size_t variable_count() const
16923 return local_data().variable_store
.size
;
16928 #ifndef exprtk_disable_string_capabilities
16929 inline std::size_t stringvar_count() const
16932 return local_data().stringvar_store
.size
;
16938 inline std::size_t function_count() const
16941 return local_data().function_store
.size
;
16946 inline std::size_t vector_count() const
16949 return local_data().vector_store
.size
;
16954 inline variable_ptr
get_variable(const std::string
& variable_name
) const
16957 return reinterpret_cast<variable_ptr
>(0);
16958 else if (!valid_symbol(variable_name
))
16959 return reinterpret_cast<variable_ptr
>(0);
16961 return local_data().variable_store
.get(variable_name
);
16964 inline variable_ptr
get_variable(const T
& var_ref
) const
16967 return reinterpret_cast<variable_ptr
>(0);
16969 return local_data().variable_store
.get_from_varptr(
16970 reinterpret_cast<const void*>(&var_ref
));
16973 #ifndef exprtk_disable_string_capabilities
16974 inline stringvar_ptr
get_stringvar(const std::string
& string_name
) const
16977 return reinterpret_cast<stringvar_ptr
>(0);
16978 else if (!valid_symbol(string_name
))
16979 return reinterpret_cast<stringvar_ptr
>(0);
16981 return local_data().stringvar_store
.get(string_name
);
16985 inline function_ptr
get_function(const std::string
& function_name
) const
16988 return reinterpret_cast<function_ptr
>(0);
16989 else if (!valid_symbol(function_name
))
16990 return reinterpret_cast<function_ptr
>(0);
16992 return local_data().function_store
.get(function_name
);
16995 inline vararg_function_ptr
get_vararg_function(const std::string
& vararg_function_name
) const
16998 return reinterpret_cast<vararg_function_ptr
>(0);
16999 else if (!valid_symbol(vararg_function_name
))
17000 return reinterpret_cast<vararg_function_ptr
>(0);
17002 return local_data().vararg_function_store
.get(vararg_function_name
);
17005 inline generic_function_ptr
get_generic_function(const std::string
& function_name
) const
17008 return reinterpret_cast<generic_function_ptr
>(0);
17009 else if (!valid_symbol(function_name
))
17010 return reinterpret_cast<generic_function_ptr
>(0);
17012 return local_data().generic_function_store
.get(function_name
);
17015 inline generic_function_ptr
get_string_function(const std::string
& function_name
) const
17018 return reinterpret_cast<generic_function_ptr
>(0);
17019 else if (!valid_symbol(function_name
))
17020 return reinterpret_cast<generic_function_ptr
>(0);
17022 return local_data().string_function_store
.get(function_name
);
17025 inline generic_function_ptr
get_overload_function(const std::string
& function_name
) const
17028 return reinterpret_cast<generic_function_ptr
>(0);
17029 else if (!valid_symbol(function_name
))
17030 return reinterpret_cast<generic_function_ptr
>(0);
17032 return local_data().overload_function_store
.get(function_name
);
17035 typedef vector_holder_t
* vector_holder_ptr
;
17037 inline vector_holder_ptr
get_vector(const std::string
& vector_name
) const
17040 return reinterpret_cast<vector_holder_ptr
>(0);
17041 else if (!valid_symbol(vector_name
))
17042 return reinterpret_cast<vector_holder_ptr
>(0);
17044 return local_data().vector_store
.get(vector_name
);
17047 inline T
& variable_ref(const std::string
& symbol_name
)
17049 static T null_var
= T(0);
17052 else if (!valid_symbol(symbol_name
))
17055 return local_data().variable_store
.type_ref(symbol_name
);
17058 #ifndef exprtk_disable_string_capabilities
17059 inline std::string
& stringvar_ref(const std::string
& symbol_name
)
17061 static std::string null_stringvar
;
17063 return null_stringvar
;
17064 else if (!valid_symbol(symbol_name
))
17065 return null_stringvar
;
17067 return local_data().stringvar_store
.type_ref(symbol_name
);
17071 inline bool is_constant_node(const std::string
& symbol_name
) const
17075 else if (!valid_symbol(symbol_name
))
17078 return local_data().variable_store
.is_constant(symbol_name
);
17081 #ifndef exprtk_disable_string_capabilities
17082 inline bool is_constant_string(const std::string
& symbol_name
) const
17086 else if (!valid_symbol(symbol_name
))
17088 else if (!local_data().stringvar_store
.symbol_exists(symbol_name
))
17091 return local_data().stringvar_store
.is_constant(symbol_name
);
17095 inline bool create_variable(const std::string
& variable_name
, const T
& value
= T(0))
17099 else if (!valid_symbol(variable_name
))
17101 else if (symbol_exists(variable_name
))
17104 local_data().local_symbol_list_
.push_back(value
);
17105 T
& t
= local_data().local_symbol_list_
.back();
17107 return add_variable(variable_name
,t
);
17110 #ifndef exprtk_disable_string_capabilities
17111 inline bool create_stringvar(const std::string
& stringvar_name
, const std::string
& value
= std::string(""))
17115 else if (!valid_symbol(stringvar_name
))
17117 else if (symbol_exists(stringvar_name
))
17120 local_data().local_stringvar_list_
.push_back(value
);
17121 std::string
& s
= local_data().local_stringvar_list_
.back();
17123 return add_stringvar(stringvar_name
,s
);
17127 inline bool add_variable(const std::string
& variable_name
, T
& t
, const bool is_constant
= false)
17131 else if (!valid_symbol(variable_name
))
17133 else if (symbol_exists(variable_name
))
17136 return local_data().variable_store
.add(variable_name
, t
, is_constant
);
17139 inline bool add_constant(const std::string
& constant_name
, const T
& value
)
17143 else if (!valid_symbol(constant_name
))
17145 else if (symbol_exists(constant_name
))
17148 local_data().local_symbol_list_
.push_back(value
);
17149 T
& t
= local_data().local_symbol_list_
.back();
17151 return add_variable(constant_name
, t
, true);
17154 #ifndef exprtk_disable_string_capabilities
17155 inline bool add_stringvar(const std::string
& stringvar_name
, std::string
& s
, const bool is_constant
= false)
17159 else if (!valid_symbol(stringvar_name
))
17161 else if (symbol_exists(stringvar_name
))
17164 return local_data().stringvar_store
.add(stringvar_name
, s
, is_constant
);
17168 inline bool add_function(const std::string
& function_name
, function_t
& function
)
17172 else if (!valid_symbol(function_name
))
17174 else if (symbol_exists(function_name
))
17177 return local_data().function_store
.add(function_name
,function
);
17180 inline bool add_function(const std::string
& vararg_function_name
, vararg_function_t
& vararg_function
)
17184 else if (!valid_symbol(vararg_function_name
))
17186 else if (symbol_exists(vararg_function_name
))
17189 return local_data().vararg_function_store
.add(vararg_function_name
,vararg_function
);
17192 inline bool add_function(const std::string
& function_name
, generic_function_t
& function
)
17196 else if (!valid_symbol(function_name
))
17198 else if (symbol_exists(function_name
))
17202 (generic_function_t::e_rtrn_scalar
== function
.rtrn_type
) ||
17203 (generic_function_t::e_rtrn_string
== function
.rtrn_type
)
17205 std::string::npos
!= function
.parameter_sequence
.find_first_not_of("STVZ*?|")
17209 (generic_function_t::e_rtrn_overload
== function
.rtrn_type
) &&
17210 std::string::npos
!= function
.parameter_sequence
.find_first_not_of("STVZ*?|:")
17214 switch (function
.rtrn_type
)
17216 case generic_function_t::e_rtrn_scalar
:
17217 return local_data().generic_function_store
.add(function_name
,function
);
17219 case generic_function_t::e_rtrn_string
:
17220 return local_data().string_function_store
.add(function_name
,function
);
17222 case generic_function_t::e_rtrn_overload
:
17223 return local_data().overload_function_store
.add(function_name
,function
);
17229 #define exprtk_define_freefunction(NN) \
17230 inline bool add_function(const std::string& function_name, ff##NN##_functor function) \
17233 { return false; } \
17234 if (!valid_symbol(function_name)) \
17235 { return false; } \
17236 if (symbol_exists(function_name)) \
17237 { return false; } \
17239 exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
17241 local_data().free_function_list_.push_back(ifunc); \
17243 return add_function(function_name,(*local_data().free_function_list_.back())); \
17246 exprtk_define_freefunction(00) exprtk_define_freefunction(01)
17247 exprtk_define_freefunction(02) exprtk_define_freefunction(03)
17248 exprtk_define_freefunction(04) exprtk_define_freefunction(05)
17249 exprtk_define_freefunction(06) exprtk_define_freefunction(07)
17250 exprtk_define_freefunction(08) exprtk_define_freefunction(09)
17251 exprtk_define_freefunction(10) exprtk_define_freefunction(11)
17252 exprtk_define_freefunction(12) exprtk_define_freefunction(13)
17253 exprtk_define_freefunction(14) exprtk_define_freefunction(15)
17255 #undef exprtk_define_freefunction
17257 inline bool add_reserved_function(const std::string
& function_name
, function_t
& function
)
17261 else if (!valid_symbol(function_name
,false))
17263 else if (symbol_exists(function_name
,false))
17266 return local_data().function_store
.add(function_name
,function
);
17269 inline bool add_reserved_function(const std::string
& vararg_function_name
, vararg_function_t
& vararg_function
)
17273 else if (!valid_symbol(vararg_function_name
,false))
17275 else if (symbol_exists(vararg_function_name
,false))
17278 return local_data().vararg_function_store
.add(vararg_function_name
,vararg_function
);
17281 inline bool add_reserved_function(const std::string
& function_name
, generic_function_t
& function
)
17285 else if (!valid_symbol(function_name
,false))
17287 else if (symbol_exists(function_name
,false))
17291 (generic_function_t::e_rtrn_scalar
== function
.rtrn_type
) ||
17292 (generic_function_t::e_rtrn_string
== function
.rtrn_type
)
17294 std::string::npos
!= function
.parameter_sequence
.find_first_not_of("STV*?|")
17298 generic_function_t::e_rtrn_overload
&&
17299 std::string::npos
!= function
.parameter_sequence
.find_first_not_of("STV*?|:")
17303 switch (function
.rtrn_type
)
17305 case generic_function_t::e_rtrn_scalar
:
17306 return local_data().generic_function_store
.add(function_name
,function
);
17308 case generic_function_t::e_rtrn_string
:
17309 return local_data().string_function_store
.add(function_name
,function
);
17311 case generic_function_t::e_rtrn_overload
:
17312 return local_data().overload_function_store
.add(function_name
,function
);
17318 template <std::size_t N
>
17319 inline bool add_vector(const std::string
& vector_name
, T (&v
)[N
])
17323 else if (!valid_symbol(vector_name
))
17325 else if (symbol_exists(vector_name
))
17328 return local_data().vector_store
.add(vector_name
,v
);
17331 inline bool add_vector(const std::string
& vector_name
, T
* v
, const std::size_t& v_size
)
17335 else if (!valid_symbol(vector_name
))
17337 else if (symbol_exists(vector_name
))
17339 else if (0 == v_size
)
17342 return local_data().vector_store
.add(vector_name
, v
, v_size
);
17345 template <typename Allocator
>
17346 inline bool add_vector(const std::string
& vector_name
, std::vector
<T
,Allocator
>& v
)
17350 else if (!valid_symbol(vector_name
))
17352 else if (symbol_exists(vector_name
))
17354 else if (0 == v
.size())
17357 return local_data().vector_store
.add(vector_name
,v
);
17360 inline bool add_vector(const std::string
& vector_name
, exprtk::vector_view
<T
>& v
)
17364 else if (!valid_symbol(vector_name
))
17366 else if (symbol_exists(vector_name
))
17368 else if (0 == v
.size())
17371 return local_data().vector_store
.add(vector_name
,v
);
17374 inline bool remove_variable(const std::string
& variable_name
, const bool delete_node
= true)
17379 return local_data().variable_store
.remove(variable_name
, delete_node
);
17382 #ifndef exprtk_disable_string_capabilities
17383 inline bool remove_stringvar(const std::string
& string_name
)
17388 return local_data().stringvar_store
.remove(string_name
);
17392 inline bool remove_function(const std::string
& function_name
)
17397 return local_data().function_store
.remove(function_name
);
17400 inline bool remove_vararg_function(const std::string
& vararg_function_name
)
17405 return local_data().vararg_function_store
.remove(vararg_function_name
);
17408 inline bool remove_vector(const std::string
& vector_name
)
17413 return local_data().vector_store
.remove(vector_name
);
17416 inline bool add_constants()
17418 return add_pi () &&
17423 inline bool add_pi()
17425 const typename
details::numeric::details::number_type
<T
>::type num_type
;
17426 static const T local_pi
= details::numeric::details::const_pi_impl
<T
>(num_type
);
17427 return add_constant("pi",local_pi
);
17430 inline bool add_epsilon()
17432 static const T local_epsilon
= details::numeric::details::epsilon_type
<T
>::value();
17433 return add_constant("epsilon",local_epsilon
);
17436 inline bool add_infinity()
17438 static const T local_infinity
= std::numeric_limits
<T
>::infinity();
17439 return add_constant("inf",local_infinity
);
17442 template <typename Package
>
17443 inline bool add_package(Package
& package
)
17445 return package
.register_package(*this);
17448 template <typename Allocator
,
17449 template <typename
, typename
> class Sequence
>
17450 inline std::size_t get_variable_list(Sequence
<std::pair
<std::string
,T
>,Allocator
>& vlist
) const
17455 return local_data().variable_store
.get_list(vlist
);
17458 template <typename Allocator
,
17459 template <typename
, typename
> class Sequence
>
17460 inline std::size_t get_variable_list(Sequence
<std::string
,Allocator
>& vlist
) const
17465 return local_data().variable_store
.get_list(vlist
);
17468 #ifndef exprtk_disable_string_capabilities
17469 template <typename Allocator
,
17470 template <typename
, typename
> class Sequence
>
17471 inline std::size_t get_stringvar_list(Sequence
<std::pair
<std::string
,std::string
>,Allocator
>& svlist
) const
17476 return local_data().stringvar_store
.get_list(svlist
);
17479 template <typename Allocator
,
17480 template <typename
, typename
> class Sequence
>
17481 inline std::size_t get_stringvar_list(Sequence
<std::string
,Allocator
>& svlist
) const
17486 return local_data().stringvar_store
.get_list(svlist
);
17490 template <typename Allocator
,
17491 template <typename
, typename
> class Sequence
>
17492 inline std::size_t get_vector_list(Sequence
<std::string
,Allocator
>& vlist
) const
17497 return local_data().vector_store
.get_list(vlist
);
17500 inline bool symbol_exists(const std::string
& symbol_name
, const bool check_reserved_symb
= true) const
17503 Function will return true if symbol_name exists as either a
17504 reserved symbol, variable, stringvar, vector or function name
17505 in any of the type stores.
17509 else if (local_data().variable_store
.symbol_exists(symbol_name
))
17511 #ifndef exprtk_disable_string_capabilities
17512 else if (local_data().stringvar_store
.symbol_exists(symbol_name
))
17515 else if (local_data().vector_store
.symbol_exists(symbol_name
))
17517 else if (local_data().function_store
.symbol_exists(symbol_name
))
17519 else if (check_reserved_symb
&& local_data().is_reserved_symbol(symbol_name
))
17525 inline bool is_variable(const std::string
& variable_name
) const
17530 return local_data().variable_store
.symbol_exists(variable_name
);
17533 #ifndef exprtk_disable_string_capabilities
17534 inline bool is_stringvar(const std::string
& stringvar_name
) const
17539 return local_data().stringvar_store
.symbol_exists(stringvar_name
);
17542 inline bool is_conststr_stringvar(const std::string
& symbol_name
) const
17546 else if (!valid_symbol(symbol_name
))
17548 else if (!local_data().stringvar_store
.symbol_exists(symbol_name
))
17552 local_data().stringvar_store
.symbol_exists(symbol_name
) ||
17553 local_data().stringvar_store
.is_constant (symbol_name
)
17558 inline bool is_function(const std::string
& function_name
) const
17563 return local_data().function_store
.symbol_exists(function_name
);
17566 inline bool is_vararg_function(const std::string
& vararg_function_name
) const
17571 return local_data().vararg_function_store
.symbol_exists(vararg_function_name
);
17574 inline bool is_vector(const std::string
& vector_name
) const
17579 return local_data().vector_store
.symbol_exists(vector_name
);
17582 inline std::string
get_variable_name(const expression_ptr
& ptr
) const
17584 return local_data().variable_store
.entity_name(ptr
);
17587 inline std::string
get_vector_name(const vector_holder_ptr
& ptr
) const
17589 return local_data().vector_store
.entity_name(ptr
);
17592 #ifndef exprtk_disable_string_capabilities
17593 inline std::string
get_stringvar_name(const expression_ptr
& ptr
) const
17595 return local_data().stringvar_store
.entity_name(ptr
);
17598 inline std::string
get_conststr_stringvar_name(const expression_ptr
& ptr
) const
17600 return local_data().stringvar_store
.entity_name(ptr
);
17604 inline bool valid() const
17606 // Symbol table sanity check.
17607 return control_block_
&& control_block_
->data_
;
17610 inline void load_from(const symbol_table
<T
>& st
)
17613 std::vector
<std::string
> name_list
;
17615 st
.local_data().function_store
.get_list(name_list
);
17617 if (!name_list
.empty())
17619 for (std::size_t i
= 0; i
< name_list
.size(); ++i
)
17621 exprtk::ifunction
<T
>& ifunc
= *st
.get_function(name_list
[i
]);
17622 add_function(name_list
[i
],ifunc
);
17628 std::vector
<std::string
> name_list
;
17630 st
.local_data().vararg_function_store
.get_list(name_list
);
17632 if (!name_list
.empty())
17634 for (std::size_t i
= 0; i
< name_list
.size(); ++i
)
17636 exprtk::ivararg_function
<T
>& ivafunc
= *st
.get_vararg_function(name_list
[i
]);
17637 add_function(name_list
[i
],ivafunc
);
17643 std::vector
<std::string
> name_list
;
17645 st
.local_data().generic_function_store
.get_list(name_list
);
17647 if (!name_list
.empty())
17649 for (std::size_t i
= 0; i
< name_list
.size(); ++i
)
17651 exprtk::igeneric_function
<T
>& ifunc
= *st
.get_generic_function(name_list
[i
]);
17652 add_function(name_list
[i
],ifunc
);
17658 std::vector
<std::string
> name_list
;
17660 st
.local_data().string_function_store
.get_list(name_list
);
17662 if (!name_list
.empty())
17664 for (std::size_t i
= 0; i
< name_list
.size(); ++i
)
17666 exprtk::igeneric_function
<T
>& ifunc
= *st
.get_string_function(name_list
[i
]);
17667 add_function(name_list
[i
],ifunc
);
17673 std::vector
<std::string
> name_list
;
17675 st
.local_data().overload_function_store
.get_list(name_list
);
17677 if (!name_list
.empty())
17679 for (std::size_t i
= 0; i
< name_list
.size(); ++i
)
17681 exprtk::igeneric_function
<T
>& ifunc
= *st
.get_overload_function(name_list
[i
]);
17682 add_function(name_list
[i
],ifunc
);
17690 inline bool valid_symbol(const std::string
& symbol
, const bool check_reserved_symb
= true) const
17692 if (symbol
.empty())
17694 else if (!details::is_letter(symbol
[0]))
17696 else if (symbol
.size() > 1)
17698 for (std::size_t i
= 1; i
< symbol
.size(); ++i
)
17701 !details::is_letter_or_digit(symbol
[i
]) &&
17705 if (('.' == symbol
[i
]) && (i
< (symbol
.size() - 1)))
17713 return (check_reserved_symb
) ? (!local_data().is_reserved_symbol(symbol
)) : true;
17716 inline bool valid_function(const std::string
& symbol
) const
17718 if (symbol
.empty())
17720 else if (!details::is_letter(symbol
[0]))
17722 else if (symbol
.size() > 1)
17724 for (std::size_t i
= 1; i
< symbol
.size(); ++i
)
17727 !details::is_letter_or_digit(symbol
[i
]) &&
17731 if (('.' == symbol
[i
]) && (i
< (symbol
.size() - 1)))
17742 typedef typename
control_block::st_data local_data_t
;
17744 inline local_data_t
& local_data()
17746 return *(control_block_
->data_
);
17749 inline const local_data_t
& local_data() const
17751 return *(control_block_
->data_
);
17754 control_block
* control_block_
;
17756 friend class parser
<T
>;
17759 template <typename T
>
17760 class function_compositor
;
17762 template <typename T
>
17767 typedef details::expression_node
<T
>* expression_ptr
;
17768 typedef details::vector_holder
<T
>* vector_holder_ptr
;
17769 typedef std::vector
<symbol_table
<T
> > symtab_list_t
;
17771 struct control_block
17791 data_pack(void* ptr
, const data_type dt
, const std::size_t sz
= 0)
17802 typedef std::vector
<data_pack
> local_data_list_t
;
17803 typedef results_context
<T
> results_context_t
;
17809 retinv_null(false),
17810 return_invoked(&retinv_null
)
17813 explicit control_block(expression_ptr e
)
17817 retinv_null(false),
17818 return_invoked(&retinv_null
)
17823 if (expr
&& details::branch_deletable(expr
))
17825 destroy_node(expr
);
17828 if (!local_data_list
.empty())
17830 for (std::size_t i
= 0; i
< local_data_list
.size(); ++i
)
17832 switch (local_data_list
[i
].type
)
17834 case e_expr
: delete reinterpret_cast<expression_ptr
>(local_data_list
[i
].pointer
);
17837 case e_vecholder
: delete reinterpret_cast<vector_holder_ptr
>(local_data_list
[i
].pointer
);
17840 case e_data
: delete (T
*)(local_data_list
[i
].pointer
);
17843 case e_vecdata
: delete [] (T
*)(local_data_list
[i
].pointer
);
17846 case e_string
: delete (std::string
*)(local_data_list
[i
].pointer
);
17860 static inline control_block
* create(expression_ptr e
)
17862 return new control_block(e
);
17865 static inline void destroy(control_block
*& cntrl_blck
)
17870 (0 != cntrl_blck
->ref_count
) &&
17871 (0 == --cntrl_blck
->ref_count
)
17881 std::size_t ref_count
;
17882 expression_ptr expr
;
17883 local_data_list_t local_data_list
;
17884 results_context_t
* results
;
17886 bool* return_invoked
;
17888 friend class function_compositor
<T
>;
17894 : control_block_(0)
17896 set_expression(new details::null_node
<T
>());
17899 expression(const expression
<T
>& e
)
17900 : control_block_ (e
.control_block_
),
17901 symbol_table_list_(e
.symbol_table_list_
)
17903 control_block_
->ref_count
++;
17906 explicit expression(const symbol_table
<T
>& symbol_table
)
17907 : control_block_(0)
17909 set_expression(new details::null_node
<T
>());
17910 symbol_table_list_
.push_back(symbol_table
);
17913 inline expression
<T
>& operator=(const expression
<T
>& e
)
17917 if (control_block_
)
17920 (0 != control_block_
->ref_count
) &&
17921 (0 == --control_block_
->ref_count
)
17924 delete control_block_
;
17927 control_block_
= 0;
17930 control_block_
= e
.control_block_
;
17931 control_block_
->ref_count
++;
17932 symbol_table_list_
= e
.symbol_table_list_
;
17938 inline bool operator==(const expression
<T
>& e
) const
17940 return (this == &e
);
17943 inline bool operator!() const
17946 (0 == control_block_
) ||
17947 (0 == control_block_
->expr
)
17951 inline expression
<T
>& release()
17953 control_block::destroy(control_block_
);
17960 control_block::destroy(control_block_
);
17963 inline T
value() const
17965 return control_block_
->expr
->value();
17968 inline T
operator() () const
17973 inline operator T() const
17978 inline operator bool() const
17980 return details::is_true(value());
17983 inline void register_symbol_table(symbol_table
<T
>& st
)
17985 symbol_table_list_
.push_back(st
);
17988 inline const symbol_table
<T
>& get_symbol_table(const std::size_t& index
= 0) const
17990 return symbol_table_list_
[index
];
17993 inline symbol_table
<T
>& get_symbol_table(const std::size_t& index
= 0)
17995 return symbol_table_list_
[index
];
17998 typedef results_context
<T
> results_context_t
;
18000 inline const results_context_t
& results() const
18002 if (control_block_
->results
)
18003 return (*control_block_
->results
);
18006 static const results_context_t null_results
;
18007 return null_results
;
18011 inline bool return_invoked() const
18013 return (*control_block_
->return_invoked
);
18018 inline symtab_list_t
get_symbol_table_list() const
18020 return symbol_table_list_
;
18023 inline void set_expression(const expression_ptr expr
)
18027 if (control_block_
)
18029 if (0 == --control_block_
->ref_count
)
18031 delete control_block_
;
18035 control_block_
= control_block::create(expr
);
18039 inline void register_local_var(expression_ptr expr
)
18043 if (control_block_
)
18046 local_data_list
.push_back(
18047 typename expression
<T
>::control_block::
18048 data_pack(reinterpret_cast<void*>(expr
),
18049 control_block::e_expr
));
18054 inline void register_local_var(vector_holder_ptr vec_holder
)
18058 if (control_block_
)
18061 local_data_list
.push_back(
18062 typename expression
<T
>::control_block::
18063 data_pack(reinterpret_cast<void*>(vec_holder
),
18064 control_block::e_vecholder
));
18069 inline void register_local_data(void* data
, const std::size_t& size
= 0, const std::size_t data_mode
= 0)
18073 if (control_block_
)
18075 typename
control_block::data_type dt
= control_block::e_data
;
18079 case 0 : dt
= control_block::e_data
; break;
18080 case 1 : dt
= control_block::e_vecdata
; break;
18081 case 2 : dt
= control_block::e_string
; break;
18085 local_data_list
.push_back(
18086 typename expression
<T
>::control_block::
18087 data_pack(reinterpret_cast<void*>(data
), dt
, size
));
18092 inline const typename
control_block::local_data_list_t
& local_data_list()
18094 if (control_block_
)
18096 return control_block_
->local_data_list
;
18100 static typename
control_block::local_data_list_t null_local_data_list
;
18101 return null_local_data_list
;
18105 inline void register_return_results(results_context_t
* rc
)
18107 if (control_block_
&& rc
)
18109 control_block_
->results
= rc
;
18113 inline void set_retinvk(bool* retinvk_ptr
)
18115 if (control_block_
)
18117 control_block_
->return_invoked
= retinvk_ptr
;
18121 control_block
* control_block_
;
18122 symtab_list_t symbol_table_list_
;
18124 friend class parser
<T
>;
18125 friend class expression_helper
<T
>;
18126 friend class function_compositor
<T
>;
18129 template <typename T
>
18130 class expression_helper
18134 static inline bool is_constant(const expression
<T
>& expr
)
18136 return details::is_constant_node(expr
.control_block_
->expr
);
18139 static inline bool is_variable(const expression
<T
>& expr
)
18141 return details::is_variable_node(expr
.control_block_
->expr
);
18144 static inline bool is_unary(const expression
<T
>& expr
)
18146 return details::is_unary_node(expr
.control_block_
->expr
);
18149 static inline bool is_binary(const expression
<T
>& expr
)
18151 return details::is_binary_node(expr
.control_block_
->expr
);
18154 static inline bool is_function(const expression
<T
>& expr
)
18156 return details::is_function(expr
.control_block_
->expr
);
18159 static inline bool is_null(const expression
<T
>& expr
)
18161 return details::is_null_node(expr
.control_block_
->expr
);
18165 template <typename T
>
18166 inline bool is_valid(const expression
<T
>& expr
)
18168 return !expression_helper
<T
>::is_null(expr
);
18171 namespace parser_error
18187 : mode(parser_error::e_unknown
),
18192 lexer::token token
;
18194 std::string diagnostic
;
18195 std::string src_location
;
18196 std::string error_line
;
18197 std::size_t line_no
;
18198 std::size_t column_no
;
18201 inline type
make_error(const error_mode mode
,
18202 const std::string
& diagnostic
= "",
18203 const std::string
& src_location
= "")
18207 t
.token
.type
= lexer::token::e_error
;
18208 t
.diagnostic
= diagnostic
;
18209 t
.src_location
= src_location
;
18210 exprtk_debug(("%s\n",diagnostic
.c_str()));
18214 inline type
make_error(const error_mode mode
,
18215 const lexer::token
& tk
,
18216 const std::string
& diagnostic
= "",
18217 const std::string
& src_location
= "")
18222 t
.diagnostic
= diagnostic
;
18223 t
.src_location
= src_location
;
18224 exprtk_debug(("%s\n",diagnostic
.c_str()));
18228 inline std::string
to_str(error_mode mode
)
18232 case e_unknown
: return std::string("Unknown Error");
18233 case e_syntax
: return std::string("Syntax Error" );
18234 case e_token
: return std::string("Token Error" );
18235 case e_numeric
: return std::string("Numeric Error");
18236 case e_symtab
: return std::string("Symbol Error" );
18237 case e_lexer
: return std::string("Lexer Error" );
18238 case e_helper
: return std::string("Helper Error" );
18239 default : return std::string("Unknown Error");
18243 inline bool update_error(type
& error
, const std::string
& expression
)
18246 expression
.empty() ||
18247 (error
.token
.position
> expression
.size()) ||
18248 (std::numeric_limits
<std::size_t>::max() == error
.token
.position
)
18254 std::size_t error_line_start
= 0;
18256 for (std::size_t i
= error
.token
.position
; i
> 0; --i
)
18258 const details::char_t c
= expression
[i
];
18260 if (('\n' == c
) || ('\r' == c
))
18262 error_line_start
= i
+ 1;
18267 std::size_t next_nl_position
= std::min(expression
.size(),
18268 expression
.find_first_of('\n',error
.token
.position
+ 1));
18270 error
.column_no
= error
.token
.position
- error_line_start
;
18271 error
.error_line
= expression
.substr(error_line_start
,
18272 next_nl_position
- error_line_start
);
18276 for (std::size_t i
= 0; i
< next_nl_position
; ++i
)
18278 if ('\n' == expression
[i
])
18285 inline void dump_error(const type
& error
)
18287 printf("Position: %02d Type: [%s] Msg: %s\n",
18288 static_cast<int>(error
.token
.position
),
18289 exprtk::parser_error::to_str(error
.mode
).c_str(),
18290 error
.diagnostic
.c_str());
18296 template <typename Parser
>
18297 inline void disable_type_checking(Parser
& p
)
18299 p
.state_
.type_check_enabled
= false;
18303 template <typename T
>
18304 class parser
: public lexer::parser_helper
18308 enum precedence_level
18327 typedef const T
& cref_t
;
18328 typedef const T const_t
;
18329 typedef ifunction
<T
> F
;
18330 typedef ivararg_function
<T
> VAF
;
18331 typedef igeneric_function
<T
> GF
;
18332 typedef ifunction
<T
> ifunction_t
;
18333 typedef ivararg_function
<T
> ivararg_function_t
;
18334 typedef igeneric_function
<T
> igeneric_function_t
;
18335 typedef details::expression_node
<T
> expression_node_t
;
18336 typedef details::literal_node
<T
> literal_node_t
;
18337 typedef details::unary_node
<T
> unary_node_t
;
18338 typedef details::binary_node
<T
> binary_node_t
;
18339 typedef details::trinary_node
<T
> trinary_node_t
;
18340 typedef details::quaternary_node
<T
> quaternary_node_t
;
18341 typedef details::conditional_node
<T
> conditional_node_t
;
18342 typedef details::cons_conditional_node
<T
> cons_conditional_node_t
;
18343 typedef details::while_loop_node
<T
> while_loop_node_t
;
18344 typedef details::repeat_until_loop_node
<T
> repeat_until_loop_node_t
;
18345 typedef details::for_loop_node
<T
> for_loop_node_t
;
18346 #ifndef exprtk_disable_break_continue
18347 typedef details::while_loop_bc_node
<T
> while_loop_bc_node_t
;
18348 typedef details::repeat_until_loop_bc_node
<T
> repeat_until_loop_bc_node_t
;
18349 typedef details::for_loop_bc_node
<T
> for_loop_bc_node_t
;
18351 typedef details::switch_node
<T
> switch_node_t
;
18352 typedef details::variable_node
<T
> variable_node_t
;
18353 typedef details::vector_elem_node
<T
> vector_elem_node_t
;
18354 typedef details::rebasevector_elem_node
<T
> rebasevector_elem_node_t
;
18355 typedef details::rebasevector_celem_node
<T
> rebasevector_celem_node_t
;
18356 typedef details::vector_node
<T
> vector_node_t
;
18357 typedef details::range_pack
<T
> range_t
;
18358 #ifndef exprtk_disable_string_capabilities
18359 typedef details::stringvar_node
<T
> stringvar_node_t
;
18360 typedef details::string_literal_node
<T
> string_literal_node_t
;
18361 typedef details::string_range_node
<T
> string_range_node_t
;
18362 typedef details::const_string_range_node
<T
> const_string_range_node_t
;
18363 typedef details::generic_string_range_node
<T
> generic_string_range_node_t
;
18364 typedef details::string_concat_node
<T
> string_concat_node_t
;
18365 typedef details::assignment_string_node
<T
> assignment_string_node_t
;
18366 typedef details::assignment_string_range_node
<T
> assignment_string_range_node_t
;
18367 typedef details::conditional_string_node
<T
> conditional_string_node_t
;
18368 typedef details::cons_conditional_str_node
<T
> cons_conditional_str_node_t
;
18370 typedef details::assignment_node
<T
> assignment_node_t
;
18371 typedef details::assignment_vec_elem_node
<T
> assignment_vec_elem_node_t
;
18372 typedef details::assignment_rebasevec_elem_node
<T
> assignment_rebasevec_elem_node_t
;
18373 typedef details::assignment_rebasevec_celem_node
<T
> assignment_rebasevec_celem_node_t
;
18374 typedef details::assignment_vec_node
<T
> assignment_vec_node_t
;
18375 typedef details::assignment_vecvec_node
<T
> assignment_vecvec_node_t
;
18376 typedef details::scand_node
<T
> scand_node_t
;
18377 typedef details::scor_node
<T
> scor_node_t
;
18378 typedef lexer::token token_t
;
18379 typedef expression_node_t
* expression_node_ptr
;
18380 typedef expression
<T
> expression_t
;
18381 typedef symbol_table
<T
> symbol_table_t
;
18382 typedef typename expression
<T
>::symtab_list_t symbol_table_list_t
;
18383 typedef details::vector_holder
<T
>* vector_holder_ptr
;
18385 typedef typename
details::functor_t
<T
> functor_t
;
18386 typedef typename
functor_t::qfunc_t quaternary_functor_t
;
18387 typedef typename
functor_t::tfunc_t trinary_functor_t
;
18388 typedef typename
functor_t::bfunc_t binary_functor_t
;
18389 typedef typename
functor_t::ufunc_t unary_functor_t
;
18391 typedef details::operator_type operator_t
;
18393 typedef std::map
<operator_t
, unary_functor_t
> unary_op_map_t
;
18394 typedef std::map
<operator_t
, binary_functor_t
> binary_op_map_t
;
18395 typedef std::map
<operator_t
,trinary_functor_t
> trinary_op_map_t
;
18397 typedef std::map
<std::string
,std::pair
<trinary_functor_t
,operator_t
> > sf3_map_t
;
18398 typedef std::map
<std::string
,std::pair
<quaternary_functor_t
,operator_t
> > sf4_map_t
;
18400 typedef std::map
<binary_functor_t
,operator_t
> inv_binary_op_map_t
;
18401 typedef std::multimap
<std::string
,details::base_operation_t
,details::ilesscompare
> base_ops_map_t
;
18402 typedef std::set
<std::string
,details::ilesscompare
> disabled_func_set_t
;
18404 typedef details::T0oT1_define
<T
, cref_t
, cref_t
> vov_t
;
18405 typedef details::T0oT1_define
<T
, const_t
, cref_t
> cov_t
;
18406 typedef details::T0oT1_define
<T
, cref_t
, const_t
> voc_t
;
18408 typedef details::T0oT1oT2_define
<T
, cref_t
, cref_t
, cref_t
> vovov_t
;
18409 typedef details::T0oT1oT2_define
<T
, cref_t
, cref_t
, const_t
> vovoc_t
;
18410 typedef details::T0oT1oT2_define
<T
, cref_t
, const_t
, cref_t
> vocov_t
;
18411 typedef details::T0oT1oT2_define
<T
, const_t
, cref_t
, cref_t
> covov_t
;
18412 typedef details::T0oT1oT2_define
<T
, const_t
, cref_t
, const_t
> covoc_t
;
18413 typedef details::T0oT1oT2_define
<T
, const_t
, const_t
, cref_t
> cocov_t
;
18414 typedef details::T0oT1oT2_define
<T
, cref_t
, const_t
, const_t
> vococ_t
;
18416 typedef details::T0oT1oT2oT3_define
<T
, cref_t
, cref_t
, cref_t
, cref_t
> vovovov_t
;
18417 typedef details::T0oT1oT2oT3_define
<T
, cref_t
, cref_t
, cref_t
, const_t
> vovovoc_t
;
18418 typedef details::T0oT1oT2oT3_define
<T
, cref_t
, cref_t
, const_t
, cref_t
> vovocov_t
;
18419 typedef details::T0oT1oT2oT3_define
<T
, cref_t
, const_t
, cref_t
, cref_t
> vocovov_t
;
18420 typedef details::T0oT1oT2oT3_define
<T
, const_t
, cref_t
, cref_t
, cref_t
> covovov_t
;
18422 typedef details::T0oT1oT2oT3_define
<T
, const_t
, cref_t
, const_t
, cref_t
> covocov_t
;
18423 typedef details::T0oT1oT2oT3_define
<T
, cref_t
, const_t
, cref_t
, const_t
> vocovoc_t
;
18424 typedef details::T0oT1oT2oT3_define
<T
, const_t
, cref_t
, cref_t
, const_t
> covovoc_t
;
18425 typedef details::T0oT1oT2oT3_define
<T
, cref_t
, const_t
, const_t
, cref_t
> vococov_t
;
18427 typedef results_context
<T
> results_context_t
;
18429 typedef parser_helper prsrhlpr_t
;
18431 struct scope_element
18442 typedef details::vector_holder
<T
> vector_holder_t
;
18443 typedef variable_node_t
* variable_node_ptr
;
18444 typedef vector_holder_t
* vector_holder_ptr
;
18445 typedef expression_node_t
* expression_node_ptr
;
18446 #ifndef exprtk_disable_string_capabilities
18447 typedef stringvar_node_t
* stringvar_node_ptr
;
18452 size (std::numeric_limits
<std::size_t>::max()),
18453 index(std::numeric_limits
<std::size_t>::max()),
18454 depth(std::numeric_limits
<std::size_t>::max()),
18462 #ifndef exprtk_disable_string_capabilities
18467 bool operator < (const scope_element
& se
) const
18469 if (ip_index
< se
.ip_index
)
18471 else if (ip_index
> se
.ip_index
)
18473 else if (depth
< se
.depth
)
18475 else if (depth
> se
.depth
)
18477 else if (index
< se
.index
)
18479 else if (index
> se
.index
)
18482 return (name
< se
.name
);
18488 size
= std::numeric_limits
<std::size_t>::max();
18489 index
= std::numeric_limits
<std::size_t>::max();
18490 depth
= std::numeric_limits
<std::size_t>::max();
18498 #ifndef exprtk_disable_string_capabilities
18507 std::size_t ref_count
;
18508 std::size_t ip_index
;
18512 expression_node_ptr var_node
;
18513 vector_holder_ptr vec_node
;
18514 #ifndef exprtk_disable_string_capabilities
18515 stringvar_node_ptr str_node
;
18519 class scope_element_manager
18523 typedef expression_node_t
* expression_node_ptr
;
18524 typedef variable_node_t
* variable_node_ptr
;
18525 typedef parser
<T
> parser_t
;
18527 explicit scope_element_manager(parser
<T
>& p
)
18529 input_param_cnt_(0)
18532 inline std::size_t size() const
18534 return element_
.size();
18537 inline bool empty() const
18539 return element_
.empty();
18542 inline scope_element
& get_element(const std::size_t& index
)
18544 if (index
< element_
.size())
18545 return element_
[index
];
18547 return null_element_
;
18550 inline scope_element
& get_element(const std::string
& var_name
,
18551 const std::size_t index
= std::numeric_limits
<std::size_t>::max())
18553 const std::size_t current_depth
= parser_
.state_
.scope_depth
;
18555 for (std::size_t i
= 0; i
< element_
.size(); ++i
)
18557 scope_element
& se
= element_
[i
];
18559 if (se
.depth
> current_depth
)
18562 details::imatch(se
.name
, var_name
) &&
18563 (se
.index
== index
)
18568 return null_element_
;
18571 inline scope_element
& get_active_element(const std::string
& var_name
,
18572 const std::size_t index
= std::numeric_limits
<std::size_t>::max())
18574 const std::size_t current_depth
= parser_
.state_
.scope_depth
;
18576 for (std::size_t i
= 0; i
< element_
.size(); ++i
)
18578 scope_element
& se
= element_
[i
];
18580 if (se
.depth
> current_depth
)
18583 details::imatch(se
.name
, var_name
) &&
18584 (se
.index
== index
) &&
18590 return null_element_
;
18593 inline bool add_element(const scope_element
& se
)
18595 for (std::size_t i
= 0; i
< element_
.size(); ++i
)
18597 scope_element
& cse
= element_
[i
];
18600 details::imatch(cse
.name
, se
.name
) &&
18601 (cse
.depth
<= se
.depth
) &&
18602 (cse
.index
== se
.index
) &&
18603 (cse
.size
== se
.size
) &&
18604 (cse
.type
== se
.type
) &&
18610 element_
.push_back(se
);
18611 std::sort(element_
.begin(),element_
.end());
18616 inline void deactivate(const std::size_t& scope_depth
)
18618 exprtk_debug(("deactivate() - Scope depth: %d\n",
18619 static_cast<int>(parser_
.state_
.scope_depth
)));
18621 for (std::size_t i
= 0; i
< element_
.size(); ++i
)
18623 scope_element
& se
= element_
[i
];
18625 if (se
.active
&& (se
.depth
>= scope_depth
))
18627 exprtk_debug(("deactivate() - element[%02d] '%s'\n",
18628 static_cast<int>(i
),
18636 inline void free_element(scope_element
& se
)
18638 #ifdef exprtk_enable_debugging
18639 exprtk_debug(("free_element() - se[%s]\n", se
.name
.c_str()));
18644 case scope_element::e_variable
: if (se
.data
) delete (T
*) se
.data
;
18645 if (se
.var_node
) delete se
.var_node
;
18648 case scope_element::e_vector
: if (se
.data
) delete[] (T
*) se
.data
;
18649 if (se
.vec_node
) delete se
.vec_node
;
18652 case scope_element::e_vecelem
: if (se
.var_node
) delete se
.var_node
;
18655 #ifndef exprtk_disable_string_capabilities
18656 case scope_element::e_string
: if (se
.data
) delete (std::string
*) se
.data
;
18657 if (se
.str_node
) delete se
.str_node
;
18667 inline void cleanup()
18669 for (std::size_t i
= 0; i
< element_
.size(); ++i
)
18671 free_element(element_
[i
]);
18676 input_param_cnt_
= 0;
18679 inline std::size_t next_ip_index()
18681 return ++input_param_cnt_
;
18684 inline expression_node_ptr
get_variable(const T
& v
)
18686 for (std::size_t i
= 0; i
< element_
.size(); ++i
)
18688 scope_element
& se
= element_
[i
];
18693 details::is_variable_node(se
.var_node
)
18696 variable_node_ptr vn
= reinterpret_cast<variable_node_ptr
>(se
.var_node
);
18698 if (&(vn
->ref()) == (&v
))
18700 return se
.var_node
;
18705 return expression_node_ptr(0);
18710 scope_element_manager
& operator=(const scope_element_manager
&);
18713 std::vector
<scope_element
> element_
;
18714 scope_element null_element_
;
18715 std::size_t input_param_cnt_
;
18718 class scope_handler
18722 typedef parser
<T
> parser_t
;
18724 explicit scope_handler(parser
<T
>& p
)
18727 parser_
.state_
.scope_depth
++;
18728 #ifdef exprtk_enable_debugging
18729 const std::string
depth(2 * parser_
.state_
.scope_depth
,'-');
18730 exprtk_debug(("%s> Scope Depth: %02d\n",
18732 static_cast<int>(parser_
.state_
.scope_depth
)));
18738 parser_
.sem_
.deactivate(parser_
.state_
.scope_depth
);
18739 parser_
.state_
.scope_depth
--;
18740 #ifdef exprtk_enable_debugging
18741 const std::string
depth(2 * parser_
.state_
.scope_depth
,'-');
18742 exprtk_debug(("<%s Scope Depth: %02d\n",
18744 static_cast<int>(parser_
.state_
.scope_depth
)));
18750 scope_handler
& operator=(const scope_handler
&);
18755 struct symtab_store
18757 symbol_table_list_t symtab_list_
;
18759 typedef typename
symbol_table_t::local_data_t local_data_t
;
18760 typedef typename
symbol_table_t::variable_ptr variable_ptr
;
18761 typedef typename
symbol_table_t::function_ptr function_ptr
;
18762 #ifndef exprtk_disable_string_capabilities
18763 typedef typename
symbol_table_t::stringvar_ptr stringvar_ptr
;
18765 typedef typename
symbol_table_t::vector_holder_ptr vector_holder_ptr
;
18766 typedef typename
symbol_table_t::vararg_function_ptr vararg_function_ptr
;
18767 typedef typename
symbol_table_t::generic_function_ptr generic_function_ptr
;
18769 inline bool empty() const
18771 return symtab_list_
.empty();
18774 inline void clear()
18776 symtab_list_
.clear();
18779 inline bool valid() const
18783 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18785 if (symtab_list_
[i
].valid())
18793 inline bool valid_symbol(const std::string
& symbol
) const
18795 if (!symtab_list_
.empty())
18796 return symtab_list_
[0].valid_symbol(symbol
);
18801 inline bool valid_function_name(const std::string
& symbol
) const
18803 if (!symtab_list_
.empty())
18804 return symtab_list_
[0].valid_function(symbol
);
18809 inline variable_ptr
get_variable(const std::string
& variable_name
) const
18811 if (!valid_symbol(variable_name
))
18812 return reinterpret_cast<variable_ptr
>(0);
18814 variable_ptr result
= reinterpret_cast<variable_ptr
>(0);
18816 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18818 if (!symtab_list_
[i
].valid())
18821 result
= local_data(i
)
18822 .variable_store
.get(variable_name
);
18830 inline variable_ptr
get_variable(const T
& var_ref
) const
18832 variable_ptr result
= reinterpret_cast<variable_ptr
>(0);
18834 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18836 if (!symtab_list_
[i
].valid())
18839 result
= local_data(i
).variable_store
18840 .get_from_varptr(reinterpret_cast<const void*>(&var_ref
));
18848 #ifndef exprtk_disable_string_capabilities
18849 inline stringvar_ptr
get_stringvar(const std::string
& string_name
) const
18851 if (!valid_symbol(string_name
))
18852 return reinterpret_cast<stringvar_ptr
>(0);
18854 stringvar_ptr result
= reinterpret_cast<stringvar_ptr
>(0);
18856 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18858 if (!symtab_list_
[i
].valid())
18861 result
= local_data(i
)
18862 .stringvar_store
.get(string_name
);
18871 inline function_ptr
get_function(const std::string
& function_name
) const
18873 if (!valid_function_name(function_name
))
18874 return reinterpret_cast<function_ptr
>(0);
18876 function_ptr result
= reinterpret_cast<function_ptr
>(0);
18878 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18880 if (!symtab_list_
[i
].valid())
18883 result
= local_data(i
)
18884 .function_store
.get(function_name
);
18892 inline vararg_function_ptr
get_vararg_function(const std::string
& vararg_function_name
) const
18894 if (!valid_function_name(vararg_function_name
))
18895 return reinterpret_cast<vararg_function_ptr
>(0);
18897 vararg_function_ptr result
= reinterpret_cast<vararg_function_ptr
>(0);
18899 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18901 if (!symtab_list_
[i
].valid())
18904 result
= local_data(i
)
18905 .vararg_function_store
.get(vararg_function_name
);
18913 inline generic_function_ptr
get_generic_function(const std::string
& function_name
) const
18915 if (!valid_function_name(function_name
))
18916 return reinterpret_cast<generic_function_ptr
>(0);
18918 generic_function_ptr result
= reinterpret_cast<generic_function_ptr
>(0);
18920 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18922 if (!symtab_list_
[i
].valid())
18925 result
= local_data(i
)
18926 .generic_function_store
.get(function_name
);
18934 inline generic_function_ptr
get_string_function(const std::string
& function_name
) const
18936 if (!valid_function_name(function_name
))
18937 return reinterpret_cast<generic_function_ptr
>(0);
18939 generic_function_ptr result
= reinterpret_cast<generic_function_ptr
>(0);
18941 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18943 if (!symtab_list_
[i
].valid())
18947 local_data(i
).string_function_store
.get(function_name
);
18955 inline generic_function_ptr
get_overload_function(const std::string
& function_name
) const
18957 if (!valid_function_name(function_name
))
18958 return reinterpret_cast<generic_function_ptr
>(0);
18960 generic_function_ptr result
= reinterpret_cast<generic_function_ptr
>(0);
18962 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18964 if (!symtab_list_
[i
].valid())
18968 local_data(i
).overload_function_store
.get(function_name
);
18976 inline vector_holder_ptr
get_vector(const std::string
& vector_name
) const
18978 if (!valid_symbol(vector_name
))
18979 return reinterpret_cast<vector_holder_ptr
>(0);
18981 vector_holder_ptr result
= reinterpret_cast<vector_holder_ptr
>(0);
18983 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
18985 if (!symtab_list_
[i
].valid())
18989 local_data(i
).vector_store
.get(vector_name
);
18997 inline bool is_constant_node(const std::string
& symbol_name
) const
18999 if (!valid_symbol(symbol_name
))
19002 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19004 if (!symtab_list_
[i
].valid())
19006 else if (local_data(i
).variable_store
.is_constant(symbol_name
))
19013 #ifndef exprtk_disable_string_capabilities
19014 inline bool is_constant_string(const std::string
& symbol_name
) const
19016 if (!valid_symbol(symbol_name
))
19019 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19021 if (!symtab_list_
[i
].valid())
19023 else if (!local_data(i
).stringvar_store
.symbol_exists(symbol_name
))
19025 else if ( local_data(i
).stringvar_store
.is_constant(symbol_name
))
19033 inline bool symbol_exists(const std::string
& symbol
) const
19035 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19037 if (!symtab_list_
[i
].valid())
19039 else if (symtab_list_
[i
].symbol_exists(symbol
))
19046 inline bool is_variable(const std::string
& variable_name
) const
19048 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19050 if (!symtab_list_
[i
].valid())
19053 symtab_list_
[i
].local_data().variable_store
19054 .symbol_exists(variable_name
)
19062 #ifndef exprtk_disable_string_capabilities
19063 inline bool is_stringvar(const std::string
& stringvar_name
) const
19065 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19067 if (!symtab_list_
[i
].valid())
19070 symtab_list_
[i
].local_data().stringvar_store
19071 .symbol_exists(stringvar_name
)
19079 inline bool is_conststr_stringvar(const std::string
& symbol_name
) const
19081 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19083 if (!symtab_list_
[i
].valid())
19086 symtab_list_
[i
].local_data().stringvar_store
19087 .symbol_exists(symbol_name
)
19091 local_data(i
).stringvar_store
.symbol_exists(symbol_name
) ||
19092 local_data(i
).stringvar_store
.is_constant (symbol_name
)
19102 inline bool is_function(const std::string
& function_name
) const
19104 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19106 if (!symtab_list_
[i
].valid())
19109 local_data(i
).vararg_function_store
19110 .symbol_exists(function_name
)
19118 inline bool is_vararg_function(const std::string
& vararg_function_name
) const
19120 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19122 if (!symtab_list_
[i
].valid())
19125 local_data(i
).vararg_function_store
19126 .symbol_exists(vararg_function_name
)
19134 inline bool is_vector(const std::string
& vector_name
) const
19136 for (std::size_t i
= 0; i
< symtab_list_
.size(); ++i
)
19138 if (!symtab_list_
[i
].valid())
19141 local_data(i
).vector_store
19142 .symbol_exists(vector_name
)
19150 inline std::string
get_variable_name(const expression_node_ptr
& ptr
) const
19152 return local_data().variable_store
.entity_name(ptr
);
19155 inline std::string
get_vector_name(const vector_holder_ptr
& ptr
) const
19157 return local_data().vector_store
.entity_name(ptr
);
19160 #ifndef exprtk_disable_string_capabilities
19161 inline std::string
get_stringvar_name(const expression_node_ptr
& ptr
) const
19163 return local_data().stringvar_store
.entity_name(ptr
);
19166 inline std::string
get_conststr_stringvar_name(const expression_node_ptr
& ptr
) const
19168 return local_data().stringvar_store
.entity_name(ptr
);
19172 inline local_data_t
& local_data(const std::size_t& index
= 0)
19174 return symtab_list_
[index
].local_data();
19177 inline const local_data_t
& local_data(const std::size_t& index
= 0) const
19179 return symtab_list_
[index
].local_data();
19182 inline symbol_table_t
& get_symbol_table(const std::size_t& index
= 0)
19184 return symtab_list_
[index
];
19188 struct parser_state
19191 : type_check_enabled(true)
19198 parsing_return_stmt
= false;
19199 parsing_break_stmt
= false;
19200 return_stmt_present
= false;
19201 side_effect_present
= false;
19205 #ifndef exprtk_enable_debugging
19206 void activate_side_effect(const std::string
&)
19208 void activate_side_effect(const std::string
& source
)
19211 if (!side_effect_present
)
19213 side_effect_present
= true;
19215 exprtk_debug(("activate_side_effect() - caller: %s\n",source
.c_str()));
19219 bool parsing_return_stmt
;
19220 bool parsing_break_stmt
;
19221 bool return_stmt_present
;
19222 bool side_effect_present
;
19223 bool type_check_enabled
;
19224 std::size_t scope_depth
;
19229 struct unknown_symbol_resolver
19232 enum usr_symbol_type
19234 e_usr_unknown_type
= 0,
19235 e_usr_variable_type
= 1,
19236 e_usr_constant_type
= 2
19241 e_usrmode_default
= 0,
19242 e_usrmode_extended
= 1
19247 unknown_symbol_resolver(const usr_mode m
= e_usrmode_default
)
19251 virtual ~unknown_symbol_resolver()
19254 virtual bool process(const std::string
& /*unknown_symbol*/,
19255 usr_symbol_type
& st
,
19257 std::string
& error_message
)
19259 if (e_usrmode_default
!= mode
)
19262 st
= e_usr_variable_type
;
19263 default_value
= T(0);
19264 error_message
.clear();
19269 virtual bool process(const std::string
& /* unknown_symbol */,
19270 symbol_table_t
& /* symbol_table */,
19271 std::string
& /* error_message */)
19280 e_ct_variables
= 1,
19281 e_ct_functions
= 2,
19282 e_ct_assignments
= 4
19293 e_st_local_variable
= 6,
19294 e_st_local_vector
= 7,
19295 e_st_local_string
= 8
19298 class dependent_entity_collector
19302 typedef std::pair
<std::string
,symbol_type
> symbol_t
;
19303 typedef std::vector
<symbol_t
> symbol_list_t
;
19305 dependent_entity_collector(const std::size_t options
= e_ct_none
)
19306 : options_(options
),
19307 collect_variables_ ((options_
& e_ct_variables
) == e_ct_variables
),
19308 collect_functions_ ((options_
& e_ct_functions
) == e_ct_functions
),
19309 collect_assignments_((options_
& e_ct_assignments
) == e_ct_assignments
),
19310 return_present_ (false),
19311 final_stmt_return_(false)
19314 template <typename Allocator
,
19315 template <typename
, typename
> class Sequence
>
19316 inline std::size_t symbols(Sequence
<symbol_t
,Allocator
>& symbols_list
)
19318 if (!collect_variables_
&& !collect_functions_
)
19320 else if (symbol_name_list_
.empty())
19323 for (std::size_t i
= 0; i
< symbol_name_list_
.size(); ++i
)
19325 details::case_normalise(symbol_name_list_
[i
].first
);
19328 std::sort(symbol_name_list_
.begin(),symbol_name_list_
.end());
19330 std::unique_copy(symbol_name_list_
.begin(),
19331 symbol_name_list_
.end (),
19332 std::back_inserter(symbols_list
));
19334 return symbols_list
.size();
19337 template <typename Allocator
,
19338 template <typename
, typename
> class Sequence
>
19339 inline std::size_t assignment_symbols(Sequence
<symbol_t
,Allocator
>& assignment_list
)
19341 if (!collect_assignments_
)
19343 else if (assignment_name_list_
.empty())
19346 for (std::size_t i
= 0; i
< assignment_name_list_
.size(); ++i
)
19348 details::case_normalise(assignment_name_list_
[i
].first
);
19351 std::sort(assignment_name_list_
.begin(),assignment_name_list_
.end());
19353 std::unique_copy(assignment_name_list_
.begin(),
19354 assignment_name_list_
.end (),
19355 std::back_inserter(assignment_list
));
19357 return assignment_list
.size();
19362 symbol_name_list_
.clear();
19363 assignment_name_list_
.clear();
19364 retparam_list_
.clear();
19365 return_present_
= false;
19366 final_stmt_return_
= false;
19369 bool& collect_variables()
19371 return collect_variables_
;
19374 bool& collect_functions()
19376 return collect_functions_
;
19379 bool& collect_assignments()
19381 return collect_assignments_
;
19384 bool return_present() const
19386 return return_present_
;
19389 bool final_stmt_return() const
19391 return final_stmt_return_
;
19394 typedef std::vector
<std::string
> retparam_list_t
;
19396 retparam_list_t
return_param_type_list() const
19398 return retparam_list_
;
19403 inline void add_symbol(const std::string
& symbol
, const symbol_type st
)
19407 case e_st_variable
:
19410 case e_st_local_variable
:
19411 case e_st_local_vector
:
19412 case e_st_local_string
: if (collect_variables_
)
19414 .push_back(std::make_pair(symbol
, st
));
19417 case e_st_function
: if (collect_functions_
)
19419 .push_back(std::make_pair(symbol
, st
));
19426 inline void add_assignment(const std::string
& symbol
, const symbol_type st
)
19430 case e_st_variable
:
19432 case e_st_string
: if (collect_assignments_
)
19433 assignment_name_list_
19434 .push_back(std::make_pair(symbol
, st
));
19441 std::size_t options_
;
19442 bool collect_variables_
;
19443 bool collect_functions_
;
19444 bool collect_assignments_
;
19445 bool return_present_
;
19446 bool final_stmt_return_
;
19447 symbol_list_t symbol_name_list_
;
19448 symbol_list_t assignment_name_list_
;
19449 retparam_list_t retparam_list_
;
19451 friend class parser
<T
>;
19454 class settings_store
19458 typedef std::set
<std::string
,details::ilesscompare
> disabled_entity_set_t
;
19459 typedef disabled_entity_set_t::iterator des_itr_t
;
19463 enum settings_compilation_options
19468 e_numeric_check
= 4,
19469 e_bracket_check
= 8,
19470 e_sequence_check
= 16,
19471 e_commutative_check
= 32,
19472 e_strength_reduction
= 64,
19473 e_disable_vardef
= 128,
19474 e_collect_vars
= 256,
19475 e_collect_funcs
= 512,
19476 e_collect_assings
= 1024,
19477 e_disable_usr_on_rsrvd
= 2048,
19478 e_disable_zero_return
= 4096
19481 enum settings_base_funcs
19484 e_bf_abs
, e_bf_acos
, e_bf_acosh
, e_bf_asin
,
19485 e_bf_asinh
, e_bf_atan
, e_bf_atan2
, e_bf_atanh
,
19486 e_bf_avg
, e_bf_ceil
, e_bf_clamp
, e_bf_cos
,
19487 e_bf_cosh
, e_bf_cot
, e_bf_csc
, e_bf_equal
,
19488 e_bf_erf
, e_bf_erfc
, e_bf_exp
, e_bf_expm1
,
19489 e_bf_floor
, e_bf_frac
, e_bf_hypot
, e_bf_iclamp
,
19490 e_bf_like
, e_bf_log
, e_bf_log10
, e_bf_log1p
,
19491 e_bf_log2
, e_bf_logn
, e_bf_mand
, e_bf_max
,
19492 e_bf_min
, e_bf_mod
, e_bf_mor
, e_bf_mul
,
19493 e_bf_ncdf
, e_bf_pow
, e_bf_root
, e_bf_round
,
19494 e_bf_roundn
, e_bf_sec
, e_bf_sgn
, e_bf_sin
,
19495 e_bf_sinc
, e_bf_sinh
, e_bf_sqrt
, e_bf_sum
,
19496 e_bf_swap
, e_bf_tan
, e_bf_tanh
, e_bf_trunc
,
19497 e_bf_not_equal
, e_bf_inrange
, e_bf_deg2grad
, e_bf_deg2rad
,
19498 e_bf_rad2deg
, e_bf_grad2deg
19501 enum settings_control_structs
19503 e_ctrl_unknown
= 0,
19508 e_ctrl_repeat_loop
,
19512 enum settings_logic_opr
19514 e_logic_unknown
= 0,
19515 e_logic_and
, e_logic_nand
, e_logic_nor
,
19516 e_logic_not
, e_logic_or
, e_logic_xnor
,
19517 e_logic_xor
, e_logic_scand
, e_logic_scor
19520 enum settings_arithmetic_opr
19522 e_arith_unknown
= 0,
19523 e_arith_add
, e_arith_sub
, e_arith_mul
,
19524 e_arith_div
, e_arith_mod
, e_arith_pow
19527 enum settings_assignment_opr
19529 e_assign_unknown
= 0,
19530 e_assign_assign
, e_assign_addass
, e_assign_subass
,
19531 e_assign_mulass
, e_assign_divass
, e_assign_modass
19534 enum settings_inequality_opr
19536 e_ineq_unknown
= 0,
19537 e_ineq_lt
, e_ineq_lte
, e_ineq_eq
,
19538 e_ineq_equal
, e_ineq_ne
, e_ineq_nequal
,
19539 e_ineq_gte
, e_ineq_gt
19542 static const std::size_t compile_all_opts
= e_replacer
+
19547 e_commutative_check
+
19548 e_strength_reduction
;
19550 settings_store(const std::size_t compile_options
= compile_all_opts
)
19552 load_compile_options(compile_options
);
19555 settings_store
& enable_all_base_functions()
19557 disabled_func_set_
.clear();
19561 settings_store
& enable_all_control_structures()
19563 disabled_ctrl_set_
.clear();
19567 settings_store
& enable_all_logic_ops()
19569 disabled_logic_set_
.clear();
19573 settings_store
& enable_all_arithmetic_ops()
19575 disabled_arithmetic_set_
.clear();
19579 settings_store
& enable_all_assignment_ops()
19581 disabled_assignment_set_
.clear();
19585 settings_store
& enable_all_inequality_ops()
19587 disabled_inequality_set_
.clear();
19591 settings_store
& enable_local_vardef()
19593 disable_vardef_
= false;
19597 settings_store
& disable_all_base_functions()
19599 std::copy(details::base_function_list
,
19600 details::base_function_list
+ details::base_function_list_size
,
19601 std::insert_iterator
<disabled_entity_set_t
>
19602 (disabled_func_set_
, disabled_func_set_
.begin()));
19606 settings_store
& disable_all_control_structures()
19608 std::copy(details::cntrl_struct_list
,
19609 details::cntrl_struct_list
+ details::cntrl_struct_list_size
,
19610 std::insert_iterator
<disabled_entity_set_t
>
19611 (disabled_ctrl_set_
, disabled_ctrl_set_
.begin()));
19615 settings_store
& disable_all_logic_ops()
19617 std::copy(details::logic_ops_list
,
19618 details::logic_ops_list
+ details::logic_ops_list_size
,
19619 std::insert_iterator
<disabled_entity_set_t
>
19620 (disabled_logic_set_
, disabled_logic_set_
.begin()));
19624 settings_store
& disable_all_arithmetic_ops()
19626 std::copy(details::arithmetic_ops_list
,
19627 details::arithmetic_ops_list
+ details::arithmetic_ops_list_size
,
19628 std::insert_iterator
<disabled_entity_set_t
>
19629 (disabled_arithmetic_set_
, disabled_arithmetic_set_
.begin()));
19633 settings_store
& disable_all_assignment_ops()
19635 std::copy(details::assignment_ops_list
,
19636 details::assignment_ops_list
+ details::assignment_ops_list_size
,
19637 std::insert_iterator
<disabled_entity_set_t
>
19638 (disabled_assignment_set_
, disabled_assignment_set_
.begin()));
19642 settings_store
& disable_all_inequality_ops()
19644 std::copy(details::inequality_ops_list
,
19645 details::inequality_ops_list
+ details::inequality_ops_list_size
,
19646 std::insert_iterator
<disabled_entity_set_t
>
19647 (disabled_inequality_set_
, disabled_inequality_set_
.begin()));
19651 settings_store
& disable_local_vardef()
19653 disable_vardef_
= true;
19657 bool replacer_enabled () const { return enable_replacer_
; }
19658 bool commutative_check_enabled () const { return enable_commutative_check_
; }
19659 bool joiner_enabled () const { return enable_joiner_
; }
19660 bool numeric_check_enabled () const { return enable_numeric_check_
; }
19661 bool bracket_check_enabled () const { return enable_bracket_check_
; }
19662 bool sequence_check_enabled () const { return enable_sequence_check_
; }
19663 bool strength_reduction_enabled () const { return enable_strength_reduction_
; }
19664 bool collect_variables_enabled () const { return enable_collect_vars_
; }
19665 bool collect_functions_enabled () const { return enable_collect_funcs_
; }
19666 bool collect_assignments_enabled() const { return enable_collect_assings_
; }
19667 bool vardef_disabled () const { return disable_vardef_
; }
19668 bool rsrvd_sym_usr_disabled () const { return disable_rsrvd_sym_usr_
; }
19669 bool zero_return_disabled () const { return disable_zero_return_
; }
19671 bool function_enabled(const std::string
& function_name
) const
19673 if (disabled_func_set_
.empty())
19676 return (disabled_func_set_
.end() == disabled_func_set_
.find(function_name
));
19679 bool control_struct_enabled(const std::string
& control_struct
) const
19681 if (disabled_ctrl_set_
.empty())
19684 return (disabled_ctrl_set_
.end() == disabled_ctrl_set_
.find(control_struct
));
19687 bool logic_enabled(const std::string
& logic_operation
) const
19689 if (disabled_logic_set_
.empty())
19692 return (disabled_logic_set_
.end() == disabled_logic_set_
.find(logic_operation
));
19695 bool arithmetic_enabled(const details::operator_type
& arithmetic_operation
) const
19697 if (disabled_logic_set_
.empty())
19700 return disabled_arithmetic_set_
.end() == disabled_arithmetic_set_
19701 .find(arith_opr_to_string(arithmetic_operation
));
19704 bool assignment_enabled(const details::operator_type
& assignment
) const
19706 if (disabled_assignment_set_
.empty())
19709 return disabled_assignment_set_
.end() == disabled_assignment_set_
19710 .find(assign_opr_to_string(assignment
));
19713 bool inequality_enabled(const details::operator_type
& inequality
) const
19715 if (disabled_inequality_set_
.empty())
19718 return disabled_inequality_set_
.end() == disabled_inequality_set_
19719 .find(inequality_opr_to_string(inequality
));
19722 bool function_disabled(const std::string
& function_name
) const
19724 if (disabled_func_set_
.empty())
19727 return (disabled_func_set_
.end() != disabled_func_set_
.find(function_name
));
19730 bool control_struct_disabled(const std::string
& control_struct
) const
19732 if (disabled_ctrl_set_
.empty())
19735 return (disabled_ctrl_set_
.end() != disabled_ctrl_set_
.find(control_struct
));
19738 bool logic_disabled(const std::string
& logic_operation
) const
19740 if (disabled_logic_set_
.empty())
19743 return (disabled_logic_set_
.end() != disabled_logic_set_
.find(logic_operation
));
19746 bool assignment_disabled(const details::operator_type assignment_operation
) const
19748 if (disabled_assignment_set_
.empty())
19751 return disabled_assignment_set_
.end() != disabled_assignment_set_
19752 .find(assign_opr_to_string(assignment_operation
));
19755 bool logic_disabled(const details::operator_type logic_operation
) const
19757 if (disabled_logic_set_
.empty())
19760 return disabled_logic_set_
.end() != disabled_logic_set_
19761 .find(logic_opr_to_string(logic_operation
));
19764 bool arithmetic_disabled(const details::operator_type arithmetic_operation
) const
19766 if (disabled_arithmetic_set_
.empty())
19769 return disabled_arithmetic_set_
.end() != disabled_arithmetic_set_
19770 .find(arith_opr_to_string(arithmetic_operation
));
19773 bool inequality_disabled(const details::operator_type
& inequality
) const
19775 if (disabled_inequality_set_
.empty())
19778 return disabled_inequality_set_
.end() != disabled_inequality_set_
19779 .find(inequality_opr_to_string(inequality
));
19782 settings_store
& disable_base_function(settings_base_funcs bf
)
19785 (e_bf_unknown
!= bf
) &&
19786 (static_cast<std::size_t>(bf
) < (details::base_function_list_size
+ 1))
19789 disabled_func_set_
.insert(details::base_function_list
[bf
- 1]);
19795 settings_store
& disable_control_structure(settings_control_structs ctrl_struct
)
19798 (e_ctrl_unknown
!= ctrl_struct
) &&
19799 (static_cast<std::size_t>(ctrl_struct
) < (details::cntrl_struct_list_size
+ 1))
19802 disabled_ctrl_set_
.insert(details::cntrl_struct_list
[ctrl_struct
- 1]);
19808 settings_store
& disable_logic_operation(settings_logic_opr logic
)
19811 (e_logic_unknown
!= logic
) &&
19812 (static_cast<std::size_t>(logic
) < (details::logic_ops_list_size
+ 1))
19815 disabled_logic_set_
.insert(details::logic_ops_list
[logic
- 1]);
19821 settings_store
& disable_arithmetic_operation(settings_arithmetic_opr arithmetic
)
19824 (e_arith_unknown
!= arithmetic
) &&
19825 (static_cast<std::size_t>(arithmetic
) < (details::arithmetic_ops_list_size
+ 1))
19828 disabled_arithmetic_set_
.insert(details::arithmetic_ops_list
[arithmetic
- 1]);
19834 settings_store
& disable_assignment_operation(settings_assignment_opr assignment
)
19837 (e_assign_unknown
!= assignment
) &&
19838 (static_cast<std::size_t>(assignment
) < (details::assignment_ops_list_size
+ 1))
19841 disabled_assignment_set_
.insert(details::assignment_ops_list
[assignment
- 1]);
19847 settings_store
& disable_inequality_operation(settings_inequality_opr inequality
)
19850 (e_ineq_unknown
!= inequality
) &&
19851 (static_cast<std::size_t>(inequality
) < (details::inequality_ops_list_size
+ 1))
19854 disabled_inequality_set_
.insert(details::inequality_ops_list
[inequality
- 1]);
19860 settings_store
& enable_base_function(settings_base_funcs bf
)
19863 (e_bf_unknown
!= bf
) &&
19864 (static_cast<std::size_t>(bf
) < (details::base_function_list_size
+ 1))
19867 const des_itr_t itr
= disabled_func_set_
.find(details::base_function_list
[bf
- 1]);
19869 if (disabled_func_set_
.end() != itr
)
19871 disabled_func_set_
.erase(itr
);
19878 settings_store
& enable_control_structure(settings_control_structs ctrl_struct
)
19881 (e_ctrl_unknown
!= ctrl_struct
) &&
19882 (static_cast<std::size_t>(ctrl_struct
) < (details::cntrl_struct_list_size
+ 1))
19885 const des_itr_t itr
= disabled_ctrl_set_
.find(details::cntrl_struct_list
[ctrl_struct
- 1]);
19887 if (disabled_ctrl_set_
.end() != itr
)
19889 disabled_ctrl_set_
.erase(itr
);
19896 settings_store
& enable_logic_operation(settings_logic_opr logic
)
19899 (e_logic_unknown
!= logic
) &&
19900 (static_cast<std::size_t>(logic
) < (details::logic_ops_list_size
+ 1))
19903 const des_itr_t itr
= disabled_logic_set_
.find(details::logic_ops_list
[logic
- 1]);
19905 if (disabled_logic_set_
.end() != itr
)
19907 disabled_logic_set_
.erase(itr
);
19914 settings_store
& enable_arithmetic_operation(settings_arithmetic_opr arithmetic
)
19917 (e_arith_unknown
!= arithmetic
) &&
19918 (static_cast<std::size_t>(arithmetic
) < (details::arithmetic_ops_list_size
+ 1))
19921 const des_itr_t itr
= disabled_arithmetic_set_
.find(details::arithmetic_ops_list
[arithmetic
- 1]);
19923 if (disabled_arithmetic_set_
.end() != itr
)
19925 disabled_arithmetic_set_
.erase(itr
);
19932 settings_store
& enable_assignment_operation(settings_assignment_opr assignment
)
19935 (e_assign_unknown
!= assignment
) &&
19936 (static_cast<std::size_t>(assignment
) < (details::assignment_ops_list_size
+ 1))
19939 const des_itr_t itr
= disabled_assignment_set_
.find(details::assignment_ops_list
[assignment
- 1]);
19941 if (disabled_assignment_set_
.end() != itr
)
19943 disabled_assignment_set_
.erase(itr
);
19950 settings_store
& enable_inequality_operation(settings_inequality_opr inequality
)
19953 (e_ineq_unknown
!= inequality
) &&
19954 (static_cast<std::size_t>(inequality
) < (details::inequality_ops_list_size
+ 1))
19957 const des_itr_t itr
= disabled_inequality_set_
.find(details::inequality_ops_list
[inequality
- 1]);
19959 if (disabled_inequality_set_
.end() != itr
)
19961 disabled_inequality_set_
.erase(itr
);
19970 void load_compile_options(const std::size_t compile_options
)
19972 enable_replacer_
= (compile_options
& e_replacer
) == e_replacer
;
19973 enable_joiner_
= (compile_options
& e_joiner
) == e_joiner
;
19974 enable_numeric_check_
= (compile_options
& e_numeric_check
) == e_numeric_check
;
19975 enable_bracket_check_
= (compile_options
& e_bracket_check
) == e_bracket_check
;
19976 enable_sequence_check_
= (compile_options
& e_sequence_check
) == e_sequence_check
;
19977 enable_commutative_check_
= (compile_options
& e_commutative_check
) == e_commutative_check
;
19978 enable_strength_reduction_
= (compile_options
& e_strength_reduction
) == e_strength_reduction
;
19979 enable_collect_vars_
= (compile_options
& e_collect_vars
) == e_collect_vars
;
19980 enable_collect_funcs_
= (compile_options
& e_collect_funcs
) == e_collect_funcs
;
19981 enable_collect_assings_
= (compile_options
& e_collect_assings
) == e_collect_assings
;
19982 disable_vardef_
= (compile_options
& e_disable_vardef
) == e_disable_vardef
;
19983 disable_rsrvd_sym_usr_
= (compile_options
& e_disable_usr_on_rsrvd
) == e_disable_usr_on_rsrvd
;
19984 disable_zero_return_
= (compile_options
& e_disable_zero_return
) == e_disable_zero_return
;
19987 std::string
assign_opr_to_string(details::operator_type opr
) const
19991 case details::e_assign
: return ":=";
19992 case details::e_addass
: return "+=";
19993 case details::e_subass
: return "-=";
19994 case details::e_mulass
: return "*=";
19995 case details::e_divass
: return "/=";
19996 case details::e_modass
: return "%=";
19997 default : return "";
20001 std::string
arith_opr_to_string(details::operator_type opr
) const
20005 case details::e_add
: return "+";
20006 case details::e_sub
: return "-";
20007 case details::e_mul
: return "*";
20008 case details::e_div
: return "/";
20009 case details::e_mod
: return "%";
20010 default : return "";
20014 std::string
inequality_opr_to_string(details::operator_type opr
) const
20018 case details::e_lt
: return "<";
20019 case details::e_lte
: return "<=";
20020 case details::e_eq
: return "==";
20021 case details::e_equal
: return "=";
20022 case details::e_ne
: return "!=";
20023 case details::e_nequal
: return "<>";
20024 case details::e_gte
: return ">=";
20025 case details::e_gt
: return ">";
20026 default : return "";
20030 std::string
logic_opr_to_string(details::operator_type opr
) const
20034 case details::e_and
: return "and" ;
20035 case details::e_or
: return "or" ;
20036 case details::e_xor
: return "xor" ;
20037 case details::e_nand
: return "nand";
20038 case details::e_nor
: return "nor" ;
20039 case details::e_xnor
: return "xnor";
20040 case details::e_notl
: return "not" ;
20041 default : return "" ;
20045 bool enable_replacer_
;
20046 bool enable_joiner_
;
20047 bool enable_numeric_check_
;
20048 bool enable_bracket_check_
;
20049 bool enable_sequence_check_
;
20050 bool enable_commutative_check_
;
20051 bool enable_strength_reduction_
;
20052 bool enable_collect_vars_
;
20053 bool enable_collect_funcs_
;
20054 bool enable_collect_assings_
;
20055 bool disable_vardef_
;
20056 bool disable_rsrvd_sym_usr_
;
20057 bool disable_zero_return_
;
20059 disabled_entity_set_t disabled_func_set_
;
20060 disabled_entity_set_t disabled_ctrl_set_
;
20061 disabled_entity_set_t disabled_logic_set_
;
20062 disabled_entity_set_t disabled_arithmetic_set_
;
20063 disabled_entity_set_t disabled_assignment_set_
;
20064 disabled_entity_set_t disabled_inequality_set_
;
20066 friend class parser
<T
>;
20069 typedef settings_store settings_t
;
20071 parser(const settings_t
& settings
= settings_t())
20072 : settings_(settings
),
20073 resolve_unknown_symbol_(false),
20074 results_context_(0),
20075 unknown_symbol_resolver_(reinterpret_cast<unknown_symbol_resolver
*>(0)),
20077 #pragma warning(push)
20078 #pragma warning (disable:4355)
20082 #pragma warning(pop)
20084 operator_joiner_2_(2),
20085 operator_joiner_3_(3)
20087 init_precompilation();
20089 load_operations_map (base_ops_map_
);
20090 load_unary_operations_map (unary_op_map_
);
20091 load_binary_operations_map (binary_op_map_
);
20092 load_inv_binary_operations_map(inv_binary_op_map_
);
20093 load_sf3_map (sf3_map_
);
20094 load_sf4_map (sf4_map_
);
20096 expression_generator_
.init_synthesize_map();
20097 expression_generator_
.set_parser(*this);
20098 expression_generator_
.set_uom(unary_op_map_
);
20099 expression_generator_
.set_bom(binary_op_map_
);
20100 expression_generator_
.set_ibom(inv_binary_op_map_
);
20101 expression_generator_
.set_sf3m(sf3_map_
);
20102 expression_generator_
.set_sf4m(sf4_map_
);
20103 expression_generator_
.set_strength_reduction_state(settings_
.strength_reduction_enabled());
20109 inline void init_precompilation()
20111 if (settings_
.collect_variables_enabled())
20112 dec_
.collect_variables() = true;
20114 if (settings_
.collect_functions_enabled())
20115 dec_
.collect_functions() = true;
20117 if (settings_
.collect_assignments_enabled())
20118 dec_
.collect_assignments() = true;
20120 if (settings_
.replacer_enabled())
20122 symbol_replacer_
.clear();
20123 symbol_replacer_
.add_replace("true" , "1", lexer::token::e_number
);
20124 symbol_replacer_
.add_replace("false", "0", lexer::token::e_number
);
20125 helper_assembly_
.token_modifier_list
.clear();
20126 helper_assembly_
.register_modifier(&symbol_replacer_
);
20129 if (settings_
.commutative_check_enabled())
20131 for (std::size_t i
= 0; i
< details::reserved_words_size
; ++i
)
20133 commutative_inserter_
.ignore_symbol(details::reserved_words
[i
]);
20136 helper_assembly_
.token_inserter_list
.clear();
20137 helper_assembly_
.register_inserter(&commutative_inserter_
);
20140 if (settings_
.joiner_enabled())
20142 helper_assembly_
.token_joiner_list
.clear();
20143 helper_assembly_
.register_joiner(&operator_joiner_2_
);
20144 helper_assembly_
.register_joiner(&operator_joiner_3_
);
20148 settings_
.numeric_check_enabled () ||
20149 settings_
.bracket_check_enabled () ||
20150 settings_
.sequence_check_enabled()
20153 helper_assembly_
.token_scanner_list
.clear();
20155 if (settings_
.numeric_check_enabled())
20157 helper_assembly_
.register_scanner(&numeric_checker_
);
20160 if (settings_
.bracket_check_enabled())
20162 helper_assembly_
.register_scanner(&bracket_checker_
);
20165 if (settings_
.sequence_check_enabled())
20167 helper_assembly_
.register_scanner(&sequence_validator_
);
20168 helper_assembly_
.register_scanner(&sequence_validator_3tkns_
);
20173 inline bool compile(const std::string
& expression_string
, expression
<T
>& expr
)
20176 error_list_
.clear();
20177 brkcnt_list_
.clear();
20178 synthesis_error_
.clear();
20183 expression_generator_
.set_allocator(node_allocator_
);
20185 if (expression_string
.empty())
20188 make_error(parser_error::e_syntax
,
20189 "ERR000 - Empty expression!",
20190 exprtk_error_location
));
20195 if (!init(expression_string
))
20197 process_lexer_errors();
20201 if (lexer().empty())
20204 make_error(parser_error::e_syntax
,
20205 "ERR001 - Empty expression!",
20206 exprtk_error_location
));
20211 if (!run_assemblies())
20216 symtab_store_
.symtab_list_
= expr
.get_symbol_table_list();
20223 expression_node_ptr e
= parse_corpus();
20225 if ((0 != e
) && (token_t::e_eof
== current_token().type
))
20227 bool* retinvk_ptr
= 0;
20229 if (state_
.return_stmt_present
)
20231 dec_
.return_present_
= true;
20233 e
= expression_generator_
20234 .return_envelope(e
, results_context_
, retinvk_ptr
);
20237 expr
.set_expression(e
);
20238 expr
.set_retinvk(retinvk_ptr
);
20240 register_local_vars(expr
);
20241 register_return_results(expr
);
20247 if (error_list_
.empty())
20250 make_error(parser_error::e_syntax
,
20252 "ERR002 - Invalid expression encountered",
20253 exprtk_error_location
));
20256 if ((0 != e
) && branch_deletable(e
))
20269 inline expression_t
compile(const std::string
& expression_string
, symbol_table_t
& symtab
)
20273 expr
.register_symbol_table(symtab
);
20275 compile(expression_string
,expr
);
20280 void process_lexer_errors()
20282 for (std::size_t i
= 0; i
< lexer().size(); ++i
)
20284 if (lexer()[i
].is_error())
20286 std::string diagnostic
= "ERR003 - ";
20288 switch (lexer()[i
].type
)
20290 case lexer::token::e_error
: diagnostic
+= "General token error";
20293 case lexer::token::e_err_symbol
: diagnostic
+= "Symbol error";
20296 case lexer::token::e_err_number
: diagnostic
+= "Invalid numeric token";
20299 case lexer::token::e_err_string
: diagnostic
+= "Invalid string token";
20302 case lexer::token::e_err_sfunc
: diagnostic
+= "Invalid special function token";
20305 default : diagnostic
+= "Unknown compiler error";
20309 make_error(parser_error::e_lexer
,
20311 diagnostic
+ ": " + lexer()[i
].value
,
20312 exprtk_error_location
));
20317 inline bool run_assemblies()
20319 if (settings_
.commutative_check_enabled())
20321 helper_assembly_
.run_inserters(lexer());
20324 if (settings_
.joiner_enabled())
20326 helper_assembly_
.run_joiners(lexer());
20329 if (settings_
.replacer_enabled())
20331 helper_assembly_
.run_modifiers(lexer());
20335 settings_
.numeric_check_enabled () ||
20336 settings_
.bracket_check_enabled () ||
20337 settings_
.sequence_check_enabled()
20340 if (!helper_assembly_
.run_scanners(lexer()))
20342 if (helper_assembly_
.error_token_scanner
)
20344 lexer::helper::bracket_checker
* bracket_checker_ptr
= 0;
20345 lexer::helper::numeric_checker
* numeric_checker_ptr
= 0;
20346 lexer::helper::sequence_validator
* sequence_validator_ptr
= 0;
20347 lexer::helper::sequence_validator_3tokens
* sequence_validator3_ptr
= 0;
20349 if (0 != (bracket_checker_ptr
= dynamic_cast<lexer::helper::bracket_checker
*>(helper_assembly_
.error_token_scanner
)))
20352 make_error(parser_error::e_token
,
20353 bracket_checker_ptr
->error_token(),
20354 "ERR004 - Mismatched brackets: '" + bracket_checker_ptr
->error_token().value
+ "'",
20355 exprtk_error_location
));
20357 else if (0 != (numeric_checker_ptr
= dynamic_cast<lexer::helper::numeric_checker
*>(helper_assembly_
.error_token_scanner
)))
20359 for (std::size_t i
= 0; i
< numeric_checker_ptr
->error_count(); ++i
)
20361 lexer::token error_token
= lexer()[numeric_checker_ptr
->error_index(i
)];
20364 make_error(parser_error::e_token
,
20366 "ERR005 - Invalid numeric token: '" + error_token
.value
+ "'",
20367 exprtk_error_location
));
20370 if (numeric_checker_ptr
->error_count())
20372 numeric_checker_ptr
->clear_errors();
20375 else if (0 != (sequence_validator_ptr
= dynamic_cast<lexer::helper::sequence_validator
*>(helper_assembly_
.error_token_scanner
)))
20377 for (std::size_t i
= 0; i
< sequence_validator_ptr
->error_count(); ++i
)
20379 std::pair
<lexer::token
,lexer::token
> error_token
= sequence_validator_ptr
->error(i
);
20382 make_error(parser_error::e_token
,
20384 "ERR006 - Invalid token sequence: '" +
20385 error_token
.first
.value
+ "' and '" +
20386 error_token
.second
.value
+ "'",
20387 exprtk_error_location
));
20390 if (sequence_validator_ptr
->error_count())
20392 sequence_validator_ptr
->clear_errors();
20395 else if (0 != (sequence_validator3_ptr
= dynamic_cast<lexer::helper::sequence_validator_3tokens
*>(helper_assembly_
.error_token_scanner
)))
20397 for (std::size_t i
= 0; i
< sequence_validator3_ptr
->error_count(); ++i
)
20399 std::pair
<lexer::token
,lexer::token
> error_token
= sequence_validator3_ptr
->error(i
);
20402 make_error(parser_error::e_token
,
20404 "ERR007 - Invalid token sequence: '" +
20405 error_token
.first
.value
+ "' and '" +
20406 error_token
.second
.value
+ "'",
20407 exprtk_error_location
));
20410 if (sequence_validator3_ptr
->error_count())
20412 sequence_validator3_ptr
->clear_errors();
20424 inline settings_store
& settings()
20429 inline parser_error::type
get_error(const std::size_t& index
) const
20431 if (index
< error_list_
.size())
20432 return error_list_
[index
];
20434 throw std::invalid_argument("parser::get_error() - Invalid error index specificed");
20437 inline std::string
error() const
20439 if (!error_list_
.empty())
20441 return error_list_
[0].diagnostic
;
20444 return std::string("No Error");
20447 inline std::size_t error_count() const
20449 return error_list_
.size();
20452 inline dependent_entity_collector
& dec()
20457 inline bool replace_symbol(const std::string
& old_symbol
, const std::string
& new_symbol
)
20459 if (!settings_
.replacer_enabled())
20461 else if (details::is_reserved_word(old_symbol
))
20464 return symbol_replacer_
.add_replace(old_symbol
,new_symbol
,lexer::token::e_symbol
);
20467 inline bool remove_replace_symbol(const std::string
& symbol
)
20469 if (!settings_
.replacer_enabled())
20471 else if (details::is_reserved_word(symbol
))
20474 return symbol_replacer_
.remove(symbol
);
20477 inline void enable_unknown_symbol_resolver(unknown_symbol_resolver
* usr
= reinterpret_cast<unknown_symbol_resolver
*>(0))
20479 resolve_unknown_symbol_
= true;
20482 unknown_symbol_resolver_
= usr
;
20484 unknown_symbol_resolver_
= &default_usr_
;
20487 inline void enable_unknown_symbol_resolver(unknown_symbol_resolver
& usr
)
20489 enable_unknown_symbol_resolver(&usr
);
20492 inline void disable_unknown_symbol_resolver()
20494 resolve_unknown_symbol_
= false;
20495 unknown_symbol_resolver_
= &default_usr_
;
20500 inline bool valid_base_operation(const std::string
& symbol
) const
20502 const std::size_t length
= symbol
.size();
20505 (length
< 3) || // Shortest base op symbol length
20506 (length
> 9) // Longest base op symbol length
20510 return settings_
.function_enabled(symbol
) &&
20511 (base_ops_map_
.end() != base_ops_map_
.find(symbol
));
20514 inline bool valid_vararg_operation(const std::string
& symbol
) const
20516 static const std::string s_sum
= "sum" ;
20517 static const std::string s_mul
= "mul" ;
20518 static const std::string s_avg
= "avg" ;
20519 static const std::string s_min
= "min" ;
20520 static const std::string s_max
= "max" ;
20521 static const std::string s_mand
= "mand";
20522 static const std::string s_mor
= "mor" ;
20523 static const std::string s_multi
= "~" ;
20524 static const std::string s_mswitch
= "[*]" ;
20528 details::imatch(symbol
,s_sum
) ||
20529 details::imatch(symbol
,s_mul
) ||
20530 details::imatch(symbol
,s_avg
) ||
20531 details::imatch(symbol
,s_min
) ||
20532 details::imatch(symbol
,s_max
) ||
20533 details::imatch(symbol
,s_mand
) ||
20534 details::imatch(symbol
,s_mor
) ||
20535 details::imatch(symbol
,s_multi
) ||
20536 details::imatch(symbol
,s_mswitch
)
20538 settings_
.function_enabled(symbol
);
20541 bool is_invalid_logic_operation(const details::operator_type operation
) const
20543 return settings_
.logic_disabled(operation
);
20546 bool is_invalid_arithmetic_operation(const details::operator_type operation
) const
20548 return settings_
.arithmetic_disabled(operation
);
20551 bool is_invalid_assignment_operation(const details::operator_type operation
) const
20553 return settings_
.assignment_disabled(operation
);
20556 bool is_invalid_inequality_operation(const details::operator_type operation
) const
20558 return settings_
.inequality_disabled(operation
);
20561 #ifdef exprtk_enable_debugging
20562 inline void next_token()
20564 const std::string ct_str
= current_token().value
;
20565 parser_helper::next_token();
20566 const std::string
depth(2 * state_
.scope_depth
,' ');
20568 "prev[%s] --> curr[%s]\n",
20571 current_token().value
.c_str()));
20575 inline expression_node_ptr
parse_corpus()
20577 std::vector
<expression_node_ptr
> arg_list
;
20578 std::vector
<bool> side_effect_list
;
20580 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
20582 lexer::token begin_token
;
20583 lexer::token end_token
;
20587 state_
.side_effect_present
= false;
20589 begin_token
= current_token();
20591 expression_node_ptr arg
= parse_expression();
20595 if (error_list_
.empty())
20598 make_error(parser_error::e_syntax
,
20600 "ERR008 - Invalid expression encountered",
20601 exprtk_error_location
));
20604 return error_node();
20608 arg_list
.push_back(arg
);
20610 side_effect_list
.push_back(state_
.side_effect_present
);
20612 end_token
= current_token();
20614 const std::string sub_expr
= construct_subexpr(begin_token
, end_token
);
20616 exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n",
20617 static_cast<int>(arg_list
.size() - 1),
20618 sub_expr
.c_str()));
20620 exprtk_debug(("parse_corpus(%02d) - Side effect present: %s\n",
20621 static_cast<int>(arg_list
.size() - 1),
20622 state_
.side_effect_present
? "true" : "false"));
20624 exprtk_debug(("-------------------------------------------------\n"));
20627 if (lexer().finished())
20629 else if (token_is(token_t::e_eof
,prsrhlpr_t::e_hold
))
20631 if (lexer().finished())
20639 !arg_list
.empty() &&
20640 is_return_node(arg_list
.back())
20643 dec_
.final_stmt_return_
= true;
20646 const expression_node_ptr result
= simplify(arg_list
,side_effect_list
);
20648 sdd
.delete_ptr
= (0 == result
);
20653 std::string
construct_subexpr(lexer::token
& begin_token
, lexer::token
& end_token
)
20655 std::string result
= lexer().substr(begin_token
.position
,end_token
.position
);
20657 for (std::size_t i
= 0; i
< result
.size(); ++i
)
20659 if (details::is_whitespace(result
[i
])) result
[i
] = ' ';
20665 static const precedence_level default_precedence
= e_level00
;
20669 inline void set(const precedence_level
& l
,
20670 const precedence_level
& r
,
20671 const details::operator_type
& o
)
20678 inline void reset()
20682 operation
= details::e_default
;
20685 precedence_level left
;
20686 precedence_level right
;
20687 details::operator_type operation
;
20690 inline expression_node_ptr
parse_expression(precedence_level precedence
= e_level00
)
20692 expression_node_ptr expression
= parse_branch(precedence
);
20694 if (0 == expression
)
20696 return error_node();
20699 bool break_loop
= false;
20701 state_t current_state
;
20705 current_state
.reset();
20707 switch (current_token().type
)
20709 case token_t::e_assign
: current_state
.set(e_level00
,e_level00
, details::e_assign
); break;
20710 case token_t::e_addass
: current_state
.set(e_level00
,e_level00
, details::e_addass
); break;
20711 case token_t::e_subass
: current_state
.set(e_level00
,e_level00
, details::e_subass
); break;
20712 case token_t::e_mulass
: current_state
.set(e_level00
,e_level00
, details::e_mulass
); break;
20713 case token_t::e_divass
: current_state
.set(e_level00
,e_level00
, details::e_divass
); break;
20714 case token_t::e_modass
: current_state
.set(e_level00
,e_level00
, details::e_modass
); break;
20715 case token_t::e_swap
: current_state
.set(e_level00
,e_level00
, details::e_swap
); break;
20716 case token_t::e_lt
: current_state
.set(e_level05
,e_level06
, details:: e_lt
); break;
20717 case token_t::e_lte
: current_state
.set(e_level05
,e_level06
, details:: e_lte
); break;
20718 case token_t::e_eq
: current_state
.set(e_level05
,e_level06
, details:: e_eq
); break;
20719 case token_t::e_ne
: current_state
.set(e_level05
,e_level06
, details:: e_ne
); break;
20720 case token_t::e_gte
: current_state
.set(e_level05
,e_level06
, details:: e_gte
); break;
20721 case token_t::e_gt
: current_state
.set(e_level05
,e_level06
, details:: e_gt
); break;
20722 case token_t::e_add
: current_state
.set(e_level07
,e_level08
, details:: e_add
); break;
20723 case token_t::e_sub
: current_state
.set(e_level07
,e_level08
, details:: e_sub
); break;
20724 case token_t::e_div
: current_state
.set(e_level10
,e_level11
, details:: e_div
); break;
20725 case token_t::e_mul
: current_state
.set(e_level10
,e_level11
, details:: e_mul
); break;
20726 case token_t::e_mod
: current_state
.set(e_level10
,e_level11
, details:: e_mod
); break;
20727 case token_t::e_pow
: current_state
.set(e_level12
,e_level12
, details:: e_pow
); break;
20728 default : if (token_t::e_symbol
== current_token().type
)
20730 static const std::string s_and
= "and";
20731 static const std::string s_nand
= "nand";
20732 static const std::string s_or
= "or";
20733 static const std::string s_nor
= "nor";
20734 static const std::string s_xor
= "xor";
20735 static const std::string s_xnor
= "xnor";
20736 static const std::string s_in
= "in";
20737 static const std::string s_like
= "like";
20738 static const std::string s_ilike
= "ilike";
20739 static const std::string s_and1
= "&";
20740 static const std::string s_or1
= "|";
20741 static const std::string s_not
= "not";
20743 if (details::imatch(current_token().value
,s_and
))
20745 current_state
.set(e_level03
, e_level04
, details::e_and
);
20748 else if (details::imatch(current_token().value
,s_and1
))
20750 #ifndef exprtk_disable_sc_andor
20751 current_state
.set(e_level03
, e_level04
, details::e_scand
);
20753 current_state
.set(e_level03
, e_level04
, details::e_and
);
20757 else if (details::imatch(current_token().value
,s_nand
))
20759 current_state
.set(e_level03
, e_level04
, details::e_nand
);
20762 else if (details::imatch(current_token().value
,s_or
))
20764 current_state
.set(e_level01
, e_level02
, details::e_or
);
20767 else if (details::imatch(current_token().value
,s_or1
))
20769 #ifndef exprtk_disable_sc_andor
20770 current_state
.set(e_level01
, e_level02
, details::e_scor
);
20772 current_state
.set(e_level01
, e_level02
, details::e_or
);
20776 else if (details::imatch(current_token().value
,s_nor
))
20778 current_state
.set(e_level01
, e_level02
, details::e_nor
);
20781 else if (details::imatch(current_token().value
,s_xor
))
20783 current_state
.set(e_level01
, e_level02
, details::e_xor
);
20786 else if (details::imatch(current_token().value
,s_xnor
))
20788 current_state
.set(e_level01
, e_level02
, details::e_xnor
);
20791 else if (details::imatch(current_token().value
,s_in
))
20793 current_state
.set(e_level04
, e_level04
, details::e_in
);
20796 else if (details::imatch(current_token().value
,s_like
))
20798 current_state
.set(e_level04
, e_level04
, details::e_like
);
20801 else if (details::imatch(current_token().value
,s_ilike
))
20803 current_state
.set(e_level04
, e_level04
, details::e_ilike
);
20806 else if (details::imatch(current_token().value
,s_not
))
20817 parse_pending_string_rangesize(expression
);
20820 else if (current_state
.left
< precedence
)
20823 const lexer::token prev_token
= current_token();
20827 expression_node_ptr right_branch
= error_node();
20828 expression_node_ptr new_expression
= error_node();
20830 if (is_invalid_logic_operation(current_state
.operation
))
20832 free_node(node_allocator_
,expression
);
20835 make_error(parser_error::e_syntax
,
20837 "ERR009 - Invalid or disabled logic operation '" + details::to_str(current_state
.operation
) + "'",
20838 exprtk_error_location
));
20840 return error_node();
20842 else if (is_invalid_arithmetic_operation(current_state
.operation
))
20844 free_node(node_allocator_
,expression
);
20847 make_error(parser_error::e_syntax
,
20849 "ERR010 - Invalid or disabled arithmetic operation '" + details::to_str(current_state
.operation
) + "'",
20850 exprtk_error_location
));
20852 return error_node();
20854 else if (is_invalid_inequality_operation(current_state
.operation
))
20856 free_node(node_allocator_
,expression
);
20859 make_error(parser_error::e_syntax
,
20861 "ERR011 - Invalid inequality operation '" + details::to_str(current_state
.operation
) + "'",
20862 exprtk_error_location
));
20864 return error_node();
20866 else if (is_invalid_assignment_operation(current_state
.operation
))
20868 free_node(node_allocator_
,expression
);
20871 make_error(parser_error::e_syntax
,
20873 "ERR012 - Invalid or disabled assignment operation '" + details::to_str(current_state
.operation
) + "'",
20874 exprtk_error_location
));
20876 return error_node();
20879 if (0 != (right_branch
= parse_expression(current_state
.right
)))
20882 details::is_return_node( expression
) ||
20883 details::is_return_node(right_branch
)
20886 free_node(node_allocator_
, expression
);
20887 free_node(node_allocator_
, right_branch
);
20890 make_error(parser_error::e_syntax
,
20892 "ERR013 - Return statements cannot be part of sub-expressions",
20893 exprtk_error_location
));
20895 return error_node();
20898 new_expression
= expression_generator_
20900 current_state
.operation
,
20906 if (0 == new_expression
)
20908 if (error_list_
.empty())
20911 make_error(parser_error::e_syntax
,
20913 !synthesis_error_
.empty() ?
20915 "ERR014 - General parsing error at token: '" + prev_token
.value
+ "'",
20916 exprtk_error_location
));
20919 free_node(node_allocator_
, expression
);
20920 free_node(node_allocator_
, right_branch
);
20922 return error_node();
20927 token_is(token_t::e_ternary
,prsrhlpr_t::e_hold
) &&
20928 (precedence
== e_level00
)
20931 expression
= parse_ternary_conditional_statement(new_expression
);
20934 expression
= new_expression
;
20936 parse_pending_string_rangesize(expression
);
20943 bool simplify_unary_negation_branch(expression_node_ptr
& node
)
20946 typedef details::unary_branch_node
<T
,details::neg_op
<T
> > ubn_t
;
20947 ubn_t
* n
= dynamic_cast<ubn_t
*>(node
);
20951 expression_node_ptr un_r
= n
->branch(0);
20953 free_node(node_allocator_
,node
);
20961 typedef details::unary_variable_node
<T
,details::neg_op
<T
> > uvn_t
;
20963 uvn_t
* n
= dynamic_cast<uvn_t
*>(node
);
20967 const T
& v
= n
->v();
20968 expression_node_ptr return_node
= error_node();
20971 (0 != (return_node
= symtab_store_
.get_variable(v
))) ||
20972 (0 != (return_node
= sem_
.get_variable(v
)))
20975 free_node(node_allocator_
,node
);
20976 node
= return_node
;
20983 make_error(parser_error::e_syntax
,
20985 "ERR015 - Failed to find variable node in symbol table",
20986 exprtk_error_location
));
20988 free_node(node_allocator_
,node
);
20998 static inline expression_node_ptr
error_node()
21000 return reinterpret_cast<expression_node_ptr
>(0);
21003 template <typename Type
, std::size_t N
>
21004 struct scoped_delete
21006 typedef Type
* ptr_t
;
21008 scoped_delete(parser
<T
>& pr
, ptr_t
& p
)
21009 : delete_ptr(true),
21014 scoped_delete(parser
<T
>& pr
, ptr_t (&p
)[N
])
21015 : delete_ptr(true),
21024 for (std::size_t i
= 0; i
< N
; ++i
)
21026 free_node(parser_
.node_allocator_
,p_
[i
]);
21032 parser
<T
>& parser_
;
21037 scoped_delete
<Type
,N
>& operator=(const scoped_delete
<Type
,N
>&);
21040 template <typename Type
>
21041 struct scoped_deq_delete
21043 typedef Type
* ptr_t
;
21045 scoped_deq_delete(parser
<T
>& pr
, std::deque
<ptr_t
>& deq
)
21046 : delete_ptr(true),
21051 ~scoped_deq_delete()
21053 if (delete_ptr
&& !deq_
.empty())
21055 for (std::size_t i
= 0; i
< deq_
.size(); ++i
)
21057 free_node(parser_
.node_allocator_
,deq_
[i
]);
21065 parser
<T
>& parser_
;
21066 std::deque
<ptr_t
>& deq_
;
21070 scoped_deq_delete
<Type
>& operator=(const scoped_deq_delete
<Type
>&);
21073 template <typename Type
>
21074 struct scoped_vec_delete
21076 typedef Type
* ptr_t
;
21078 scoped_vec_delete(parser
<T
>& pr
, std::vector
<ptr_t
>& vec
)
21079 : delete_ptr(true),
21084 ~scoped_vec_delete()
21086 if (delete_ptr
&& !vec_
.empty())
21088 for (std::size_t i
= 0; i
< vec_
.size(); ++i
)
21090 free_node(parser_
.node_allocator_
,vec_
[i
]);
21098 parser
<T
>& parser_
;
21099 std::vector
<ptr_t
>& vec_
;
21103 scoped_vec_delete
<Type
>& operator=(const scoped_vec_delete
<Type
>&);
21106 struct scoped_bool_negator
21108 explicit scoped_bool_negator(bool& bb
)
21112 ~scoped_bool_negator()
21118 struct scoped_bool_or_restorer
21120 explicit scoped_bool_or_restorer(bool& bb
)
21122 original_value_(bb
)
21125 ~scoped_bool_or_restorer()
21127 b
= b
|| original_value_
;
21131 bool original_value_
;
21134 inline expression_node_ptr
parse_function_invocation(ifunction
<T
>* function
, const std::string
& function_name
)
21136 expression_node_ptr func_node
= reinterpret_cast<expression_node_ptr
>(0);
21138 switch (function
->param_count
)
21140 case 0 : func_node
= parse_function_call_0 (function
,function_name
); break;
21141 case 1 : func_node
= parse_function_call
< 1>(function
,function_name
); break;
21142 case 2 : func_node
= parse_function_call
< 2>(function
,function_name
); break;
21143 case 3 : func_node
= parse_function_call
< 3>(function
,function_name
); break;
21144 case 4 : func_node
= parse_function_call
< 4>(function
,function_name
); break;
21145 case 5 : func_node
= parse_function_call
< 5>(function
,function_name
); break;
21146 case 6 : func_node
= parse_function_call
< 6>(function
,function_name
); break;
21147 case 7 : func_node
= parse_function_call
< 7>(function
,function_name
); break;
21148 case 8 : func_node
= parse_function_call
< 8>(function
,function_name
); break;
21149 case 9 : func_node
= parse_function_call
< 9>(function
,function_name
); break;
21150 case 10 : func_node
= parse_function_call
<10>(function
,function_name
); break;
21151 case 11 : func_node
= parse_function_call
<11>(function
,function_name
); break;
21152 case 12 : func_node
= parse_function_call
<12>(function
,function_name
); break;
21153 case 13 : func_node
= parse_function_call
<13>(function
,function_name
); break;
21154 case 14 : func_node
= parse_function_call
<14>(function
,function_name
); break;
21155 case 15 : func_node
= parse_function_call
<15>(function
,function_name
); break;
21156 case 16 : func_node
= parse_function_call
<16>(function
,function_name
); break;
21157 case 17 : func_node
= parse_function_call
<17>(function
,function_name
); break;
21158 case 18 : func_node
= parse_function_call
<18>(function
,function_name
); break;
21159 case 19 : func_node
= parse_function_call
<19>(function
,function_name
); break;
21160 case 20 : func_node
= parse_function_call
<20>(function
,function_name
); break;
21163 make_error(parser_error::e_syntax
,
21165 "ERR016 - Invalid number of parameters for function: '" + function_name
+ "'",
21166 exprtk_error_location
));
21168 return error_node();
21177 make_error(parser_error::e_syntax
,
21179 "ERR017 - Failed to generate call to function: '" + function_name
+ "'",
21180 exprtk_error_location
));
21182 return error_node();
21186 template <std::size_t NumberofParameters
>
21187 inline expression_node_ptr
parse_function_call(ifunction
<T
>* function
, const std::string
& function_name
)
21190 #pragma warning(push)
21191 #pragma warning(disable: 4127)
21193 if (0 == NumberofParameters
)
21196 make_error(parser_error::e_syntax
,
21198 "ERR018 - Expecting ifunction '" + function_name
+ "' to have non-zero parameter count",
21199 exprtk_error_location
));
21201 return error_node();
21204 #pragma warning(pop)
21207 expression_node_ptr branch
[NumberofParameters
];
21208 expression_node_ptr result
= error_node();
21210 std::fill_n(branch
, NumberofParameters
, reinterpret_cast<expression_node_ptr
>(0));
21212 scoped_delete
<expression_node_t
,NumberofParameters
> sd((*this),branch
);
21216 if (!token_is(token_t::e_lbracket
))
21219 make_error(parser_error::e_syntax
,
21221 "ERR019 - Expecting argument list for function: '" + function_name
+ "'",
21222 exprtk_error_location
));
21224 return error_node();
21227 for (int i
= 0; i
< static_cast<int>(NumberofParameters
); ++i
)
21229 branch
[i
] = parse_expression();
21231 if (0 == branch
[i
])
21234 make_error(parser_error::e_syntax
,
21236 "ERR020 - Failed to parse argument " + details::to_str(i
) + " for function: '" + function_name
+ "'",
21237 exprtk_error_location
));
21239 return error_node();
21241 else if (i
< static_cast<int>(NumberofParameters
- 1))
21243 if (!token_is(token_t::e_comma
))
21246 make_error(parser_error::e_syntax
,
21248 "ERR021 - Invalid number of arguments for function: '" + function_name
+ "'",
21249 exprtk_error_location
));
21251 return error_node();
21256 if (!token_is(token_t::e_rbracket
))
21259 make_error(parser_error::e_syntax
,
21261 "ERR022 - Invalid number of arguments for function: '" + function_name
+ "'",
21262 exprtk_error_location
));
21264 return error_node();
21267 result
= expression_generator_
.function(function
,branch
);
21269 sd
.delete_ptr
= false;
21274 inline expression_node_ptr
parse_function_call_0(ifunction
<T
>* function
, const std::string
& function_name
)
21276 expression_node_ptr result
= expression_generator_
.function(function
);
21278 state_
.side_effect_present
= function
->has_side_effects();
21283 token_is(token_t::e_lbracket
) &&
21284 !token_is(token_t::e_rbracket
)
21288 make_error(parser_error::e_syntax
,
21290 "ERR023 - Expecting '()' to proceed call to function: '" + function_name
+ "'",
21291 exprtk_error_location
));
21293 free_node(node_allocator_
,result
);
21295 return error_node();
21301 template <std::size_t MaxNumberofParameters
>
21302 inline std::size_t parse_base_function_call(expression_node_ptr (¶m_list
)[MaxNumberofParameters
], const std::string
& function_name
= "")
21304 std::fill_n(param_list
, MaxNumberofParameters
, reinterpret_cast<expression_node_ptr
>(0));
21306 scoped_delete
<expression_node_t
,MaxNumberofParameters
> sd((*this),param_list
);
21310 if (!token_is(token_t::e_lbracket
))
21313 make_error(parser_error::e_syntax
,
21315 "ERR024 - Expected a '(' at start of function call to '" + function_name
+
21316 "', instead got: '" + current_token().value
+ "'",
21317 exprtk_error_location
));
21322 if (token_is(token_t::e_rbracket
, e_hold
))
21325 make_error(parser_error::e_syntax
,
21327 "ERR025 - Expected at least one input parameter for function call '" + function_name
+ "'",
21328 exprtk_error_location
));
21333 std::size_t param_index
= 0;
21335 for (; param_index
< MaxNumberofParameters
; ++param_index
)
21337 param_list
[param_index
] = parse_expression();
21339 if (0 == param_list
[param_index
])
21341 else if (token_is(token_t::e_rbracket
))
21343 sd
.delete_ptr
= false;
21346 else if (token_is(token_t::e_comma
))
21351 make_error(parser_error::e_syntax
,
21353 "ERR026 - Expected a ',' between function input parameters, instead got: '" + current_token().value
+ "'",
21354 exprtk_error_location
));
21363 make_error(parser_error::e_syntax
,
21365 "ERR027 - Invalid number of input parameters passed to function '" + function_name
+ "'",
21366 exprtk_error_location
));
21371 return (param_index
+ 1);
21374 inline expression_node_ptr
parse_base_operation()
21376 typedef std::pair
<base_ops_map_t::iterator
,base_ops_map_t::iterator
> map_range_t
;
21378 const std::string operation_name
= current_token().value
;
21379 const token_t diagnostic_token
= current_token();
21381 map_range_t itr_range
= base_ops_map_
.equal_range(operation_name
);
21383 if (0 == std::distance(itr_range
.first
,itr_range
.second
))
21386 make_error(parser_error::e_syntax
,
21388 "ERR028 - No entry found for base operation: " + operation_name
,
21389 exprtk_error_location
));
21391 return error_node();
21394 static const std::size_t MaxNumberofParameters
= 4;
21395 expression_node_ptr param_list
[MaxNumberofParameters
] = {0};
21397 const std::size_t parameter_count
= parse_base_function_call(param_list
, operation_name
);
21399 if ((parameter_count
> 0) && (parameter_count
<= MaxNumberofParameters
))
21401 for (base_ops_map_t::iterator itr
= itr_range
.first
; itr
!= itr_range
.second
; ++itr
)
21403 const details::base_operation_t
& operation
= itr
->second
;
21405 if (operation
.num_params
== parameter_count
)
21407 switch (parameter_count
)
21409 #define base_opr_case(N) \
21411 expression_node_ptr pl##N[N] = {0}; \
21412 std::copy(param_list, param_list + N, pl##N); \
21413 lodge_symbol(operation_name, e_st_function); \
21414 return expression_generator_(operation.type, pl##N); \
21421 #undef base_opr_case
21427 for (std::size_t i
= 0; i
< MaxNumberofParameters
; ++i
)
21429 free_node(node_allocator_
, param_list
[i
]);
21433 make_error(parser_error::e_syntax
,
21435 "ERR029 - Invalid number of input parameters for call to function: '" + operation_name
+ "'",
21436 exprtk_error_location
));
21438 return error_node();
21441 inline expression_node_ptr
parse_conditional_statement_01(expression_node_ptr condition
)
21443 // Parse: [if][(][condition][,][consequent][,][alternative][)]
21445 expression_node_ptr consequent
= error_node();
21446 expression_node_ptr alternative
= error_node();
21448 bool result
= true;
21450 if (!token_is(token_t::e_comma
))
21453 make_error(parser_error::e_syntax
,
21455 "ERR030 - Expected ',' between if-statement condition and consequent",
21456 exprtk_error_location
));
21459 else if (0 == (consequent
= parse_expression()))
21462 make_error(parser_error::e_syntax
,
21464 "ERR031 - Failed to parse consequent for if-statement",
21465 exprtk_error_location
));
21468 else if (!token_is(token_t::e_comma
))
21471 make_error(parser_error::e_syntax
,
21473 "ERR032 - Expected ',' between if-statement consequent and alternative",
21474 exprtk_error_location
));
21477 else if (0 == (alternative
= parse_expression()))
21480 make_error(parser_error::e_syntax
,
21482 "ERR033 - Failed to parse alternative for if-statement",
21483 exprtk_error_location
));
21486 else if (!token_is(token_t::e_rbracket
))
21489 make_error(parser_error::e_syntax
,
21491 "ERR034 - Expected ')' at the end of if-statement",
21492 exprtk_error_location
));
21496 #ifndef exprtk_disable_string_capabilities
21499 const bool consq_is_str
= is_generally_string_node( consequent
);
21500 const bool alter_is_str
= is_generally_string_node(alternative
);
21502 if (consq_is_str
|| alter_is_str
)
21504 if (consq_is_str
&& alter_is_str
)
21506 return expression_generator_
21507 .conditional_string(condition
, consequent
, alternative
);
21511 make_error(parser_error::e_syntax
,
21513 "ERR035 - Return types of ternary if-statement differ",
21514 exprtk_error_location
));
21523 free_node(node_allocator_
, condition
);
21524 free_node(node_allocator_
, consequent
);
21525 free_node(node_allocator_
,alternative
);
21527 return error_node();
21530 return expression_generator_
21531 .conditional(condition
, consequent
, alternative
);
21534 inline expression_node_ptr
parse_conditional_statement_02(expression_node_ptr condition
)
21536 expression_node_ptr consequent
= error_node();
21537 expression_node_ptr alternative
= error_node();
21539 bool result
= true;
21541 if (token_is(token_t::e_lcrlbracket
,prsrhlpr_t::e_hold
))
21543 if (0 == (consequent
= parse_multi_sequence("if-statement-01")))
21546 make_error(parser_error::e_syntax
,
21548 "ERR036 - Failed to parse body of consequent for if-statement",
21549 exprtk_error_location
));
21557 settings_
.commutative_check_enabled() &&
21558 token_is(token_t::e_mul
,prsrhlpr_t::e_hold
)
21564 if (0 != (consequent
= parse_expression()))
21566 if (!token_is(token_t::e_eof
))
21569 make_error(parser_error::e_syntax
,
21571 "ERR037 - Expected ';' at the end of the consequent for if-statement",
21572 exprtk_error_location
));
21580 make_error(parser_error::e_syntax
,
21582 "ERR038 - Failed to parse body of consequent for if-statement",
21583 exprtk_error_location
));
21591 if (details::imatch(current_token().value
,"else"))
21595 if (token_is(token_t::e_lcrlbracket
,prsrhlpr_t::e_hold
))
21597 if (0 == (alternative
= parse_multi_sequence("else-statement-01")))
21600 make_error(parser_error::e_syntax
,
21602 "ERR039 - Failed to parse body of the 'else' for if-statement",
21603 exprtk_error_location
));
21608 else if (details::imatch(current_token().value
,"if"))
21610 if (0 == (alternative
= parse_conditional_statement()))
21613 make_error(parser_error::e_syntax
,
21615 "ERR040 - Failed to parse body of if-else statement",
21616 exprtk_error_location
));
21621 else if (0 != (alternative
= parse_expression()))
21623 if (!token_is(token_t::e_eof
))
21626 make_error(parser_error::e_syntax
,
21628 "ERR041 - Expected ';' at the end of the 'else-if' for the if-statement",
21629 exprtk_error_location
));
21637 make_error(parser_error::e_syntax
,
21639 "ERR042 - Failed to parse body of the 'else' for if-statement",
21640 exprtk_error_location
));
21647 #ifndef exprtk_disable_string_capabilities
21650 const bool consq_is_str
= is_generally_string_node( consequent
);
21651 const bool alter_is_str
= is_generally_string_node(alternative
);
21653 if (consq_is_str
|| alter_is_str
)
21655 if (consq_is_str
&& alter_is_str
)
21657 return expression_generator_
21658 .conditional_string(condition
, consequent
, alternative
);
21662 make_error(parser_error::e_syntax
,
21664 "ERR043 - Return types of ternary if-statement differ",
21665 exprtk_error_location
));
21674 free_node(node_allocator_
, condition
);
21675 free_node(node_allocator_
, consequent
);
21676 free_node(node_allocator_
, alternative
);
21678 return error_node();
21681 return expression_generator_
21682 .conditional(condition
, consequent
, alternative
);
21685 inline expression_node_ptr
parse_conditional_statement()
21687 expression_node_ptr condition
= error_node();
21691 if (!token_is(token_t::e_lbracket
))
21694 make_error(parser_error::e_syntax
,
21696 "ERR044 - Expected '(' at start of if-statement, instead got: '" + current_token().value
+ "'",
21697 exprtk_error_location
));
21699 return error_node();
21701 else if (0 == (condition
= parse_expression()))
21704 make_error(parser_error::e_syntax
,
21706 "ERR045 - Failed to parse condition for if-statement",
21707 exprtk_error_location
));
21709 return error_node();
21711 else if (token_is(token_t::e_comma
,prsrhlpr_t::e_hold
))
21714 return parse_conditional_statement_01(condition
);
21716 else if (token_is(token_t::e_rbracket
))
21719 // 01. if (x) y; else z;
21720 // 02. if (x) y; else {z0; ... zn;}
21721 // 03. if (x) y; else if (z) w;
21722 // 04. if (x) y; else if (z) w; else u;
21723 // 05. if (x) y; else if (z) w; else {u0; ... un;}
21724 // 06. if (x) y; else if (z) {w0; ... wn;}
21725 // 07. if (x) {y0; ... yn;}
21726 // 08. if (x) {y0; ... yn;} else z;
21727 // 09. if (x) {y0; ... yn;} else {z0; ... zn;};
21728 // 10. if (x) {y0; ... yn;} else if (z) w;
21729 // 11. if (x) {y0; ... yn;} else if (z) w; else u;
21730 // 12. if (x) {y0; ... nex;} else if (z) w; else {u0 ... un;}
21731 // 13. if (x) {y0; ... yn;} else if (z) {w0; ... wn;}
21732 return parse_conditional_statement_02(condition
);
21736 make_error(parser_error::e_syntax
,
21738 "ERR046 - Invalid if-statement",
21739 exprtk_error_location
));
21741 free_node(node_allocator_
,condition
);
21743 return error_node();
21746 inline expression_node_ptr
parse_ternary_conditional_statement(expression_node_ptr condition
)
21748 // Parse: [condition][?][consequent][:][alternative]
21749 expression_node_ptr consequent
= error_node();
21750 expression_node_ptr alternative
= error_node();
21752 bool result
= true;
21754 if (0 == condition
)
21757 make_error(parser_error::e_syntax
,
21759 "ERR047 - Encountered invalid condition branch for ternary if-statement",
21760 exprtk_error_location
));
21762 return error_node();
21764 else if (!token_is(token_t::e_ternary
))
21767 make_error(parser_error::e_syntax
,
21769 "ERR048 - Expected '?' after condition of ternary if-statement",
21770 exprtk_error_location
));
21774 else if (0 == (consequent
= parse_expression()))
21777 make_error(parser_error::e_syntax
,
21779 "ERR049 - Failed to parse consequent for ternary if-statement",
21780 exprtk_error_location
));
21784 else if (!token_is(token_t::e_colon
))
21787 make_error(parser_error::e_syntax
,
21789 "ERR050 - Expected ':' between ternary if-statement consequent and alternative",
21790 exprtk_error_location
));
21794 else if (0 == (alternative
= parse_expression()))
21797 make_error(parser_error::e_syntax
,
21799 "ERR051 - Failed to parse alternative for ternary if-statement",
21800 exprtk_error_location
));
21805 #ifndef exprtk_disable_string_capabilities
21808 const bool consq_is_str
= is_generally_string_node( consequent
);
21809 const bool alter_is_str
= is_generally_string_node(alternative
);
21811 if (consq_is_str
|| alter_is_str
)
21813 if (consq_is_str
&& alter_is_str
)
21815 return expression_generator_
21816 .conditional_string(condition
, consequent
, alternative
);
21820 make_error(parser_error::e_syntax
,
21822 "ERR052 - Return types of ternary if-statement differ",
21823 exprtk_error_location
));
21832 free_node(node_allocator_
, condition
);
21833 free_node(node_allocator_
, consequent
);
21834 free_node(node_allocator_
, alternative
);
21836 return error_node();
21839 return expression_generator_
21840 .conditional(condition
, consequent
, alternative
);
21843 inline expression_node_ptr
parse_not_statement()
21845 if (settings_
.logic_disabled("not"))
21848 make_error(parser_error::e_syntax
,
21850 "ERR053 - Invalid or disabled logic operation 'not'",
21851 exprtk_error_location
));
21853 return error_node();
21856 return parse_base_operation();
21859 inline expression_node_ptr
parse_while_loop()
21861 // Parse: [while][(][test expr][)][{][expression][}]
21862 expression_node_ptr condition
= error_node();
21863 expression_node_ptr branch
= error_node();
21864 expression_node_ptr result_node
= error_node();
21866 bool result
= true;
21870 if (!token_is(token_t::e_lbracket
))
21873 make_error(parser_error::e_syntax
,
21875 "ERR054 - Expected '(' at start of while-loop condition statement",
21876 exprtk_error_location
));
21878 return error_node();
21880 else if (0 == (condition
= parse_expression()))
21883 make_error(parser_error::e_syntax
,
21885 "ERR055 - Failed to parse condition for while-loop",
21886 exprtk_error_location
));
21888 return error_node();
21890 else if (!token_is(token_t::e_rbracket
))
21893 make_error(parser_error::e_syntax
,
21895 "ERR056 - Expected ')' at end of while-loop condition statement",
21896 exprtk_error_location
));
21901 brkcnt_list_
.push_front(false);
21905 if (0 == (branch
= parse_multi_sequence("while-loop")))
21908 make_error(parser_error::e_syntax
,
21910 "ERR057 - Failed to parse body of while-loop"));
21913 else if (0 == (result_node
= expression_generator_
.while_loop(condition
,
21915 brkcnt_list_
.front())))
21918 make_error(parser_error::e_syntax
,
21920 "ERR058 - Failed to synthesize while-loop",
21921 exprtk_error_location
));
21929 free_node(node_allocator_
, branch
);
21930 free_node(node_allocator_
, condition
);
21931 free_node(node_allocator_
, result_node
);
21933 brkcnt_list_
.pop_front();
21935 return error_node();
21938 return result_node
;
21941 inline expression_node_ptr
parse_repeat_until_loop()
21943 // Parse: [repeat][{][expression][}][until][(][test expr][)]
21944 expression_node_ptr condition
= error_node();
21945 expression_node_ptr branch
= error_node();
21948 std::vector
<expression_node_ptr
> arg_list
;
21949 std::vector
<bool> side_effect_list
;
21951 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
21953 brkcnt_list_
.push_front(false);
21955 if (details::imatch(current_token().value
,"until"))
21958 branch
= node_allocator_
.allocate
<details::null_node
<T
> >();
21962 const token_t::token_type seperator
= token_t::e_eof
;
21964 scope_handler
sh(*this);
21966 scoped_bool_or_restorer
sbr(state_
.side_effect_present
);
21970 state_
.side_effect_present
= false;
21972 expression_node_ptr arg
= parse_expression();
21975 return error_node();
21978 arg_list
.push_back(arg
);
21979 side_effect_list
.push_back(state_
.side_effect_present
);
21982 if (details::imatch(current_token().value
,"until"))
21988 const bool is_next_until
= peek_token_is(token_t::e_symbol
) &&
21989 peek_token_is("until");
21991 if (!token_is(seperator
) && is_next_until
)
21994 make_error(parser_error::e_syntax
,
21996 "ERR059 - Expected '" + token_t::to_str(seperator
) + "' in body of repeat until loop",
21997 exprtk_error_location
));
21999 return error_node();
22002 if (details::imatch(current_token().value
,"until"))
22009 branch
= simplify(arg_list
,side_effect_list
);
22011 sdd
.delete_ptr
= (0 == branch
);
22013 if (sdd
.delete_ptr
)
22015 brkcnt_list_
.pop_front();
22018 make_error(parser_error::e_syntax
,
22020 "ERR060 - Failed to parse body of repeat until loop",
22021 exprtk_error_location
));
22023 return error_node();
22027 if (!token_is(token_t::e_lbracket
))
22029 brkcnt_list_
.pop_front();
22032 make_error(parser_error::e_syntax
,
22034 "ERR061 - Expected '(' before condition statement of repeat until loop",
22035 exprtk_error_location
));
22037 free_node(node_allocator_
,branch
);
22039 return error_node();
22041 else if (0 == (condition
= parse_expression()))
22043 brkcnt_list_
.pop_front();
22046 make_error(parser_error::e_syntax
,
22048 "ERR062 - Failed to parse condition for repeat until loop",
22049 exprtk_error_location
));
22051 free_node(node_allocator_
,branch
);
22053 return error_node();
22055 else if (!token_is(token_t::e_rbracket
))
22058 make_error(parser_error::e_syntax
,
22060 "ERR063 - Expected ')' after condition of repeat until loop",
22061 exprtk_error_location
));
22063 free_node(node_allocator_
, branch
);
22064 free_node(node_allocator_
, condition
);
22066 brkcnt_list_
.pop_front();
22068 return error_node();
22071 expression_node_ptr result
;
22073 result
= expression_generator_
22074 .repeat_until_loop(condition
, branch
, brkcnt_list_
.front());
22079 make_error(parser_error::e_syntax
,
22081 "ERR064 - Failed to synthesize repeat until loop",
22082 exprtk_error_location
));
22084 free_node(node_allocator_
,condition
);
22086 brkcnt_list_
.pop_front();
22088 return error_node();
22092 brkcnt_list_
.pop_front();
22097 inline expression_node_ptr
parse_for_loop()
22099 expression_node_ptr initialiser
= error_node();
22100 expression_node_ptr condition
= error_node();
22101 expression_node_ptr incrementor
= error_node();
22102 expression_node_ptr loop_body
= error_node();
22104 scope_element
* se
= 0;
22105 bool result
= true;
22109 scope_handler
sh(*this);
22111 if (!token_is(token_t::e_lbracket
))
22114 make_error(parser_error::e_syntax
,
22116 "ERR065 - Expected '(' at start of for-loop",
22117 exprtk_error_location
));
22119 return error_node();
22122 if (!token_is(token_t::e_eof
))
22125 !token_is(token_t::e_symbol
,prsrhlpr_t::e_hold
) &&
22126 details::imatch(current_token().value
,"var")
22131 if (!token_is(token_t::e_symbol
,prsrhlpr_t::e_hold
))
22134 make_error(parser_error::e_syntax
,
22136 "ERR066 - Expected a variable at the start of initialiser section of for-loop",
22137 exprtk_error_location
));
22139 return error_node();
22141 else if (!peek_token_is(token_t::e_assign
))
22144 make_error(parser_error::e_syntax
,
22146 "ERR067 - Expected variable assignment of initialiser section of for-loop",
22147 exprtk_error_location
));
22149 return error_node();
22152 const std::string loop_counter_symbol
= current_token().value
;
22154 se
= &sem_
.get_element(loop_counter_symbol
);
22156 if ((se
->name
== loop_counter_symbol
) && se
->active
)
22159 make_error(parser_error::e_syntax
,
22161 "ERR068 - For-loop variable '" + loop_counter_symbol
+ "' is being shadowed by a previous declaration",
22162 exprtk_error_location
));
22164 return error_node();
22166 else if (!symtab_store_
.is_variable(loop_counter_symbol
))
22170 (se
->name
== loop_counter_symbol
) &&
22171 (se
->type
== scope_element::e_variable
)
22180 nse
.name
= loop_counter_symbol
;
22183 nse
.type
= scope_element::e_variable
;
22184 nse
.depth
= state_
.scope_depth
;
22185 nse
.data
= new T(T(0));
22186 nse
.var_node
= node_allocator_
.allocate
<variable_node_t
>(*(T
*)(nse
.data
));
22188 if (!sem_
.add_element(nse
))
22191 make_error(parser_error::e_syntax
,
22193 "ERR069 - Failed to add new local variable '" + loop_counter_symbol
+ "' to SEM",
22194 exprtk_error_location
));
22196 sem_
.free_element(nse
);
22202 exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n",nse
.name
.c_str()));
22204 state_
.activate_side_effect("parse_for_loop()");
22210 if (0 == (initialiser
= parse_expression()))
22213 make_error(parser_error::e_syntax
,
22215 "ERR070 - Failed to parse initialiser of for-loop",
22216 exprtk_error_location
));
22220 else if (!token_is(token_t::e_eof
))
22223 make_error(parser_error::e_syntax
,
22225 "ERR071 - Expected ';' after initialiser of for-loop",
22226 exprtk_error_location
));
22232 if (!token_is(token_t::e_eof
))
22234 if (0 == (condition
= parse_expression()))
22237 make_error(parser_error::e_syntax
,
22239 "ERR072 - Failed to parse condition of for-loop",
22240 exprtk_error_location
));
22244 else if (!token_is(token_t::e_eof
))
22247 make_error(parser_error::e_syntax
,
22249 "ERR073 - Expected ';' after condition section of for-loop",
22250 exprtk_error_location
));
22256 if (!token_is(token_t::e_rbracket
))
22258 if (0 == (incrementor
= parse_expression()))
22261 make_error(parser_error::e_syntax
,
22263 "ERR074 - Failed to parse incrementor of for-loop",
22264 exprtk_error_location
));
22268 else if (!token_is(token_t::e_rbracket
))
22271 make_error(parser_error::e_syntax
,
22273 "ERR075 - Expected ')' after incrementor section of for-loop",
22274 exprtk_error_location
));
22282 brkcnt_list_
.push_front(false);
22284 if (0 == (loop_body
= parse_multi_sequence("for-loop")))
22287 make_error(parser_error::e_syntax
,
22289 "ERR076 - Failed to parse body of for-loop",
22290 exprtk_error_location
));
22303 free_node(node_allocator_
, initialiser
);
22304 free_node(node_allocator_
, condition
);
22305 free_node(node_allocator_
, incrementor
);
22306 free_node(node_allocator_
, loop_body
);
22308 if (!brkcnt_list_
.empty())
22310 brkcnt_list_
.pop_front();
22313 return error_node();
22317 expression_node_ptr result_node
=
22318 expression_generator_
.for_loop(initialiser
,
22322 brkcnt_list_
.front());
22323 brkcnt_list_
.pop_front();
22325 return result_node
;
22329 inline expression_node_ptr
parse_switch_statement()
22331 std::vector
<expression_node_ptr
> arg_list
;
22332 expression_node_ptr result
= error_node();
22334 if (!details::imatch(current_token().value
,"switch"))
22337 make_error(parser_error::e_syntax
,
22339 "ERR077 - Expected keyword 'switch'",
22340 exprtk_error_location
));
22342 return error_node();
22345 scoped_vec_delete
<expression_node_t
> svd((*this),arg_list
);
22349 if (!token_is(token_t::e_lcrlbracket
))
22352 make_error(parser_error::e_syntax
,
22354 "ERR078 - Expected '{' for call to switch statement",
22355 exprtk_error_location
));
22357 return error_node();
22362 if (!details::imatch("case",current_token().value
))
22365 make_error(parser_error::e_syntax
,
22367 "ERR079 - Expected either a 'case' or 'default' statement",
22368 exprtk_error_location
));
22370 return error_node();
22375 expression_node_ptr condition
= parse_expression();
22377 if (0 == condition
)
22378 return error_node();
22379 else if (!token_is(token_t::e_colon
))
22382 make_error(parser_error::e_syntax
,
22384 "ERR080 - Expected ':' for case of switch statement",
22385 exprtk_error_location
));
22387 return error_node();
22390 expression_node_ptr consequent
= parse_expression();
22392 if (0 == consequent
)
22393 return error_node();
22394 else if (!token_is(token_t::e_eof
))
22397 make_error(parser_error::e_syntax
,
22399 "ERR081 - Expected ';' at end of case for switch statement",
22400 exprtk_error_location
));
22402 return error_node();
22405 // Can we optimise away the case statement?
22406 if (is_constant_node(condition
) && is_false(condition
))
22408 free_node(node_allocator_
, condition
);
22409 free_node(node_allocator_
, consequent
);
22413 arg_list
.push_back( condition
);
22414 arg_list
.push_back(consequent
);
22417 if (details::imatch("default",current_token().value
))
22420 if (!token_is(token_t::e_colon
))
22423 make_error(parser_error::e_syntax
,
22425 "ERR082 - Expected ':' for default of switch statement",
22426 exprtk_error_location
));
22428 return error_node();
22431 expression_node_ptr default_statement
= error_node();
22433 if (token_is(token_t::e_lcrlbracket
,prsrhlpr_t::e_hold
))
22434 default_statement
= parse_multi_sequence("switch-default");
22436 default_statement
= parse_expression();
22438 if (0 == default_statement
)
22439 return error_node();
22440 else if (!token_is(token_t::e_eof
))
22442 free_node(node_allocator_
,default_statement
);
22445 make_error(parser_error::e_syntax
,
22447 "ERR083 - Expected ';' at end of default for switch statement",
22448 exprtk_error_location
));
22450 return error_node();
22453 arg_list
.push_back(default_statement
);
22458 if (!token_is(token_t::e_rcrlbracket
))
22461 make_error(parser_error::e_syntax
,
22463 "ERR084 - Expected '}' at end of switch statement",
22464 exprtk_error_location
));
22466 return error_node();
22469 result
= expression_generator_
.switch_statement(arg_list
);
22471 svd
.delete_ptr
= (0 == result
);
22476 inline expression_node_ptr
parse_multi_switch_statement()
22478 std::vector
<expression_node_ptr
> arg_list
;
22480 if (!details::imatch(current_token().value
,"[*]"))
22483 make_error(parser_error::e_syntax
,
22485 "ERR085 - Expected token '[*]'",
22486 exprtk_error_location
));
22488 return error_node();
22491 scoped_vec_delete
<expression_node_t
> svd((*this),arg_list
);
22495 if (!token_is(token_t::e_lcrlbracket
))
22498 make_error(parser_error::e_syntax
,
22500 "ERR086 - Expected '{' for call to [*] statement",
22501 exprtk_error_location
));
22503 return error_node();
22508 if (!details::imatch("case",current_token().value
))
22511 make_error(parser_error::e_syntax
,
22513 "ERR087 - Expected a 'case' statement for multi-switch",
22514 exprtk_error_location
));
22516 return error_node();
22521 expression_node_ptr condition
= parse_expression();
22523 if (0 == condition
)
22524 return error_node();
22526 if (!token_is(token_t::e_colon
))
22529 make_error(parser_error::e_syntax
,
22531 "ERR088 - Expected ':' for case of [*] statement",
22532 exprtk_error_location
));
22534 return error_node();
22537 expression_node_ptr consequent
= parse_expression();
22539 if (0 == consequent
)
22540 return error_node();
22542 if (!token_is(token_t::e_eof
))
22545 make_error(parser_error::e_syntax
,
22547 "ERR089 - Expected ';' at end of case for [*] statement",
22548 exprtk_error_location
));
22550 return error_node();
22553 // Can we optimise away the case statement?
22554 if (is_constant_node(condition
) && is_false(condition
))
22556 free_node(node_allocator_
, condition
);
22557 free_node(node_allocator_
, consequent
);
22561 arg_list
.push_back( condition
);
22562 arg_list
.push_back(consequent
);
22565 if (token_is(token_t::e_rcrlbracket
,prsrhlpr_t::e_hold
))
22571 if (!token_is(token_t::e_rcrlbracket
))
22574 make_error(parser_error::e_syntax
,
22576 "ERR090 - Expected '}' at end of [*] statement",
22577 exprtk_error_location
));
22579 return error_node();
22582 const expression_node_ptr result
= expression_generator_
.multi_switch_statement(arg_list
);
22584 svd
.delete_ptr
= (0 == result
);
22589 inline expression_node_ptr
parse_vararg_function()
22591 std::vector
<expression_node_ptr
> arg_list
;
22593 details::operator_type opt_type
= details::e_default
;
22594 const std::string symbol
= current_token().value
;
22596 if (details::imatch(symbol
,"~"))
22599 return parse_multi_sequence();
22601 else if (details::imatch(symbol
,"[*]"))
22603 return parse_multi_switch_statement();
22605 else if (details::imatch(symbol
, "avg" )) opt_type
= details::e_avg
;
22606 else if (details::imatch(symbol
, "mand")) opt_type
= details::e_mand
;
22607 else if (details::imatch(symbol
, "max" )) opt_type
= details::e_max
;
22608 else if (details::imatch(symbol
, "min" )) opt_type
= details::e_min
;
22609 else if (details::imatch(symbol
, "mor" )) opt_type
= details::e_mor
;
22610 else if (details::imatch(symbol
, "mul" )) opt_type
= details::e_prod
;
22611 else if (details::imatch(symbol
, "sum" )) opt_type
= details::e_sum
;
22615 make_error(parser_error::e_syntax
,
22617 "ERR091 - Unsupported vararg function: " + symbol
,
22618 exprtk_error_location
));
22620 return error_node();
22623 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
22625 lodge_symbol(symbol
, e_st_function
);
22629 if (!token_is(token_t::e_lbracket
))
22632 make_error(parser_error::e_syntax
,
22634 "ERR092 - Expected '(' for call to vararg function: " + symbol
,
22635 exprtk_error_location
));
22637 return error_node();
22642 expression_node_ptr arg
= parse_expression();
22645 return error_node();
22647 arg_list
.push_back(arg
);
22649 if (token_is(token_t::e_rbracket
))
22651 else if (!token_is(token_t::e_comma
))
22654 make_error(parser_error::e_syntax
,
22656 "ERR093 - Expected ',' for call to vararg function: " + symbol
,
22657 exprtk_error_location
));
22659 return error_node();
22663 const expression_node_ptr result
= expression_generator_
.vararg_function(opt_type
,arg_list
);
22665 sdd
.delete_ptr
= (0 == result
);
22669 #ifndef exprtk_disable_string_capabilities
22670 inline expression_node_ptr
parse_string_range_statement(expression_node_ptr
& expression
)
22672 if (!token_is(token_t::e_lsqrbracket
))
22675 make_error(parser_error::e_syntax
,
22677 "ERR094 - Expected '[' as start of string range definition",
22678 exprtk_error_location
));
22680 free_node(node_allocator_
,expression
);
22682 return error_node();
22684 else if (token_is(token_t::e_rsqrbracket
))
22686 return node_allocator_
.allocate
<details::string_size_node
<T
> >(expression
);
22691 if (!parse_range(rp
,true))
22693 free_node(node_allocator_
,expression
);
22695 return error_node();
22698 expression_node_ptr result
= expression_generator_(expression
,rp
);
22703 make_error(parser_error::e_syntax
,
22705 "ERR095 - Failed to generate string range node",
22706 exprtk_error_location
));
22708 free_node(node_allocator_
,expression
);
22716 inline expression_node_ptr
parse_string_range_statement(expression_node_ptr
&)
22718 return error_node();
22722 inline void parse_pending_string_rangesize(expression_node_ptr
& expression
)
22724 // Allow no more than 100 range calls, eg: s[][][]...[][]
22725 const std::size_t max_rangesize_parses
= 100;
22731 (0 != expression
) &&
22732 (i
++ < max_rangesize_parses
) &&
22733 error_list_
.empty() &&
22734 is_generally_string_node(expression
) &&
22735 token_is(token_t::e_lsqrbracket
,prsrhlpr_t::e_hold
)
22738 expression
= parse_string_range_statement(expression
);
22742 template <typename Allocator1
,
22743 typename Allocator2
,
22744 template <typename
, typename
> class Sequence
>
22745 inline expression_node_ptr
simplify(Sequence
<expression_node_ptr
,Allocator1
>& expression_list
,
22746 Sequence
<bool,Allocator2
>& side_effect_list
,
22747 const bool specialise_on_final_type
= false)
22749 if (expression_list
.empty())
22750 return error_node();
22751 else if (1 == expression_list
.size())
22752 return expression_list
[0];
22754 Sequence
<expression_node_ptr
,Allocator1
> tmp_expression_list
;
22756 bool return_node_present
= false;
22758 for (std::size_t i
= 0; i
< (expression_list
.size() - 1); ++i
)
22760 if (is_variable_node(expression_list
[i
]))
22763 is_return_node (expression_list
[i
]) ||
22764 is_break_node (expression_list
[i
]) ||
22765 is_continue_node(expression_list
[i
])
22768 tmp_expression_list
.push_back(expression_list
[i
]);
22770 // Remove all subexpressions after first short-circuit
22771 // node has been encountered.
22773 for (std::size_t j
= i
+ 1; j
< expression_list
.size(); ++j
)
22775 free_node(node_allocator_
,expression_list
[j
]);
22778 return_node_present
= true;
22783 is_constant_node(expression_list
[i
]) ||
22784 is_null_node (expression_list
[i
]) ||
22785 !side_effect_list
[i
]
22788 free_node(node_allocator_
,expression_list
[i
]);
22792 tmp_expression_list
.push_back(expression_list
[i
]);
22795 if (!return_node_present
)
22797 tmp_expression_list
.push_back(expression_list
.back());
22800 expression_list
.swap(tmp_expression_list
);
22802 if (tmp_expression_list
.size() > expression_list
.size())
22804 exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n",
22805 static_cast<int>(tmp_expression_list
.size()),
22806 static_cast<int>(expression_list
.size())));
22810 return_node_present
||
22811 side_effect_list
.back() ||
22812 (expression_list
.size() > 1)
22814 state_
.activate_side_effect("simplify()");
22816 if (1 == expression_list
.size())
22817 return expression_list
[0];
22818 else if (specialise_on_final_type
&& is_generally_string_node(expression_list
.back()))
22819 return expression_generator_
.vararg_function(details::e_smulti
,expression_list
);
22821 return expression_generator_
.vararg_function(details::e_multi
,expression_list
);
22824 inline expression_node_ptr
parse_multi_sequence(const std::string
& source
= "")
22826 token_t::token_type close_bracket
= token_t::e_rcrlbracket
;
22827 token_t::token_type seperator
= token_t::e_eof
;
22829 if (!token_is(token_t::e_lcrlbracket
))
22831 if (token_is(token_t::e_lbracket
))
22833 close_bracket
= token_t::e_rbracket
;
22834 seperator
= token_t::e_comma
;
22839 make_error(parser_error::e_syntax
,
22841 "ERR096 - Expected '" + token_t::to_str(close_bracket
) + "' for call to multi-sequence" +
22842 ((!source
.empty()) ? std::string(" section of " + source
): ""),
22843 exprtk_error_location
));
22845 return error_node();
22848 else if (token_is(token_t::e_rcrlbracket
))
22850 return node_allocator_
.allocate
<details::null_node
<T
> >();
22853 std::vector
<expression_node_ptr
> arg_list
;
22854 std::vector
<bool> side_effect_list
;
22856 expression_node_ptr result
= error_node();
22858 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
22860 scope_handler
sh(*this);
22862 scoped_bool_or_restorer
sbr(state_
.side_effect_present
);
22866 state_
.side_effect_present
= false;
22868 expression_node_ptr arg
= parse_expression();
22871 return error_node();
22874 arg_list
.push_back(arg
);
22875 side_effect_list
.push_back(state_
.side_effect_present
);
22878 if (token_is(close_bracket
))
22881 const bool is_next_close
= peek_token_is(close_bracket
);
22883 if (!token_is(seperator
) && is_next_close
)
22886 make_error(parser_error::e_syntax
,
22888 "ERR097 - Expected '" + details::to_str(seperator
) + "' for call to multi-sequence section of " + source
,
22889 exprtk_error_location
));
22891 return error_node();
22894 if (token_is(close_bracket
))
22898 result
= simplify(arg_list
,side_effect_list
,source
.empty());
22900 sdd
.delete_ptr
= (0 == result
);
22904 inline bool parse_range(range_t
& rp
, const bool skip_lsqr
= false)
22906 // Examples of valid ranges:
22907 // 1. [1:5] -> 1..5
22908 // 2. [ :5] -> 0..5
22909 // 3. [1: ] -> 1..end
22910 // 4. [x:y] -> x..y where x <= y
22911 // 5. [x+1:y/2] -> x+1..y/2 where x+1 <= y/2
22912 // 6. [ :y] -> 0..y where 0 <= y
22913 // 7. [x: ] -> x..end where x <= end
22917 if (!skip_lsqr
&& !token_is(token_t::e_lsqrbracket
))
22920 make_error(parser_error::e_syntax
,
22922 "ERR098 - Expected '[' for start of range",
22923 exprtk_error_location
));
22928 if (token_is(token_t::e_colon
))
22930 rp
.n0_c
.first
= true;
22931 rp
.n0_c
.second
= 0;
22932 rp
.cache
.first
= 0;
22936 expression_node_ptr r0
= parse_expression();
22941 make_error(parser_error::e_syntax
,
22943 "ERR099 - Failed parse begin section of range",
22944 exprtk_error_location
));
22948 else if (is_constant_node(r0
))
22950 const T r0_value
= r0
->value();
22952 if (r0_value
>= T(0))
22954 rp
.n0_c
.first
= true;
22955 rp
.n0_c
.second
= static_cast<std::size_t>(details::numeric::to_int64(r0_value
));
22956 rp
.cache
.first
= rp
.n0_c
.second
;
22959 free_node(node_allocator_
,r0
);
22961 if (r0_value
< T(0))
22964 make_error(parser_error::e_syntax
,
22966 "ERR100 - Range lower bound less than zero! Constraint: r0 >= 0",
22967 exprtk_error_location
));
22974 rp
.n0_e
.first
= true;
22975 rp
.n0_e
.second
= r0
;
22978 if (!token_is(token_t::e_colon
))
22981 make_error(parser_error::e_syntax
,
22983 "ERR101 - Expected ':' for break in range",
22984 exprtk_error_location
));
22992 if (token_is(token_t::e_rsqrbracket
))
22994 rp
.n1_c
.first
= true;
22995 rp
.n1_c
.second
= std::numeric_limits
<std::size_t>::max();
22999 expression_node_ptr r1
= parse_expression();
23004 make_error(parser_error::e_syntax
,
23006 "ERR102 - Failed parse end section of range",
23007 exprtk_error_location
));
23013 else if (is_constant_node(r1
))
23015 const T r1_value
= r1
->value();
23017 if (r1_value
>= T(0))
23019 rp
.n1_c
.first
= true;
23020 rp
.n1_c
.second
= static_cast<std::size_t>(details::numeric::to_int64(r1_value
));
23021 rp
.cache
.second
= rp
.n1_c
.second
;
23024 free_node(node_allocator_
,r1
);
23026 if (r1_value
< T(0))
23029 make_error(parser_error::e_syntax
,
23031 "ERR103 - Range upper bound less than zero! Constraint: r1 >= 0",
23032 exprtk_error_location
));
23039 rp
.n1_e
.first
= true;
23040 rp
.n1_e
.second
= r1
;
23043 if (!token_is(token_t::e_rsqrbracket
))
23046 make_error(parser_error::e_syntax
,
23048 "ERR104 - Expected ']' for start of range",
23049 exprtk_error_location
));
23057 if (rp
.const_range())
23059 std::size_t r0
= 0;
23060 std::size_t r1
= 0;
23062 const bool rp_result
= rp(r0
,r1
);
23064 if (!rp_result
|| (r0
> r1
))
23067 make_error(parser_error::e_syntax
,
23069 "ERR105 - Invalid range, Constraint: r0 <= r1",
23070 exprtk_error_location
));
23079 inline void lodge_symbol(const std::string
& symbol
,
23080 const symbol_type st
)
23082 dec_
.add_symbol(symbol
,st
);
23085 #ifndef exprtk_disable_string_capabilities
23086 inline expression_node_ptr
parse_string()
23088 const std::string symbol
= current_token().value
;
23090 typedef details::stringvar_node
<T
>* strvar_node_t
;
23092 expression_node_ptr result
= error_node();
23093 strvar_node_t const_str_node
= static_cast<strvar_node_t
>(0);
23095 scope_element
& se
= sem_
.get_active_element(symbol
);
23097 if (scope_element::e_string
== se
.type
)
23100 result
= se
.str_node
;
23101 lodge_symbol(symbol
, e_st_local_string
);
23105 if (!symtab_store_
.is_conststr_stringvar(symbol
))
23108 make_error(parser_error::e_syntax
,
23110 "ERR106 - Unknown string symbol",
23111 exprtk_error_location
));
23113 return error_node();
23116 result
= symtab_store_
.get_stringvar(symbol
);
23118 if (symtab_store_
.is_constant_string(symbol
))
23120 const_str_node
= static_cast<strvar_node_t
>(result
);
23121 result
= expression_generator_(const_str_node
->str());
23124 lodge_symbol(symbol
, e_st_string
);
23127 if (peek_token_is(token_t::e_lsqrbracket
))
23131 if (peek_token_is(token_t::e_rsqrbracket
))
23136 if (const_str_node
)
23138 free_node(node_allocator_
,result
);
23140 return expression_generator_(T(const_str_node
->size()));
23143 return node_allocator_
.allocate
<details::stringvar_size_node
<T
> >
23144 (static_cast<details::stringvar_node
<T
>*>(result
)->ref());
23149 if (!parse_range(rp
))
23151 free_node(node_allocator_
,result
);
23153 return error_node();
23155 else if (const_str_node
)
23157 free_node(node_allocator_
,result
);
23158 result
= expression_generator_(const_str_node
->ref(),rp
);
23161 result
= expression_generator_(static_cast<details::stringvar_node
<T
>*>
23162 (result
)->ref(), rp
);
23173 inline expression_node_ptr
parse_string()
23175 return error_node();
23179 #ifndef exprtk_disable_string_capabilities
23180 inline expression_node_ptr
parse_const_string()
23182 const std::string const_str
= current_token().value
;
23183 expression_node_ptr result
= expression_generator_(const_str
);
23185 if (peek_token_is(token_t::e_lsqrbracket
))
23189 if (peek_token_is(token_t::e_rsqrbracket
))
23194 free_node(node_allocator_
,result
);
23196 return expression_generator_(T(const_str
.size()));
23201 if (!parse_range(rp
))
23203 free_node(node_allocator_
,result
);
23205 return error_node();
23208 free_node(node_allocator_
,result
);
23210 if (rp
.n1_c
.first
&& (rp
.n1_c
.second
== std::numeric_limits
<std::size_t>::max()))
23212 rp
.n1_c
.second
= const_str
.size() - 1;
23213 rp
.cache
.second
= rp
.n1_c
.second
;
23217 (rp
.n0_c
.first
&& (rp
.n0_c
.second
>= const_str
.size())) ||
23218 (rp
.n1_c
.first
&& (rp
.n1_c
.second
>= const_str
.size()))
23222 make_error(parser_error::e_syntax
,
23224 "ERR107 - Overflow in range for string: '" + const_str
+ "'[" +
23225 (rp
.n0_c
.first
? details::to_str(static_cast<int>(rp
.n0_c
.second
)) : "?") + ":" +
23226 (rp
.n1_c
.first
? details::to_str(static_cast<int>(rp
.n1_c
.second
)) : "?") + "]",
23227 exprtk_error_location
));
23229 return error_node();
23232 result
= expression_generator_(const_str
,rp
);
23243 inline expression_node_ptr
parse_const_string()
23245 return error_node();
23249 inline expression_node_ptr
parse_vector()
23251 const std::string symbol
= current_token().value
;
23253 vector_holder_ptr vec
= vector_holder_ptr(0);
23255 const scope_element
& se
= sem_
.get_active_element(symbol
);
23258 !details::imatch(se
.name
, symbol
) ||
23259 (se
.depth
> state_
.scope_depth
) ||
23260 (scope_element::e_vector
!= se
.type
)
23263 if (0 == (vec
= symtab_store_
.get_vector(symbol
)))
23266 make_error(parser_error::e_syntax
,
23268 "ERR108 - Symbol '" + symbol
+ " not a vector",
23269 exprtk_error_location
));
23271 return error_node();
23277 expression_node_ptr index_expr
= error_node();
23281 if (!token_is(token_t::e_lsqrbracket
))
23283 return node_allocator_
.allocate
<vector_node_t
>(vec
);
23285 else if (token_is(token_t::e_rsqrbracket
))
23287 return expression_generator_(T(vec
->size()));
23289 else if (0 == (index_expr
= parse_expression()))
23292 make_error(parser_error::e_syntax
,
23294 "ERR109 - Failed to parse index for vector: '" + symbol
+ "'",
23295 exprtk_error_location
));
23297 return error_node();
23299 else if (!token_is(token_t::e_rsqrbracket
))
23302 make_error(parser_error::e_syntax
,
23304 "ERR110 - Expected ']' for index of vector: '" + symbol
+ "'",
23305 exprtk_error_location
));
23307 free_node(node_allocator_
,index_expr
);
23309 return error_node();
23312 // Perform compile-time range check
23313 if (details::is_constant_node(index_expr
))
23315 const std::size_t index
= static_cast<std::size_t>(details::numeric::to_int32(index_expr
->value()));
23316 const std::size_t vec_size
= vec
->size();
23318 if (index
>= vec_size
)
23321 make_error(parser_error::e_syntax
,
23323 "ERR111 - Index of " + details::to_str(index
) + " out of range for "
23324 "vector '" + symbol
+ "' of size " + details::to_str(vec_size
),
23325 exprtk_error_location
));
23327 free_node(node_allocator_
,index_expr
);
23329 return error_node();
23333 return expression_generator_
.vector_element(symbol
, vec
, index_expr
);
23336 inline expression_node_ptr
parse_vararg_function_call(ivararg_function
<T
>* vararg_function
, const std::string
& vararg_function_name
)
23338 std::vector
<expression_node_ptr
> arg_list
;
23340 expression_node_ptr result
= error_node();
23342 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
23346 if (token_is(token_t::e_lbracket
))
23348 if (token_is(token_t::e_rbracket
))
23350 if (!vararg_function
->allow_zero_parameters())
23353 make_error(parser_error::e_syntax
,
23355 "ERR112 - Zero parameter call to vararg function: "
23356 + vararg_function_name
+ " not allowed",
23357 exprtk_error_location
));
23359 return error_node();
23366 expression_node_ptr arg
= parse_expression();
23369 return error_node();
23371 arg_list
.push_back(arg
);
23373 if (token_is(token_t::e_rbracket
))
23375 else if (!token_is(token_t::e_comma
))
23378 make_error(parser_error::e_syntax
,
23380 "ERR113 - Expected ',' for call to vararg function: "
23381 + vararg_function_name
,
23382 exprtk_error_location
));
23384 return error_node();
23389 else if (!vararg_function
->allow_zero_parameters())
23392 make_error(parser_error::e_syntax
,
23394 "ERR114 - Zero parameter call to vararg function: "
23395 + vararg_function_name
+ " not allowed",
23396 exprtk_error_location
));
23398 return error_node();
23401 if (arg_list
.size() < vararg_function
->min_num_args())
23404 make_error(parser_error::e_syntax
,
23406 "ERR115 - Invalid number of parameters to call to vararg function: "
23407 + vararg_function_name
+ ", require at least "
23408 + details::to_str(static_cast<int>(vararg_function
->min_num_args())) + " parameters",
23409 exprtk_error_location
));
23411 return error_node();
23413 else if (arg_list
.size() > vararg_function
->max_num_args())
23416 make_error(parser_error::e_syntax
,
23418 "ERR116 - Invalid number of parameters to call to vararg function: "
23419 + vararg_function_name
+ ", require no more than "
23420 + details::to_str(static_cast<int>(vararg_function
->max_num_args())) + " parameters",
23421 exprtk_error_location
));
23423 return error_node();
23426 result
= expression_generator_
.vararg_function_call(vararg_function
,arg_list
);
23428 sdd
.delete_ptr
= (0 == result
);
23444 struct function_prototype_t
23446 return_type_t return_type
;
23447 std::string param_seq
;
23450 typedef parser
<T
> parser_t
;
23451 typedef std::vector
<function_prototype_t
> function_definition_list_t
;
23453 type_checker(parser_t
& p
,
23454 const std::string
& func_name
,
23455 const std::string
& func_prototypes
,
23456 const return_type_t default_return_type
)
23457 : invalid_state_(true),
23459 function_name_(func_name
),
23460 default_return_type_(default_return_type
)
23462 parse_function_prototypes(func_prototypes
);
23465 void set_default_return_type(const std::string
& return_type
)
23467 default_return_type_
= return_type
;
23470 bool verify(const std::string
& param_seq
, std::size_t& pseq_index
)
23472 if (function_definition_list_
.empty())
23475 std::vector
<std::pair
<std::size_t,char> > error_list
;
23477 for (std::size_t i
= 0; i
< function_definition_list_
.size(); ++i
)
23479 details::char_t diff_value
= 0;
23480 std::size_t diff_index
= 0;
23482 const bool result
= details::sequence_match(function_definition_list_
[i
].param_seq
,
23484 diff_index
, diff_value
);
23492 error_list
.push_back(std::make_pair(diff_index
, diff_value
));
23495 if (1 == error_list
.size())
23499 make_error(parser_error::e_syntax
,
23500 parser_
.current_token(),
23501 "ERR117 - Failed parameter type check for function '" + function_name_
+ "', "
23502 "Expected '" + function_definition_list_
[0].param_seq
+
23503 "' call set: '" + param_seq
+ "'",
23504 exprtk_error_location
));
23508 // find first with largest diff_index;
23509 std::size_t max_diff_index
= 0;
23511 for (std::size_t i
= 1; i
< error_list
.size(); ++i
)
23513 if (error_list
[i
].first
> error_list
[max_diff_index
].first
)
23515 max_diff_index
= i
;
23521 make_error(parser_error::e_syntax
,
23522 parser_
.current_token(),
23523 "ERR118 - Failed parameter type check for function '" + function_name_
+ "', "
23524 "Best match: '" + function_definition_list_
[max_diff_index
].param_seq
+
23525 "' call set: '" + param_seq
+ "'",
23526 exprtk_error_location
));
23532 std::size_t paramseq_count() const
23534 return function_definition_list_
.size();
23537 std::string
paramseq(const std::size_t& index
) const
23539 return function_definition_list_
[index
].param_seq
;
23542 return_type_t
return_type(const std::size_t& index
) const
23544 return function_definition_list_
[index
].return_type
;
23547 bool invalid() const
23549 return !invalid_state_
;
23552 bool allow_zero_parameters() const
23555 for (std::size_t i
= 0; i
< function_definition_list_
.size(); ++i
)
23557 if (std::string::npos
!= function_definition_list_
[i
].param_seq
.find("Z"))
23568 std::vector
<std::string
> split_param_seq(const std::string
& param_seq
, const details::char_t delimiter
= '|') const
23570 std::string::const_iterator current_begin
= param_seq
.begin();
23571 std::string::const_iterator iter
= param_seq
.begin();
23573 std::vector
<std::string
> result
;
23575 while (iter
!= param_seq
.end())
23577 if (*iter
== delimiter
)
23579 result
.push_back(std::string(current_begin
, iter
));
23580 current_begin
= ++iter
;
23586 if (current_begin
!= iter
)
23588 result
.push_back(std::string(current_begin
, iter
));
23594 inline bool is_valid_token(std::string param_seq
,
23595 function_prototype_t
& funcproto
) const
23597 // Determine return type
23598 funcproto
.return_type
= default_return_type_
;
23600 if (param_seq
.size() > 2)
23602 if (':' == param_seq
[1])
23604 // Note: Only overloaded igeneric functions can have return
23605 // type definitions.
23606 if (type_checker::e_overload
!= default_return_type_
)
23609 switch (param_seq
[0])
23611 case 'T' : funcproto
.return_type
= type_checker::e_numeric
;
23614 case 'S' : funcproto
.return_type
= type_checker::e_string
;
23617 default : return false;
23620 param_seq
.erase(0,2);
23625 (std::string::npos
!= param_seq
.find("?*")) ||
23626 (std::string::npos
!= param_seq
.find("**"))
23632 (std::string::npos
== param_seq
.find_first_not_of("STV*?|")) ||
23636 funcproto
.param_seq
= param_seq
;
23643 void parse_function_prototypes(const std::string
& func_prototypes
)
23645 if (func_prototypes
.empty())
23648 std::vector
<std::string
> param_seq_list
= split_param_seq(func_prototypes
);
23650 typedef std::map
<std::string
,std::size_t> param_seq_map_t
;
23651 param_seq_map_t param_seq_map
;
23653 for (std::size_t i
= 0; i
< param_seq_list
.size(); ++i
)
23655 function_prototype_t func_proto
;
23657 if (!is_valid_token(param_seq_list
[i
], func_proto
))
23659 invalid_state_
= false;
23663 make_error(parser_error::e_syntax
,
23664 parser_
.current_token(),
23665 "ERR119 - Invalid parameter sequence of '" + param_seq_list
[i
] +
23666 "' for function: " + function_name_
,
23667 exprtk_error_location
));
23671 param_seq_map_t::const_iterator seq_itr
= param_seq_map
.find(param_seq_list
[i
]);
23673 if (param_seq_map
.end() != seq_itr
)
23675 invalid_state_
= false;
23679 make_error(parser_error::e_syntax
,
23680 parser_
.current_token(),
23681 "ERR120 - Function '" + function_name_
+ "' has a parameter sequence conflict between " +
23682 "pseq_idx[" + details::to_str(seq_itr
->second
) + "] and" +
23683 "pseq_idx[" + details::to_str(i
) + "] " +
23684 "param seq: " + param_seq_list
[i
],
23685 exprtk_error_location
));
23689 function_definition_list_
.push_back(func_proto
);
23693 type_checker(const type_checker
&);
23694 type_checker
& operator=(const type_checker
&);
23696 bool invalid_state_
;
23698 std::string function_name_
;
23699 const return_type_t default_return_type_
;
23700 function_definition_list_t function_definition_list_
;
23703 inline expression_node_ptr
parse_generic_function_call(igeneric_function
<T
>* function
, const std::string
& function_name
)
23705 std::vector
<expression_node_ptr
> arg_list
;
23707 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
23711 std::string param_type_list
;
23713 type_checker
tc((*this), function_name
, function
->parameter_sequence
, type_checker::e_string
);
23718 make_error(parser_error::e_syntax
,
23720 "ERR121 - Type checker instantiation failure for generic function: " + function_name
,
23721 exprtk_error_location
));
23723 return error_node();
23726 if (token_is(token_t::e_lbracket
))
23728 if (token_is(token_t::e_rbracket
))
23731 !function
->allow_zero_parameters() &&
23732 !tc
.allow_zero_parameters()
23736 make_error(parser_error::e_syntax
,
23738 "ERR122 - Zero parameter call to generic function: "
23739 + function_name
+ " not allowed",
23740 exprtk_error_location
));
23742 return error_node();
23749 expression_node_ptr arg
= parse_expression();
23752 return error_node();
23754 if (is_ivector_node(arg
))
23755 param_type_list
+= 'V';
23756 else if (is_generally_string_node(arg
))
23757 param_type_list
+= 'S';
23758 else // Everything else is assumed to be a scalar returning expression
23759 param_type_list
+= 'T';
23761 arg_list
.push_back(arg
);
23763 if (token_is(token_t::e_rbracket
))
23765 else if (!token_is(token_t::e_comma
))
23768 make_error(parser_error::e_syntax
,
23770 "ERR123 - Expected ',' for call to generic function: " + function_name
,
23771 exprtk_error_location
));
23773 return error_node();
23779 !function
->parameter_sequence
.empty() &&
23780 function
->allow_zero_parameters () &&
23781 !tc
.allow_zero_parameters ()
23785 make_error(parser_error::e_syntax
,
23787 "ERR124 - Zero parameter call to generic function: "
23788 + function_name
+ " not allowed",
23789 exprtk_error_location
));
23791 return error_node();
23794 std::size_t param_seq_index
= 0;
23797 state_
.type_check_enabled
&&
23798 !tc
.verify(param_type_list
, param_seq_index
)
23802 make_error(parser_error::e_syntax
,
23804 "ERR125 - Invalid input parameter sequence for call to generic function: " + function_name
,
23805 exprtk_error_location
));
23807 return error_node();
23810 expression_node_ptr result
= error_node();
23812 if (tc
.paramseq_count() <= 1)
23813 result
= expression_generator_
23814 .generic_function_call(function
, arg_list
);
23816 result
= expression_generator_
23817 .generic_function_call(function
, arg_list
, param_seq_index
);
23819 sdd
.delete_ptr
= (0 == result
);
23824 inline bool parse_igeneric_function_params(std::string
& param_type_list
,
23825 std::vector
<expression_node_ptr
>& arg_list
,
23826 const std::string
& function_name
,
23827 igeneric_function
<T
>* function
,
23828 const type_checker
& tc
)
23830 if (token_is(token_t::e_lbracket
))
23832 if (token_is(token_t::e_rbracket
))
23835 !function
->allow_zero_parameters() &&
23836 !tc
.allow_zero_parameters()
23840 make_error(parser_error::e_syntax
,
23842 "ERR126 - Zero parameter call to generic function: "
23843 + function_name
+ " not allowed",
23844 exprtk_error_location
));
23853 expression_node_ptr arg
= parse_expression();
23858 if (is_ivector_node(arg
))
23859 param_type_list
+= 'V';
23860 else if (is_generally_string_node(arg
))
23861 param_type_list
+= 'S';
23862 else // Everything else is a scalar returning expression
23863 param_type_list
+= 'T';
23865 arg_list
.push_back(arg
);
23867 if (token_is(token_t::e_rbracket
))
23869 else if (!token_is(token_t::e_comma
))
23872 make_error(parser_error::e_syntax
,
23874 "ERR127 - Expected ',' for call to string function: " + function_name
,
23875 exprtk_error_location
));
23888 #ifndef exprtk_disable_string_capabilities
23889 inline expression_node_ptr
parse_string_function_call(igeneric_function
<T
>* function
, const std::string
& function_name
)
23891 // Move pass the function name
23894 std::string param_type_list
;
23896 type_checker
tc((*this), function_name
, function
->parameter_sequence
, type_checker::e_string
);
23899 (!function
->parameter_sequence
.empty()) &&
23900 (0 == tc
.paramseq_count())
23903 return error_node();
23906 std::vector
<expression_node_ptr
> arg_list
;
23907 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
23909 if (!parse_igeneric_function_params(param_type_list
, arg_list
, function_name
, function
, tc
))
23911 return error_node();
23914 std::size_t param_seq_index
= 0;
23916 if (!tc
.verify(param_type_list
, param_seq_index
))
23919 make_error(parser_error::e_syntax
,
23921 "ERR128 - Invalid input parameter sequence for call to string function: " + function_name
,
23922 exprtk_error_location
));
23924 return error_node();
23927 expression_node_ptr result
= error_node();
23929 if (tc
.paramseq_count() <= 1)
23930 result
= expression_generator_
23931 .string_function_call(function
, arg_list
);
23933 result
= expression_generator_
23934 .string_function_call(function
, arg_list
, param_seq_index
);
23936 sdd
.delete_ptr
= (0 == result
);
23941 inline expression_node_ptr
parse_overload_function_call(igeneric_function
<T
>* function
, const std::string
& function_name
)
23943 // Move pass the function name
23946 std::string param_type_list
;
23948 type_checker
tc((*this), function_name
, function
->parameter_sequence
, type_checker::e_overload
);
23951 (!function
->parameter_sequence
.empty()) &&
23952 (0 == tc
.paramseq_count())
23955 return error_node();
23958 std::vector
<expression_node_ptr
> arg_list
;
23959 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
23961 if (!parse_igeneric_function_params(param_type_list
, arg_list
, function_name
, function
, tc
))
23963 return error_node();
23966 std::size_t param_seq_index
= 0;
23968 if (!tc
.verify(param_type_list
, param_seq_index
))
23971 make_error(parser_error::e_syntax
,
23973 "ERR129 - Invalid input parameter sequence for call to overloaded function: " + function_name
,
23974 exprtk_error_location
));
23976 return error_node();
23979 expression_node_ptr result
= error_node();
23981 if (type_checker::e_numeric
== tc
.return_type(param_seq_index
))
23983 if (tc
.paramseq_count() <= 1)
23984 result
= expression_generator_
23985 .generic_function_call(function
, arg_list
);
23987 result
= expression_generator_
23988 .generic_function_call(function
, arg_list
, param_seq_index
);
23990 else if (type_checker::e_string
== tc
.return_type(param_seq_index
))
23992 if (tc
.paramseq_count() <= 1)
23993 result
= expression_generator_
23994 .string_function_call(function
, arg_list
);
23996 result
= expression_generator_
23997 .string_function_call(function
, arg_list
, param_seq_index
);
24002 make_error(parser_error::e_syntax
,
24004 "ERR130 - Invalid return type for call to overloaded function: " + function_name
,
24005 exprtk_error_location
));
24008 sdd
.delete_ptr
= (0 == result
);
24013 template <typename Type
, std::size_t NumberOfParameters
>
24014 struct parse_special_function_impl
24016 static inline expression_node_ptr
process(parser
<Type
>& p
, const details::operator_type opt_type
, const std::string
& sf_name
)
24018 expression_node_ptr branch
[NumberOfParameters
];
24019 expression_node_ptr result
= error_node();
24021 std::fill_n(branch
,NumberOfParameters
,reinterpret_cast<expression_node_ptr
>(0));
24023 scoped_delete
<expression_node_t
,NumberOfParameters
> sd(p
,branch
);
24027 if (!p
.token_is(token_t::e_lbracket
))
24030 make_error(parser_error::e_syntax
,
24032 "ERR131 - Expected '(' for special function '" + sf_name
+ "'",
24033 exprtk_error_location
));
24035 return error_node();
24038 for (std::size_t i
= 0; i
< NumberOfParameters
; ++i
)
24040 branch
[i
] = p
.parse_expression();
24042 if (0 == branch
[i
])
24044 return p
.error_node();
24046 else if (i
< (NumberOfParameters
- 1))
24048 if (!p
.token_is(token_t::e_comma
))
24051 make_error(parser_error::e_syntax
,
24053 "ERR132 - Expected ',' before next parameter of special function '" + sf_name
+ "'",
24054 exprtk_error_location
));
24056 return p
.error_node();
24061 if (!p
.token_is(token_t::e_rbracket
))
24064 make_error(parser_error::e_syntax
,
24066 "ERR133 - Invalid number of parameters for special function '" + sf_name
+ "'",
24067 exprtk_error_location
));
24069 return p
.error_node();
24072 result
= p
.expression_generator_
.special_function(opt_type
,branch
);
24074 sd
.delete_ptr
= (0 == result
);
24080 inline expression_node_ptr
parse_special_function()
24082 const std::string sf_name
= current_token().value
;
24084 // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
24086 !details::is_digit(sf_name
[2]) ||
24087 !details::is_digit(sf_name
[3])
24091 make_error(parser_error::e_token
,
24093 "ERR134 - Invalid special function[1]: " + sf_name
,
24094 exprtk_error_location
));
24096 return error_node();
24099 const int id
= (sf_name
[2] - '0') * 10 +
24100 (sf_name
[3] - '0');
24102 if (id
>= details::e_sffinal
)
24105 make_error(parser_error::e_token
,
24107 "ERR135 - Invalid special function[2]: " + sf_name
,
24108 exprtk_error_location
));
24110 return error_node();
24113 const int sf_3_to_4
= details::e_sf48
;
24114 const details::operator_type opt_type
= details::operator_type(id
+ 1000);
24115 const std::size_t NumberOfParameters
= (id
< (sf_3_to_4
- 1000)) ? 3U : 4U;
24117 switch (NumberOfParameters
)
24119 case 3 : return parse_special_function_impl
<T
,3>::process((*this), opt_type
, sf_name
);
24120 case 4 : return parse_special_function_impl
<T
,4>::process((*this), opt_type
, sf_name
);
24121 default : return error_node();
24125 inline expression_node_ptr
parse_null_statement()
24128 return node_allocator_
.allocate
<details::null_node
<T
> >();
24131 #ifndef exprtk_disable_break_continue
24132 inline expression_node_ptr
parse_break_statement()
24134 if (state_
.parsing_break_stmt
)
24137 make_error(parser_error::e_syntax
,
24139 "ERR136 - Break call within a break call is not allowed",
24140 exprtk_error_location
));
24142 return error_node();
24145 scoped_bool_negator
sbn(state_
.parsing_break_stmt
);
24147 if (!brkcnt_list_
.empty())
24151 brkcnt_list_
.front() = true;
24153 expression_node_ptr return_expr
= error_node();
24155 if (token_is(token_t::e_lsqrbracket
))
24157 if (0 == (return_expr
= parse_expression()))
24160 make_error(parser_error::e_syntax
,
24162 "ERR137 - Failed to parse return expression for 'break' statement",
24163 exprtk_error_location
));
24165 return error_node();
24167 else if (!token_is(token_t::e_rsqrbracket
))
24170 make_error(parser_error::e_syntax
,
24172 "ERR138 - Expected ']' at the completion of break's return expression",
24173 exprtk_error_location
));
24175 free_node(node_allocator_
,return_expr
);
24177 return error_node();
24181 state_
.activate_side_effect("parse_break_statement()");
24183 return node_allocator_
.allocate
<details::break_node
<T
> >(return_expr
);
24188 make_error(parser_error::e_syntax
,
24190 "ERR139 - Invalid use of 'break', allowed only in the scope of a loop",
24191 exprtk_error_location
));
24194 return error_node();
24197 inline expression_node_ptr
parse_continue_statement()
24199 if (!brkcnt_list_
.empty())
24203 brkcnt_list_
.front() = true;
24204 state_
.activate_side_effect("parse_continue_statement()");
24206 return node_allocator_
.allocate
<details::continue_node
<T
> >();
24211 make_error(parser_error::e_syntax
,
24213 "ERR140 - Invalid use of 'continue', allowed only in the scope of a loop",
24214 exprtk_error_location
));
24216 return error_node();
24221 inline expression_node_ptr
parse_define_vector_statement(const std::string
& vec_name
)
24223 expression_node_ptr size_expr
= error_node();
24225 if (!token_is(token_t::e_lsqrbracket
))
24228 make_error(parser_error::e_syntax
,
24230 "ERR141 - Expected '[' as part of vector size definition",
24231 exprtk_error_location
));
24233 return error_node();
24235 else if (0 == (size_expr
= parse_expression()))
24238 make_error(parser_error::e_syntax
,
24240 "ERR142 - Failed to determine size of vector '" + vec_name
+ "'",
24241 exprtk_error_location
));
24243 return error_node();
24245 else if (!is_constant_node(size_expr
))
24247 free_node(node_allocator_
,size_expr
);
24250 make_error(parser_error::e_syntax
,
24252 "ERR143 - Expected a literal number as size of vector '" + vec_name
+ "'",
24253 exprtk_error_location
));
24255 return error_node();
24258 const T vector_size
= size_expr
->value();
24260 free_node(node_allocator_
,size_expr
);
24262 const T max_vector_size
= T(2000000000.0);
24265 (vector_size
<= T(0)) ||
24266 std::not_equal_to
<T
>()
24267 (T(0),vector_size
- details::numeric::trunc(vector_size
)) ||
24268 (vector_size
> max_vector_size
)
24272 make_error(parser_error::e_syntax
,
24274 "ERR144 - Invalid vector size. Must be an integer in the range [0,2e9], size: " +
24275 details::to_str(details::numeric::to_int32(vector_size
)),
24276 exprtk_error_location
));
24278 return error_node();
24281 std::vector
<expression_node_ptr
> vec_initilizer_list
;
24283 scoped_vec_delete
<expression_node_t
> svd((*this),vec_initilizer_list
);
24285 bool single_value_initialiser
= false;
24286 bool vec_to_vec_initialiser
= false;
24287 bool null_initialisation
= false;
24289 if (!token_is(token_t::e_rsqrbracket
))
24292 make_error(parser_error::e_syntax
,
24294 "ERR145 - Expected ']' as part of vector size definition",
24295 exprtk_error_location
));
24297 return error_node();
24299 else if (!token_is(token_t::e_eof
))
24301 if (!token_is(token_t::e_assign
))
24304 make_error(parser_error::e_syntax
,
24306 "ERR146 - Expected ':=' as part of vector definition",
24307 exprtk_error_location
));
24309 return error_node();
24311 else if (token_is(token_t::e_lsqrbracket
))
24313 expression_node_ptr initialiser
= parse_expression();
24315 if (0 == initialiser
)
24318 make_error(parser_error::e_syntax
,
24320 "ERR147 - Failed to parse single vector initialiser",
24321 exprtk_error_location
));
24323 return error_node();
24326 vec_initilizer_list
.push_back(initialiser
);
24328 if (!token_is(token_t::e_rsqrbracket
))
24331 make_error(parser_error::e_syntax
,
24333 "ERR148 - Expected ']' to close single value vector initialiser",
24334 exprtk_error_location
));
24336 return error_node();
24339 single_value_initialiser
= true;
24341 else if (!token_is(token_t::e_lcrlbracket
))
24343 expression_node_ptr initialiser
= error_node();
24345 // Is this a vector to vector assignment and initialisation?
24346 if (token_t::e_symbol
== current_token().type
)
24348 // Is it a locally defined vector?
24349 scope_element
& se
= sem_
.get_active_element(current_token().value
);
24351 if (scope_element::e_vector
== se
.type
)
24353 if (0 != (initialiser
= parse_expression()))
24354 vec_initilizer_list
.push_back(initialiser
);
24356 return error_node();
24358 // Are we dealing with a user defined vector?
24359 else if (symtab_store_
.is_vector(current_token().value
))
24361 lodge_symbol(current_token().value
, e_st_vector
);
24363 if (0 != (initialiser
= parse_expression()))
24364 vec_initilizer_list
.push_back(initialiser
);
24366 return error_node();
24368 // Are we dealing with a null initialisation vector definition?
24369 else if (token_is(token_t::e_symbol
,"null"))
24370 null_initialisation
= true;
24373 if (!null_initialisation
)
24375 if (0 == initialiser
)
24378 make_error(parser_error::e_syntax
,
24380 "ERR149 - Expected '{' as part of vector initialiser list",
24381 exprtk_error_location
));
24383 return error_node();
24386 vec_to_vec_initialiser
= true;
24389 else if (!token_is(token_t::e_rcrlbracket
))
24393 expression_node_ptr initialiser
= parse_expression();
24395 if (0 == initialiser
)
24398 make_error(parser_error::e_syntax
,
24400 "ERR150 - Expected '{' as part of vector initialiser list",
24401 exprtk_error_location
));
24403 return error_node();
24406 vec_initilizer_list
.push_back(initialiser
);
24408 if (token_is(token_t::e_rcrlbracket
))
24411 const bool is_next_close
= peek_token_is(token_t::e_rcrlbracket
);
24413 if (!token_is(token_t::e_comma
) && is_next_close
)
24416 make_error(parser_error::e_syntax
,
24418 "ERR151 - Expected ',' between vector initialisers",
24419 exprtk_error_location
));
24421 return error_node();
24424 if (token_is(token_t::e_rcrlbracket
))
24430 !token_is(token_t::e_rbracket
, prsrhlpr_t::e_hold
) &&
24431 !token_is(token_t::e_rcrlbracket
, prsrhlpr_t::e_hold
) &&
24432 !token_is(token_t::e_rsqrbracket
, prsrhlpr_t::e_hold
)
24435 if (!token_is(token_t::e_eof
))
24438 make_error(parser_error::e_syntax
,
24440 "ERR152 - Expected ';' at end of vector definition",
24441 exprtk_error_location
));
24443 return error_node();
24447 if (vec_initilizer_list
.size() > vector_size
)
24450 make_error(parser_error::e_syntax
,
24452 "ERR153 - Initialiser list larger than the number of elements in the vector: '" + vec_name
+ "'",
24453 exprtk_error_location
));
24455 return error_node();
24459 typename
symbol_table_t::vector_holder_ptr vec_holder
= typename
symbol_table_t::vector_holder_ptr(0);
24461 const std::size_t vec_size
= static_cast<std::size_t>(details::numeric::to_int32(vector_size
));
24463 scope_element
& se
= sem_
.get_element(vec_name
);
24465 if (se
.name
== vec_name
)
24470 make_error(parser_error::e_syntax
,
24472 "ERR154 - Illegal redefinition of local vector: '" + vec_name
+ "'",
24473 exprtk_error_location
));
24475 return error_node();
24478 (se
.size
== vec_size
) &&
24479 (scope_element::e_vector
== se
.type
)
24482 vec_holder
= se
.vec_node
;
24484 se
.depth
= state_
.scope_depth
;
24489 if (0 == vec_holder
)
24492 nse
.name
= vec_name
;
24495 nse
.type
= scope_element::e_vector
;
24496 nse
.depth
= state_
.scope_depth
;
24497 nse
.size
= vec_size
;
24498 nse
.data
= new T
[vec_size
];
24499 nse
.vec_node
= new typename
scope_element::vector_holder_t((T
*)(nse
.data
),nse
.size
);
24501 if (!sem_
.add_element(nse
))
24504 make_error(parser_error::e_syntax
,
24506 "ERR155 - Failed to add new local vector '" + vec_name
+ "' to SEM",
24507 exprtk_error_location
));
24509 sem_
.free_element(nse
);
24511 return error_node();
24514 vec_holder
= nse
.vec_node
;
24516 exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n",
24518 static_cast<int>(nse
.size
)));
24521 state_
.activate_side_effect("parse_define_vector_statement()");
24523 lodge_symbol(vec_name
, e_st_local_vector
);
24525 expression_node_ptr result
= error_node();
24527 if (null_initialisation
)
24528 result
= expression_generator_(T(0.0));
24529 else if (vec_to_vec_initialiser
)
24531 expression_node_ptr vec_node
= node_allocator_
.allocate
<vector_node_t
>(vec_holder
);
24533 result
= expression_generator_(
24536 vec_initilizer_list
[0]);
24539 result
= node_allocator_
24540 .allocate
<details::vector_assignment_node
<T
> >(
24543 vec_initilizer_list
,
24544 single_value_initialiser
);
24546 svd
.delete_ptr
= (0 == result
);
24551 #ifndef exprtk_disable_string_capabilities
24552 inline expression_node_ptr
parse_define_string_statement(const std::string
& str_name
, expression_node_ptr initialisation_expression
)
24554 stringvar_node_t
* str_node
= reinterpret_cast<stringvar_node_t
*>(0);
24556 scope_element
& se
= sem_
.get_element(str_name
);
24558 if (se
.name
== str_name
)
24563 make_error(parser_error::e_syntax
,
24565 "ERR156 - Illegal redefinition of local variable: '" + str_name
+ "'",
24566 exprtk_error_location
));
24568 free_node(node_allocator_
,initialisation_expression
);
24570 return error_node();
24572 else if (scope_element::e_string
== se
.type
)
24574 str_node
= se
.str_node
;
24576 se
.depth
= state_
.scope_depth
;
24584 nse
.name
= str_name
;
24587 nse
.type
= scope_element::e_string
;
24588 nse
.depth
= state_
.scope_depth
;
24589 nse
.data
= new std::string
;
24590 nse
.str_node
= new stringvar_node_t(*(std::string
*)(nse
.data
));
24592 if (!sem_
.add_element(nse
))
24595 make_error(parser_error::e_syntax
,
24597 "ERR157 - Failed to add new local string variable '" + str_name
+ "' to SEM",
24598 exprtk_error_location
));
24600 free_node(node_allocator_
,initialisation_expression
);
24602 sem_
.free_element(nse
);
24604 return error_node();
24607 str_node
= nse
.str_node
;
24609 exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n",nse
.name
.c_str()));
24612 lodge_symbol(str_name
, e_st_local_string
);
24614 state_
.activate_side_effect("parse_define_string_statement()");
24616 expression_node_ptr branch
[2] = {0};
24618 branch
[0] = str_node
;
24619 branch
[1] = initialisation_expression
;
24621 return expression_generator_(details::e_assign
,branch
);
24624 inline expression_node_ptr
parse_define_string_statement(const std::string
&, expression_node_ptr
)
24626 return error_node();
24630 inline bool local_variable_is_shadowed(const std::string
& symbol
)
24632 const scope_element
& se
= sem_
.get_element(symbol
);
24633 return (se
.name
== symbol
) && se
.active
;
24636 inline expression_node_ptr
parse_define_var_statement()
24638 if (settings_
.vardef_disabled())
24641 make_error(parser_error::e_syntax
,
24643 "ERR158 - Illegal variable definition",
24644 exprtk_error_location
));
24646 return error_node();
24648 else if (!details::imatch(current_token().value
,"var"))
24650 return error_node();
24655 const std::string var_name
= current_token().value
;
24657 expression_node_ptr initialisation_expression
= error_node();
24659 if (!token_is(token_t::e_symbol
))
24662 make_error(parser_error::e_syntax
,
24664 "ERR159 - Expected a symbol for variable definition",
24665 exprtk_error_location
));
24667 return error_node();
24669 else if (details::is_reserved_symbol(var_name
))
24672 make_error(parser_error::e_syntax
,
24674 "ERR160 - Illegal redefinition of reserved keyword: '" + var_name
+ "'",
24675 exprtk_error_location
));
24677 return error_node();
24679 else if (symtab_store_
.symbol_exists(var_name
))
24682 make_error(parser_error::e_syntax
,
24684 "ERR161 - Illegal redefinition of variable '" + var_name
+ "'",
24685 exprtk_error_location
));
24687 return error_node();
24689 else if (local_variable_is_shadowed(var_name
))
24692 make_error(parser_error::e_syntax
,
24694 "ERR162 - Illegal redefinition of local variable: '" + var_name
+ "'",
24695 exprtk_error_location
));
24697 return error_node();
24699 else if (token_is(token_t::e_lsqrbracket
,prsrhlpr_t::e_hold
))
24701 return parse_define_vector_statement(var_name
);
24703 else if (token_is(token_t::e_lcrlbracket
,prsrhlpr_t::e_hold
))
24705 return parse_uninitialised_var_statement(var_name
);
24707 else if (token_is(token_t::e_assign
))
24709 if (0 == (initialisation_expression
= parse_expression()))
24712 make_error(parser_error::e_syntax
,
24714 "ERR163 - Failed to parse initialisation expression",
24715 exprtk_error_location
));
24717 return error_node();
24722 !token_is(token_t::e_rbracket
, prsrhlpr_t::e_hold
) &&
24723 !token_is(token_t::e_rcrlbracket
, prsrhlpr_t::e_hold
) &&
24724 !token_is(token_t::e_rsqrbracket
, prsrhlpr_t::e_hold
)
24727 if (!token_is(token_t::e_eof
,prsrhlpr_t::e_hold
))
24730 make_error(parser_error::e_syntax
,
24732 "ERR164 - Expected ';' after variable definition",
24733 exprtk_error_location
));
24735 free_node(node_allocator_
,initialisation_expression
);
24737 return error_node();
24742 (0 != initialisation_expression
) &&
24743 details::is_generally_string_node(initialisation_expression
)
24746 return parse_define_string_statement(var_name
,initialisation_expression
);
24749 expression_node_ptr var_node
= reinterpret_cast<expression_node_ptr
>(0);
24751 scope_element
& se
= sem_
.get_element(var_name
);
24753 if (se
.name
== var_name
)
24758 make_error(parser_error::e_syntax
,
24760 "ERR165 - Illegal redefinition of local variable: '" + var_name
+ "'",
24761 exprtk_error_location
));
24763 free_node(node_allocator_
, initialisation_expression
);
24765 return error_node();
24767 else if (scope_element::e_variable
== se
.type
)
24769 var_node
= se
.var_node
;
24771 se
.depth
= state_
.scope_depth
;
24779 nse
.name
= var_name
;
24782 nse
.type
= scope_element::e_variable
;
24783 nse
.depth
= state_
.scope_depth
;
24784 nse
.data
= new T(T(0));
24785 nse
.var_node
= node_allocator_
.allocate
<variable_node_t
>(*(T
*)(nse
.data
));
24787 if (!sem_
.add_element(nse
))
24790 make_error(parser_error::e_syntax
,
24792 "ERR166 - Failed to add new local variable '" + var_name
+ "' to SEM",
24793 exprtk_error_location
));
24795 free_node(node_allocator_
, initialisation_expression
);
24797 sem_
.free_element(nse
);
24799 return error_node();
24802 var_node
= nse
.var_node
;
24804 exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n",nse
.name
.c_str()));
24807 state_
.activate_side_effect("parse_define_var_statement()");
24809 lodge_symbol(var_name
, e_st_local_variable
);
24811 expression_node_ptr branch
[2] = {0};
24813 branch
[0] = var_node
;
24814 branch
[1] = initialisation_expression
? initialisation_expression
: expression_generator_(T(0));
24816 return expression_generator_(details::e_assign
,branch
);
24819 inline expression_node_ptr
parse_uninitialised_var_statement(const std::string
& var_name
)
24822 !token_is(token_t::e_lcrlbracket
) ||
24823 !token_is(token_t::e_rcrlbracket
)
24827 make_error(parser_error::e_syntax
,
24829 "ERR167 - Expected a '{}' for uninitialised var definition",
24830 exprtk_error_location
));
24832 return error_node();
24834 else if (!token_is(token_t::e_eof
,prsrhlpr_t::e_hold
))
24837 make_error(parser_error::e_syntax
,
24839 "ERR168 - Expected ';' after uninitialised variable definition",
24840 exprtk_error_location
));
24842 return error_node();
24845 expression_node_ptr var_node
= reinterpret_cast<expression_node_ptr
>(0);
24847 scope_element
& se
= sem_
.get_element(var_name
);
24849 if (se
.name
== var_name
)
24854 make_error(parser_error::e_syntax
,
24856 "ERR169 - Illegal redefinition of local variable: '" + var_name
+ "'",
24857 exprtk_error_location
));
24859 return error_node();
24861 else if (scope_element::e_variable
== se
.type
)
24863 var_node
= se
.var_node
;
24872 nse
.name
= var_name
;
24875 nse
.type
= scope_element::e_variable
;
24876 nse
.depth
= state_
.scope_depth
;
24877 nse
.ip_index
= sem_
.next_ip_index();
24878 nse
.data
= new T(T(0));
24879 nse
.var_node
= node_allocator_
.allocate
<variable_node_t
>(*(T
*)(nse
.data
));
24881 if (!sem_
.add_element(nse
))
24884 make_error(parser_error::e_syntax
,
24886 "ERR170 - Failed to add new local variable '" + var_name
+ "' to SEM",
24887 exprtk_error_location
));
24889 sem_
.free_element(nse
);
24891 return error_node();
24894 exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n",
24895 nse
.name
.c_str()));
24898 lodge_symbol(var_name
, e_st_local_variable
);
24900 state_
.activate_side_effect("parse_uninitialised_var_statement()");
24902 return expression_generator_(T(0));
24905 inline expression_node_ptr
parse_swap_statement()
24907 if (!details::imatch(current_token().value
,"swap"))
24909 return error_node();
24914 if (!token_is(token_t::e_lbracket
))
24917 make_error(parser_error::e_syntax
,
24919 "ERR171 - Expected '(' at start of swap statement",
24920 exprtk_error_location
));
24922 return error_node();
24925 expression_node_ptr variable0
= error_node();
24926 expression_node_ptr variable1
= error_node();
24928 bool variable0_generated
= false;
24929 bool variable1_generated
= false;
24931 const std::string var0_name
= current_token().value
;
24933 if (!token_is(token_t::e_symbol
,prsrhlpr_t::e_hold
))
24936 make_error(parser_error::e_syntax
,
24938 "ERR172 - Expected a symbol for variable or vector element definition",
24939 exprtk_error_location
));
24941 return error_node();
24943 else if (peek_token_is(token_t::e_lsqrbracket
))
24945 if (0 == (variable0
= parse_vector()))
24948 make_error(parser_error::e_syntax
,
24950 "ERR173 - First parameter to swap is an invalid vector element: '" + var0_name
+ "'",
24951 exprtk_error_location
));
24953 return error_node();
24956 variable0_generated
= true;
24960 if (symtab_store_
.is_variable(var0_name
))
24962 variable0
= symtab_store_
.get_variable(var0_name
);
24965 scope_element
& se
= sem_
.get_element(var0_name
);
24969 (se
.name
== var0_name
) &&
24970 (scope_element::e_variable
== se
.type
)
24973 variable0
= se
.var_node
;
24976 lodge_symbol(var0_name
, e_st_variable
);
24978 if (0 == variable0
)
24981 make_error(parser_error::e_syntax
,
24983 "ERR174 - First parameter to swap is an invalid variable: '" + var0_name
+ "'",
24984 exprtk_error_location
));
24986 return error_node();
24992 if (!token_is(token_t::e_comma
))
24995 make_error(parser_error::e_syntax
,
24997 "ERR175 - Expected ',' between parameters to swap",
24998 exprtk_error_location
));
25000 if (variable0_generated
)
25002 free_node(node_allocator_
,variable0
);
25005 return error_node();
25008 const std::string var1_name
= current_token().value
;
25010 if (!token_is(token_t::e_symbol
,prsrhlpr_t::e_hold
))
25013 make_error(parser_error::e_syntax
,
25015 "ERR176 - Expected a symbol for variable or vector element definition",
25016 exprtk_error_location
));
25018 if (variable0_generated
)
25020 free_node(node_allocator_
,variable0
);
25023 return error_node();
25025 else if (peek_token_is(token_t::e_lsqrbracket
))
25027 if (0 == (variable1
= parse_vector()))
25030 make_error(parser_error::e_syntax
,
25032 "ERR177 - Second parameter to swap is an invalid vector element: '" + var1_name
+ "'",
25033 exprtk_error_location
));
25035 if (variable0_generated
)
25037 free_node(node_allocator_
,variable0
);
25040 return error_node();
25043 variable1_generated
= true;
25047 if (symtab_store_
.is_variable(var1_name
))
25049 variable1
= symtab_store_
.get_variable(var1_name
);
25052 scope_element
& se
= sem_
.get_element(var1_name
);
25056 (se
.name
== var1_name
) &&
25057 (scope_element::e_variable
== se
.type
)
25060 variable1
= se
.var_node
;
25063 lodge_symbol(var1_name
, e_st_variable
);
25065 if (0 == variable1
)
25068 make_error(parser_error::e_syntax
,
25070 "ERR178 - Second parameter to swap is an invalid variable: '" + var1_name
+ "'",
25071 exprtk_error_location
));
25073 if (variable0_generated
)
25075 free_node(node_allocator_
,variable0
);
25078 return error_node();
25084 if (!token_is(token_t::e_rbracket
))
25087 make_error(parser_error::e_syntax
,
25089 "ERR179 - Expected ')' at end of swap statement",
25090 exprtk_error_location
));
25092 if (variable0_generated
)
25094 free_node(node_allocator_
,variable0
);
25097 if (variable1_generated
)
25099 free_node(node_allocator_
,variable1
);
25102 return error_node();
25105 typedef details::variable_node
<T
>* variable_node_ptr
;
25107 variable_node_ptr v0
= variable_node_ptr(0);
25108 variable_node_ptr v1
= variable_node_ptr(0);
25110 expression_node_ptr result
= error_node();
25113 (0 != (v0
= dynamic_cast<variable_node_ptr
>(variable0
))) &&
25114 (0 != (v1
= dynamic_cast<variable_node_ptr
>(variable1
)))
25117 result
= node_allocator_
.allocate
<details::swap_node
<T
> >(v0
, v1
);
25119 if (variable0_generated
)
25121 free_node(node_allocator_
,variable0
);
25124 if (variable1_generated
)
25126 free_node(node_allocator_
,variable1
);
25130 result
= node_allocator_
.allocate
<details::swap_generic_node
<T
> >
25131 (variable0
, variable1
);
25133 state_
.activate_side_effect("parse_swap_statement()");
25138 #ifndef exprtk_disable_return_statement
25139 inline expression_node_ptr
parse_return_statement()
25141 if (state_
.parsing_return_stmt
)
25144 make_error(parser_error::e_syntax
,
25146 "ERR180 - Return call within a return call is not allowed",
25147 exprtk_error_location
));
25149 return error_node();
25152 scoped_bool_negator
sbn(state_
.parsing_return_stmt
);
25154 std::vector
<expression_node_ptr
> arg_list
;
25156 scoped_vec_delete
<expression_node_t
> sdd((*this),arg_list
);
25158 if (!details::imatch(current_token().value
,"return"))
25160 return error_node();
25165 if (!token_is(token_t::e_lsqrbracket
))
25168 make_error(parser_error::e_syntax
,
25170 "ERR181 - Expected '[' at start of return statement",
25171 exprtk_error_location
));
25173 return error_node();
25175 else if (!token_is(token_t::e_rsqrbracket
))
25179 expression_node_ptr arg
= parse_expression();
25182 return error_node();
25184 arg_list
.push_back(arg
);
25186 if (token_is(token_t::e_rsqrbracket
))
25188 else if (!token_is(token_t::e_comma
))
25191 make_error(parser_error::e_syntax
,
25193 "ERR182 - Expected ',' between values during call to return",
25194 exprtk_error_location
));
25196 return error_node();
25200 else if (settings_
.zero_return_disabled())
25203 make_error(parser_error::e_syntax
,
25205 "ERR183 - Zero parameter return statement not allowed",
25206 exprtk_error_location
));
25208 return error_node();
25211 const lexer::token prev_token
= current_token();
25213 if (token_is(token_t::e_rsqrbracket
))
25215 if (!arg_list
.empty())
25218 make_error(parser_error::e_syntax
,
25220 "ERR184 - Invalid ']' found during return call",
25221 exprtk_error_location
));
25223 return error_node();
25227 std::string ret_param_type_list
;
25229 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
25231 if (0 == arg_list
[i
])
25232 return error_node();
25233 else if (is_ivector_node(arg_list
[i
]))
25234 ret_param_type_list
+= 'V';
25235 else if (is_generally_string_node(arg_list
[i
]))
25236 ret_param_type_list
+= 'S';
25238 ret_param_type_list
+= 'T';
25241 dec_
.retparam_list_
.push_back(ret_param_type_list
);
25243 expression_node_ptr result
= expression_generator_
.return_call(arg_list
);
25245 sdd
.delete_ptr
= (0 == result
);
25247 state_
.return_stmt_present
= true;
25249 state_
.activate_side_effect("parse_return_statement()");
25254 inline expression_node_ptr
parse_return_statement()
25256 return error_node();
25260 inline bool post_variable_process(const std::string
& symbol
)
25263 peek_token_is(token_t::e_lbracket
) ||
25264 peek_token_is(token_t::e_lcrlbracket
) ||
25265 peek_token_is(token_t::e_lsqrbracket
)
25268 if (!settings_
.commutative_check_enabled())
25271 make_error(parser_error::e_syntax
,
25273 "ERR185 - Invalid sequence of variable '"+ symbol
+ "' and bracket",
25274 exprtk_error_location
));
25279 lexer().insert_front(token_t::e_mul
);
25285 inline bool post_bracket_process(const typename
token_t::token_type
& token
, expression_node_ptr
& branch
)
25287 bool implied_mul
= false;
25289 if (is_generally_string_node(branch
))
25292 const lexer::parser_helper::token_advance_mode hold
= prsrhlpr_t::e_hold
;
25296 case token_t::e_lcrlbracket
: implied_mul
= token_is(token_t::e_lbracket
,hold
) ||
25297 token_is(token_t::e_lcrlbracket
,hold
) ||
25298 token_is(token_t::e_lsqrbracket
,hold
) ;
25301 case token_t::e_lbracket
: implied_mul
= token_is(token_t::e_lbracket
,hold
) ||
25302 token_is(token_t::e_lcrlbracket
,hold
) ||
25303 token_is(token_t::e_lsqrbracket
,hold
) ;
25306 case token_t::e_lsqrbracket
: implied_mul
= token_is(token_t::e_lbracket
,hold
) ||
25307 token_is(token_t::e_lcrlbracket
,hold
) ||
25308 token_is(token_t::e_lsqrbracket
,hold
) ;
25311 default : return true;
25316 if (!settings_
.commutative_check_enabled())
25319 make_error(parser_error::e_syntax
,
25321 "ERR186 - Invalid sequence of brackets",
25322 exprtk_error_location
));
25326 else if (token_t::e_eof
!= current_token().type
)
25328 lexer().insert_front(current_token().type
);
25329 lexer().insert_front(token_t::e_mul
);
25337 inline expression_node_ptr
parse_symtab_symbol()
25339 const std::string symbol
= current_token().value
;
25341 // Are we dealing with a variable or a special constant?
25342 expression_node_ptr variable
= symtab_store_
.get_variable(symbol
);
25346 if (symtab_store_
.is_constant_node(symbol
))
25348 variable
= expression_generator_(variable
->value());
25351 if (!post_variable_process(symbol
))
25352 return error_node();
25354 lodge_symbol(symbol
, e_st_variable
);
25360 // Are we dealing with a locally defined variable, vector or string?
25363 scope_element
& se
= sem_
.get_active_element(symbol
);
25365 if (se
.active
&& details::imatch(se
.name
, symbol
))
25367 if (scope_element::e_variable
== se
.type
)
25370 lodge_symbol(symbol
, e_st_local_variable
);
25372 if (!post_variable_process(symbol
))
25373 return error_node();
25377 return se
.var_node
;
25379 else if (scope_element::e_vector
== se
.type
)
25381 return parse_vector();
25383 #ifndef exprtk_disable_string_capabilities
25384 else if (scope_element::e_string
== se
.type
)
25386 return parse_string();
25392 #ifndef exprtk_disable_string_capabilities
25393 // Are we dealing with a string variable?
25394 if (symtab_store_
.is_stringvar(symbol
))
25396 return parse_string();
25401 // Are we dealing with a function?
25402 ifunction
<T
>* function
= symtab_store_
.get_function(symbol
);
25406 lodge_symbol(symbol
, e_st_function
);
25408 expression_node_ptr func_node
=
25409 parse_function_invocation(function
,symbol
);
25416 make_error(parser_error::e_syntax
,
25418 "ERR187 - Failed to generate node for function: '" + symbol
+ "'",
25419 exprtk_error_location
));
25421 return error_node();
25427 // Are we dealing with a vararg function?
25428 ivararg_function
<T
>* vararg_function
= symtab_store_
.get_vararg_function(symbol
);
25430 if (vararg_function
)
25432 lodge_symbol(symbol
, e_st_function
);
25434 expression_node_ptr vararg_func_node
=
25435 parse_vararg_function_call(vararg_function
, symbol
);
25437 if (vararg_func_node
)
25438 return vararg_func_node
;
25442 make_error(parser_error::e_syntax
,
25444 "ERR188 - Failed to generate node for vararg function: '" + symbol
+ "'",
25445 exprtk_error_location
));
25447 return error_node();
25453 // Are we dealing with a vararg generic function?
25454 igeneric_function
<T
>* generic_function
= symtab_store_
.get_generic_function(symbol
);
25456 if (generic_function
)
25458 lodge_symbol(symbol
, e_st_function
);
25460 expression_node_ptr genericfunc_node
=
25461 parse_generic_function_call(generic_function
, symbol
);
25463 if (genericfunc_node
)
25464 return genericfunc_node
;
25468 make_error(parser_error::e_syntax
,
25470 "ERR189 - Failed to generate node for generic function: '" + symbol
+ "'",
25471 exprtk_error_location
));
25473 return error_node();
25478 #ifndef exprtk_disable_string_capabilities
25480 // Are we dealing with a vararg string returning function?
25481 igeneric_function
<T
>* string_function
= symtab_store_
.get_string_function(symbol
);
25483 if (string_function
)
25485 lodge_symbol(symbol
, e_st_function
);
25487 expression_node_ptr stringfunc_node
=
25488 parse_string_function_call(string_function
, symbol
);
25490 if (stringfunc_node
)
25491 return stringfunc_node
;
25495 make_error(parser_error::e_syntax
,
25497 "ERR190 - Failed to generate node for string function: '" + symbol
+ "'",
25498 exprtk_error_location
));
25500 return error_node();
25506 // Are we dealing with a vararg overloaded scalar/string returning function?
25507 igeneric_function
<T
>* overload_function
= symtab_store_
.get_overload_function(symbol
);
25509 if (overload_function
)
25511 lodge_symbol(symbol
, e_st_function
);
25513 expression_node_ptr overloadfunc_node
=
25514 parse_overload_function_call(overload_function
, symbol
);
25516 if (overloadfunc_node
)
25517 return overloadfunc_node
;
25521 make_error(parser_error::e_syntax
,
25523 "ERR191 - Failed to generate node for overload function: '" + symbol
+ "'",
25524 exprtk_error_location
));
25526 return error_node();
25532 // Are we dealing with a vector?
25533 if (symtab_store_
.is_vector(symbol
))
25535 lodge_symbol(symbol
, e_st_vector
);
25536 return parse_vector();
25539 if (details::is_reserved_symbol(symbol
))
25542 settings_
.function_enabled(symbol
) ||
25543 !details::is_base_function(symbol
)
25547 make_error(parser_error::e_syntax
,
25549 "ERR192 - Invalid use of reserved symbol '" + symbol
+ "'",
25550 exprtk_error_location
));
25552 return error_node();
25556 // Should we handle unknown symbols?
25557 if (resolve_unknown_symbol_
&& unknown_symbol_resolver_
)
25559 if (!(settings_
.rsrvd_sym_usr_disabled() && details::is_reserved_symbol(symbol
)))
25561 symbol_table_t
& symtab
= symtab_store_
.get_symbol_table();
25563 std::string error_message
;
25565 if (unknown_symbol_resolver::e_usrmode_default
== unknown_symbol_resolver_
->mode
)
25567 T default_value
= T(0);
25569 typename
unknown_symbol_resolver::usr_symbol_type usr_symbol_type
= unknown_symbol_resolver::e_usr_unknown_type
;
25571 if (unknown_symbol_resolver_
->process(symbol
, usr_symbol_type
, default_value
, error_message
))
25573 bool create_result
= false;
25575 switch (usr_symbol_type
)
25577 case unknown_symbol_resolver::e_usr_variable_type
: create_result
= symtab
.create_variable(symbol
, default_value
);
25580 case unknown_symbol_resolver::e_usr_constant_type
: create_result
= symtab
.add_constant(symbol
, default_value
);
25583 default : create_result
= false;
25588 expression_node_ptr var
= symtab_store_
.get_variable(symbol
);
25592 if (symtab_store_
.is_constant_node(symbol
))
25594 var
= expression_generator_(var
->value());
25597 lodge_symbol(symbol
, e_st_variable
);
25599 if (!post_variable_process(symbol
))
25600 return error_node();
25610 make_error(parser_error::e_symtab
,
25612 "ERR193 - Failed to create variable: '" + symbol
+ "'" +
25613 (error_message
.empty() ? "" : " - " + error_message
),
25614 exprtk_error_location
));
25617 else if (unknown_symbol_resolver::e_usrmode_extended
== unknown_symbol_resolver_
->mode
)
25619 if (unknown_symbol_resolver_
->process(symbol
, symtab
, error_message
))
25621 expression_node_ptr result
= parse_symtab_symbol();
25630 make_error(parser_error::e_symtab
,
25632 "ERR194 - Failed to resolve symbol: '" + symbol
+ "'" +
25633 (error_message
.empty() ? "" : " - " + error_message
),
25634 exprtk_error_location
));
25637 return error_node();
25642 make_error(parser_error::e_syntax
,
25644 "ERR195 - Undefined symbol: '" + symbol
+ "'",
25645 exprtk_error_location
));
25647 return error_node();
25650 inline expression_node_ptr
parse_symbol()
25652 static const std::string symbol_if
= "if" ;
25653 static const std::string symbol_while
= "while" ;
25654 static const std::string symbol_repeat
= "repeat" ;
25655 static const std::string symbol_for
= "for" ;
25656 static const std::string symbol_switch
= "switch" ;
25657 static const std::string symbol_null
= "null" ;
25658 static const std::string symbol_break
= "break" ;
25659 static const std::string symbol_continue
= "continue";
25660 static const std::string symbol_var
= "var" ;
25661 static const std::string symbol_swap
= "swap" ;
25662 static const std::string symbol_return
= "return" ;
25663 static const std::string symbol_not
= "not" ;
25665 if (valid_vararg_operation(current_token().value
))
25667 return parse_vararg_function();
25669 else if (details::imatch(current_token().value
, symbol_not
))
25671 return parse_not_statement();
25673 else if (valid_base_operation(current_token().value
))
25675 return parse_base_operation();
25678 details::imatch(current_token().value
, symbol_if
) &&
25679 settings_
.control_struct_enabled(current_token().value
)
25682 return parse_conditional_statement();
25685 details::imatch(current_token().value
, symbol_while
) &&
25686 settings_
.control_struct_enabled(current_token().value
)
25689 return parse_while_loop();
25692 details::imatch(current_token().value
, symbol_repeat
) &&
25693 settings_
.control_struct_enabled(current_token().value
)
25696 return parse_repeat_until_loop();
25699 details::imatch(current_token().value
, symbol_for
) &&
25700 settings_
.control_struct_enabled(current_token().value
)
25703 return parse_for_loop();
25706 details::imatch(current_token().value
, symbol_switch
) &&
25707 settings_
.control_struct_enabled(current_token().value
)
25710 return parse_switch_statement();
25712 else if (details::is_valid_sf_symbol(current_token().value
))
25714 return parse_special_function();
25716 else if (details::imatch(current_token().value
, symbol_null
))
25718 return parse_null_statement();
25720 #ifndef exprtk_disable_break_continue
25721 else if (details::imatch(current_token().value
, symbol_break
))
25723 return parse_break_statement();
25725 else if (details::imatch(current_token().value
, symbol_continue
))
25727 return parse_continue_statement();
25730 else if (details::imatch(current_token().value
, symbol_var
))
25732 return parse_define_var_statement();
25734 else if (details::imatch(current_token().value
, symbol_swap
))
25736 return parse_swap_statement();
25738 #ifndef exprtk_disable_return_statement
25740 details::imatch(current_token().value
, symbol_return
) &&
25741 settings_
.control_struct_enabled(current_token().value
)
25744 return parse_return_statement();
25747 else if (symtab_store_
.valid() || !sem_
.empty())
25749 return parse_symtab_symbol();
25754 make_error(parser_error::e_symtab
,
25756 "ERR196 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value
,
25757 exprtk_error_location
));
25759 return error_node();
25763 inline expression_node_ptr
parse_branch(precedence_level precedence
= e_level00
)
25765 expression_node_ptr branch
= error_node();
25767 if (token_t::e_number
== current_token().type
)
25769 T numeric_value
= T(0);
25771 if (details::string_to_real(current_token().value
, numeric_value
))
25773 expression_node_ptr literal_exp
= expression_generator_(numeric_value
);
25775 if (0 == literal_exp
)
25778 make_error(parser_error::e_numeric
,
25780 "ERR197 - Failed generate node for scalar: '" + current_token().value
+ "'",
25781 exprtk_error_location
));
25783 return error_node();
25787 branch
= literal_exp
;
25792 make_error(parser_error::e_numeric
,
25794 "ERR198 - Failed to convert '" + current_token().value
+ "' to a number",
25795 exprtk_error_location
));
25797 return error_node();
25800 else if (token_t::e_symbol
== current_token().type
)
25802 branch
= parse_symbol();
25804 #ifndef exprtk_disable_string_capabilities
25805 else if (token_t::e_string
== current_token().type
)
25807 branch
= parse_const_string();
25810 else if (token_t::e_lbracket
== current_token().type
)
25814 if (0 == (branch
= parse_expression()))
25815 return error_node();
25816 else if (!token_is(token_t::e_rbracket
))
25819 make_error(parser_error::e_syntax
,
25821 "ERR199 - Expected ')' instead of: '" + current_token().value
+ "'",
25822 exprtk_error_location
));
25824 free_node(node_allocator_
,branch
);
25826 return error_node();
25828 else if (!post_bracket_process(token_t::e_lbracket
,branch
))
25830 free_node(node_allocator_
,branch
);
25832 return error_node();
25835 else if (token_t::e_lsqrbracket
== current_token().type
)
25839 if (0 == (branch
= parse_expression()))
25840 return error_node();
25841 else if (!token_is(token_t::e_rsqrbracket
))
25844 make_error(parser_error::e_syntax
,
25846 "ERR200 - Expected ']' instead of: '" + current_token().value
+ "'",
25847 exprtk_error_location
));
25849 free_node(node_allocator_
,branch
);
25851 return error_node();
25853 else if (!post_bracket_process(token_t::e_lsqrbracket
,branch
))
25855 free_node(node_allocator_
,branch
);
25857 return error_node();
25860 else if (token_t::e_lcrlbracket
== current_token().type
)
25864 if (0 == (branch
= parse_expression()))
25865 return error_node();
25866 else if (!token_is(token_t::e_rcrlbracket
))
25869 make_error(parser_error::e_syntax
,
25871 "ERR201 - Expected '}' instead of: '" + current_token().value
+ "'",
25872 exprtk_error_location
));
25874 free_node(node_allocator_
,branch
);
25876 return error_node();
25878 else if (!post_bracket_process(token_t::e_lcrlbracket
,branch
))
25880 free_node(node_allocator_
,branch
);
25882 return error_node();
25885 else if (token_t::e_sub
== current_token().type
)
25888 branch
= parse_expression(e_level11
);
25893 details::is_neg_unary_node (branch
) &&
25894 simplify_unary_negation_branch(branch
)
25898 branch
= expression_generator_(details::e_neg
,branch
);
25901 else if (token_t::e_add
== current_token().type
)
25904 branch
= parse_expression(e_level13
);
25906 else if (token_t::e_eof
== current_token().type
)
25909 make_error(parser_error::e_syntax
,
25911 "ERR202 - Premature end of expression[1]",
25912 exprtk_error_location
));
25914 return error_node();
25919 make_error(parser_error::e_syntax
,
25921 "ERR203 - Premature end of expression[2]",
25922 exprtk_error_location
));
25924 return error_node();
25929 (e_level00
== precedence
) &&
25930 token_is(token_t::e_ternary
,prsrhlpr_t::e_hold
)
25933 branch
= parse_ternary_conditional_statement(branch
);
25936 parse_pending_string_rangesize(branch
);
25941 template <typename Type
>
25942 class expression_generator
25946 typedef details::expression_node
<Type
>* expression_node_ptr
;
25947 typedef expression_node_ptr (*synthesize_functor_t
)(expression_generator
<T
>&, const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]);
25948 typedef std::map
<std::string
,synthesize_functor_t
> synthesize_map_t
;
25949 typedef typename
exprtk::parser
<Type
> parser_t
;
25950 typedef const Type
& vtype
;
25951 typedef const Type ctype
;
25953 inline void init_synthesize_map()
25955 #ifndef exprtk_disable_enhanced_features
25956 synthesize_map_
["(v)o(v)"] = synthesize_vov_expression::process
;
25957 synthesize_map_
["(c)o(v)"] = synthesize_cov_expression::process
;
25958 synthesize_map_
["(v)o(c)"] = synthesize_voc_expression::process
;
25960 #define register_synthezier(S) \
25961 synthesize_map_[S ::node_type::id()] = S ::process; \
25963 register_synthezier(synthesize_vovov_expression0)
25964 register_synthezier(synthesize_vovov_expression1
)
25965 register_synthezier(synthesize_vovoc_expression0
)
25966 register_synthezier(synthesize_vovoc_expression1
)
25967 register_synthezier(synthesize_vocov_expression0
)
25968 register_synthezier(synthesize_vocov_expression1
)
25969 register_synthezier(synthesize_covov_expression0
)
25970 register_synthezier(synthesize_covov_expression1
)
25971 register_synthezier(synthesize_covoc_expression0
)
25972 register_synthezier(synthesize_covoc_expression1
)
25973 register_synthezier(synthesize_cocov_expression1
)
25974 register_synthezier(synthesize_vococ_expression0
)
25976 register_synthezier(synthesize_vovovov_expression0
)
25977 register_synthezier(synthesize_vovovoc_expression0
)
25978 register_synthezier(synthesize_vovocov_expression0
)
25979 register_synthezier(synthesize_vocovov_expression0
)
25980 register_synthezier(synthesize_covovov_expression0
)
25981 register_synthezier(synthesize_covocov_expression0
)
25982 register_synthezier(synthesize_vocovoc_expression0
)
25983 register_synthezier(synthesize_covovoc_expression0
)
25984 register_synthezier(synthesize_vococov_expression0
)
25986 register_synthezier(synthesize_vovovov_expression1
)
25987 register_synthezier(synthesize_vovovoc_expression1
)
25988 register_synthezier(synthesize_vovocov_expression1
)
25989 register_synthezier(synthesize_vocovov_expression1
)
25990 register_synthezier(synthesize_covovov_expression1
)
25991 register_synthezier(synthesize_covocov_expression1
)
25992 register_synthezier(synthesize_vocovoc_expression1
)
25993 register_synthezier(synthesize_covovoc_expression1
)
25994 register_synthezier(synthesize_vococov_expression1
)
25996 register_synthezier(synthesize_vovovov_expression2
)
25997 register_synthezier(synthesize_vovovoc_expression2
)
25998 register_synthezier(synthesize_vovocov_expression2
)
25999 register_synthezier(synthesize_vocovov_expression2
)
26000 register_synthezier(synthesize_covovov_expression2
)
26001 register_synthezier(synthesize_covocov_expression2
)
26002 register_synthezier(synthesize_vocovoc_expression2
)
26003 register_synthezier(synthesize_covovoc_expression2
)
26005 register_synthezier(synthesize_vovovov_expression3
)
26006 register_synthezier(synthesize_vovovoc_expression3
)
26007 register_synthezier(synthesize_vovocov_expression3
)
26008 register_synthezier(synthesize_vocovov_expression3
)
26009 register_synthezier(synthesize_covovov_expression3
)
26010 register_synthezier(synthesize_covocov_expression3
)
26011 register_synthezier(synthesize_vocovoc_expression3
)
26012 register_synthezier(synthesize_covovoc_expression3
)
26013 register_synthezier(synthesize_vococov_expression3
)
26015 register_synthezier(synthesize_vovovov_expression4
)
26016 register_synthezier(synthesize_vovovoc_expression4
)
26017 register_synthezier(synthesize_vovocov_expression4
)
26018 register_synthezier(synthesize_vocovov_expression4
)
26019 register_synthezier(synthesize_covovov_expression4
)
26020 register_synthezier(synthesize_covocov_expression4
)
26021 register_synthezier(synthesize_vocovoc_expression4
)
26022 register_synthezier(synthesize_covovoc_expression4
)
26026 inline void set_parser(parser_t
& p
)
26031 inline void set_uom(unary_op_map_t
& unary_op_map
)
26033 unary_op_map_
= &unary_op_map
;
26036 inline void set_bom(binary_op_map_t
& binary_op_map
)
26038 binary_op_map_
= &binary_op_map
;
26041 inline void set_ibom(inv_binary_op_map_t
& inv_binary_op_map
)
26043 inv_binary_op_map_
= &inv_binary_op_map
;
26046 inline void set_sf3m(sf3_map_t
& sf3_map
)
26048 sf3_map_
= &sf3_map
;
26051 inline void set_sf4m(sf4_map_t
& sf4_map
)
26053 sf4_map_
= &sf4_map
;
26056 inline void set_allocator(details::node_allocator
& na
)
26058 node_allocator_
= &na
;
26061 inline void set_strength_reduction_state(const bool enabled
)
26063 strength_reduction_enabled_
= enabled
;
26066 inline bool strength_reduction_enabled() const
26068 return strength_reduction_enabled_
;
26071 inline bool valid_operator(const details::operator_type
& operation
, binary_functor_t
& bop
)
26073 typename
binary_op_map_t::iterator bop_itr
= binary_op_map_
->find(operation
);
26075 if ((*binary_op_map_
).end() == bop_itr
)
26078 bop
= bop_itr
->second
;
26083 inline bool valid_operator(const details::operator_type
& operation
, unary_functor_t
& uop
)
26085 typename
unary_op_map_t::iterator uop_itr
= unary_op_map_
->find(operation
);
26087 if ((*unary_op_map_
).end() == uop_itr
)
26090 uop
= uop_itr
->second
;
26095 inline details::operator_type
get_operator(const binary_functor_t
& bop
) const
26097 return (*inv_binary_op_map_
).find(bop
)->second
;
26100 inline expression_node_ptr
operator() (const Type
& v
) const
26102 return node_allocator_
->allocate
<literal_node_t
>(v
);
26105 #ifndef exprtk_disable_string_capabilities
26106 inline expression_node_ptr
operator() (const std::string
& s
) const
26108 return node_allocator_
->allocate
<string_literal_node_t
>(s
);
26111 inline expression_node_ptr
operator() (std::string
& s
, range_t
& rp
) const
26113 return node_allocator_
->allocate_rr
<string_range_node_t
>(s
,rp
);
26116 inline expression_node_ptr
operator() (const std::string
& s
, range_t
& rp
) const
26118 return node_allocator_
->allocate_tt
<const_string_range_node_t
>(s
,rp
);
26121 inline expression_node_ptr
operator() (expression_node_ptr branch
, range_t
& rp
) const
26123 if (is_generally_string_node(branch
))
26124 return node_allocator_
->allocate_tt
<generic_string_range_node_t
>(branch
,rp
);
26126 return error_node();
26130 inline bool unary_optimisable(const details::operator_type
& operation
) const
26132 return (details::e_abs
== operation
) || (details::e_acos
== operation
) ||
26133 (details::e_acosh
== operation
) || (details::e_asin
== operation
) ||
26134 (details::e_asinh
== operation
) || (details::e_atan
== operation
) ||
26135 (details::e_atanh
== operation
) || (details::e_ceil
== operation
) ||
26136 (details::e_cos
== operation
) || (details::e_cosh
== operation
) ||
26137 (details::e_exp
== operation
) || (details::e_expm1
== operation
) ||
26138 (details::e_floor
== operation
) || (details::e_log
== operation
) ||
26139 (details::e_log10
== operation
) || (details::e_log2
== operation
) ||
26140 (details::e_log1p
== operation
) || (details::e_neg
== operation
) ||
26141 (details::e_pos
== operation
) || (details::e_round
== operation
) ||
26142 (details::e_sin
== operation
) || (details::e_sinc
== operation
) ||
26143 (details::e_sinh
== operation
) || (details::e_sqrt
== operation
) ||
26144 (details::e_tan
== operation
) || (details::e_tanh
== operation
) ||
26145 (details::e_cot
== operation
) || (details::e_sec
== operation
) ||
26146 (details::e_csc
== operation
) || (details::e_r2d
== operation
) ||
26147 (details::e_d2r
== operation
) || (details::e_d2g
== operation
) ||
26148 (details::e_g2d
== operation
) || (details::e_notl
== operation
) ||
26149 (details::e_sgn
== operation
) || (details::e_erf
== operation
) ||
26150 (details::e_erfc
== operation
) || (details::e_ncdf
== operation
) ||
26151 (details::e_frac
== operation
) || (details::e_trunc
== operation
) ;
26154 inline bool sf3_optimisable(const std::string
& sf3id
, trinary_functor_t
& tfunc
) const
26156 typename
sf3_map_t::const_iterator itr
= sf3_map_
->find(sf3id
);
26158 if (sf3_map_
->end() == itr
)
26161 tfunc
= itr
->second
.first
;
26166 inline bool sf4_optimisable(const std::string
& sf4id
, quaternary_functor_t
& qfunc
) const
26168 typename
sf4_map_t::const_iterator itr
= sf4_map_
->find(sf4id
);
26170 if (sf4_map_
->end() == itr
)
26173 qfunc
= itr
->second
.first
;
26178 inline bool sf3_optimisable(const std::string
& sf3id
, details::operator_type
& operation
) const
26180 typename
sf3_map_t::const_iterator itr
= sf3_map_
->find(sf3id
);
26182 if (sf3_map_
->end() == itr
)
26185 operation
= itr
->second
.second
;
26190 inline bool sf4_optimisable(const std::string
& sf4id
, details::operator_type
& operation
) const
26192 typename
sf4_map_t::const_iterator itr
= sf4_map_
->find(sf4id
);
26194 if (sf4_map_
->end() == itr
)
26197 operation
= itr
->second
.second
;
26202 inline expression_node_ptr
operator() (const details::operator_type
& operation
, expression_node_ptr (&branch
)[1])
26204 if (0 == branch
[0])
26206 return error_node();
26208 else if (details::is_null_node(branch
[0]))
26212 else if (details::is_break_node(branch
[0]))
26214 return error_node();
26216 else if (details::is_continue_node(branch
[0]))
26218 return error_node();
26220 else if (details::is_constant_node(branch
[0]))
26222 return synthesize_expression
<unary_node_t
,1>(operation
,branch
);
26224 else if (unary_optimisable(operation
) && details::is_variable_node(branch
[0]))
26226 return synthesize_uv_expression(operation
,branch
);
26228 else if (unary_optimisable(operation
) && details::is_ivector_node(branch
[0]))
26230 return synthesize_uvec_expression(operation
,branch
);
26233 return synthesize_unary_expression(operation
,branch
);
26236 inline bool is_assignment_operation(const details::operator_type
& operation
) const
26239 (details::e_addass
== operation
) ||
26240 (details::e_subass
== operation
) ||
26241 (details::e_mulass
== operation
) ||
26242 (details::e_divass
== operation
) ||
26243 (details::e_modass
== operation
)
26245 parser_
->settings_
.assignment_enabled(operation
);
26248 #ifndef exprtk_disable_string_capabilities
26249 inline bool valid_string_operation(const details::operator_type
& operation
) const
26251 return (details::e_add
== operation
) ||
26252 (details::e_lt
== operation
) ||
26253 (details::e_lte
== operation
) ||
26254 (details::e_gt
== operation
) ||
26255 (details::e_gte
== operation
) ||
26256 (details::e_eq
== operation
) ||
26257 (details::e_ne
== operation
) ||
26258 (details::e_in
== operation
) ||
26259 (details::e_like
== operation
) ||
26260 (details::e_ilike
== operation
) ||
26261 (details::e_assign
== operation
) ||
26262 (details::e_addass
== operation
) ||
26263 (details::e_swap
== operation
) ;
26266 inline bool valid_string_operation(const details::operator_type
&) const
26272 inline std::string
to_str(const details::operator_type
& operation
) const
26276 case details::e_add
: return "+" ;
26277 case details::e_sub
: return "-" ;
26278 case details::e_mul
: return "*" ;
26279 case details::e_div
: return "/" ;
26280 case details::e_mod
: return "%" ;
26281 case details::e_pow
: return "^" ;
26282 case details::e_lt
: return "<" ;
26283 case details::e_lte
: return "<=" ;
26284 case details::e_gt
: return ">" ;
26285 case details::e_gte
: return ">=" ;
26286 case details::e_eq
: return "==" ;
26287 case details::e_ne
: return "!=" ;
26288 case details::e_and
: return "and" ;
26289 case details::e_nand
: return "nand" ;
26290 case details::e_or
: return "or" ;
26291 case details::e_nor
: return "nor" ;
26292 case details::e_xor
: return "xor" ;
26293 case details::e_xnor
: return "xnor" ;
26294 default : return "UNKNOWN";
26298 inline bool operation_optimisable(const details::operator_type
& operation
) const
26300 return (details::e_add
== operation
) ||
26301 (details::e_sub
== operation
) ||
26302 (details::e_mul
== operation
) ||
26303 (details::e_div
== operation
) ||
26304 (details::e_mod
== operation
) ||
26305 (details::e_pow
== operation
) ||
26306 (details::e_lt
== operation
) ||
26307 (details::e_lte
== operation
) ||
26308 (details::e_gt
== operation
) ||
26309 (details::e_gte
== operation
) ||
26310 (details::e_eq
== operation
) ||
26311 (details::e_ne
== operation
) ||
26312 (details::e_and
== operation
) ||
26313 (details::e_nand
== operation
) ||
26314 (details::e_or
== operation
) ||
26315 (details::e_nor
== operation
) ||
26316 (details::e_xor
== operation
) ||
26317 (details::e_xnor
== operation
) ;
26320 inline std::string
branch_to_id(expression_node_ptr branch
) const
26322 static const std::string
null_str ("(null)" );
26323 static const std::string
const_str ("(c)" );
26324 static const std::string
var_str ("(v)" );
26325 static const std::string
vov_str ("(vov)" );
26326 static const std::string
cov_str ("(cov)" );
26327 static const std::string
voc_str ("(voc)" );
26328 static const std::string
str_str ("(s)" );
26329 static const std::string
strrng_str ("(rngs)" );
26330 static const std::string
cs_str ("(cs)" );
26331 static const std::string
cstrrng_str("(crngs)");
26333 if (details::is_null_node(branch
))
26335 else if (details::is_constant_node(branch
))
26337 else if (details::is_variable_node(branch
))
26339 else if (details::is_vov_node(branch
))
26341 else if (details::is_cov_node(branch
))
26343 else if (details::is_voc_node(branch
))
26345 else if (details::is_string_node(branch
))
26347 else if (details::is_const_string_node(branch
))
26349 else if (details::is_string_range_node(branch
))
26351 else if (details::is_const_string_range_node(branch
))
26352 return cstrrng_str
;
26353 else if (details::is_t0ot1ot2_node(branch
))
26354 return "(" + dynamic_cast<details::T0oT1oT2_base_node
<T
>*>(branch
)->type_id() + ")";
26355 else if (details::is_t0ot1ot2ot3_node(branch
))
26356 return "(" + dynamic_cast<details::T0oT1oT2oT3_base_node
<T
>*>(branch
)->type_id() + ")";
26361 inline std::string
branch_to_id(expression_node_ptr (&branch
)[2]) const
26363 return branch_to_id(branch
[0]) + std::string("o") + branch_to_id(branch
[1]);
26366 inline bool cov_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26368 if (!operation_optimisable(operation
))
26371 return details::is_constant_node(branch
[0]) &&
26372 details::is_variable_node(branch
[1]) ;
26375 inline bool voc_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26377 if (!operation_optimisable(operation
))
26380 return details::is_variable_node(branch
[0]) &&
26381 details::is_constant_node(branch
[1]) ;
26384 inline bool vov_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26386 if (!operation_optimisable(operation
))
26389 return details::is_variable_node(branch
[0]) &&
26390 details::is_variable_node(branch
[1]) ;
26393 inline bool cob_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26395 if (!operation_optimisable(operation
))
26398 return details::is_constant_node(branch
[0]) &&
26399 !details::is_constant_node(branch
[1]) ;
26402 inline bool boc_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26404 if (!operation_optimisable(operation
))
26407 return !details::is_constant_node(branch
[0]) &&
26408 details::is_constant_node(branch
[1]) ;
26411 inline bool cocob_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26414 (details::e_add
== operation
) ||
26415 (details::e_sub
== operation
) ||
26416 (details::e_mul
== operation
) ||
26417 (details::e_div
== operation
)
26420 return (details::is_constant_node(branch
[0]) && details::is_cob_node(branch
[1])) ||
26421 (details::is_constant_node(branch
[1]) && details::is_cob_node(branch
[0])) ;
26427 inline bool coboc_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26430 (details::e_add
== operation
) ||
26431 (details::e_sub
== operation
) ||
26432 (details::e_mul
== operation
) ||
26433 (details::e_div
== operation
)
26436 return (details::is_constant_node(branch
[0]) && details::is_boc_node(branch
[1])) ||
26437 (details::is_constant_node(branch
[1]) && details::is_boc_node(branch
[0])) ;
26443 inline bool uvouv_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26445 if (!operation_optimisable(operation
))
26448 return details::is_uv_node(branch
[0]) &&
26449 details::is_uv_node(branch
[1]) ;
26452 inline bool vob_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26454 if (!operation_optimisable(operation
))
26457 return details::is_variable_node(branch
[0]) &&
26458 !details::is_variable_node(branch
[1]) ;
26461 inline bool bov_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26463 if (!operation_optimisable(operation
))
26466 return !details::is_variable_node(branch
[0]) &&
26467 details::is_variable_node(branch
[1]) ;
26470 inline bool binext_optimisable(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26472 if (!operation_optimisable(operation
))
26475 return !details::is_constant_node(branch
[0]) ||
26476 !details::is_constant_node(branch
[1]) ;
26479 inline bool is_invalid_assignment_op(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26481 if (is_assignment_operation(operation
))
26483 const bool b1_is_genstring
= details::is_generally_string_node(branch
[1]);
26485 if (details::is_string_node(branch
[0]))
26486 return !b1_is_genstring
;
26489 !details::is_variable_node (branch
[0]) &&
26490 !details::is_vector_elem_node (branch
[0]) &&
26491 !details::is_rebasevector_elem_node (branch
[0]) &&
26492 !details::is_rebasevector_celem_node(branch
[0]) &&
26493 !details::is_vector_node (branch
[0])
26495 || b1_is_genstring
;
26501 inline bool is_constpow_operation(const details::operator_type
& operation
, expression_node_ptr(&branch
)[2]) const
26504 !details::is_constant_node(branch
[1]) ||
26505 details::is_constant_node(branch
[0]) ||
26506 details::is_variable_node(branch
[0]) ||
26507 details::is_vector_node (branch
[0]) ||
26508 details::is_generally_string_node(branch
[0])
26512 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
26514 return cardinal_pow_optimisable(operation
, c
);
26517 inline bool is_invalid_break_continue_op(expression_node_ptr (&branch
)[2]) const
26520 details::is_break_node (branch
[0]) ||
26521 details::is_break_node (branch
[1]) ||
26522 details::is_continue_node(branch
[0]) ||
26523 details::is_continue_node(branch
[1])
26527 inline bool is_invalid_string_op(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26529 const bool b0_string
= is_generally_string_node(branch
[0]);
26530 const bool b1_string
= is_generally_string_node(branch
[1]);
26532 bool result
= false;
26534 if (b0_string
!= b1_string
)
26536 else if (!valid_string_operation(operation
) && b0_string
&& b1_string
)
26541 parser_
->set_synthesis_error("Invalid string operation");
26547 inline bool is_invalid_string_op(const details::operator_type
& operation
, expression_node_ptr (&branch
)[3]) const
26549 const bool b0_string
= is_generally_string_node(branch
[0]);
26550 const bool b1_string
= is_generally_string_node(branch
[1]);
26551 const bool b2_string
= is_generally_string_node(branch
[2]);
26553 bool result
= false;
26555 if ((b0_string
!= b1_string
) || (b1_string
!= b2_string
))
26557 else if ((details::e_inrange
!= operation
) && b0_string
&& b1_string
&& b2_string
)
26562 parser_
->set_synthesis_error("Invalid string operation");
26568 inline bool is_string_operation(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26570 const bool b0_string
= is_generally_string_node(branch
[0]);
26571 const bool b1_string
= is_generally_string_node(branch
[1]);
26573 return (b0_string
&& b1_string
&& valid_string_operation(operation
));
26576 inline bool is_string_operation(const details::operator_type
& operation
, expression_node_ptr (&branch
)[3]) const
26578 const bool b0_string
= is_generally_string_node(branch
[0]);
26579 const bool b1_string
= is_generally_string_node(branch
[1]);
26580 const bool b2_string
= is_generally_string_node(branch
[2]);
26582 return (b0_string
&& b1_string
&& b2_string
&& (details::e_inrange
== operation
));
26585 #ifndef exprtk_disable_sc_andor
26586 inline bool is_shortcircuit_expression(const details::operator_type
& operation
) const
26589 (details::e_scand
== operation
) ||
26590 (details::e_scor
== operation
)
26594 inline bool is_shortcircuit_expression(const details::operator_type
&) const
26600 inline bool is_null_present(expression_node_ptr (&branch
)[2]) const
26603 details::is_null_node(branch
[0]) ||
26604 details::is_null_node(branch
[1])
26608 inline bool is_vector_eqineq_logic_operation(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26610 if (!is_ivector_node(branch
[0]) && !is_ivector_node(branch
[1]))
26614 (details::e_lt
== operation
) ||
26615 (details::e_lte
== operation
) ||
26616 (details::e_gt
== operation
) ||
26617 (details::e_gte
== operation
) ||
26618 (details::e_eq
== operation
) ||
26619 (details::e_ne
== operation
) ||
26620 (details::e_equal
== operation
) ||
26621 (details::e_and
== operation
) ||
26622 (details::e_nand
== operation
) ||
26623 (details:: e_or
== operation
) ||
26624 (details:: e_nor
== operation
) ||
26625 (details:: e_xor
== operation
) ||
26626 (details::e_xnor
== operation
)
26630 inline bool is_vector_arithmetic_operation(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2]) const
26632 if (!is_ivector_node(branch
[0]) && !is_ivector_node(branch
[1]))
26636 (details::e_add
== operation
) ||
26637 (details::e_sub
== operation
) ||
26638 (details::e_mul
== operation
) ||
26639 (details::e_div
== operation
) ||
26640 (details::e_pow
== operation
)
26644 inline expression_node_ptr
operator() (const details::operator_type
& operation
, expression_node_ptr (&branch
)[2])
26646 if ((0 == branch
[0]) || (0 == branch
[1]))
26648 return error_node();
26650 else if (is_invalid_string_op(operation
,branch
))
26652 return error_node();
26654 else if (is_invalid_assignment_op(operation
,branch
))
26656 return error_node();
26658 else if (is_invalid_break_continue_op(branch
))
26660 return error_node();
26662 else if (details::e_assign
== operation
)
26664 return synthesize_assignment_expression(operation
, branch
);
26666 else if (details::e_swap
== operation
)
26668 return synthesize_swap_expression(branch
);
26670 else if (is_assignment_operation(operation
))
26672 return synthesize_assignment_operation_expression(operation
, branch
);
26674 else if (is_vector_eqineq_logic_operation(operation
, branch
))
26676 return synthesize_veceqineqlogic_operation_expression(operation
, branch
);
26678 else if (is_vector_arithmetic_operation(operation
, branch
))
26680 return synthesize_vecarithmetic_operation_expression(operation
, branch
);
26682 else if (is_shortcircuit_expression(operation
))
26684 return synthesize_shortcircuit_expression(operation
, branch
);
26686 else if (is_string_operation(operation
, branch
))
26688 return synthesize_string_expression(operation
, branch
);
26690 else if (is_null_present(branch
))
26692 return synthesize_null_expression(operation
, branch
);
26694 #ifndef exprtk_disable_cardinal_pow_optimisation
26695 else if (is_constpow_operation(operation
, branch
))
26697 return cardinal_pow_optimisation(branch
);
26701 expression_node_ptr result
= error_node();
26703 #ifndef exprtk_disable_enhanced_features
26704 if (synthesize_expression(operation
, branch
, result
))
26713 Possible reductions:
26719 result
= error_node();
26721 if (cocob_optimisable(operation
, branch
))
26723 result
= synthesize_cocob_expression::process((*this), operation
, branch
);
26725 else if (coboc_optimisable(operation
, branch
) && (0 == result
))
26727 result
= synthesize_coboc_expression::process((*this), operation
, branch
);
26734 if (uvouv_optimisable(operation
, branch
))
26736 return synthesize_uvouv_expression(operation
, branch
);
26738 else if (vob_optimisable(operation
, branch
))
26740 return synthesize_vob_expression::process((*this), operation
, branch
);
26742 else if (bov_optimisable(operation
, branch
))
26744 return synthesize_bov_expression::process((*this), operation
, branch
);
26746 else if (cob_optimisable(operation
, branch
))
26748 return synthesize_cob_expression::process((*this), operation
, branch
);
26750 else if (boc_optimisable(operation
, branch
))
26752 return synthesize_boc_expression::process((*this), operation
, branch
);
26754 #ifndef exprtk_disable_enhanced_features
26755 else if (cov_optimisable(operation
, branch
))
26757 return synthesize_cov_expression::process((*this), operation
, branch
);
26760 else if (binext_optimisable(operation
, branch
))
26762 return synthesize_binary_ext_expression::process((*this), operation
, branch
);
26765 return synthesize_expression
<binary_node_t
,2>(operation
, branch
);
26768 inline expression_node_ptr
operator() (const details::operator_type
& operation
, expression_node_ptr (&branch
)[3])
26771 (0 == branch
[0]) ||
26772 (0 == branch
[1]) ||
26776 details::free_all_nodes(*node_allocator_
,branch
);
26778 return error_node();
26780 else if (is_invalid_string_op(operation
, branch
))
26782 return error_node();
26784 else if (is_string_operation(operation
, branch
))
26786 return synthesize_string_expression(operation
, branch
);
26789 return synthesize_expression
<trinary_node_t
,3>(operation
, branch
);
26792 inline expression_node_ptr
operator() (const details::operator_type
& operation
, expression_node_ptr (&branch
)[4])
26794 return synthesize_expression
<quaternary_node_t
,4>(operation
,branch
);
26797 inline expression_node_ptr
operator() (const details::operator_type
& operation
, expression_node_ptr b0
)
26799 expression_node_ptr branch
[1] = { b0
};
26800 return (*this)(operation
,branch
);
26803 inline expression_node_ptr
operator() (const details::operator_type
& operation
, expression_node_ptr
& b0
, expression_node_ptr
& b1
)
26805 expression_node_ptr result
= error_node();
26807 if ((0 != b0
) && (0 != b1
))
26809 expression_node_ptr branch
[2] = { b0
, b1
};
26810 result
= expression_generator
<Type
>::operator()(operation
, branch
);
26818 inline expression_node_ptr
conditional(expression_node_ptr condition
,
26819 expression_node_ptr consequent
,
26820 expression_node_ptr alternative
) const
26822 if ((0 == condition
) || (0 == consequent
))
26824 free_node(*node_allocator_
, condition
);
26825 free_node(*node_allocator_
, consequent
);
26826 free_node(*node_allocator_
, alternative
);
26828 return error_node();
26830 // Can the condition be immediately evaluated? if so optimise.
26831 else if (details::is_constant_node(condition
))
26834 if (details::is_true(condition
))
26836 free_node(*node_allocator_
, condition
);
26837 free_node(*node_allocator_
, alternative
);
26844 free_node(*node_allocator_
, condition
);
26845 free_node(*node_allocator_
, consequent
);
26848 return alternative
;
26850 return node_allocator_
->allocate
<details::null_node
<T
> >();
26853 else if ((0 != consequent
) && (0 != alternative
))
26855 return node_allocator_
->
26856 allocate
<conditional_node_t
>(condition
, consequent
, alternative
);
26859 return node_allocator_
->
26860 allocate
<cons_conditional_node_t
>(condition
, consequent
);
26863 #ifndef exprtk_disable_string_capabilities
26864 inline expression_node_ptr
conditional_string(expression_node_ptr condition
,
26865 expression_node_ptr consequent
,
26866 expression_node_ptr alternative
) const
26868 if ((0 == condition
) || (0 == consequent
))
26870 free_node(*node_allocator_
, condition
);
26871 free_node(*node_allocator_
, consequent
);
26872 free_node(*node_allocator_
, alternative
);
26874 return error_node();
26876 // Can the condition be immediately evaluated? if so optimise.
26877 else if (details::is_constant_node(condition
))
26880 if (details::is_true(condition
))
26882 free_node(*node_allocator_
, condition
);
26883 free_node(*node_allocator_
, alternative
);
26890 free_node(*node_allocator_
, condition
);
26891 free_node(*node_allocator_
, consequent
);
26894 return alternative
;
26896 return node_allocator_
->
26897 allocate_c
<details::string_literal_node
<Type
> >("");
26900 else if ((0 != consequent
) && (0 != alternative
))
26901 return node_allocator_
->
26902 allocate
<conditional_string_node_t
>(condition
, consequent
, alternative
);
26904 return error_node();
26907 inline expression_node_ptr
conditional_string(expression_node_ptr
,
26908 expression_node_ptr
,
26909 expression_node_ptr
) const
26911 return error_node();
26915 inline expression_node_ptr
while_loop(expression_node_ptr
& condition
,
26916 expression_node_ptr
& branch
,
26917 const bool brkcont
= false) const
26919 if (!brkcont
&& details::is_constant_node(condition
))
26921 expression_node_ptr result
= error_node();
26922 if (details::is_true(condition
))
26923 // Infinite loops are not allowed.
26924 result
= error_node();
26926 result
= node_allocator_
->allocate
<details::null_node
<Type
> >();
26928 free_node(*node_allocator_
, condition
);
26929 free_node(*node_allocator_
, branch
);
26933 else if (details::is_null_node(condition
))
26935 free_node(*node_allocator_
,condition
);
26940 return node_allocator_
->allocate
<while_loop_node_t
>(condition
,branch
);
26941 #ifndef exprtk_disable_break_continue
26943 return node_allocator_
->allocate
<while_loop_bc_node_t
>(condition
,branch
);
26945 return error_node();
26949 inline expression_node_ptr
repeat_until_loop(expression_node_ptr
& condition
,
26950 expression_node_ptr
& branch
,
26951 const bool brkcont
= false) const
26953 if (!brkcont
&& details::is_constant_node(condition
))
26956 details::is_true(condition
) &&
26957 details::is_constant_node(branch
)
26960 free_node(*node_allocator_
,condition
);
26965 free_node(*node_allocator_
, condition
);
26966 free_node(*node_allocator_
, branch
);
26968 return error_node();
26970 else if (details::is_null_node(condition
))
26972 free_node(*node_allocator_
,condition
);
26977 return node_allocator_
->allocate
<repeat_until_loop_node_t
>(condition
,branch
);
26978 #ifndef exprtk_disable_break_continue
26980 return node_allocator_
->allocate
<repeat_until_loop_bc_node_t
>(condition
,branch
);
26982 return error_node();
26986 inline expression_node_ptr
for_loop(expression_node_ptr
& initialiser
,
26987 expression_node_ptr
& condition
,
26988 expression_node_ptr
& incrementor
,
26989 expression_node_ptr
& loop_body
,
26990 bool brkcont
= false) const
26992 if (!brkcont
&& details::is_constant_node(condition
))
26994 expression_node_ptr result
= error_node();
26996 if (details::is_true(condition
))
26997 // Infinite loops are not allowed.
26998 result
= error_node();
27000 result
= node_allocator_
->allocate
<details::null_node
<Type
> >();
27002 free_node(*node_allocator_
, initialiser
);
27003 free_node(*node_allocator_
, condition
);
27004 free_node(*node_allocator_
, incrementor
);
27005 free_node(*node_allocator_
, loop_body
);
27009 else if (details::is_null_node(condition
) || (0 == condition
))
27011 free_node(*node_allocator_
, initialiser
);
27012 free_node(*node_allocator_
, condition
);
27013 free_node(*node_allocator_
, incrementor
);
27018 return node_allocator_
->allocate
<for_loop_node_t
>
27026 #ifndef exprtk_disable_break_continue
27028 return node_allocator_
->allocate
<for_loop_bc_node_t
>
27036 return error_node();
27040 template <typename Allocator
,
27041 template <typename
, typename
> class Sequence
>
27042 inline expression_node_ptr
const_optimise_switch(Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27044 expression_node_ptr result
= error_node();
27046 for (std::size_t i
= 0; i
< (arg_list
.size() / 2); ++i
)
27048 expression_node_ptr condition
= arg_list
[(2 * i
) ];
27049 expression_node_ptr consequent
= arg_list
[(2 * i
) + 1];
27051 if ((0 == result
) && details::is_true(condition
))
27053 result
= consequent
;
27060 result
= arg_list
.back();
27063 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
27065 expression_node_ptr current_expr
= arg_list
[i
];
27067 if (current_expr
&& (current_expr
!= result
))
27069 free_node(*node_allocator_
,current_expr
);
27076 template <typename Allocator
,
27077 template <typename
, typename
> class Sequence
>
27078 inline expression_node_ptr
const_optimise_mswitch(Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27080 expression_node_ptr result
= error_node();
27082 for (std::size_t i
= 0; i
< (arg_list
.size() / 2); ++i
)
27084 expression_node_ptr condition
= arg_list
[(2 * i
) ];
27085 expression_node_ptr consequent
= arg_list
[(2 * i
) + 1];
27087 if (details::is_true(condition
))
27089 result
= consequent
;
27096 result
= node_allocator_
->allocate
<literal_node_t
>(zero
);
27099 for (std::size_t i
= 0; i
< arg_list
.size(); ++i
)
27101 expression_node_ptr
& current_expr
= arg_list
[i
];
27103 if (current_expr
&& (current_expr
!= result
))
27105 free_node(*node_allocator_
,current_expr
);
27112 struct switch_nodes
27114 typedef std::vector
<expression_node_ptr
> arg_list_t
;
27116 #define case_stmt(N) \
27117 if (is_true(arg[(2 * N)])) { return arg[(2 * N) + 1]->value(); } \
27121 static inline T
process(const arg_list_t
& arg
)
27125 return arg
.back()->value();
27131 static inline T
process(const arg_list_t
& arg
)
27133 case_stmt(0) case_stmt(1)
27135 return arg
.back()->value();
27141 static inline T
process(const arg_list_t
& arg
)
27143 case_stmt(0) case_stmt(1)
27146 return arg
.back()->value();
27152 static inline T
process(const arg_list_t
& arg
)
27154 case_stmt(0) case_stmt(1)
27155 case_stmt(2) case_stmt(3)
27157 return arg
.back()->value();
27163 static inline T
process(const arg_list_t
& arg
)
27165 case_stmt(0) case_stmt(1)
27166 case_stmt(2) case_stmt(3)
27169 return arg
.back()->value();
27175 static inline T
process(const arg_list_t
& arg
)
27177 case_stmt(0) case_stmt(1)
27178 case_stmt(2) case_stmt(3)
27179 case_stmt(4) case_stmt(5)
27181 return arg
.back()->value();
27187 static inline T
process(const arg_list_t
& arg
)
27189 case_stmt(0) case_stmt(1)
27190 case_stmt(2) case_stmt(3)
27191 case_stmt(4) case_stmt(5)
27194 return arg
.back()->value();
27201 template <typename Allocator
,
27202 template <typename
, typename
> class Sequence
>
27203 inline expression_node_ptr
switch_statement(Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27205 if (arg_list
.empty())
27206 return error_node();
27208 !all_nodes_valid(arg_list
) ||
27209 (arg_list
.size() < 3) ||
27210 ((arg_list
.size() % 2) != 1)
27213 details::free_all_nodes(*node_allocator_
,arg_list
);
27215 return error_node();
27217 else if (is_constant_foldable(arg_list
))
27218 return const_optimise_switch(arg_list
);
27220 switch ((arg_list
.size() - 1) / 2)
27222 #define case_stmt(N) \
27224 return node_allocator_-> \
27225 allocate<details::switch_n_node \
27226 <Type,typename switch_nodes::switch_##N> >(arg_list); \
27237 default : return node_allocator_
->allocate
<details::switch_node
<Type
> >(arg_list
);
27241 template <typename Allocator
,
27242 template <typename
, typename
> class Sequence
>
27243 inline expression_node_ptr
multi_switch_statement(Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27245 if (!all_nodes_valid(arg_list
))
27247 details::free_all_nodes(*node_allocator_
,arg_list
);
27249 return error_node();
27251 else if (is_constant_foldable(arg_list
))
27252 return const_optimise_mswitch(arg_list
);
27254 return node_allocator_
->allocate
<details::multi_switch_node
<Type
> >(arg_list
);
27257 #define unary_opr_switch_statements \
27258 case_stmt(details:: e_abs, details:: abs_op) \
27259 case_stmt(details:: e_acos, details:: acos_op) \
27260 case_stmt(details::e_acosh, details::acosh_op) \
27261 case_stmt(details:: e_asin, details:: asin_op) \
27262 case_stmt(details::e_asinh, details::asinh_op) \
27263 case_stmt(details:: e_atan, details:: atan_op) \
27264 case_stmt(details::e_atanh, details::atanh_op) \
27265 case_stmt(details:: e_ceil, details:: ceil_op) \
27266 case_stmt(details:: e_cos, details:: cos_op) \
27267 case_stmt(details:: e_cosh, details:: cosh_op) \
27268 case_stmt(details:: e_exp, details:: exp_op) \
27269 case_stmt(details::e_expm1, details::expm1_op) \
27270 case_stmt(details::e_floor, details::floor_op) \
27271 case_stmt(details:: e_log, details:: log_op) \
27272 case_stmt(details::e_log10, details::log10_op) \
27273 case_stmt(details:: e_log2, details:: log2_op) \
27274 case_stmt(details::e_log1p, details::log1p_op) \
27275 case_stmt(details:: e_neg, details:: neg_op) \
27276 case_stmt(details:: e_pos, details:: pos_op) \
27277 case_stmt(details::e_round, details::round_op) \
27278 case_stmt(details:: e_sin, details:: sin_op) \
27279 case_stmt(details:: e_sinc, details:: sinc_op) \
27280 case_stmt(details:: e_sinh, details:: sinh_op) \
27281 case_stmt(details:: e_sqrt, details:: sqrt_op) \
27282 case_stmt(details:: e_tan, details:: tan_op) \
27283 case_stmt(details:: e_tanh, details:: tanh_op) \
27284 case_stmt(details:: e_cot, details:: cot_op) \
27285 case_stmt(details:: e_sec, details:: sec_op) \
27286 case_stmt(details:: e_csc, details:: csc_op) \
27287 case_stmt(details:: e_r2d, details:: r2d_op) \
27288 case_stmt(details:: e_d2r, details:: d2r_op) \
27289 case_stmt(details:: e_d2g, details:: d2g_op) \
27290 case_stmt(details:: e_g2d, details:: g2d_op) \
27291 case_stmt(details:: e_notl, details:: notl_op) \
27292 case_stmt(details:: e_sgn, details:: sgn_op) \
27293 case_stmt(details:: e_erf, details:: erf_op) \
27294 case_stmt(details:: e_erfc, details:: erfc_op) \
27295 case_stmt(details:: e_ncdf, details:: ncdf_op) \
27296 case_stmt(details:: e_frac, details:: frac_op) \
27297 case_stmt(details::e_trunc, details::trunc_op) \
27299 inline expression_node_ptr synthesize_uv_expression(const details::operator_type& operation,
27300 expression_node_ptr (&branch
)[1])
27302 T
& v
= static_cast<details::variable_node
<T
>*>(branch
[0])->ref();
27306 #define case_stmt(op0,op1) \
27307 case op0 : return node_allocator_-> \
27308 allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \
27310 unary_opr_switch_statements
27312 default : return error_node();
27316 inline expression_node_ptr
synthesize_uvec_expression(const details::operator_type
& operation
,
27317 expression_node_ptr (&branch
)[1])
27321 #define case_stmt(op0,op1) \
27322 case op0 : return node_allocator_-> \
27323 allocate<typename details::unary_vector_node<Type,op1<Type> > > \
27324 (operation, branch[0]); \
27326 unary_opr_switch_statements
27328 default : return error_node();
27332 inline expression_node_ptr
synthesize_unary_expression(const details::operator_type
& operation
,
27333 expression_node_ptr (&branch
)[1])
27337 #define case_stmt(op0,op1) \
27338 case op0 : return node_allocator_-> \
27339 allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \
27341 unary_opr_switch_statements
27343 default : return error_node();
27347 inline expression_node_ptr
const_optimise_sf3(const details::operator_type
& operation
,
27348 expression_node_ptr (&branch
)[3])
27350 expression_node_ptr temp_node
= error_node();
27354 #define case_stmt(op) \
27355 case details::e_sf##op : temp_node = node_allocator_-> \
27356 allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
27357 (operation, branch); \
27360 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
27361 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
27362 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
27363 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
27364 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
27365 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
27366 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
27367 case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
27368 case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
27369 case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
27370 case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
27371 case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
27373 default : return error_node();
27376 const T v
= temp_node
->value();
27378 details::free_node(*node_allocator_
,temp_node
);
27380 return node_allocator_
->allocate
<literal_node_t
>(v
);
27383 inline expression_node_ptr
varnode_optimise_sf3(const details::operator_type
& operation
, expression_node_ptr (&branch
)[3])
27385 typedef details::variable_node
<Type
>* variable_ptr
;
27387 const Type
& v0
= static_cast<variable_ptr
>(branch
[0])->ref();
27388 const Type
& v1
= static_cast<variable_ptr
>(branch
[1])->ref();
27389 const Type
& v2
= static_cast<variable_ptr
>(branch
[2])->ref();
27393 #define case_stmt(op) \
27394 case details::e_sf##op : return node_allocator_-> \
27395 allocate_rrr<details::sf3_var_node<Type,details::sf##op##_op<Type> > > \
27398 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
27399 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
27400 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
27401 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
27402 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
27403 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
27404 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
27405 case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
27406 case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
27407 case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
27408 case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
27409 case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
27411 default : return error_node();
27415 inline expression_node_ptr
special_function(const details::operator_type
& operation
, expression_node_ptr (&branch
)[3])
27417 if (!all_nodes_valid(branch
))
27418 return error_node();
27419 else if (is_constant_foldable(branch
))
27420 return const_optimise_sf3(operation
,branch
);
27421 else if (all_nodes_variables(branch
))
27422 return varnode_optimise_sf3(operation
,branch
);
27427 #define case_stmt(op) \
27428 case details::e_sf##op : return node_allocator_-> \
27429 allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
27430 (operation, branch); \
27432 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
27433 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
27434 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
27435 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
27436 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
27437 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
27438 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
27439 case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
27440 case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
27441 case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
27442 case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
27443 case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
27445 default : return error_node();
27450 inline expression_node_ptr
const_optimise_sf4(const details::operator_type
& operation
, expression_node_ptr (&branch
)[4])
27452 expression_node_ptr temp_node
= error_node();
27456 #define case_stmt(op) \
27457 case details::e_sf##op : temp_node = node_allocator_-> \
27458 allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
27459 (operation, branch); \
27462 case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
27463 case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
27464 case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
27465 case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
27466 case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
27467 case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
27468 case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
27469 case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
27470 case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
27471 case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
27472 case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
27473 case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
27474 case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
27476 default : return error_node();
27479 const T v
= temp_node
->value();
27481 details::free_node(*node_allocator_
,temp_node
);
27483 return node_allocator_
->allocate
<literal_node_t
>(v
);
27486 inline expression_node_ptr
varnode_optimise_sf4(const details::operator_type
& operation
, expression_node_ptr (&branch
)[4])
27488 typedef details::variable_node
<Type
>* variable_ptr
;
27490 const Type
& v0
= static_cast<variable_ptr
>(branch
[0])->ref();
27491 const Type
& v1
= static_cast<variable_ptr
>(branch
[1])->ref();
27492 const Type
& v2
= static_cast<variable_ptr
>(branch
[2])->ref();
27493 const Type
& v3
= static_cast<variable_ptr
>(branch
[3])->ref();
27497 #define case_stmt(op) \
27498 case details::e_sf##op : return node_allocator_-> \
27499 allocate_rrrr<details::sf4_var_node<Type,details::sf##op##_op<Type> > > \
27500 (v0, v1, v2, v3); \
27502 case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
27503 case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
27504 case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
27505 case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
27506 case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
27507 case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
27508 case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
27509 case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
27510 case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
27511 case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
27512 case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
27513 case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
27514 case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
27516 default : return error_node();
27520 inline expression_node_ptr
special_function(const details::operator_type
& operation
, expression_node_ptr (&branch
)[4])
27522 if (!all_nodes_valid(branch
))
27523 return error_node();
27524 else if (is_constant_foldable(branch
))
27525 return const_optimise_sf4(operation
,branch
);
27526 else if (all_nodes_variables(branch
))
27527 return varnode_optimise_sf4(operation
,branch
);
27530 #define case_stmt(op) \
27531 case details::e_sf##op : return node_allocator_-> \
27532 allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
27533 (operation, branch); \
27535 case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
27536 case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
27537 case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
27538 case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
27539 case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
27540 case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
27541 case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
27542 case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
27543 case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
27544 case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
27545 case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
27546 case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
27547 case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
27549 default : return error_node();
27553 template <typename Allocator
,
27554 template <typename
, typename
> class Sequence
>
27555 inline expression_node_ptr
const_optimise_varargfunc(const details::operator_type
& operation
, Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27557 expression_node_ptr temp_node
= error_node();
27561 #define case_stmt(op0,op1) \
27562 case op0 : temp_node = node_allocator_-> \
27563 allocate<details::vararg_node<Type,op1<Type> > > \
27567 case_stmt(details::e_sum , details::vararg_add_op )
27568 case_stmt(details::e_prod
, details::vararg_mul_op
)
27569 case_stmt(details::e_avg
, details::vararg_avg_op
)
27570 case_stmt(details::e_min
, details::vararg_min_op
)
27571 case_stmt(details::e_max
, details::vararg_max_op
)
27572 case_stmt(details::e_mand
, details::vararg_mand_op
)
27573 case_stmt(details::e_mor
, details::vararg_mor_op
)
27574 case_stmt(details::e_multi
, details::vararg_multi_op
)
27576 default : return error_node();
27579 const T v
= temp_node
->value();
27581 details::free_node(*node_allocator_
,temp_node
);
27583 return node_allocator_
->allocate
<literal_node_t
>(v
);
27586 inline bool special_one_parameter_vararg(const details::operator_type
& operation
) const
27589 (details::e_sum
== operation
) ||
27590 (details::e_prod
== operation
) ||
27591 (details::e_avg
== operation
) ||
27592 (details::e_min
== operation
) ||
27593 (details::e_max
== operation
)
27597 template <typename Allocator
,
27598 template <typename
, typename
> class Sequence
>
27599 inline expression_node_ptr
varnode_optimise_varargfunc(const details::operator_type
& operation
, Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27603 #define case_stmt(op0,op1) \
27604 case op0 : return node_allocator_-> \
27605 allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \
27607 case_stmt(details::e_sum , details::vararg_add_op )
27608 case_stmt(details::e_prod
, details::vararg_mul_op
)
27609 case_stmt(details::e_avg
, details::vararg_avg_op
)
27610 case_stmt(details::e_min
, details::vararg_min_op
)
27611 case_stmt(details::e_max
, details::vararg_max_op
)
27612 case_stmt(details::e_mand
, details::vararg_mand_op
)
27613 case_stmt(details::e_mor
, details::vararg_mor_op
)
27614 case_stmt(details::e_multi
, details::vararg_multi_op
)
27616 default : return error_node();
27620 template <typename Allocator
,
27621 template <typename
, typename
> class Sequence
>
27622 inline expression_node_ptr
vectorize_func(const details::operator_type
& operation
, Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27624 if (1 == arg_list
.size())
27628 #define case_stmt(op0,op1) \
27629 case op0 : return node_allocator_-> \
27630 allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \
27632 case_stmt(details::e_sum , details::vec_add_op)
27633 case_stmt(details::e_prod
, details::vec_mul_op
)
27634 case_stmt(details::e_avg
, details::vec_avg_op
)
27635 case_stmt(details::e_min
, details::vec_min_op
)
27636 case_stmt(details::e_max
, details::vec_max_op
)
27638 default : return error_node();
27642 return error_node();
27645 template <typename Allocator
,
27646 template <typename
, typename
> class Sequence
>
27647 inline expression_node_ptr
vararg_function(const details::operator_type
& operation
, Sequence
<expression_node_ptr
,Allocator
>& arg_list
)
27649 if (!all_nodes_valid(arg_list
))
27651 details::free_all_nodes(*node_allocator_
,arg_list
);
27653 return error_node();
27655 else if (is_constant_foldable(arg_list
))
27656 return const_optimise_varargfunc(operation
,arg_list
);
27657 else if ((arg_list
.size() == 1) && details::is_ivector_node(arg_list
[0]))
27658 return vectorize_func(operation
,arg_list
);
27659 else if ((arg_list
.size() == 1) && special_one_parameter_vararg(operation
))
27660 return arg_list
[0];
27661 else if (all_nodes_variables(arg_list
))
27662 return varnode_optimise_varargfunc(operation
,arg_list
);
27664 #ifndef exprtk_disable_string_capabilities
27665 if (details::e_smulti
== operation
)
27667 return node_allocator_
->
27668 allocate
<details::str_vararg_node
<Type
,details::vararg_multi_op
<Type
> > >(arg_list
);
27675 #define case_stmt(op0,op1) \
27676 case op0 : return node_allocator_-> \
27677 allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \
27679 case_stmt(details::e_sum , details::vararg_add_op )
27680 case_stmt(details::e_prod
, details::vararg_mul_op
)
27681 case_stmt(details::e_avg
, details::vararg_avg_op
)
27682 case_stmt(details::e_min
, details::vararg_min_op
)
27683 case_stmt(details::e_max
, details::vararg_max_op
)
27684 case_stmt(details::e_mand
, details::vararg_mand_op
)
27685 case_stmt(details::e_mor
, details::vararg_mor_op
)
27686 case_stmt(details::e_multi
, details::vararg_multi_op
)
27688 default : return error_node();
27693 template <std::size_t N
>
27694 inline expression_node_ptr
function(ifunction_t
* f
, expression_node_ptr (&b
)[N
])
27696 typedef typename
details::function_N_node
<T
,ifunction_t
,N
> function_N_node_t
;
27697 expression_node_ptr result
= synthesize_expression
<function_N_node_t
,N
>(f
,b
);
27700 return error_node();
27703 // Can the function call be completely optimised?
27704 if (details::is_constant_node(result
))
27706 else if (!all_nodes_valid(b
))
27707 return error_node();
27708 else if (N
!= f
->param_count
)
27710 details::free_all_nodes(*node_allocator_
,b
);
27712 return error_node();
27715 function_N_node_t
* func_node_ptr
= static_cast<function_N_node_t
*>(result
);
27717 if (func_node_ptr
->init_branches(b
))
27721 details::free_all_nodes(*node_allocator_
,b
);
27723 return error_node();
27728 inline expression_node_ptr
function(ifunction_t
* f
)
27730 typedef typename
details::function_N_node
<Type
,ifunction_t
,0> function_N_node_t
;
27731 return node_allocator_
->allocate
<function_N_node_t
>(f
);
27734 inline expression_node_ptr
vararg_function_call(ivararg_function_t
* vaf
,
27735 std::vector
<expression_node_ptr
>& arg_list
)
27737 if (!all_nodes_valid(arg_list
))
27739 details::free_all_nodes(*node_allocator_
,arg_list
);
27741 return error_node();
27744 typedef details::vararg_function_node
<Type
,ivararg_function_t
> alloc_type
;
27746 expression_node_ptr result
= node_allocator_
->allocate
<alloc_type
>(vaf
,arg_list
);
27749 !arg_list
.empty() &&
27750 !vaf
->has_side_effects() &&
27751 is_constant_foldable(arg_list
)
27754 const Type v
= result
->value();
27755 details::free_node(*node_allocator_
,result
);
27756 result
= node_allocator_
->allocate
<literal_node_t
>(v
);
27759 parser_
->state_
.activate_side_effect("vararg_function_call()");
27764 inline expression_node_ptr
generic_function_call(igeneric_function_t
* gf
,
27765 std::vector
<expression_node_ptr
>& arg_list
,
27766 const std::size_t& param_seq_index
= std::numeric_limits
<std::size_t>::max())
27768 if (!all_nodes_valid(arg_list
))
27770 details::free_all_nodes(*node_allocator_
,arg_list
);
27771 return error_node();
27774 typedef details::generic_function_node
<Type
,igeneric_function_t
> alloc_type1
;
27775 typedef details::multimode_genfunction_node
<Type
,igeneric_function_t
> alloc_type2
;
27777 const std::size_t no_psi
= std::numeric_limits
<std::size_t>::max();
27779 expression_node_ptr result
= error_node();
27781 if (no_psi
== param_seq_index
)
27782 result
= node_allocator_
->allocate
<alloc_type1
>(arg_list
,gf
);
27784 result
= node_allocator_
->allocate
<alloc_type2
>(gf
, param_seq_index
, arg_list
);
27786 alloc_type1
* genfunc_node_ptr
= static_cast<alloc_type1
*>(result
);
27789 !arg_list
.empty() &&
27790 !gf
->has_side_effects() &&
27791 parser_
->state_
.type_check_enabled
&&
27792 is_constant_foldable(arg_list
)
27795 genfunc_node_ptr
->init_branches();
27797 const Type v
= result
->value();
27799 details::free_node(*node_allocator_
,result
);
27801 return node_allocator_
->allocate
<literal_node_t
>(v
);
27803 else if (genfunc_node_ptr
->init_branches())
27805 parser_
->state_
.activate_side_effect("generic_function_call()");
27811 details::free_node(*node_allocator_
, result
);
27812 details::free_all_nodes(*node_allocator_
, arg_list
);
27814 return error_node();
27818 #ifndef exprtk_disable_string_capabilities
27819 inline expression_node_ptr
string_function_call(igeneric_function_t
* gf
,
27820 std::vector
<expression_node_ptr
>& arg_list
,
27821 const std::size_t& param_seq_index
= std::numeric_limits
<std::size_t>::max())
27823 if (!all_nodes_valid(arg_list
))
27825 details::free_all_nodes(*node_allocator_
,arg_list
);
27826 return error_node();
27829 typedef details::string_function_node
<Type
,igeneric_function_t
> alloc_type1
;
27830 typedef details::multimode_strfunction_node
<Type
,igeneric_function_t
> alloc_type2
;
27832 const std::size_t no_psi
= std::numeric_limits
<std::size_t>::max();
27834 expression_node_ptr result
= error_node();
27836 if (no_psi
== param_seq_index
)
27837 result
= node_allocator_
->allocate
<alloc_type1
>(gf
,arg_list
);
27839 result
= node_allocator_
->allocate
<alloc_type2
>(gf
, param_seq_index
, arg_list
);
27841 alloc_type1
* strfunc_node_ptr
= static_cast<alloc_type1
*>(result
);
27844 !arg_list
.empty() &&
27845 !gf
->has_side_effects() &&
27846 is_constant_foldable(arg_list
)
27849 strfunc_node_ptr
->init_branches();
27851 const Type v
= result
->value();
27853 details::free_node(*node_allocator_
,result
);
27855 return node_allocator_
->allocate
<literal_node_t
>(v
);
27857 else if (strfunc_node_ptr
->init_branches())
27859 parser_
->state_
.activate_side_effect("string_function_call()");
27865 details::free_node (*node_allocator_
,result
);
27866 details::free_all_nodes(*node_allocator_
,arg_list
);
27868 return error_node();
27873 #ifndef exprtk_disable_return_statement
27874 inline expression_node_ptr
return_call(std::vector
<expression_node_ptr
>& arg_list
)
27876 if (!all_nodes_valid(arg_list
))
27878 details::free_all_nodes(*node_allocator_
,arg_list
);
27879 return error_node();
27882 typedef details::return_node
<Type
> alloc_type
;
27884 expression_node_ptr result
= node_allocator_
->
27885 allocate_rr
<alloc_type
>(arg_list
,parser_
->results_ctx());
27887 alloc_type
* return_node_ptr
= static_cast<alloc_type
*>(result
);
27889 if (return_node_ptr
->init_branches())
27891 parser_
->state_
.activate_side_effect("return_call()");
27897 details::free_node (*node_allocator_
,result
);
27898 details::free_all_nodes(*node_allocator_
,arg_list
);
27900 return error_node();
27904 inline expression_node_ptr
return_envelope(expression_node_ptr body
,
27905 results_context_t
* rc
,
27906 bool*& return_invoked
)
27908 typedef details::return_envelope_node
<Type
> alloc_type
;
27910 expression_node_ptr result
= node_allocator_
->
27911 allocate_cr
<alloc_type
>(body
,(*rc
));
27913 return_invoked
= static_cast<alloc_type
*>(result
)->retinvk_ptr();
27918 inline expression_node_ptr
return_call(std::vector
<expression_node_ptr
>&)
27920 return error_node();
27923 inline expression_node_ptr
return_envelope(expression_node_ptr
,
27924 results_context_t
*,
27927 return error_node();
27931 inline expression_node_ptr
vector_element(const std::string
& symbol
,
27932 vector_holder_ptr vector_base
,
27933 expression_node_ptr index
)
27935 expression_node_ptr result
= error_node();
27937 if (details::is_constant_node(index
))
27939 std::size_t i
= static_cast<std::size_t>(details::numeric::to_int64(index
->value()));
27941 details::free_node(*node_allocator_
,index
);
27943 if (vector_base
->rebaseable())
27945 return node_allocator_
->allocate
<rebasevector_celem_node_t
>(i
,vector_base
);
27948 scope_element
& se
= parser_
->sem_
.get_element(symbol
,i
);
27952 result
= se
.var_node
;
27960 nse
.type
= scope_element::e_vecelem
;
27962 nse
.depth
= parser_
->state_
.scope_depth
;
27964 nse
.var_node
= node_allocator_
->allocate
<variable_node_t
>((*(*vector_base
)[i
]));
27966 if (!parser_
->sem_
.add_element(nse
))
27968 parser_
->set_synthesis_error("Failed to add new local vector element to SEM [1]");
27970 parser_
->sem_
.free_element(nse
);
27972 result
= error_node();
27975 exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n",nse
.name
.c_str()));
27977 parser_
->state_
.activate_side_effect("vector_element()");
27979 result
= nse
.var_node
;
27982 else if (vector_base
->rebaseable())
27983 result
= node_allocator_
->allocate
<rebasevector_elem_node_t
>(index
,vector_base
);
27985 result
= node_allocator_
->allocate
<vector_elem_node_t
>(index
,vector_base
);
27992 template <std::size_t N
, typename NodePtr
>
27993 inline bool is_constant_foldable(NodePtr (&b
)[N
]) const
27995 for (std::size_t i
= 0; i
< N
; ++i
)
27999 else if (!details::is_constant_node(b
[i
]))
28006 template <typename NodePtr
,
28007 typename Allocator
,
28008 template <typename
, typename
> class Sequence
>
28009 inline bool is_constant_foldable(const Sequence
<NodePtr
,Allocator
>& b
) const
28011 for (std::size_t i
= 0; i
< b
.size(); ++i
)
28015 else if (!details::is_constant_node(b
[i
]))
28022 void lodge_assignment(symbol_type cst
, expression_node_ptr node
)
28024 parser_
->state_
.activate_side_effect("lodge_assignment()");
28026 if (!parser_
->dec_
.collect_assignments())
28029 std::string symbol_name
;
28033 case e_st_variable
: symbol_name
= parser_
->symtab_store_
28034 .get_variable_name(node
);
28037 #ifndef exprtk_disable_string_capabilities
28038 case e_st_string
: symbol_name
= parser_
->symtab_store_
28039 .get_stringvar_name(node
);
28043 case e_st_vector
: {
28044 typedef details::vector_holder
<T
> vector_holder_t
;
28046 vector_holder_t
& vh
= static_cast<vector_node_t
*>(node
)->vec_holder();
28048 symbol_name
= parser_
->symtab_store_
.get_vector_name(&vh
);
28052 case e_st_vecelem
: {
28053 typedef details::vector_holder
<T
> vector_holder_t
;
28055 vector_holder_t
& vh
= static_cast<vector_elem_node_t
*>(node
)->vec_holder();
28057 symbol_name
= parser_
->symtab_store_
.get_vector_name(&vh
);
28066 if (!symbol_name
.empty())
28068 parser_
->dec_
.add_assignment(symbol_name
,cst
);
28072 inline expression_node_ptr
synthesize_assignment_expression(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2])
28074 if (details::is_variable_node(branch
[0]))
28076 lodge_assignment(e_st_variable
,branch
[0]);
28078 return synthesize_expression
<assignment_node_t
,2>(operation
,branch
);
28080 else if (details::is_vector_elem_node(branch
[0]))
28082 lodge_assignment(e_st_vecelem
,branch
[0]);
28084 return synthesize_expression
<assignment_vec_elem_node_t
, 2>(operation
, branch
);
28086 else if (details::is_rebasevector_elem_node(branch
[0]))
28088 lodge_assignment(e_st_vecelem
,branch
[0]);
28090 return synthesize_expression
<assignment_rebasevec_elem_node_t
, 2>(operation
, branch
);
28092 else if (details::is_rebasevector_celem_node(branch
[0]))
28094 lodge_assignment(e_st_vecelem
,branch
[0]);
28096 return synthesize_expression
<assignment_rebasevec_celem_node_t
, 2>(operation
, branch
);
28098 #ifndef exprtk_disable_string_capabilities
28099 else if (details::is_string_node(branch
[0]))
28101 lodge_assignment(e_st_string
,branch
[0]);
28103 return synthesize_expression
<assignment_string_node_t
,2>(operation
, branch
);
28105 else if (details::is_string_range_node(branch
[0]))
28107 lodge_assignment(e_st_string
,branch
[0]);
28109 return synthesize_expression
<assignment_string_range_node_t
,2>(operation
, branch
);
28112 else if (details::is_vector_node(branch
[0]))
28114 lodge_assignment(e_st_vector
,branch
[0]);
28116 if (details::is_ivector_node(branch
[1]))
28117 return synthesize_expression
<assignment_vecvec_node_t
,2>(operation
, branch
);
28119 return synthesize_expression
<assignment_vec_node_t
,2>(operation
, branch
);
28123 parser_
->set_synthesis_error("Invalid assignment operation.[1]");
28125 return error_node();
28129 inline expression_node_ptr
synthesize_assignment_operation_expression(const details::operator_type
& operation
,
28130 expression_node_ptr (&branch
)[2])
28132 if (details::is_variable_node(branch
[0]))
28134 lodge_assignment(e_st_variable
,branch
[0]);
28138 #define case_stmt(op0,op1) \
28139 case op0 : return node_allocator_-> \
28140 template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \
28141 (operation, branch[0], branch[1]); \
28143 case_stmt(details::e_addass,details::add_op)
28144 case_stmt(details::e_subass
,details::sub_op
)
28145 case_stmt(details::e_mulass
,details::mul_op
)
28146 case_stmt(details::e_divass
,details::div_op
)
28147 case_stmt(details::e_modass
,details::mod_op
)
28149 default : return error_node();
28152 else if (details::is_vector_elem_node(branch
[0]))
28154 lodge_assignment(e_st_vecelem
,branch
[0]);
28158 #define case_stmt(op0,op1) \
28159 case op0 : return node_allocator_-> \
28160 template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \
28161 (operation, branch[0], branch[1]); \
28163 case_stmt(details::e_addass,details::add_op)
28164 case_stmt(details::e_subass
,details::sub_op
)
28165 case_stmt(details::e_mulass
,details::mul_op
)
28166 case_stmt(details::e_divass
,details::div_op
)
28167 case_stmt(details::e_modass
,details::mod_op
)
28169 default : return error_node();
28172 else if (details::is_rebasevector_elem_node(branch
[0]))
28174 lodge_assignment(e_st_vecelem
,branch
[0]);
28178 #define case_stmt(op0,op1) \
28179 case op0 : return node_allocator_-> \
28180 template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \
28181 (operation, branch[0], branch[1]); \
28183 case_stmt(details::e_addass,details::add_op)
28184 case_stmt(details::e_subass
,details::sub_op
)
28185 case_stmt(details::e_mulass
,details::mul_op
)
28186 case_stmt(details::e_divass
,details::div_op
)
28187 case_stmt(details::e_modass
,details::mod_op
)
28189 default : return error_node();
28192 else if (details::is_rebasevector_celem_node(branch
[0]))
28194 lodge_assignment(e_st_vecelem
,branch
[0]);
28198 #define case_stmt(op0,op1) \
28199 case op0 : return node_allocator_-> \
28200 template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \
28201 (operation, branch[0], branch[1]); \
28203 case_stmt(details::e_addass,details::add_op)
28204 case_stmt(details::e_subass
,details::sub_op
)
28205 case_stmt(details::e_mulass
,details::mul_op
)
28206 case_stmt(details::e_divass
,details::div_op
)
28207 case_stmt(details::e_modass
,details::mod_op
)
28209 default : return error_node();
28212 else if (details::is_vector_node(branch
[0]))
28214 lodge_assignment(e_st_vector
,branch
[0]);
28216 if (details::is_ivector_node(branch
[1]))
28220 #define case_stmt(op0,op1) \
28221 case op0 : return node_allocator_-> \
28222 template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \
28223 (operation, branch[0], branch[1]); \
28225 case_stmt(details::e_addass,details::add_op)
28226 case_stmt(details::e_subass
,details::sub_op
)
28227 case_stmt(details::e_mulass
,details::mul_op
)
28228 case_stmt(details::e_divass
,details::div_op
)
28229 case_stmt(details::e_modass
,details::mod_op
)
28231 default : return error_node();
28238 #define case_stmt(op0,op1) \
28239 case op0 : return node_allocator_-> \
28240 template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \
28241 (operation, branch[0], branch[1]); \
28243 case_stmt(details::e_addass,details::add_op)
28244 case_stmt(details::e_subass
,details::sub_op
)
28245 case_stmt(details::e_mulass
,details::mul_op
)
28246 case_stmt(details::e_divass
,details::div_op
)
28247 case_stmt(details::e_modass
,details::mod_op
)
28249 default : return error_node();
28253 #ifndef exprtk_disable_string_capabilities
28255 (details::e_addass
== operation
) &&
28256 details::is_string_node(branch
[0])
28259 typedef details::assignment_string_node
<T
,details::asn_addassignment
> addass_t
;
28261 lodge_assignment(e_st_string
,branch
[0]);
28263 return synthesize_expression
<addass_t
,2>(operation
,branch
);
28268 parser_
->set_synthesis_error("Invalid assignment operation[2]");
28270 return error_node();
28274 inline expression_node_ptr
synthesize_veceqineqlogic_operation_expression(const details::operator_type
& operation
,
28275 expression_node_ptr (&branch
)[2])
28277 const bool is_b0_ivec
= details::is_ivector_node(branch
[0]);
28278 const bool is_b1_ivec
= details::is_ivector_node(branch
[1]);
28280 #define batch_eqineq_logic_case \
28281 case_stmt(details:: e_lt, details:: lt_op) \
28282 case_stmt(details:: e_lte, details:: lte_op) \
28283 case_stmt(details:: e_gt, details:: gt_op) \
28284 case_stmt(details:: e_gte, details:: gte_op) \
28285 case_stmt(details:: e_eq, details:: eq_op) \
28286 case_stmt(details:: e_ne, details:: ne_op) \
28287 case_stmt(details::e_equal, details::equal_op) \
28288 case_stmt(details:: e_and, details:: and_op) \
28289 case_stmt(details:: e_nand, details:: nand_op) \
28290 case_stmt(details:: e_or, details:: or_op) \
28291 case_stmt(details:: e_nor, details:: nor_op) \
28292 case_stmt(details:: e_xor, details:: xor_op) \
28293 case_stmt(details:: e_xnor, details:: xnor_op) \
28295 if (is_b0_ivec && is_b1_ivec)
28299 #define case_stmt(op0,op1) \
28300 case op0 : return node_allocator_-> \
28301 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
28302 (operation, branch[0], branch[1]); \
28304 batch_eqineq_logic_case
28306 default : return error_node();
28309 else if (is_b0_ivec
&& !is_b1_ivec
)
28313 #define case_stmt(op0,op1) \
28314 case op0 : return node_allocator_-> \
28315 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
28316 (operation, branch[0], branch[1]); \
28318 batch_eqineq_logic_case
28320 default : return error_node();
28323 else if (!is_b0_ivec
&& is_b1_ivec
)
28327 #define case_stmt(op0,op1) \
28328 case op0 : return node_allocator_-> \
28329 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
28330 (operation, branch[0], branch[1]); \
28332 batch_eqineq_logic_case
28334 default : return error_node();
28338 return error_node();
28340 #undef batch_eqineq_logic_case
28343 inline expression_node_ptr
synthesize_vecarithmetic_operation_expression(const details::operator_type
& operation
,
28344 expression_node_ptr (&branch
)[2])
28346 const bool is_b0_ivec
= details::is_ivector_node(branch
[0]);
28347 const bool is_b1_ivec
= details::is_ivector_node(branch
[1]);
28349 #define vector_ops \
28350 case_stmt(details::e_add,details::add_op) \
28351 case_stmt(details::e_sub,details::sub_op) \
28352 case_stmt(details::e_mul,details::mul_op) \
28353 case_stmt(details::e_div,details::div_op) \
28354 case_stmt(details::e_mod,details::mod_op) \
28356 if (is_b0_ivec && is_b1_ivec)
28360 #define case_stmt(op0,op1) \
28361 case op0 : return node_allocator_-> \
28362 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
28363 (operation, branch[0], branch[1]); \
28366 case_stmt(details::e_pow
,details:: pow_op
)
28368 default : return error_node();
28371 else if (is_b0_ivec
&& !is_b1_ivec
)
28375 #define case_stmt(op0,op1) \
28376 case op0 : return node_allocator_-> \
28377 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
28378 (operation, branch[0], branch[1]); \
28381 case_stmt(details::e_pow
,details:: pow_op
)
28383 default : return error_node();
28386 else if (!is_b0_ivec
&& is_b1_ivec
)
28390 #define case_stmt(op0,op1) \
28391 case op0 : return node_allocator_-> \
28392 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
28393 (operation, branch[0], branch[1]); \
28397 default : return error_node();
28401 return error_node();
28406 inline expression_node_ptr
synthesize_swap_expression(expression_node_ptr (&branch
)[2])
28408 const bool v0_is_ivar
= details::is_ivariable_node(branch
[0]);
28409 const bool v1_is_ivar
= details::is_ivariable_node(branch
[1]);
28411 const bool v0_is_ivec
= details::is_ivector_node (branch
[0]);
28412 const bool v1_is_ivec
= details::is_ivector_node (branch
[1]);
28414 #ifndef exprtk_disable_string_capabilities
28415 const bool v0_is_str
= details::is_generally_string_node(branch
[0]);
28416 const bool v1_is_str
= details::is_generally_string_node(branch
[1]);
28419 expression_node_ptr result
= error_node();
28421 if (v0_is_ivar
&& v1_is_ivar
)
28423 typedef details::variable_node
<T
>* variable_node_ptr
;
28425 variable_node_ptr v0
= variable_node_ptr(0);
28426 variable_node_ptr v1
= variable_node_ptr(0);
28429 (0 != (v0
= dynamic_cast<variable_node_ptr
>(branch
[0]))) &&
28430 (0 != (v1
= dynamic_cast<variable_node_ptr
>(branch
[1])))
28433 result
= node_allocator_
->allocate
<details::swap_node
<T
> >(v0
,v1
);
28436 result
= node_allocator_
->allocate
<details::swap_generic_node
<T
> >(branch
[0],branch
[1]);
28438 else if (v0_is_ivec
&& v1_is_ivec
)
28440 result
= node_allocator_
->allocate
<details::swap_vecvec_node
<T
> >(branch
[0],branch
[1]);
28442 #ifndef exprtk_disable_string_capabilities
28443 else if (v0_is_str
&& v1_is_str
)
28445 if (is_string_node(branch
[0]) && is_string_node(branch
[1]))
28446 result
= node_allocator_
->allocate
<details::swap_string_node
<T
> >
28447 (branch
[0], branch
[1]);
28449 result
= node_allocator_
->allocate
<details::swap_genstrings_node
<T
> >
28450 (branch
[0], branch
[1]);
28455 parser_
->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped");
28457 return error_node();
28460 parser_
->state_
.activate_side_effect("synthesize_swap_expression()");
28465 #ifndef exprtk_disable_sc_andor
28466 inline expression_node_ptr
synthesize_shortcircuit_expression(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2])
28468 expression_node_ptr result
= error_node();
28470 if (details::is_constant_node(branch
[0]))
28473 (details::e_scand
== operation
) &&
28474 std::equal_to
<T
>()(T(0),branch
[0]->value())
28476 result
= node_allocator_
->allocate_c
<literal_node_t
>(T(0));
28478 (details::e_scor
== operation
) &&
28479 std::not_equal_to
<T
>()(T(0),branch
[0]->value())
28481 result
= node_allocator_
->allocate_c
<literal_node_t
>(T(1));
28484 if (details::is_constant_node(branch
[1]) && (0 == result
))
28487 (details::e_scand
== operation
) &&
28488 std::equal_to
<T
>()(T(0),branch
[1]->value())
28490 result
= node_allocator_
->allocate_c
<literal_node_t
>(T(0));
28492 (details::e_scor
== operation
) &&
28493 std::not_equal_to
<T
>()(T(0),branch
[1]->value())
28495 result
= node_allocator_
->allocate_c
<literal_node_t
>(T(1));
28500 free_node(*node_allocator_
, branch
[0]);
28501 free_node(*node_allocator_
, branch
[1]);
28505 else if (details::e_scand
== operation
)
28507 return synthesize_expression
<scand_node_t
,2>(operation
, branch
);
28509 else if (details::e_scor
== operation
)
28511 return synthesize_expression
<scor_node_t
,2>(operation
, branch
);
28514 return error_node();
28517 inline expression_node_ptr
synthesize_shortcircuit_expression(const details::operator_type
&, expression_node_ptr (&)[2])
28519 return error_node();
28523 #define basic_opr_switch_statements \
28524 case_stmt(details::e_add, details::add_op) \
28525 case_stmt(details::e_sub, details::sub_op) \
28526 case_stmt(details::e_mul, details::mul_op) \
28527 case_stmt(details::e_div, details::div_op) \
28528 case_stmt(details::e_mod, details::mod_op) \
28529 case_stmt(details::e_pow, details::pow_op) \
28531 #define extended_opr_switch_statements \
28532 case_stmt(details:: e_lt, details:: lt_op) \
28533 case_stmt(details:: e_lte, details:: lte_op) \
28534 case_stmt(details:: e_gt, details:: gt_op) \
28535 case_stmt(details:: e_gte, details:: gte_op) \
28536 case_stmt(details:: e_eq, details:: eq_op) \
28537 case_stmt(details:: e_ne, details:: ne_op) \
28538 case_stmt(details:: e_and, details:: and_op) \
28539 case_stmt(details::e_nand, details::nand_op) \
28540 case_stmt(details:: e_or, details:: or_op) \
28541 case_stmt(details:: e_nor, details:: nor_op) \
28542 case_stmt(details:: e_xor, details:: xor_op) \
28543 case_stmt(details::e_xnor, details::xnor_op) \
28545 #ifndef exprtk_disable_cardinal_pow_optimisation
28546 template <typename TType
, template <typename
, typename
> class IPowNode
>
28547 inline expression_node_ptr
cardinal_pow_optimisation_impl(const TType
& v
, const unsigned int& p
)
28551 #define case_stmt(cp) \
28552 case cp : return node_allocator_-> \
28553 allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
28555 case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
28556 case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
28557 case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
28558 case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16)
28559 case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20)
28560 case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24)
28561 case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28)
28562 case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32)
28563 case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36)
28564 case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40)
28565 case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44)
28566 case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48)
28567 case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52)
28568 case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56)
28569 case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60)
28571 default : return error_node();
28575 inline expression_node_ptr
cardinal_pow_optimisation(const T
& v
, const T
& c
)
28577 const bool not_recipricol
= (c
>= T(0));
28578 const unsigned int p
= static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c
)));
28581 return node_allocator_
->allocate_c
<literal_node_t
>(T(1));
28582 else if (std::equal_to
<T
>()(T(2),c
))
28584 return node_allocator_
->
28585 template allocate_rr
<typename
details::vov_node
<Type
,details::mul_op
<Type
> > >(v
,v
);
28589 if (not_recipricol
)
28590 return cardinal_pow_optimisation_impl
<T
,details::ipow_node
>(v
,p
);
28592 return cardinal_pow_optimisation_impl
<T
,details::ipowinv_node
>(v
,p
);
28596 inline bool cardinal_pow_optimisable(const details::operator_type
& operation
, const T
& c
) const
28598 return (details::e_pow
== operation
) && (details::numeric::abs(c
) <= T(60)) && details::numeric::is_integer(c
);
28601 inline expression_node_ptr
cardinal_pow_optimisation(expression_node_ptr (&branch
)[2])
28603 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
28604 const bool not_recipricol
= (c
>= T(0));
28605 const unsigned int p
= static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c
)));
28607 node_allocator_
->free(branch
[1]);
28611 details::free_all_nodes(*node_allocator_
, branch
);
28613 return node_allocator_
->allocate_c
<literal_node_t
>(T(1));
28615 else if (not_recipricol
)
28616 return cardinal_pow_optimisation_impl
<expression_node_ptr
,details::bipow_node
>(branch
[0],p
);
28618 return cardinal_pow_optimisation_impl
<expression_node_ptr
,details::bipowninv_node
>(branch
[0],p
);
28621 inline expression_node_ptr
cardinal_pow_optimisation(T
&, const T
&)
28623 return error_node();
28626 inline bool cardinal_pow_optimisable(const details::operator_type
&, const T
&)
28631 inline expression_node_ptr
cardinal_pow_optimisation(expression_node_ptr(&)[2])
28633 return error_node();
28637 struct synthesize_binary_ext_expression
28639 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
28640 const details::operator_type
& operation
,
28641 expression_node_ptr (&branch
)[2])
28643 const bool left_neg
= is_neg_unary_node(branch
[0]);
28644 const bool right_neg
= is_neg_unary_node(branch
[1]);
28646 if (left_neg
&& right_neg
)
28649 (details::e_add
== operation
) ||
28650 (details::e_sub
== operation
) ||
28651 (details::e_mul
== operation
) ||
28652 (details::e_div
== operation
)
28656 !expr_gen
.parser_
->simplify_unary_negation_branch(branch
[0]) ||
28657 !expr_gen
.parser_
->simplify_unary_negation_branch(branch
[1])
28660 details::free_all_nodes(*expr_gen
.node_allocator_
,branch
);
28662 return error_node();
28668 // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1))
28669 case details::e_add
: return expr_gen(details::e_neg
,
28670 expr_gen
.node_allocator_
->
28671 template allocate
<typename
details::binary_ext_node
<Type
,details::add_op
<Type
> > >
28672 (branch
[0],branch
[1]));
28674 // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1)
28675 case details::e_sub
: return expr_gen
.node_allocator_
->
28676 template allocate
<typename
details::binary_ext_node
<Type
,details::sub_op
<Type
> > >
28677 (branch
[1],branch
[0]);
28682 else if (left_neg
&& !right_neg
)
28685 (details::e_add
== operation
) ||
28686 (details::e_sub
== operation
) ||
28687 (details::e_mul
== operation
) ||
28688 (details::e_div
== operation
)
28691 if (!expr_gen
.parser_
->simplify_unary_negation_branch(branch
[0]))
28693 details::free_all_nodes(*expr_gen
.node_allocator_
,branch
);
28695 return error_node();
28700 // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1)
28701 case details::e_add
: return expr_gen
.node_allocator_
->
28702 template allocate
<typename
details::binary_ext_node
<Type
,details::sub_op
<Type
> > >
28703 (branch
[1], branch
[0]);
28705 // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1))
28706 case details::e_sub
: return expr_gen(details::e_neg
,
28707 expr_gen
.node_allocator_
->
28708 template allocate
<typename
details::binary_ext_node
<Type
,details::add_op
<Type
> > >
28709 (branch
[0], branch
[1]));
28711 // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1))
28712 case details::e_mul
: return expr_gen(details::e_neg
,
28713 expr_gen
.node_allocator_
->
28714 template allocate
<typename
details::binary_ext_node
<Type
,details::mul_op
<Type
> > >
28715 (branch
[0], branch
[1]));
28717 // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1))
28718 case details::e_div
: return expr_gen(details::e_neg
,
28719 expr_gen
.node_allocator_
->
28720 template allocate
<typename
details::binary_ext_node
<Type
,details::div_op
<Type
> > >
28721 (branch
[0], branch
[1]));
28723 default : return error_node();
28727 else if (!left_neg
&& right_neg
)
28730 (details::e_add
== operation
) ||
28731 (details::e_sub
== operation
) ||
28732 (details::e_mul
== operation
) ||
28733 (details::e_div
== operation
)
28736 if (!expr_gen
.parser_
->simplify_unary_negation_branch(branch
[1]))
28738 details::free_all_nodes(*expr_gen
.node_allocator_
,branch
);
28740 return error_node();
28745 // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1)
28746 case details::e_add
: return expr_gen
.node_allocator_
->
28747 template allocate
<typename
details::binary_ext_node
<Type
,details::sub_op
<Type
> > >
28748 (branch
[0], branch
[1]);
28750 // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1)
28751 case details::e_sub
: return expr_gen
.node_allocator_
->
28752 template allocate
<typename
details::binary_ext_node
<Type
,details::add_op
<Type
> > >
28753 (branch
[0], branch
[1]);
28755 // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1))
28756 case details::e_mul
: return expr_gen(details::e_neg
,
28757 expr_gen
.node_allocator_
->
28758 template allocate
<typename
details::binary_ext_node
<Type
,details::mul_op
<Type
> > >
28759 (branch
[0], branch
[1]));
28761 // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1))
28762 case details::e_div
: return expr_gen(details::e_neg
,
28763 expr_gen
.node_allocator_
->
28764 template allocate
<typename
details::binary_ext_node
<Type
,details::div_op
<Type
> > >
28765 (branch
[0], branch
[1]));
28767 default : return error_node();
28774 #define case_stmt(op0,op1) \
28775 case op0 : return expr_gen.node_allocator_-> \
28776 template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
28777 (branch[0], branch[1]); \
28779 basic_opr_switch_statements
28780 extended_opr_switch_statements
28782 default : return error_node();
28787 struct synthesize_vob_expression
28789 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
28790 const details::operator_type
& operation
,
28791 expression_node_ptr (&branch
)[2])
28793 const Type
& v
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
28795 #ifndef exprtk_disable_enhanced_features
28796 if (details::is_sf3ext_node(branch
[1]))
28798 expression_node_ptr result
= error_node();
28800 const bool synthesis_result
=
28801 synthesize_sf4ext_expression::template compile_right
<vtype
>
28802 (expr_gen
, v
, operation
, branch
[1], result
);
28804 if (synthesis_result
)
28806 free_node(*expr_gen
.node_allocator_
,branch
[1]);
28813 (details::e_mul
== operation
) ||
28814 (details::e_div
== operation
)
28817 if (details::is_uv_node(branch
[1]))
28819 typedef details::uv_base_node
<Type
>* uvbn_ptr_t
;
28821 details::operator_type o
= static_cast<uvbn_ptr_t
>(branch
[1])->operation();
28823 if (details::e_neg
== o
)
28825 const Type
& v1
= static_cast<uvbn_ptr_t
>(branch
[1])->v();
28827 free_node(*expr_gen
.node_allocator_
,branch
[1]);
28831 case details::e_mul
: return expr_gen(details::e_neg
,
28832 expr_gen
.node_allocator_
->
28833 template allocate_rr
<typename
details::
28834 vov_node
<Type
,details::mul_op
<Type
> > >(v
,v1
));
28836 case details::e_div
: return expr_gen(details::e_neg
,
28837 expr_gen
.node_allocator_
->
28838 template allocate_rr
<typename
details::
28839 vov_node
<Type
,details::div_op
<Type
> > >(v
,v1
));
28849 #define case_stmt(op0,op1) \
28850 case op0 : return expr_gen.node_allocator_-> \
28851 template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
28854 basic_opr_switch_statements
28855 extended_opr_switch_statements
28857 default : return error_node();
28862 struct synthesize_bov_expression
28864 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
28865 const details::operator_type
& operation
,
28866 expression_node_ptr (&branch
)[2])
28868 const Type
& v
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
28870 #ifndef exprtk_disable_enhanced_features
28871 if (details::is_sf3ext_node(branch
[0]))
28873 expression_node_ptr result
= error_node();
28875 const bool synthesis_result
=
28876 synthesize_sf4ext_expression::template compile_left
<vtype
>
28877 (expr_gen
, v
, operation
, branch
[0], result
);
28879 if (synthesis_result
)
28881 free_node(*expr_gen
.node_allocator_
, branch
[0]);
28889 (details::e_add
== operation
) ||
28890 (details::e_sub
== operation
) ||
28891 (details::e_mul
== operation
) ||
28892 (details::e_div
== operation
)
28895 if (details::is_uv_node(branch
[0]))
28897 typedef details::uv_base_node
<Type
>* uvbn_ptr_t
;
28899 details::operator_type o
= static_cast<uvbn_ptr_t
>(branch
[0])->operation();
28901 if (details::e_neg
== o
)
28903 const Type
& v0
= static_cast<uvbn_ptr_t
>(branch
[0])->v();
28905 free_node(*expr_gen
.node_allocator_
,branch
[0]);
28909 case details::e_add
: return expr_gen
.node_allocator_
->
28910 template allocate_rr
<typename
details::
28911 vov_node
<Type
,details::sub_op
<Type
> > >(v
,v0
);
28913 case details::e_sub
: return expr_gen(details::e_neg
,
28914 expr_gen
.node_allocator_
->
28915 template allocate_rr
<typename
details::
28916 vov_node
<Type
,details::add_op
<Type
> > >(v0
,v
));
28918 case details::e_mul
: return expr_gen(details::e_neg
,
28919 expr_gen
.node_allocator_
->
28920 template allocate_rr
<typename
details::
28921 vov_node
<Type
,details::mul_op
<Type
> > >(v0
,v
));
28923 case details::e_div
: return expr_gen(details::e_neg
,
28924 expr_gen
.node_allocator_
->
28925 template allocate_rr
<typename
details::
28926 vov_node
<Type
,details::div_op
<Type
> > >(v0
,v
));
28935 #define case_stmt(op0,op1) \
28936 case op0 : return expr_gen.node_allocator_-> \
28937 template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
28940 basic_opr_switch_statements
28941 extended_opr_switch_statements
28943 default : return error_node();
28948 struct synthesize_cob_expression
28950 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
28951 const details::operator_type
& operation
,
28952 expression_node_ptr (&branch
)[2])
28954 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
28956 free_node(*expr_gen
.node_allocator_
,branch
[0]);
28958 if (std::equal_to
<T
>()(T(0),c
) && (details::e_mul
== operation
))
28960 free_node(*expr_gen
.node_allocator_
,branch
[1]);
28962 return expr_gen(T(0));
28964 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_div
== operation
))
28966 free_node(*expr_gen
.node_allocator_
, branch
[1]);
28968 return expr_gen(T(0));
28970 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_add
== operation
))
28972 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_mul
== operation
))
28975 if (details::is_cob_node(branch
[1]))
28977 // Simplify expressions of the form:
28978 // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x)
28979 // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x
28981 (operation
== details::e_mul
) ||
28982 (operation
== details::e_add
)
28985 details::cob_base_node
<Type
>* cobnode
= static_cast<details::cob_base_node
<Type
>*>(branch
[1]);
28987 if (operation
== cobnode
->operation())
28991 case details::e_add
: cobnode
->set_c(c
+ cobnode
->c()); break;
28992 case details::e_mul
: cobnode
->set_c(c
* cobnode
->c()); break;
28993 default : return error_node();
29000 if (operation
== details::e_mul
)
29002 details::cob_base_node
<Type
>* cobnode
= static_cast<details::cob_base_node
<Type
>*>(branch
[1]);
29003 details::operator_type cob_opr
= cobnode
->operation();
29006 (details::e_div
== cob_opr
) ||
29007 (details::e_mul
== cob_opr
)
29012 case details::e_div
: cobnode
->set_c(c
* cobnode
->c()); break;
29013 case details::e_mul
: cobnode
->set_c(cobnode
->c() / c
); break;
29014 default : return error_node();
29020 else if (operation
== details::e_div
)
29022 details::cob_base_node
<Type
>* cobnode
= static_cast<details::cob_base_node
<Type
>*>(branch
[1]);
29023 details::operator_type cob_opr
= cobnode
->operation();
29026 (details::e_div
== cob_opr
) ||
29027 (details::e_mul
== cob_opr
)
29030 details::expression_node
<Type
>* new_cobnode
= error_node();
29034 case details::e_div
: new_cobnode
= expr_gen
.node_allocator_
->
29035 template allocate_tt
<typename
details::cob_node
<Type
,details::mul_op
<Type
> > >
29036 (c
/ cobnode
->c(), cobnode
->move_branch(0));
29039 case details::e_mul
: new_cobnode
= expr_gen
.node_allocator_
->
29040 template allocate_tt
<typename
details::cob_node
<Type
,details::div_op
<Type
> > >
29041 (c
/ cobnode
->c(), cobnode
->move_branch(0));
29044 default : return error_node();
29047 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29049 return new_cobnode
;
29053 #ifndef exprtk_disable_enhanced_features
29054 else if (details::is_sf3ext_node(branch
[1]))
29056 expression_node_ptr result
= error_node();
29058 const bool synthesis_result
=
29059 synthesize_sf4ext_expression::template compile_right
<ctype
>
29060 (expr_gen
, c
, operation
, branch
[1], result
);
29062 if (synthesis_result
)
29064 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29073 #define case_stmt(op0,op1) \
29074 case op0 : return expr_gen.node_allocator_-> \
29075 template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
29078 basic_opr_switch_statements
29079 extended_opr_switch_statements
29081 default : return error_node();
29086 struct synthesize_boc_expression
29088 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29089 const details::operator_type
& operation
,
29090 expression_node_ptr (&branch
)[2])
29092 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
29094 details::free_node(*(expr_gen
.node_allocator_
), branch
[1]);
29096 if (std::equal_to
<T
>()(T(0),c
) && (details::e_mul
== operation
))
29098 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29100 return expr_gen(T(0));
29102 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_div
== operation
))
29104 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29106 return expr_gen(std::numeric_limits
<T
>::quiet_NaN());
29108 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_add
== operation
))
29110 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_mul
== operation
))
29113 if (details::is_boc_node(branch
[0]))
29115 // Simplify expressions of the form:
29116 // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320
29117 // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45
29119 (operation
== details::e_mul
) ||
29120 (operation
== details::e_add
)
29123 details::boc_base_node
<Type
>* bocnode
= static_cast<details::boc_base_node
<Type
>*>(branch
[0]);
29125 if (operation
== bocnode
->operation())
29129 case details::e_add
: bocnode
->set_c(c
+ bocnode
->c()); break;
29130 case details::e_mul
: bocnode
->set_c(c
* bocnode
->c()); break;
29131 default : return error_node();
29137 else if (operation
== details::e_div
)
29139 details::boc_base_node
<Type
>* bocnode
= static_cast<details::boc_base_node
<Type
>*>(branch
[0]);
29140 details::operator_type boc_opr
= bocnode
->operation();
29143 (details::e_div
== boc_opr
) ||
29144 (details::e_mul
== boc_opr
)
29149 case details::e_div
: bocnode
->set_c(c
* bocnode
->c()); break;
29150 case details::e_mul
: bocnode
->set_c(bocnode
->c() / c
); break;
29151 default : return error_node();
29157 else if (operation
== details::e_pow
)
29159 // (v ^ c0) ^ c1 --> v ^(c0 * c1)
29160 details::boc_base_node
<Type
>* bocnode
= static_cast<details::boc_base_node
<Type
>*>(branch
[0]);
29161 details::operator_type boc_opr
= bocnode
->operation();
29163 if (details::e_pow
== boc_opr
)
29165 bocnode
->set_c(bocnode
->c() * c
);
29172 #ifndef exprtk_disable_enhanced_features
29173 if (details::is_sf3ext_node(branch
[0]))
29175 expression_node_ptr result
= error_node();
29177 const bool synthesis_result
=
29178 synthesize_sf4ext_expression::template compile_left
<ctype
>
29179 (expr_gen
, c
, operation
, branch
[0], result
);
29181 if (synthesis_result
)
29183 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29192 #define case_stmt(op0,op1) \
29193 case op0 : return expr_gen.node_allocator_-> \
29194 template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
29197 basic_opr_switch_statements
29198 extended_opr_switch_statements
29200 default : return error_node();
29205 struct synthesize_cocob_expression
29207 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29208 const details::operator_type
& operation
,
29209 expression_node_ptr (&branch
)[2])
29211 expression_node_ptr result
= error_node();
29213 // (cob) o c --> cob
29214 if (details::is_cob_node(branch
[0]))
29216 details::cob_base_node
<Type
>* cobnode
= static_cast<details::cob_base_node
<Type
>*>(branch
[0]);
29218 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
29220 if (std::equal_to
<T
>()(T(0),c
) && (details::e_mul
== operation
))
29222 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29223 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29225 return expr_gen(T(0));
29227 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_div
== operation
))
29229 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29230 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29232 return expr_gen(T(std::numeric_limits
<T
>::quiet_NaN()));
29234 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_add
== operation
))
29236 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29240 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_mul
== operation
))
29242 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29246 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_div
== operation
))
29248 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29253 const bool op_addsub
= (details::e_add
== cobnode
->operation()) ||
29254 (details::e_sub
== cobnode
->operation()) ;
29260 case details::e_add
: cobnode
->set_c(cobnode
->c() + c
); break;
29261 case details::e_sub
: cobnode
->set_c(cobnode
->c() - c
); break;
29262 default : return error_node();
29267 else if (details::e_mul
== cobnode
->operation())
29271 case details::e_mul
: cobnode
->set_c(cobnode
->c() * c
); break;
29272 case details::e_div
: cobnode
->set_c(cobnode
->c() / c
); break;
29273 default : return error_node();
29278 else if (details::e_div
== cobnode
->operation())
29280 if (details::e_mul
== operation
)
29282 cobnode
->set_c(cobnode
->c() * c
);
29285 else if (details::e_div
== operation
)
29287 result
= expr_gen
.node_allocator_
->
29288 template allocate_tt
<typename
details::cob_node
<Type
,details::div_op
<Type
> > >
29289 (cobnode
->c() / c
, cobnode
->move_branch(0));
29291 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29297 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29301 // c o (cob) --> cob
29302 else if (details::is_cob_node(branch
[1]))
29304 details::cob_base_node
<Type
>* cobnode
= static_cast<details::cob_base_node
<Type
>*>(branch
[1]);
29306 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
29308 if (std::equal_to
<T
>()(T(0),c
) && (details::e_mul
== operation
))
29310 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29311 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29313 return expr_gen(T(0));
29315 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_div
== operation
))
29317 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29318 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29320 return expr_gen(T(0));
29322 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_add
== operation
))
29324 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29328 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_mul
== operation
))
29330 free_node(*expr_gen
.node_allocator_
, branch
[0]);
29335 if (details::e_add
== cobnode
->operation())
29337 if (details::e_add
== operation
)
29339 cobnode
->set_c(c
+ cobnode
->c());
29342 else if (details::e_sub
== operation
)
29344 result
= expr_gen
.node_allocator_
->
29345 template allocate_tt
<typename
details::cob_node
<Type
,details::sub_op
<Type
> > >
29346 (c
- cobnode
->c(), cobnode
->move_branch(0));
29348 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29351 else if (details::e_sub
== cobnode
->operation())
29353 if (details::e_add
== operation
)
29355 cobnode
->set_c(c
+ cobnode
->c());
29358 else if (details::e_sub
== operation
)
29360 result
= expr_gen
.node_allocator_
->
29361 template allocate_tt
<typename
details::cob_node
<Type
,details::add_op
<Type
> > >
29362 (c
- cobnode
->c(), cobnode
->move_branch(0));
29364 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29367 else if (details::e_mul
== cobnode
->operation())
29369 if (details::e_mul
== operation
)
29371 cobnode
->set_c(c
* cobnode
->c());
29374 else if (details::e_div
== operation
)
29376 result
= expr_gen
.node_allocator_
->
29377 template allocate_tt
<typename
details::cob_node
<Type
,details::div_op
<Type
> > >
29378 (c
/ cobnode
->c(), cobnode
->move_branch(0));
29380 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29383 else if (details::e_div
== cobnode
->operation())
29385 if (details::e_mul
== operation
)
29387 cobnode
->set_c(c
* cobnode
->c());
29390 else if (details::e_div
== operation
)
29392 result
= expr_gen
.node_allocator_
->
29393 template allocate_tt
<typename
details::cob_node
<Type
,details::mul_op
<Type
> > >
29394 (c
/ cobnode
->c(), cobnode
->move_branch(0));
29396 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29402 free_node(*expr_gen
.node_allocator_
,branch
[0]);
29410 struct synthesize_coboc_expression
29412 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29413 const details::operator_type
& operation
,
29414 expression_node_ptr (&branch
)[2])
29416 expression_node_ptr result
= error_node();
29418 // (boc) o c --> boc
29419 if (details::is_boc_node(branch
[0]))
29421 details::boc_base_node
<Type
>* bocnode
= static_cast<details::boc_base_node
<Type
>*>(branch
[0]);
29423 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
29425 if (details::e_add
== bocnode
->operation())
29429 case details::e_add
: bocnode
->set_c(bocnode
->c() + c
); break;
29430 case details::e_sub
: bocnode
->set_c(bocnode
->c() - c
); break;
29431 default : return error_node();
29436 else if (details::e_mul
== bocnode
->operation())
29440 case details::e_mul
: bocnode
->set_c(bocnode
->c() * c
); break;
29441 case details::e_div
: bocnode
->set_c(bocnode
->c() / c
); break;
29442 default : return error_node();
29447 else if (details::e_sub
== bocnode
->operation())
29449 if (details::e_add
== operation
)
29451 result
= expr_gen
.node_allocator_
->
29452 template allocate_tt
<typename
details::boc_node
<Type
,details::add_op
<Type
> > >
29453 (bocnode
->move_branch(0), c
- bocnode
->c());
29455 free_node(*expr_gen
.node_allocator_
,branch
[0]);
29457 else if (details::e_sub
== operation
)
29459 bocnode
->set_c(bocnode
->c() + c
);
29463 else if (details::e_div
== bocnode
->operation())
29467 case details::e_div
: bocnode
->set_c(bocnode
->c() * c
); break;
29468 case details::e_mul
: bocnode
->set_c(bocnode
->c() / c
); break;
29469 default : return error_node();
29477 free_node(*expr_gen
.node_allocator_
, branch
[1]);
29481 // c o (boc) --> boc
29482 else if (details::is_boc_node(branch
[1]))
29484 details::boc_base_node
<Type
>* bocnode
= static_cast<details::boc_base_node
<Type
>*>(branch
[1]);
29486 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
29488 if (details::e_add
== bocnode
->operation())
29490 if (details::e_add
== operation
)
29492 bocnode
->set_c(c
+ bocnode
->c());
29495 else if (details::e_sub
== operation
)
29497 result
= expr_gen
.node_allocator_
->
29498 template allocate_tt
<typename
details::cob_node
<Type
,details::sub_op
<Type
> > >
29499 (c
- bocnode
->c(), bocnode
->move_branch(0));
29501 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29504 else if (details::e_sub
== bocnode
->operation())
29506 if (details::e_add
== operation
)
29508 result
= expr_gen
.node_allocator_
->
29509 template allocate_tt
<typename
details::boc_node
<Type
,details::add_op
<Type
> > >
29510 (bocnode
->move_branch(0), c
- bocnode
->c());
29512 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29514 else if (details::e_sub
== operation
)
29516 result
= expr_gen
.node_allocator_
->
29517 template allocate_tt
<typename
details::cob_node
<Type
,details::sub_op
<Type
> > >
29518 (c
+ bocnode
->c(), bocnode
->move_branch(0));
29520 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29523 else if (details::e_mul
== bocnode
->operation())
29525 if (details::e_mul
== operation
)
29527 bocnode
->set_c(c
* bocnode
->c());
29530 else if (details::e_div
== operation
)
29532 result
= expr_gen
.node_allocator_
->
29533 template allocate_tt
<typename
details::cob_node
<Type
,details::div_op
<Type
> > >
29534 (c
/ bocnode
->c(), bocnode
->move_branch(0));
29536 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29539 else if (details::e_div
== bocnode
->operation())
29541 if (details::e_mul
== operation
)
29543 bocnode
->set_c(bocnode
->c() / c
);
29546 else if (details::e_div
== operation
)
29548 result
= expr_gen
.node_allocator_
->
29549 template allocate_tt
<typename
details::cob_node
<Type
,details::div_op
<Type
> > >
29550 (c
* bocnode
->c(), bocnode
->move_branch(0));
29552 free_node(*expr_gen
.node_allocator_
,branch
[1]);
29558 free_node(*expr_gen
.node_allocator_
,branch
[0]);
29566 #ifndef exprtk_disable_enhanced_features
29567 inline bool synthesize_expression(const details::operator_type
& operation
,
29568 expression_node_ptr (&branch
)[2],
29569 expression_node_ptr
& result
)
29571 result
= error_node();
29573 if (!operation_optimisable(operation
))
29576 const std::string node_id
= branch_to_id(branch
);
29578 const typename
synthesize_map_t::iterator itr
= synthesize_map_
.find(node_id
);
29580 if (synthesize_map_
.end() != itr
)
29582 result
= itr
->second((*this), operation
, branch
);
29590 struct synthesize_vov_expression
29592 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29593 const details::operator_type
& operation
,
29594 expression_node_ptr (&branch
)[2])
29596 const Type
& v1
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
29597 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
29601 #define case_stmt(op0,op1) \
29602 case op0 : return expr_gen.node_allocator_-> \
29603 template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
29606 basic_opr_switch_statements
29607 extended_opr_switch_statements
29609 default : return error_node();
29614 struct synthesize_cov_expression
29616 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29617 const details::operator_type
& operation
,
29618 expression_node_ptr (&branch
)[2])
29620 const Type c
= static_cast<details::literal_node
<Type
>*> (branch
[0])->value();
29621 const Type
& v
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref ();
29623 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
29625 if (std::equal_to
<T
>()(T(0),c
) && (details::e_mul
== operation
))
29626 return expr_gen(T(0));
29627 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_div
== operation
))
29628 return expr_gen(T(0));
29629 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_add
== operation
))
29630 return static_cast<details::variable_node
<Type
>*>(branch
[1]);
29631 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_mul
== operation
))
29632 return static_cast<details::variable_node
<Type
>*>(branch
[1]);
29636 #define case_stmt(op0,op1) \
29637 case op0 : return expr_gen.node_allocator_-> \
29638 template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
29641 basic_opr_switch_statements
29642 extended_opr_switch_statements
29644 default : return error_node();
29649 struct synthesize_voc_expression
29651 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29652 const details::operator_type
& operation
,
29653 expression_node_ptr (&branch
)[2])
29655 const Type
& v
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref ();
29656 const Type c
= static_cast<details::literal_node
<Type
>*> (branch
[1])->value();
29658 details::free_node(*(expr_gen
.node_allocator_
), branch
[1]);
29660 if (expr_gen
.cardinal_pow_optimisable(operation
,c
))
29662 if (std::equal_to
<T
>()(T(1),c
))
29665 return expr_gen
.cardinal_pow_optimisation(v
,c
);
29667 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_mul
== operation
))
29668 return expr_gen(T(0));
29669 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_div
== operation
))
29670 return expr_gen(std::numeric_limits
<T
>::quiet_NaN());
29671 else if (std::equal_to
<T
>()(T(0),c
) && (details::e_add
== operation
))
29672 return static_cast<details::variable_node
<Type
>*>(branch
[0]);
29673 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_mul
== operation
))
29674 return static_cast<details::variable_node
<Type
>*>(branch
[0]);
29675 else if (std::equal_to
<T
>()(T(1),c
) && (details::e_div
== operation
))
29676 return static_cast<details::variable_node
<Type
>*>(branch
[0]);
29680 #define case_stmt(op0,op1) \
29681 case op0 : return expr_gen.node_allocator_-> \
29682 template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
29685 basic_opr_switch_statements
29686 extended_opr_switch_statements
29688 default : return error_node();
29693 struct synthesize_sf3ext_expression
29695 template <typename T0
, typename T1
, typename T2
>
29696 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29697 const details::operator_type
& sf3opr
,
29698 T0 t0
, T1 t1
, T2 t2
)
29702 #define case_stmt(op) \
29703 case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
29704 allocate(*(expr_gen.node_allocator_), t0, t1, t2); \
29706 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
29707 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
29708 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
29709 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
29710 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
29711 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
29712 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
29713 case_stmt(28) case_stmt(29) case_stmt(30)
29715 default : return error_node();
29719 template <typename T0
, typename T1
, typename T2
>
29720 static inline bool compile(expression_generator
<Type
>& expr_gen
, const std::string
& id
,
29721 T0 t0
, T1 t1
, T2 t2
,
29722 expression_node_ptr
& result
)
29724 details::operator_type sf3opr
;
29726 if (!expr_gen
.sf3_optimisable(id
,sf3opr
))
29729 result
= synthesize_sf3ext_expression::template process
<T0
, T1
, T2
>
29730 (expr_gen
, sf3opr
, t0
, t1
, t2
);
29736 struct synthesize_sf4ext_expression
29738 template <typename T0
, typename T1
, typename T2
, typename T3
>
29739 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29740 const details::operator_type
& sf4opr
,
29741 T0 t0
, T1 t1
, T2 t2
, T3 t3
)
29745 #define case_stmt0(op) \
29746 case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
29747 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
29750 #define case_stmt1(op) \
29751 case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
29752 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
29754 case_stmt0(48) case_stmt0(49) case_stmt0(50) case_stmt0(51)
29755 case_stmt0(52) case_stmt0(53) case_stmt0(54) case_stmt0(55)
29756 case_stmt0(56) case_stmt0(57) case_stmt0(58) case_stmt0(59)
29757 case_stmt0(60) case_stmt0(61) case_stmt0(62) case_stmt0(63)
29758 case_stmt0(64) case_stmt0(65) case_stmt0(66) case_stmt0(67)
29759 case_stmt0(68) case_stmt0(69) case_stmt0(70) case_stmt0(71)
29760 case_stmt0(72) case_stmt0(73) case_stmt0(74) case_stmt0(75)
29761 case_stmt0(76) case_stmt0(77) case_stmt0(78) case_stmt0(79)
29762 case_stmt0(80) case_stmt0(81) case_stmt0(82) case_stmt0(83)
29764 case_stmt1(00) case_stmt1(01) case_stmt1(02) case_stmt1(03)
29765 case_stmt1(04) case_stmt1(05) case_stmt1(06) case_stmt1(07)
29766 case_stmt1(08) case_stmt1(09) case_stmt1(10) case_stmt1(11)
29767 case_stmt1(12) case_stmt1(13) case_stmt1(14) case_stmt1(15)
29768 case_stmt1(16) case_stmt1(17) case_stmt1(18) case_stmt1(19)
29769 case_stmt1(20) case_stmt1(21) case_stmt1(22) case_stmt1(23)
29770 case_stmt1(24) case_stmt1(25) case_stmt1(26) case_stmt1(27)
29771 case_stmt1(28) case_stmt1(29) case_stmt1(30) case_stmt1(31)
29772 case_stmt1(32) case_stmt1(33) case_stmt1(34) case_stmt1(35)
29773 case_stmt1(36) case_stmt1(37) case_stmt1(38) case_stmt1(39)
29774 case_stmt1(40) case_stmt1(41) case_stmt1(42) case_stmt1(43)
29775 case_stmt1(44) case_stmt1(45) case_stmt1(46) case_stmt1(47)
29776 case_stmt1(48) case_stmt1(49) case_stmt1(50) case_stmt1(51)
29777 case_stmt1(52) case_stmt1(53) case_stmt1(54) case_stmt1(55)
29778 case_stmt1(56) case_stmt1(57) case_stmt1(58) case_stmt1(59)
29779 case_stmt1(60) case_stmt1(61)
29783 default : return error_node();
29787 template <typename T0
, typename T1
, typename T2
, typename T3
>
29788 static inline bool compile(expression_generator
<Type
>& expr_gen
, const std::string
& id
,
29789 T0 t0
, T1 t1
, T2 t2
, T3 t3
,
29790 expression_node_ptr
& result
)
29792 details::operator_type sf4opr
;
29794 if (!expr_gen
.sf4_optimisable(id
,sf4opr
))
29797 result
= synthesize_sf4ext_expression::template process
<T0
, T1
, T2
, T3
>
29798 (expr_gen
, sf4opr
, t0
, t1
, t2
, t3
);
29804 template <typename ExternalType
>
29805 static inline bool compile_right(expression_generator
<Type
>& expr_gen
,
29807 const details::operator_type
& operation
,
29808 expression_node_ptr
& sf3node
,
29809 expression_node_ptr
& result
)
29811 if (!details::is_sf3ext_node(sf3node
))
29814 typedef details::T0oT1oT2_base_node
<Type
>* sf3ext_base_ptr
;
29816 sf3ext_base_ptr n
= static_cast<sf3ext_base_ptr
>(sf3node
);
29817 const std::string id
= "t" + expr_gen
.to_str(operation
) + "(" + n
->type_id() + ")";
29821 case details::expression_node
<Type
>::e_covoc
: return compile_right_impl
29822 <typename
covoc_t::sf3_type_node
,ExternalType
, ctype
, vtype
, ctype
>
29823 (expr_gen
, id
, t
, sf3node
, result
);
29825 case details::expression_node
<Type
>::e_covov
: return compile_right_impl
29826 <typename
covov_t::sf3_type_node
,ExternalType
, ctype
, vtype
, vtype
>
29827 (expr_gen
, id
, t
, sf3node
, result
);
29829 case details::expression_node
<Type
>::e_vocov
: return compile_right_impl
29830 <typename
vocov_t::sf3_type_node
,ExternalType
, vtype
, ctype
, vtype
>
29831 (expr_gen
, id
, t
, sf3node
, result
);
29833 case details::expression_node
<Type
>::e_vovoc
: return compile_right_impl
29834 <typename
vovoc_t::sf3_type_node
,ExternalType
, vtype
, vtype
, ctype
>
29835 (expr_gen
, id
, t
, sf3node
, result
);
29837 case details::expression_node
<Type
>::e_vovov
: return compile_right_impl
29838 <typename
vovov_t::sf3_type_node
,ExternalType
, vtype
, vtype
, vtype
>
29839 (expr_gen
, id
, t
, sf3node
, result
);
29841 default : return false;
29846 template <typename ExternalType
>
29847 static inline bool compile_left(expression_generator
<Type
>& expr_gen
,
29849 const details::operator_type
& operation
,
29850 expression_node_ptr
& sf3node
,
29851 expression_node_ptr
& result
)
29853 if (!details::is_sf3ext_node(sf3node
))
29856 typedef details::T0oT1oT2_base_node
<Type
>* sf3ext_base_ptr
;
29858 sf3ext_base_ptr n
= static_cast<sf3ext_base_ptr
>(sf3node
);
29860 const std::string id
= "(" + n
->type_id() + ")" + expr_gen
.to_str(operation
) + "t";
29864 case details::expression_node
<Type
>::e_covoc
: return compile_left_impl
29865 <typename
covoc_t::sf3_type_node
,ExternalType
, ctype
, vtype
, ctype
>
29866 (expr_gen
, id
, t
, sf3node
, result
);
29868 case details::expression_node
<Type
>::e_covov
: return compile_left_impl
29869 <typename
covov_t::sf3_type_node
,ExternalType
, ctype
, vtype
, vtype
>
29870 (expr_gen
, id
, t
, sf3node
, result
);
29872 case details::expression_node
<Type
>::e_vocov
: return compile_left_impl
29873 <typename
vocov_t::sf3_type_node
,ExternalType
, vtype
, ctype
, vtype
>
29874 (expr_gen
, id
, t
, sf3node
, result
);
29876 case details::expression_node
<Type
>::e_vovoc
: return compile_left_impl
29877 <typename
vovoc_t::sf3_type_node
,ExternalType
, vtype
, vtype
, ctype
>
29878 (expr_gen
, id
, t
, sf3node
, result
);
29880 case details::expression_node
<Type
>::e_vovov
: return compile_left_impl
29881 <typename
vovov_t::sf3_type_node
,ExternalType
, vtype
, vtype
, vtype
>
29882 (expr_gen
, id
, t
, sf3node
, result
);
29884 default : return false;
29888 template <typename SF3TypeNode
, typename ExternalType
, typename T0
, typename T1
, typename T2
>
29889 static inline bool compile_right_impl(expression_generator
<Type
>& expr_gen
,
29890 const std::string
& id
,
29892 expression_node_ptr
& node
,
29893 expression_node_ptr
& result
)
29895 SF3TypeNode
* n
= dynamic_cast<SF3TypeNode
*>(node
);
29903 return synthesize_sf4ext_expression::template compile
<ExternalType
, T0
, T1
, T2
>
29904 (expr_gen
, id
, t
, t0
, t1
, t2
, result
);
29910 template <typename SF3TypeNode
, typename ExternalType
, typename T0
, typename T1
, typename T2
>
29911 static inline bool compile_left_impl(expression_generator
<Type
>& expr_gen
,
29912 const std::string
& id
,
29914 expression_node_ptr
& node
,
29915 expression_node_ptr
& result
)
29917 SF3TypeNode
* n
= dynamic_cast<SF3TypeNode
*>(node
);
29925 return synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, ExternalType
>
29926 (expr_gen
, id
, t0
, t1
, t2
, t
, result
);
29933 struct synthesize_vovov_expression0
29935 typedef typename
vovov_t::type0 node_type
;
29936 typedef typename
vovov_t::sf3_type sf3_type
;
29938 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
29939 const details::operator_type
& operation
,
29940 expression_node_ptr (&branch
)[2])
29942 // (v0 o0 v1) o1 (v2)
29943 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[0]);
29944 const Type
& v0
= vov
->v0();
29945 const Type
& v1
= vov
->v1();
29946 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
29947 const details::operator_type o0
= vov
->operation();
29948 const details::operator_type o1
= operation
;
29950 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
29951 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
29953 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
29955 expression_node_ptr result
= error_node();
29957 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
29959 // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)
29960 if ((details::e_div
== o0
) && (details::e_div
== o1
))
29962 const bool synthesis_result
=
29963 synthesize_sf3ext_expression::
29964 template compile
<vtype
,vtype
,vtype
>(expr_gen
, "t/(t*t)", v0
, v1
, v2
, result
);
29966 exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
29968 return (synthesis_result
) ? result
: error_node();
29972 const bool synthesis_result
=
29973 synthesize_sf3ext_expression::template compile
<vtype
, vtype
, vtype
>
29974 (expr_gen
, id(expr_gen
, o0
, o1
), v0
, v1
, v2
, result
);
29976 if (synthesis_result
)
29978 else if (!expr_gen
.valid_operator(o0
,f0
))
29979 return error_node();
29980 else if (!expr_gen
.valid_operator(o1
,f1
))
29981 return error_node();
29983 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, f0
, f1
);
29986 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
29987 const details::operator_type o0
, const details::operator_type o1
)
29989 return details::build_string()
29990 << "(t" << expr_gen
.to_str(o0
)
29991 << "t)" << expr_gen
.to_str(o1
)
29996 struct synthesize_vovov_expression1
29998 typedef typename
vovov_t::type1 node_type
;
29999 typedef typename
vovov_t::sf3_type sf3_type
;
30001 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30002 const details::operator_type
& operation
,
30003 expression_node_ptr (&branch
)[2])
30005 // (v0) o0 (v1 o1 v2)
30006 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[1]);
30007 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
30008 const Type
& v1
= vov
->v0();
30009 const Type
& v2
= vov
->v1();
30010 const details::operator_type o0
= operation
;
30011 const details::operator_type o1
= vov
->operation();
30013 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30014 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30016 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30018 expression_node_ptr result
= error_node();
30020 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30022 // v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1
30023 if ((details::e_div
== o0
) && (details::e_div
== o1
))
30025 const bool synthesis_result
=
30026 synthesize_sf3ext_expression::
30027 template compile
<vtype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", v0
, v2
, v1
, result
);
30029 exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
30031 return (synthesis_result
) ? result
: error_node();
30035 const bool synthesis_result
=
30036 synthesize_sf3ext_expression::template compile
<vtype
, vtype
, vtype
>
30037 (expr_gen
, id(expr_gen
, o0
, o1
), v0
, v1
, v2
, result
);
30039 if (synthesis_result
)
30041 else if (!expr_gen
.valid_operator(o0
,f0
))
30042 return error_node();
30043 else if (!expr_gen
.valid_operator(o1
,f1
))
30044 return error_node();
30046 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, f0
, f1
);
30049 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30050 const details::operator_type o0
, const details::operator_type o1
)
30052 return details::build_string()
30053 << "t" << expr_gen
.to_str(o0
)
30054 << "(t" << expr_gen
.to_str(o1
)
30059 struct synthesize_vovoc_expression0
30061 typedef typename
vovoc_t::type0 node_type
;
30062 typedef typename
vovoc_t::sf3_type sf3_type
;
30064 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30065 const details::operator_type
& operation
,
30066 expression_node_ptr (&branch
)[2])
30068 // (v0 o0 v1) o1 (c)
30069 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[0]);
30070 const Type
& v0
= vov
->v0();
30071 const Type
& v1
= vov
->v1();
30072 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
30073 const details::operator_type o0
= vov
->operation();
30074 const details::operator_type o1
= operation
;
30076 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30077 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30079 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30080 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30082 expression_node_ptr result
= error_node();
30084 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30086 // (v0 / v1) / c --> (vovoc) v0 / (v1 * c)
30087 if ((details::e_div
== o0
) && (details::e_div
== o1
))
30089 const bool synthesis_result
=
30090 synthesize_sf3ext_expression::
30091 template compile
<vtype
,vtype
,ctype
>(expr_gen
, "t/(t*t)", v0
, v1
, c
, result
);
30093 exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
30095 return (synthesis_result
) ? result
: error_node();
30099 const bool synthesis_result
=
30100 synthesize_sf3ext_expression::template compile
<vtype
, vtype
, ctype
>
30101 (expr_gen
, id(expr_gen
, o0
, o1
), v0
, v1
, c
, result
);
30103 if (synthesis_result
)
30105 else if (!expr_gen
.valid_operator(o0
,f0
))
30106 return error_node();
30107 else if (!expr_gen
.valid_operator(o1
,f1
))
30108 return error_node();
30110 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, c
, f0
, f1
);
30113 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30114 const details::operator_type o0
, const details::operator_type o1
)
30116 return details::build_string()
30117 << "(t" << expr_gen
.to_str(o0
)
30118 << "t)" << expr_gen
.to_str(o1
)
30123 struct synthesize_vovoc_expression1
30125 typedef typename
vovoc_t::type1 node_type
;
30126 typedef typename
vovoc_t::sf3_type sf3_type
;
30128 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30129 const details::operator_type
& operation
,
30130 expression_node_ptr (&branch
)[2])
30132 // (v0) o0 (v1 o1 c)
30133 const details::voc_base_node
<Type
>* voc
= static_cast<const details::voc_base_node
<Type
>*>(branch
[1]);
30134 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
30135 const Type
& v1
= voc
->v();
30136 const Type c
= voc
->c();
30137 const details::operator_type o0
= operation
;
30138 const details::operator_type o1
= voc
->operation();
30140 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30141 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30143 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30145 expression_node_ptr result
= error_node();
30147 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30149 // v0 / (v1 / c) --> (vocov) (v0 * c) / v1
30150 if ((details::e_div
== o0
) && (details::e_div
== o1
))
30152 const bool synthesis_result
=
30153 synthesize_sf3ext_expression::
30154 template compile
<vtype
,ctype
,vtype
>(expr_gen
, "(t*t)/t", v0
, c
, v1
, result
);
30156 exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
30158 return (synthesis_result
) ? result
: error_node();
30162 const bool synthesis_result
=
30163 synthesize_sf3ext_expression::template compile
<vtype
, vtype
, ctype
>
30164 (expr_gen
, id(expr_gen
, o0
, o1
), v0
, v1
, c
, result
);
30166 if (synthesis_result
)
30168 else if (!expr_gen
.valid_operator(o0
,f0
))
30169 return error_node();
30170 else if (!expr_gen
.valid_operator(o1
,f1
))
30171 return error_node();
30173 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, c
, f0
, f1
);
30176 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30177 const details::operator_type o0
, const details::operator_type o1
)
30179 return details::build_string()
30180 << "t" << expr_gen
.to_str(o0
)
30181 << "(t" << expr_gen
.to_str(o1
)
30186 struct synthesize_vocov_expression0
30188 typedef typename
vocov_t::type0 node_type
;
30189 typedef typename
vocov_t::sf3_type sf3_type
;
30191 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30192 const details::operator_type
& operation
,
30193 expression_node_ptr (&branch
)[2])
30195 // (v0 o0 c) o1 (v1)
30196 const details::voc_base_node
<Type
>* voc
= static_cast<details::voc_base_node
<Type
>*>(branch
[0]);
30197 const Type
& v0
= voc
->v();
30198 const Type c
= voc
->c();
30199 const Type
& v1
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
30200 const details::operator_type o0
= voc
->operation();
30201 const details::operator_type o1
= operation
;
30203 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30204 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30206 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30208 expression_node_ptr result
= error_node();
30210 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30212 // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c)
30213 if ((details::e_div
== o0
) && (details::e_div
== o1
))
30215 const bool synthesis_result
=
30216 synthesize_sf3ext_expression::
30217 template compile
<vtype
,vtype
,ctype
>(expr_gen
, "t/(t*t)", v0
, v1
, c
, result
);
30219 exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
30221 return (synthesis_result
) ? result
: error_node();
30225 const bool synthesis_result
=
30226 synthesize_sf3ext_expression::template compile
<vtype
, ctype
, vtype
>
30227 (expr_gen
, id(expr_gen
, o0
, o1
), v0
, c
, v1
, result
);
30229 if (synthesis_result
)
30231 else if (!expr_gen
.valid_operator(o0
,f0
))
30232 return error_node();
30233 else if (!expr_gen
.valid_operator(o1
,f1
))
30234 return error_node();
30236 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c
, v1
, f0
, f1
);
30239 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30240 const details::operator_type o0
, const details::operator_type o1
)
30242 return details::build_string()
30243 << "(t" << expr_gen
.to_str(o0
)
30244 << "t)" << expr_gen
.to_str(o1
)
30249 struct synthesize_vocov_expression1
30251 typedef typename
vocov_t::type1 node_type
;
30252 typedef typename
vocov_t::sf3_type sf3_type
;
30254 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30255 const details::operator_type
& operation
,
30256 expression_node_ptr (&branch
)[2])
30258 // (v0) o0 (c o1 v1)
30259 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[1]);
30260 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
30261 const Type c
= cov
->c();
30262 const Type
& v1
= cov
->v();
30263 const details::operator_type o0
= operation
;
30264 const details::operator_type o1
= cov
->operation();
30266 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30267 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30269 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30271 expression_node_ptr result
= error_node();
30273 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30275 // v0 / (c / v1) --> (vovoc) (v0 * v1) / c
30276 if ((details::e_div
== o0
) && (details::e_div
== o1
))
30278 const bool synthesis_result
=
30279 synthesize_sf3ext_expression::
30280 template compile
<vtype
, vtype
, ctype
>(expr_gen
, "(t*t)/t", v0
, v1
, c
, result
);
30282 exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
30284 return (synthesis_result
) ? result
: error_node();
30288 const bool synthesis_result
=
30289 synthesize_sf3ext_expression::template compile
<vtype
, ctype
, vtype
>
30290 (expr_gen
, id(expr_gen
, o0
, o1
), v0
, c
, v1
, result
);
30292 if (synthesis_result
)
30294 else if (!expr_gen
.valid_operator(o0
,f0
))
30295 return error_node();
30296 else if (!expr_gen
.valid_operator(o1
,f1
))
30297 return error_node();
30299 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c
, v1
, f0
, f1
);
30302 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30303 const details::operator_type o0
, const details::operator_type o1
)
30305 return details::build_string()
30306 << "t" << expr_gen
.to_str(o0
)
30307 << "(t" << expr_gen
.to_str(o1
)
30312 struct synthesize_covov_expression0
30314 typedef typename
covov_t::type0 node_type
;
30315 typedef typename
covov_t::sf3_type sf3_type
;
30317 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30318 const details::operator_type
& operation
,
30319 expression_node_ptr (&branch
)[2])
30321 // (c o0 v0) o1 (v1)
30322 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[0]);
30323 const Type c
= cov
->c();
30324 const Type
& v0
= cov
->v();
30325 const Type
& v1
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
30326 const details::operator_type o0
= cov
->operation();
30327 const details::operator_type o1
= operation
;
30329 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30330 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30332 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30334 expression_node_ptr result
= error_node();
30336 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30338 // (c / v0) / v1 --> (covov) c / (v0 * v1)
30339 if ((details::e_div
== o0
) && (details::e_div
== o1
))
30341 const bool synthesis_result
=
30342 synthesize_sf3ext_expression::
30343 template compile
<ctype
, vtype
, vtype
>(expr_gen
, "t/(t*t)", c
, v0
, v1
, result
);
30345 exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
30347 return (synthesis_result
) ? result
: error_node();
30351 const bool synthesis_result
=
30352 synthesize_sf3ext_expression::template compile
<ctype
, vtype
, vtype
>
30353 (expr_gen
, id(expr_gen
, o0
, o1
), c
, v0
, v1
, result
);
30355 if (synthesis_result
)
30357 else if (!expr_gen
.valid_operator(o0
,f0
))
30358 return error_node();
30359 else if (!expr_gen
.valid_operator(o1
,f1
))
30360 return error_node();
30362 return node_type::allocate(*(expr_gen
.node_allocator_
), c
, v0
, v1
, f0
, f1
);
30365 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30366 const details::operator_type o0
, const details::operator_type o1
)
30368 return details::build_string()
30369 << "(t" << expr_gen
.to_str(o0
)
30370 << "t)" << expr_gen
.to_str(o1
)
30375 struct synthesize_covov_expression1
30377 typedef typename
covov_t::type1 node_type
;
30378 typedef typename
covov_t::sf3_type sf3_type
;
30380 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30381 const details::operator_type
& operation
,
30382 expression_node_ptr (&branch
)[2])
30384 // (c) o0 (v0 o1 v1)
30385 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[1]);
30386 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
30387 const Type
& v0
= vov
->v0();
30388 const Type
& v1
= vov
->v1();
30389 const details::operator_type o0
= operation
;
30390 const details::operator_type o1
= vov
->operation();
30392 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30393 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30395 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30396 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30398 expression_node_ptr result
= error_node();
30400 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30402 // c / (v0 / v1) --> (covov) (c * v1) / v0
30403 if ((details::e_div
== o0
) && (details::e_div
== o1
))
30405 const bool synthesis_result
=
30406 synthesize_sf3ext_expression::
30407 template compile
<ctype
, vtype
, vtype
>(expr_gen
, "(t*t)/t", c
, v1
, v0
, result
);
30409 exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
30411 return (synthesis_result
) ? result
: error_node();
30415 const bool synthesis_result
=
30416 synthesize_sf3ext_expression::template compile
<ctype
, vtype
, vtype
>
30417 (expr_gen
, id(expr_gen
, o0
, o1
), c
, v0
, v1
, result
);
30419 if (synthesis_result
)
30421 else if (!expr_gen
.valid_operator(o0
,f0
))
30422 return error_node();
30423 else if (!expr_gen
.valid_operator(o1
,f1
))
30424 return error_node();
30426 return node_type::allocate(*(expr_gen
.node_allocator_
), c
, v0
, v1
, f0
, f1
);
30429 static inline std::string
id(expression_generator
<Type
>& expr_gen
, const details::operator_type o0
, const details::operator_type o1
)
30431 return details::build_string()
30432 << "t" << expr_gen
.to_str(o0
)
30433 << "(t" << expr_gen
.to_str(o1
)
30438 struct synthesize_covoc_expression0
30440 typedef typename
covoc_t::type0 node_type
;
30441 typedef typename
covoc_t::sf3_type sf3_type
;
30443 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30444 const details::operator_type
& operation
,
30445 expression_node_ptr (&branch
)[2])
30447 // (c0 o0 v) o1 (c1)
30448 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[0]);
30449 const Type c0
= cov
->c();
30450 const Type
& v
= cov
->v();
30451 const Type c1
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
30452 const details::operator_type o0
= cov
->operation();
30453 const details::operator_type o1
= operation
;
30455 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30456 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30458 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30459 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30461 expression_node_ptr result
= error_node();
30463 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30465 // (c0 + v) + c1 --> (cov) (c0 + c1) + v
30466 if ((details::e_add
== o0
) && (details::e_add
== o1
))
30468 exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
30470 return expr_gen
.node_allocator_
->
30471 template allocate_cr
<typename
details::cov_node
<Type
,details::add_op
<Type
> > >(c0
+ c1
, v
);
30473 // (c0 + v) - c1 --> (cov) (c0 - c1) + v
30474 else if ((details::e_add
== o0
) && (details::e_sub
== o1
))
30476 exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
30478 return expr_gen
.node_allocator_
->
30479 template allocate_cr
<typename
details::cov_node
<Type
,details::add_op
<Type
> > >(c0
- c1
, v
);
30481 // (c0 - v) + c1 --> (cov) (c0 + c1) - v
30482 else if ((details::e_sub
== o0
) && (details::e_add
== o1
))
30484 exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
30486 return expr_gen
.node_allocator_
->
30487 template allocate_cr
<typename
details::cov_node
<Type
,details::sub_op
<Type
> > >(c0
+ c1
, v
);
30489 // (c0 - v) - c1 --> (cov) (c0 - c1) - v
30490 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
))
30492 exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
30494 return expr_gen
.node_allocator_
->
30495 template allocate_cr
<typename
details::cov_node
<Type
,details::sub_op
<Type
> > >(c0
- c1
, v
);
30497 // (c0 * v) * c1 --> (cov) (c0 * c1) * v
30498 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
))
30500 exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
30502 return expr_gen
.node_allocator_
->
30503 template allocate_cr
<typename
details::cov_node
<Type
,details::mul_op
<Type
> > >(c0
* c1
, v
);
30505 // (c0 * v) / c1 --> (cov) (c0 / c1) * v
30506 else if ((details::e_mul
== o0
) && (details::e_div
== o1
))
30508 exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
30510 return expr_gen
.node_allocator_
->
30511 template allocate_cr
<typename
details::cov_node
<Type
,details::mul_op
<Type
> > >(c0
/ c1
, v
);
30513 // (c0 / v) * c1 --> (cov) (c0 * c1) / v
30514 else if ((details::e_div
== o0
) && (details::e_mul
== o1
))
30516 exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
30518 return expr_gen
.node_allocator_
->
30519 template allocate_cr
<typename
details::cov_node
<Type
,details::div_op
<Type
> > >(c0
* c1
, v
);
30521 // (c0 / v) / c1 --> (cov) (c0 / c1) / v
30522 else if ((details::e_div
== o0
) && (details::e_div
== o1
))
30524 exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
30526 return expr_gen
.node_allocator_
->
30527 template allocate_cr
<typename
details::cov_node
<Type
,details::div_op
<Type
> > >(c0
/ c1
, v
);
30531 const bool synthesis_result
=
30532 synthesize_sf3ext_expression::template compile
<ctype
, vtype
, ctype
>
30533 (expr_gen
, id(expr_gen
, o0
, o1
), c0
, v
, c1
, result
);
30535 if (synthesis_result
)
30537 else if (!expr_gen
.valid_operator(o0
,f0
))
30538 return error_node();
30539 else if (!expr_gen
.valid_operator(o1
,f1
))
30540 return error_node();
30542 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v
, c1
, f0
, f1
);
30545 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30546 const details::operator_type o0
, const details::operator_type o1
)
30548 return details::build_string()
30549 << "(t" << expr_gen
.to_str(o0
)
30550 << "t)" << expr_gen
.to_str(o1
)
30555 struct synthesize_covoc_expression1
30557 typedef typename
covoc_t::type1 node_type
;
30558 typedef typename
covoc_t::sf3_type sf3_type
;
30560 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30561 const details::operator_type
& operation
,
30562 expression_node_ptr (&branch
)[2])
30564 // (c0) o0 (v o1 c1)
30565 const details::voc_base_node
<Type
>* voc
= static_cast<details::voc_base_node
<Type
>*>(branch
[1]);
30566 const Type c0
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
30567 const Type
& v
= voc
->v();
30568 const Type c1
= voc
->c();
30569 const details::operator_type o0
= operation
;
30570 const details::operator_type o1
= voc
->operation();
30572 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30573 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30575 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30576 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30578 expression_node_ptr result
= error_node();
30580 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30582 // (c0) + (v + c1) --> (cov) (c0 + c1) + v
30583 if ((details::e_add
== o0
) && (details::e_add
== o1
))
30585 exprtk_debug(("(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
30587 return expr_gen
.node_allocator_
->
30588 template allocate_cr
<typename
details::cov_node
<Type
,details::add_op
<Type
> > >(c0
+ c1
, v
);
30590 // (c0) + (v - c1) --> (cov) (c0 - c1) + v
30591 else if ((details::e_add
== o0
) && (details::e_sub
== o1
))
30593 exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
30595 return expr_gen
.node_allocator_
->
30596 template allocate_cr
<typename
details::cov_node
<Type
,details::add_op
<Type
> > >(c0
- c1
, v
);
30598 // (c0) - (v + c1) --> (cov) (c0 - c1) - v
30599 else if ((details::e_sub
== o0
) && (details::e_add
== o1
))
30601 exprtk_debug(("(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
30603 return expr_gen
.node_allocator_
->
30604 template allocate_cr
<typename
details::cov_node
<Type
,details::sub_op
<Type
> > >(c0
- c1
, v
);
30606 // (c0) - (v - c1) --> (cov) (c0 + c1) - v
30607 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
))
30609 exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
30611 return expr_gen
.node_allocator_
->
30612 template allocate_cr
<typename
details::cov_node
<Type
,details::sub_op
<Type
> > >(c0
+ c1
, v
);
30614 // (c0) * (v * c1) --> (voc) v * (c0 * c1)
30615 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
))
30617 exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
30619 return expr_gen
.node_allocator_
->
30620 template allocate_cr
<typename
details::cov_node
<Type
,details::mul_op
<Type
> > >(c0
* c1
, v
);
30622 // (c0) * (v / c1) --> (cov) (c0 / c1) * v
30623 else if ((details::e_mul
== o0
) && (details::e_div
== o1
))
30625 exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
30627 return expr_gen
.node_allocator_
->
30628 template allocate_cr
<typename
details::cov_node
<Type
,details::mul_op
<Type
> > >(c0
/ c1
, v
);
30630 // (c0) / (v * c1) --> (cov) (c0 / c1) / v
30631 else if ((details::e_div
== o0
) && (details::e_mul
== o1
))
30633 exprtk_debug(("(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
30635 return expr_gen
.node_allocator_
->
30636 template allocate_cr
<typename
details::cov_node
<Type
,details::div_op
<Type
> > >(c0
/ c1
, v
);
30638 // (c0) / (v / c1) --> (cov) (c0 * c1) / v
30639 else if ((details::e_div
== o0
) && (details::e_div
== o1
))
30641 exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
30643 return expr_gen
.node_allocator_
->
30644 template allocate_cr
<typename
details::cov_node
<Type
,details::div_op
<Type
> > >(c0
* c1
, v
);
30648 const bool synthesis_result
=
30649 synthesize_sf3ext_expression::template compile
<ctype
, vtype
, ctype
>
30650 (expr_gen
, id(expr_gen
, o0
, o1
), c0
, v
, c1
, result
);
30652 if (synthesis_result
)
30654 else if (!expr_gen
.valid_operator(o0
,f0
))
30655 return error_node();
30656 else if (!expr_gen
.valid_operator(o1
,f1
))
30657 return error_node();
30659 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v
, c1
, f0
, f1
);
30662 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30663 const details::operator_type o0
, const details::operator_type o1
)
30665 return details::build_string()
30666 << "t" << expr_gen
.to_str(o0
)
30667 << "(t" << expr_gen
.to_str(o1
)
30672 struct synthesize_cocov_expression0
30674 typedef typename
cocov_t::type0 node_type
;
30675 static inline expression_node_ptr
process(expression_generator
<Type
>&, const details::operator_type
&, expression_node_ptr (&)[2])
30677 // (c0 o0 c1) o1 (v) - Not possible.
30678 return error_node();
30682 struct synthesize_cocov_expression1
30684 typedef typename
cocov_t::type1 node_type
;
30685 typedef typename
cocov_t::sf3_type sf3_type
;
30687 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30688 const details::operator_type
& operation
,
30689 expression_node_ptr (&branch
)[2])
30691 // (c0) o0 (c1 o1 v)
30692 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[1]);
30693 const Type c0
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
30694 const Type c1
= cov
->c();
30695 const Type
& v
= cov
->v();
30696 const details::operator_type o0
= operation
;
30697 const details::operator_type o1
= cov
->operation();
30699 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30700 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30702 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30703 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30705 expression_node_ptr result
= error_node();
30707 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30709 // (c0) + (c1 + v) --> (cov) (c0 + c1) + v
30710 if ((details::e_add
== o0
) && (details::e_add
== o1
))
30712 exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
30714 return expr_gen
.node_allocator_
->
30715 template allocate_cr
<typename
details::cov_node
<Type
,details::add_op
<Type
> > >(c0
+ c1
, v
);
30717 // (c0) + (c1 - v) --> (cov) (c0 + c1) - v
30718 else if ((details::e_add
== o0
) && (details::e_sub
== o1
))
30720 exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
30722 return expr_gen
.node_allocator_
->
30723 template allocate_cr
<typename
details::cov_node
<Type
,details::sub_op
<Type
> > >(c0
+ c1
, v
);
30725 // (c0) - (c1 + v) --> (cov) (c0 - c1) - v
30726 else if ((details::e_sub
== o0
) && (details::e_add
== o1
))
30728 exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
30730 return expr_gen
.node_allocator_
->
30731 template allocate_cr
<typename
details::cov_node
<Type
,details::sub_op
<Type
> > >(c0
- c1
, v
);
30733 // (c0) - (c1 - v) --> (cov) (c0 - c1) + v
30734 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
))
30736 exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
30738 return expr_gen
.node_allocator_
->
30739 template allocate_cr
<typename
details::cov_node
<Type
,details::add_op
<Type
> > >(c0
- c1
, v
);
30741 // (c0) * (c1 * v) --> (cov) (c0 * c1) * v
30742 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
))
30744 exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
30746 return expr_gen
.node_allocator_
->
30747 template allocate_cr
<typename
details::cov_node
<Type
,details::mul_op
<Type
> > >(c0
* c1
, v
);
30749 // (c0) * (c1 / v) --> (cov) (c0 * c1) / v
30750 else if ((details::e_mul
== o0
) && (details::e_div
== o1
))
30752 exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
30754 return expr_gen
.node_allocator_
->
30755 template allocate_cr
<typename
details::cov_node
<Type
,details::div_op
<Type
> > >(c0
* c1
, v
);
30757 // (c0) / (c1 * v) --> (cov) (c0 / c1) / v
30758 else if ((details::e_div
== o0
) && (details::e_mul
== o1
))
30760 exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
30762 return expr_gen
.node_allocator_
->
30763 template allocate_cr
<typename
details::cov_node
<Type
,details::div_op
<Type
> > >(c0
/ c1
, v
);
30765 // (c0) / (c1 / v) --> (cov) (c0 / c1) * v
30766 else if ((details::e_div
== o0
) && (details::e_div
== o1
))
30768 exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
30770 return expr_gen
.node_allocator_
->
30771 template allocate_cr
<typename
details::cov_node
<Type
,details::mul_op
<Type
> > >(c0
/ c1
, v
);
30775 const bool synthesis_result
=
30776 synthesize_sf3ext_expression::template compile
<ctype
, ctype
, vtype
>
30777 (expr_gen
, id(expr_gen
, o0
, o1
), c0
, c1
, v
, result
);
30779 if (synthesis_result
)
30781 else if (!expr_gen
.valid_operator(o0
,f0
))
30782 return error_node();
30783 else if (!expr_gen
.valid_operator(o1
,f1
))
30784 return error_node();
30786 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, c1
, v
, f0
, f1
);
30789 static inline std::string
id(expression_generator
<Type
>& expr_gen
, const details::operator_type o0
, const details::operator_type o1
)
30791 return details::build_string()
30792 << "t" << expr_gen
.to_str(o0
)
30793 << "(t" << expr_gen
.to_str(o1
)
30798 struct synthesize_vococ_expression0
30800 typedef typename
vococ_t::type0 node_type
;
30801 typedef typename
vococ_t::sf3_type sf3_type
;
30803 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30804 const details::operator_type
& operation
,
30805 expression_node_ptr (&branch
)[2])
30807 // (v o0 c0) o1 (c1)
30808 const details::voc_base_node
<Type
>* voc
= static_cast<details::voc_base_node
<Type
>*>(branch
[0]);
30809 const Type
& v
= voc
->v();
30810 const Type
& c0
= voc
->c();
30811 const Type
& c1
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
30812 const details::operator_type o0
= voc
->operation();
30813 const details::operator_type o1
= operation
;
30815 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30816 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30818 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30819 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30821 expression_node_ptr result
= error_node();
30823 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30825 // (v + c0) + c1 --> (voc) v + (c0 + c1)
30826 if ((details::e_add
== o0
) && (details::e_add
== o1
))
30828 exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
30830 return expr_gen
.node_allocator_
->
30831 template allocate_rc
<typename
details::voc_node
<Type
,details::add_op
<Type
> > >(v
, c0
+ c1
);
30833 // (v + c0) - c1 --> (voc) v + (c0 - c1)
30834 else if ((details::e_add
== o0
) && (details::e_sub
== o1
))
30836 exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
30838 return expr_gen
.node_allocator_
->
30839 template allocate_rc
<typename
details::voc_node
<Type
,details::add_op
<Type
> > >(v
, c0
- c1
);
30841 // (v - c0) + c1 --> (voc) v - (c0 + c1)
30842 else if ((details::e_sub
== o0
) && (details::e_add
== o1
))
30844 exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
30846 return expr_gen
.node_allocator_
->
30847 template allocate_rc
<typename
details::voc_node
<Type
,details::add_op
<Type
> > >(v
, c1
- c0
);
30849 // (v - c0) - c1 --> (voc) v - (c0 + c1)
30850 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
))
30852 exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
30854 return expr_gen
.node_allocator_
->
30855 template allocate_rc
<typename
details::voc_node
<Type
,details::sub_op
<Type
> > >(v
, c0
+ c1
);
30857 // (v * c0) * c1 --> (voc) v * (c0 * c1)
30858 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
))
30860 exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
30862 return expr_gen
.node_allocator_
->
30863 template allocate_rc
<typename
details::voc_node
<Type
,details::mul_op
<Type
> > >(v
, c0
* c1
);
30865 // (v * c0) / c1 --> (voc) v * (c0 / c1)
30866 else if ((details::e_mul
== o0
) && (details::e_div
== o1
))
30868 exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
30870 return expr_gen
.node_allocator_
->
30871 template allocate_rc
<typename
details::voc_node
<Type
,details::mul_op
<Type
> > >(v
, c0
/ c1
);
30873 // (v / c0) * c1 --> (voc) v * (c1 / c0)
30874 else if ((details::e_div
== o0
) && (details::e_mul
== o1
))
30876 exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
30878 return expr_gen
.node_allocator_
->
30879 template allocate_rc
<typename
details::voc_node
<Type
,details::mul_op
<Type
> > >(v
, c1
/ c0
);
30881 // (v / c0) / c1 --> (voc) v / (c0 * c1)
30882 else if ((details::e_div
== o0
) && (details::e_div
== o1
))
30884 exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
30886 return expr_gen
.node_allocator_
->
30887 template allocate_rc
<typename
details::voc_node
<Type
,details::div_op
<Type
> > >(v
, c0
* c1
);
30889 // (v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)
30890 else if ((details::e_pow
== o0
) && (details::e_pow
== o1
))
30892 exprtk_debug(("(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n"));
30894 return expr_gen
.node_allocator_
->
30895 template allocate_rc
<typename
details::voc_node
<Type
,details::pow_op
<Type
> > >(v
, c0
* c1
);
30899 const bool synthesis_result
=
30900 synthesize_sf3ext_expression::template compile
<vtype
, ctype
, ctype
>
30901 (expr_gen
, id(expr_gen
, o0
, o1
), v
, c0
, c1
, result
);
30903 if (synthesis_result
)
30905 else if (!expr_gen
.valid_operator(o0
,f0
))
30906 return error_node();
30907 else if (!expr_gen
.valid_operator(o1
,f1
))
30908 return error_node();
30910 return node_type::allocate(*(expr_gen
.node_allocator_
), v
, c0
, c1
, f0
, f1
);
30913 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
30914 const details::operator_type o0
, const details::operator_type o1
)
30916 return details::build_string()
30917 << "(t" << expr_gen
.to_str(o0
)
30918 << "t)" << expr_gen
.to_str(o1
)
30923 struct synthesize_vococ_expression1
30925 typedef typename
vococ_t::type0 node_type
;
30927 static inline expression_node_ptr
process(expression_generator
<Type
>&, const details::operator_type
&, expression_node_ptr (&)[2])
30929 // (v) o0 (c0 o1 c1) - Not possible.
30930 exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n"));
30931 return error_node();
30935 struct synthesize_vovovov_expression0
30937 typedef typename
vovovov_t::type0 node_type
;
30938 typedef typename
vovovov_t::sf4_type sf4_type
;
30939 typedef typename
node_type::T0 T0
;
30940 typedef typename
node_type::T1 T1
;
30941 typedef typename
node_type::T2 T2
;
30942 typedef typename
node_type::T3 T3
;
30944 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
30945 const details::operator_type
& operation
,
30946 expression_node_ptr (&branch
)[2])
30948 // (v0 o0 v1) o1 (v2 o2 v3)
30949 const details::vov_base_node
<Type
>* vov0
= static_cast<details::vov_base_node
<Type
>*>(branch
[0]);
30950 const details::vov_base_node
<Type
>* vov1
= static_cast<details::vov_base_node
<Type
>*>(branch
[1]);
30951 const Type
& v0
= vov0
->v0();
30952 const Type
& v1
= vov0
->v1();
30953 const Type
& v2
= vov1
->v0();
30954 const Type
& v3
= vov1
->v1();
30955 const details::operator_type o0
= vov0
->operation();
30956 const details::operator_type o1
= operation
;
30957 const details::operator_type o2
= vov1
->operation();
30959 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
30960 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
30961 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
30963 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
30964 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
30966 expression_node_ptr result
= error_node();
30968 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
30970 // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)
30971 if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
30973 const bool synthesis_result
=
30974 synthesize_sf4ext_expression::
30975 template compile
<vtype
,vtype
,vtype
,vtype
>(expr_gen
, "(t*t)/(t*t)", v0
, v2
, v1
, v3
, result
);
30977 exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
30979 return (synthesis_result
) ? result
: error_node();
30981 // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)
30982 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
30984 const bool synthesis_result
=
30985 synthesize_sf4ext_expression::
30986 template compile
<vtype
,vtype
,vtype
,vtype
>(expr_gen
, "(t*t)/(t*t)", v0
, v3
, v1
, v2
, result
);
30988 exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
30990 return (synthesis_result
) ? result
: error_node();
30992 // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
30993 else if ((details::e_add
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
30995 const bool synthesis_result
=
30996 synthesize_sf4ext_expression::
30997 template compile
<vtype
,vtype
,vtype
,vtype
>(expr_gen
, "(t+t)*(t/t)", v0
, v1
, v3
, v2
, result
);
30999 exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
31001 return (synthesis_result
) ? result
: error_node();
31003 // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
31004 else if ((details::e_sub
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31006 const bool synthesis_result
=
31007 synthesize_sf4ext_expression::
31008 template compile
<vtype
,vtype
,vtype
,vtype
>(expr_gen
, "(t-t)*(t/t)", v0
, v1
, v3
, v2
, result
);
31010 exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
31012 return (synthesis_result
) ? result
: error_node();
31014 // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2
31015 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31017 const bool synthesis_result
=
31018 synthesize_sf4ext_expression::
31019 template compile
<vtype
,vtype
,vtype
,vtype
>(expr_gen
, "((t*t)*t)/t", v0
, v1
, v3
, v2
, result
);
31021 exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
31023 return (synthesis_result
) ? result
: error_node();
31027 const bool synthesis_result
=
31028 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
31029 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, v3
, result
);
31031 if (synthesis_result
)
31033 else if (!expr_gen
.valid_operator(o0
,f0
))
31034 return error_node();
31035 else if (!expr_gen
.valid_operator(o1
,f1
))
31036 return error_node();
31037 else if (!expr_gen
.valid_operator(o2
,f2
))
31038 return error_node();
31040 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, v3
, f0
, f1
, f2
);
31043 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
31044 const details::operator_type o0
,
31045 const details::operator_type o1
,
31046 const details::operator_type o2
)
31048 return details::build_string()
31049 << "(t" << expr_gen
.to_str(o0
)
31050 << "t)" << expr_gen
.to_str(o1
)
31051 << "(t" << expr_gen
.to_str(o2
)
31056 struct synthesize_vovovoc_expression0
31058 typedef typename
vovovoc_t::type0 node_type
;
31059 typedef typename
vovovoc_t::sf4_type sf4_type
;
31060 typedef typename
node_type::T0 T0
;
31061 typedef typename
node_type::T1 T1
;
31062 typedef typename
node_type::T2 T2
;
31063 typedef typename
node_type::T3 T3
;
31065 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
31066 const details::operator_type
& operation
,
31067 expression_node_ptr (&branch
)[2])
31069 // (v0 o0 v1) o1 (v2 o2 c)
31070 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[0]);
31071 const details::voc_base_node
<Type
>* voc
= static_cast<details::voc_base_node
<Type
>*>(branch
[1]);
31072 const Type
& v0
= vov
->v0();
31073 const Type
& v1
= vov
->v1();
31074 const Type
& v2
= voc
->v ();
31075 const Type c
= voc
->c ();
31076 const details::operator_type o0
= vov
->operation();
31077 const details::operator_type o1
= operation
;
31078 const details::operator_type o2
= voc
->operation();
31080 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
31081 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
31082 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
31084 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
31085 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
31087 expression_node_ptr result
= error_node();
31089 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
31091 // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)
31092 if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
31094 const bool synthesis_result
=
31095 synthesize_sf4ext_expression::
31096 template compile
<vtype
,vtype
,vtype
,ctype
>(expr_gen
, "(t*t)/(t*t)", v0
, v2
, v1
, c
, result
);
31098 exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
31100 return (synthesis_result
) ? result
: error_node();
31102 // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)
31103 if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31105 const bool synthesis_result
=
31106 synthesize_sf4ext_expression::
31107 template compile
<vtype
,ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/(t*t)", v0
, c
, v1
, v2
, result
);
31109 exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
31111 return (synthesis_result
) ? result
: error_node();
31115 const bool synthesis_result
=
31116 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
31117 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, c
, result
);
31119 if (synthesis_result
)
31121 else if (!expr_gen
.valid_operator(o0
,f0
))
31122 return error_node();
31123 else if (!expr_gen
.valid_operator(o1
,f1
))
31124 return error_node();
31125 else if (!expr_gen
.valid_operator(o2
,f2
))
31126 return error_node();
31128 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, c
, f0
, f1
, f2
);
31131 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
31132 const details::operator_type o0
,
31133 const details::operator_type o1
,
31134 const details::operator_type o2
)
31136 return details::build_string()
31137 << "(t" << expr_gen
.to_str(o0
)
31138 << "t)" << expr_gen
.to_str(o1
)
31139 << "(t" << expr_gen
.to_str(o2
)
31144 struct synthesize_vovocov_expression0
31146 typedef typename
vovocov_t::type0 node_type
;
31147 typedef typename
vovocov_t::sf4_type sf4_type
;
31148 typedef typename
node_type::T0 T0
;
31149 typedef typename
node_type::T1 T1
;
31150 typedef typename
node_type::T2 T2
;
31151 typedef typename
node_type::T3 T3
;
31153 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
31154 const details::operator_type
& operation
,
31155 expression_node_ptr (&branch
)[2])
31157 // (v0 o0 v1) o1 (c o2 v2)
31158 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[0]);
31159 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[1]);
31160 const Type
& v0
= vov
->v0();
31161 const Type
& v1
= vov
->v1();
31162 const Type
& v2
= cov
->v ();
31163 const Type c
= cov
->c ();
31164 const details::operator_type o0
= vov
->operation();
31165 const details::operator_type o1
= operation
;
31166 const details::operator_type o2
= cov
->operation();
31168 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
31169 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
31170 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
31172 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
31173 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
31175 expression_node_ptr result
= error_node();
31177 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
31179 // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)
31180 if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
31182 const bool synthesis_result
=
31183 synthesize_sf4ext_expression::
31184 template compile
<vtype
,ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/(t*t)", v0
, c
, v1
, v2
, result
);
31186 exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
31188 return (synthesis_result
) ? result
: error_node();
31190 // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)
31191 if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31193 const bool synthesis_result
=
31194 synthesize_sf4ext_expression::
31195 template compile
<vtype
,vtype
,vtype
,ctype
>(expr_gen
, "(t*t)/(t*t)", v0
, v2
, v1
, c
, result
);
31197 exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
31199 return (synthesis_result
) ? result
: error_node();
31203 const bool synthesis_result
=
31204 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
31205 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, c
, v2
, result
);
31207 if (synthesis_result
)
31209 else if (!expr_gen
.valid_operator(o0
,f0
))
31210 return error_node();
31211 else if (!expr_gen
.valid_operator(o1
,f1
))
31212 return error_node();
31213 else if (!expr_gen
.valid_operator(o2
,f2
))
31214 return error_node();
31216 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, c
, v2
, f0
, f1
, f2
);
31219 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
31220 const details::operator_type o0
,
31221 const details::operator_type o1
,
31222 const details::operator_type o2
)
31224 return details::build_string()
31225 << "(t" << expr_gen
.to_str(o0
)
31226 << "t)" << expr_gen
.to_str(o1
)
31227 << "(t" << expr_gen
.to_str(o2
)
31232 struct synthesize_vocovov_expression0
31234 typedef typename
vocovov_t::type0 node_type
;
31235 typedef typename
vocovov_t::sf4_type sf4_type
;
31236 typedef typename
node_type::T0 T0
;
31237 typedef typename
node_type::T1 T1
;
31238 typedef typename
node_type::T2 T2
;
31239 typedef typename
node_type::T3 T3
;
31241 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
31242 const details::operator_type
& operation
,
31243 expression_node_ptr (&branch
)[2])
31245 // (v0 o0 c) o1 (v1 o2 v2)
31246 const details::voc_base_node
<Type
>* voc
= static_cast<details::voc_base_node
<Type
>*>(branch
[0]);
31247 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[1]);
31248 const Type c
= voc
->c ();
31249 const Type
& v0
= voc
->v ();
31250 const Type
& v1
= vov
->v0();
31251 const Type
& v2
= vov
->v1();
31252 const details::operator_type o0
= voc
->operation();
31253 const details::operator_type o1
= operation
;
31254 const details::operator_type o2
= vov
->operation();
31256 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
31257 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
31258 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
31260 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
31261 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
31263 expression_node_ptr result
= error_node();
31265 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
31267 // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)
31268 if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
31270 const bool synthesis_result
=
31271 synthesize_sf4ext_expression::
31272 template compile
<vtype
,vtype
,ctype
,vtype
>(expr_gen
, "(t*t)/(t*t)", v0
, v1
, c
, v2
, result
);
31274 exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
31276 return (synthesis_result
) ? result
: error_node();
31278 // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)
31279 if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31281 const bool synthesis_result
=
31282 synthesize_sf4ext_expression::
31283 template compile
<vtype
,vtype
,ctype
,vtype
>(expr_gen
, "(t*t)/(t*t)", v0
, v2
, c
, v1
, result
);
31285 exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
31287 return (synthesis_result
) ? result
: error_node();
31291 const bool synthesis_result
=
31292 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
31293 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c
, v1
, v2
, result
);
31295 if (synthesis_result
)
31297 else if (!expr_gen
.valid_operator(o0
,f0
))
31298 return error_node();
31299 else if (!expr_gen
.valid_operator(o1
,f1
))
31300 return error_node();
31301 else if (!expr_gen
.valid_operator(o2
,f2
))
31302 return error_node();
31304 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c
, v1
, v2
, f0
, f1
, f2
);
31307 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
31308 const details::operator_type o0
,
31309 const details::operator_type o1
,
31310 const details::operator_type o2
)
31312 return details::build_string()
31313 << "(t" << expr_gen
.to_str(o0
)
31314 << "t)" << expr_gen
.to_str(o1
)
31315 << "(t" << expr_gen
.to_str(o2
)
31320 struct synthesize_covovov_expression0
31322 typedef typename
covovov_t::type0 node_type
;
31323 typedef typename
covovov_t::sf4_type sf4_type
;
31324 typedef typename
node_type::T0 T0
;
31325 typedef typename
node_type::T1 T1
;
31326 typedef typename
node_type::T2 T2
;
31327 typedef typename
node_type::T3 T3
;
31329 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
31330 const details::operator_type
& operation
,
31331 expression_node_ptr (&branch
)[2])
31333 // (c o0 v0) o1 (v1 o2 v2)
31334 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[0]);
31335 const details::vov_base_node
<Type
>* vov
= static_cast<details::vov_base_node
<Type
>*>(branch
[1]);
31336 const Type c
= cov
->c ();
31337 const Type
& v0
= cov
->v ();
31338 const Type
& v1
= vov
->v0();
31339 const Type
& v2
= vov
->v1();
31340 const details::operator_type o0
= cov
->operation();
31341 const details::operator_type o1
= operation
;
31342 const details::operator_type o2
= vov
->operation();
31344 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
31345 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
31346 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
31348 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
31349 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
31351 expression_node_ptr result
= error_node();
31353 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
31355 // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)
31356 if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
31358 const bool synthesis_result
=
31359 synthesize_sf4ext_expression::
31360 template compile
<ctype
,vtype
,vtype
,vtype
>(expr_gen
, "(t*t)/(t*t)", c
, v1
, v0
, v2
, result
);
31362 exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
31364 return (synthesis_result
) ? result
: error_node();
31366 // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)
31367 if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31369 const bool synthesis_result
=
31370 synthesize_sf4ext_expression::
31371 template compile
<ctype
,vtype
,vtype
,vtype
>(expr_gen
, "(t*t)/(t*t)", c
, v2
, v0
, v1
, result
);
31373 exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
31375 return (synthesis_result
) ? result
: error_node();
31379 const bool synthesis_result
=
31380 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
31381 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c
, v0
, v1
, v2
, result
);
31383 if (synthesis_result
)
31385 else if (!expr_gen
.valid_operator(o0
,f0
))
31386 return error_node();
31387 else if (!expr_gen
.valid_operator(o1
,f1
))
31388 return error_node();
31389 else if (!expr_gen
.valid_operator(o2
,f2
))
31390 return error_node();
31392 return node_type::allocate(*(expr_gen
.node_allocator_
), c
, v0
, v1
, v2
, f0
, f1
, f2
);
31395 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
31396 const details::operator_type o0
,
31397 const details::operator_type o1
,
31398 const details::operator_type o2
)
31400 return details::build_string()
31401 << "(t" << expr_gen
.to_str(o0
)
31402 << "t)" << expr_gen
.to_str(o1
)
31403 << "(t" << expr_gen
.to_str(o2
)
31408 struct synthesize_covocov_expression0
31410 typedef typename
covocov_t::type0 node_type
;
31411 typedef typename
covocov_t::sf4_type sf4_type
;
31412 typedef typename
node_type::T0 T0
;
31413 typedef typename
node_type::T1 T1
;
31414 typedef typename
node_type::T2 T2
;
31415 typedef typename
node_type::T3 T3
;
31417 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
31418 const details::operator_type
& operation
,
31419 expression_node_ptr (&branch
)[2])
31421 // (c0 o0 v0) o1 (c1 o2 v1)
31422 const details::cov_base_node
<Type
>* cov0
= static_cast<details::cov_base_node
<Type
>*>(branch
[0]);
31423 const details::cov_base_node
<Type
>* cov1
= static_cast<details::cov_base_node
<Type
>*>(branch
[1]);
31424 const Type c0
= cov0
->c();
31425 const Type
& v0
= cov0
->v();
31426 const Type c1
= cov1
->c();
31427 const Type
& v1
= cov1
->v();
31428 const details::operator_type o0
= cov0
->operation();
31429 const details::operator_type o1
= operation
;
31430 const details::operator_type o2
= cov1
->operation();
31432 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
31433 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
31434 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
31436 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
31437 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
31439 expression_node_ptr result
= error_node();
31441 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
31443 // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
31444 if ((details::e_add
== o0
) && (details::e_add
== o1
) && (details::e_add
== o2
))
31446 const bool synthesis_result
=
31447 synthesize_sf3ext_expression::
31448 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)+t", (c0
+ c1
), v0
, v1
, result
);
31450 exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
31452 return (synthesis_result
) ? result
: error_node();
31454 // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
31455 else if ((details::e_add
== o0
) && (details::e_sub
== o1
) && (details::e_add
== o2
))
31457 const bool synthesis_result
=
31458 synthesize_sf3ext_expression::
31459 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)-t", (c0
- c1
), v0
, v1
, result
);
31461 exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
31463 return (synthesis_result
) ? result
: error_node();
31465 // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1
31466 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
) && (details::e_sub
== o2
))
31468 const bool synthesis_result
=
31469 synthesize_sf3ext_expression::
31470 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t-t)+t", (c0
- c1
), v0
, v1
, result
);
31472 exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
31474 return (synthesis_result
) ? result
: error_node();
31476 // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
31477 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
) && (details::e_mul
== o2
))
31479 const bool synthesis_result
=
31480 synthesize_sf3ext_expression::
31481 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)*t", (c0
* c1
), v0
, v1
, result
);
31483 exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
31485 return (synthesis_result
) ? result
: error_node();
31487 // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)
31488 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
31490 const bool synthesis_result
=
31491 synthesize_sf3ext_expression::
31492 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c0
/ c1
), v0
, v1
, result
);
31494 exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
31496 return (synthesis_result
) ? result
: error_node();
31498 // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)
31499 else if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
31501 const bool synthesis_result
=
31502 synthesize_sf3ext_expression::
31503 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t/(t*t)", (c0
* c1
), v0
, v1
, result
);
31505 exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
31507 return (synthesis_result
) ? result
: error_node();
31509 // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0
31510 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31512 const bool synthesis_result
=
31513 synthesize_sf3ext_expression::
31514 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c0
/ c1
), v1
, v0
, result
);
31516 exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
31518 return (synthesis_result
) ? result
: error_node();
31520 // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
31521 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31523 const bool synthesis_result
=
31524 synthesize_sf3ext_expression::
31525 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t*(t*t)", (c0
/ c1
), v0
, v1
, result
);
31527 exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
31529 return (synthesis_result
) ? result
: error_node();
31531 // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)
31532 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
31534 const bool synthesis_result
=
31535 synthesize_sf3ext_expression::
31536 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t/(t*t)", (c0
/ c1
), v0
, v1
, result
);
31538 exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
31540 return (synthesis_result
) ? result
: error_node();
31542 // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)
31544 (std::equal_to
<T
>()(c0
,c1
)) &&
31545 (details::e_mul
== o0
) &&
31546 (details::e_mul
== o2
) &&
31548 (details::e_add
== o1
) ||
31549 (details::e_sub
== o1
)
31553 std::string specfunc
;
31557 case details::e_add
: specfunc
= "t*(t+t)"; break;
31558 case details::e_sub
: specfunc
= "t*(t-t)"; break;
31559 default : return error_node();
31562 const bool synthesis_result
=
31563 synthesize_sf3ext_expression::
31564 template compile
<ctype
, vtype
, vtype
>(expr_gen
, specfunc
, c0
, v0
, v1
, result
);
31566 exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
31568 return (synthesis_result
) ? result
: error_node();
31572 const bool synthesis_result
=
31573 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
31574 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, c1
, v1
, result
);
31576 if (synthesis_result
)
31578 else if (!expr_gen
.valid_operator(o0
,f0
))
31579 return error_node();
31580 else if (!expr_gen
.valid_operator(o1
,f1
))
31581 return error_node();
31582 else if (!expr_gen
.valid_operator(o2
,f2
))
31583 return error_node();
31585 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, c1
, v1
, f0
, f1
, f2
);
31588 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
31589 const details::operator_type o0
,
31590 const details::operator_type o1
,
31591 const details::operator_type o2
)
31593 return details::build_string()
31594 << "(t" << expr_gen
.to_str(o0
)
31595 << "t)" << expr_gen
.to_str(o1
)
31596 << "(t" << expr_gen
.to_str(o2
)
31601 struct synthesize_vocovoc_expression0
31603 typedef typename
vocovoc_t::type0 node_type
;
31604 typedef typename
vocovoc_t::sf4_type sf4_type
;
31605 typedef typename
node_type::T0 T0
;
31606 typedef typename
node_type::T1 T1
;
31607 typedef typename
node_type::T2 T2
;
31608 typedef typename
node_type::T3 T3
;
31610 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
31611 const details::operator_type
& operation
,
31612 expression_node_ptr (&branch
)[2])
31614 // (v0 o0 c0) o1 (v1 o2 c1)
31615 const details::voc_base_node
<Type
>* voc0
= static_cast<details::voc_base_node
<Type
>*>(branch
[0]);
31616 const details::voc_base_node
<Type
>* voc1
= static_cast<details::voc_base_node
<Type
>*>(branch
[1]);
31617 const Type c0
= voc0
->c();
31618 const Type
& v0
= voc0
->v();
31619 const Type c1
= voc1
->c();
31620 const Type
& v1
= voc1
->v();
31621 const details::operator_type o0
= voc0
->operation();
31622 const details::operator_type o1
= operation
;
31623 const details::operator_type o2
= voc1
->operation();
31625 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
31626 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
31627 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
31629 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
31630 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
31632 expression_node_ptr result
= error_node();
31634 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
31636 // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
31637 if ((details::e_add
== o0
) && (details::e_add
== o1
) && (details::e_add
== o2
))
31639 const bool synthesis_result
=
31640 synthesize_sf3ext_expression::
31641 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)+t", (c0
+ c1
), v0
, v1
, result
);
31643 exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
31645 return (synthesis_result
) ? result
: error_node();
31647 // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
31648 else if ((details::e_add
== o0
) && (details::e_sub
== o1
) && (details::e_add
== o2
))
31650 const bool synthesis_result
=
31651 synthesize_sf3ext_expression::
31652 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)-t", (c0
- c1
), v0
, v1
, result
);
31654 exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
31656 return (synthesis_result
) ? result
: error_node();
31658 // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1
31659 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
) && (details::e_sub
== o2
))
31661 const bool synthesis_result
=
31662 synthesize_sf3ext_expression::
31663 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)-t", (c1
- c0
), v0
, v1
, result
);
31665 exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
31667 return (synthesis_result
) ? result
: error_node();
31669 // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
31670 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
) && (details::e_mul
== o2
))
31672 const bool synthesis_result
=
31673 synthesize_sf3ext_expression::
31674 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)*t", (c0
* c1
), v0
, v1
, result
);
31676 exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
31678 return (synthesis_result
) ? result
: error_node();
31680 // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
31681 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
31683 const bool synthesis_result
=
31684 synthesize_sf3ext_expression::
31685 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c0
/ c1
), v0
, v1
, result
);
31687 exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
31689 return (synthesis_result
) ? result
: error_node();
31691 // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1
31692 else if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
31694 const bool synthesis_result
=
31695 synthesize_sf3ext_expression::
31696 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)*t", Type(1) / (c0
* c1
), v0
, v1
, result
);
31698 exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
31700 return (synthesis_result
) ? result
: error_node();
31702 // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1
31703 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31705 const bool synthesis_result
=
31706 synthesize_sf3ext_expression::
31707 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c1
/ c0
), v0
, v1
, result
);
31709 exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
31711 return (synthesis_result
) ? result
: error_node();
31713 // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
31714 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31716 const bool synthesis_result
=
31717 synthesize_sf3ext_expression::
31718 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t*(t/t)", (c0
* c1
), v0
, v1
, result
);
31720 exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
31722 return (synthesis_result
) ? result
: error_node();
31724 // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1
31725 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
31727 const bool synthesis_result
=
31728 synthesize_sf3ext_expression::
31729 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t*(t/t)", Type(1) / (c0
* c1
), v0
, v1
, result
);
31731 exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
31733 return (synthesis_result
) ? result
: error_node();
31735 // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)
31736 else if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_add
== o2
))
31738 const bool synthesis_result
=
31739 synthesize_sf4ext_expression::
31740 template compile
<vtype
,ctype
,vtype
,ctype
>(expr_gen
, "(t*t)*(t+t)", v0
, T(1) / c0
, v1
, c1
, result
);
31742 exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
31744 return (synthesis_result
) ? result
: error_node();
31746 // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)
31747 else if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_sub
== o2
))
31749 const bool synthesis_result
=
31750 synthesize_sf4ext_expression::
31751 template compile
<vtype
,ctype
,vtype
,ctype
>(expr_gen
, "(t*t)*(t-t)", v0
, T(1) / c0
, v1
, c1
, result
);
31753 exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
31755 return (synthesis_result
) ? result
: error_node();
31757 // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
31759 (std::equal_to
<T
>()(c0
,c1
)) &&
31760 (details::e_mul
== o0
) &&
31761 (details::e_mul
== o2
) &&
31763 (details::e_add
== o1
) ||
31764 (details::e_sub
== o1
)
31768 std::string specfunc
;
31772 case details::e_add
: specfunc
= "t*(t+t)"; break;
31773 case details::e_sub
: specfunc
= "t*(t-t)"; break;
31774 default : return error_node();
31777 const bool synthesis_result
=
31778 synthesize_sf3ext_expression::
31779 template compile
<ctype
,vtype
,vtype
>(expr_gen
, specfunc
, c0
, v0
, v1
, result
);
31781 exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
31783 return (synthesis_result
) ? result
: error_node();
31785 // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c
31787 (std::equal_to
<T
>()(c0
,c1
)) &&
31788 (details::e_div
== o0
) &&
31789 (details::e_div
== o2
) &&
31791 (details::e_add
== o1
) ||
31792 (details::e_sub
== o1
)
31796 std::string specfunc
;
31800 case details::e_add
: specfunc
= "(t+t)/t"; break;
31801 case details::e_sub
: specfunc
= "(t-t)/t"; break;
31802 default : return error_node();
31805 const bool synthesis_result
=
31806 synthesize_sf3ext_expression::
31807 template compile
<vtype
,vtype
,ctype
>(expr_gen
, specfunc
, v0
, v1
, c0
, result
);
31809 exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
31811 return (synthesis_result
) ? result
: error_node();
31815 const bool synthesis_result
=
31816 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
31817 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, v1
, c1
, result
);
31819 if (synthesis_result
)
31821 else if (!expr_gen
.valid_operator(o0
,f0
))
31822 return error_node();
31823 else if (!expr_gen
.valid_operator(o1
,f1
))
31824 return error_node();
31825 else if (!expr_gen
.valid_operator(o2
,f2
))
31826 return error_node();
31828 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, v1
, c1
, f0
, f1
, f2
);
31831 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
31832 const details::operator_type o0
,
31833 const details::operator_type o1
,
31834 const details::operator_type o2
)
31836 return details::build_string()
31837 << "(t" << expr_gen
.to_str(o0
)
31838 << "t)" << expr_gen
.to_str(o1
)
31839 << "(t" << expr_gen
.to_str(o2
)
31844 struct synthesize_covovoc_expression0
31846 typedef typename
covovoc_t::type0 node_type
;
31847 typedef typename
covovoc_t::sf4_type sf4_type
;
31848 typedef typename
node_type::T0 T0
;
31849 typedef typename
node_type::T1 T1
;
31850 typedef typename
node_type::T2 T2
;
31851 typedef typename
node_type::T3 T3
;
31853 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
31854 const details::operator_type
& operation
,
31855 expression_node_ptr (&branch
)[2])
31857 // (c0 o0 v0) o1 (v1 o2 c1)
31858 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[0]);
31859 const details::voc_base_node
<Type
>* voc
= static_cast<details::voc_base_node
<Type
>*>(branch
[1]);
31860 const Type c0
= cov
->c();
31861 const Type
& v0
= cov
->v();
31862 const Type c1
= voc
->c();
31863 const Type
& v1
= voc
->v();
31864 const details::operator_type o0
= cov
->operation();
31865 const details::operator_type o1
= operation
;
31866 const details::operator_type o2
= voc
->operation();
31868 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
31869 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
31870 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
31872 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
31873 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
31875 expression_node_ptr result
= error_node();
31877 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
31879 // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
31880 if ((details::e_add
== o0
) && (details::e_add
== o1
) && (details::e_add
== o2
))
31882 const bool synthesis_result
=
31883 synthesize_sf3ext_expression::
31884 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)+t", (c0
+ c1
), v0
, v1
, result
);
31886 exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
31888 return (synthesis_result
) ? result
: error_node();
31890 // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
31891 else if ((details::e_add
== o0
) && (details::e_sub
== o1
) && (details::e_add
== o2
))
31893 const bool synthesis_result
=
31894 synthesize_sf3ext_expression::
31895 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)-t", (c0
- c1
), v0
, v1
, result
);
31897 exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
31899 return (synthesis_result
) ? result
: error_node();
31901 // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1
31902 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
) && (details::e_sub
== o2
))
31904 const bool synthesis_result
=
31905 synthesize_sf3ext_expression::
31906 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t-(t+t)", (c0
+ c1
), v0
, v1
, result
);
31908 exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
31910 return (synthesis_result
) ? result
: error_node();
31912 // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
31913 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
) && (details::e_mul
== o2
))
31915 const bool synthesis_result
=
31916 synthesize_sf3ext_expression::
31917 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)*t", (c0
* c1
), v0
, v1
, result
);
31919 exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
31921 return (synthesis_result
) ? result
: error_node();
31923 // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
31924 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
31926 const bool synthesis_result
=
31927 synthesize_sf3ext_expression::
31928 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c0
/ c1
), v0
, v1
, result
);
31930 exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
31932 return (synthesis_result
) ? result
: error_node();
31934 // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)
31935 else if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
31937 const bool synthesis_result
=
31938 synthesize_sf3ext_expression::
31939 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t*(t/t)", (c0
/ c1
), v1
, v0
, result
);
31941 exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
31943 return (synthesis_result
) ? result
: error_node();
31945 // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)
31946 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31948 const bool synthesis_result
=
31949 synthesize_sf3ext_expression::
31950 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t/(t*t)", (c0
* c1
), v0
, v1
, result
);
31952 exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
31954 return (synthesis_result
) ? result
: error_node();
31956 // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
31957 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
31959 const bool synthesis_result
=
31960 synthesize_sf3ext_expression::
31961 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c0
* c1
), v0
, v1
, result
);
31963 exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
31965 return (synthesis_result
) ? result
: error_node();
31967 // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)
31968 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
31970 const bool synthesis_result
=
31971 synthesize_sf3ext_expression::
31972 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "t/(t*t)", (c0
/ c1
), v0
, v1
, result
);
31974 exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
31976 return (synthesis_result
) ? result
: error_node();
31978 // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
31980 (std::equal_to
<T
>()(c0
,c1
)) &&
31981 (details::e_mul
== o0
) &&
31982 (details::e_mul
== o2
) &&
31984 (details::e_add
== o1
) ||
31985 (details::e_sub
== o1
)
31989 std::string specfunc
;
31993 case details::e_add
: specfunc
= "t*(t+t)"; break;
31994 case details::e_sub
: specfunc
= "t*(t-t)"; break;
31995 default : return error_node();
31998 const bool synthesis_result
=
31999 synthesize_sf3ext_expression::
32000 template compile
<ctype
,vtype
,vtype
>(expr_gen
,specfunc
, c0
, v0
, v1
, result
);
32002 exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
32004 return (synthesis_result
) ? result
: error_node();
32008 const bool synthesis_result
=
32009 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32010 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, v1
, c1
, result
);
32012 if (synthesis_result
)
32014 else if (!expr_gen
.valid_operator(o0
,f0
))
32015 return error_node();
32016 else if (!expr_gen
.valid_operator(o1
,f1
))
32017 return error_node();
32018 else if (!expr_gen
.valid_operator(o2
,f2
))
32019 return error_node();
32021 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, v1
, c1
, f0
, f1
, f2
);
32024 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32025 const details::operator_type o0
,
32026 const details::operator_type o1
,
32027 const details::operator_type o2
)
32029 return details::build_string()
32030 << "(t" << expr_gen
.to_str(o0
)
32031 << "t)" << expr_gen
.to_str(o1
)
32032 << "(t" << expr_gen
.to_str(o2
)
32037 struct synthesize_vococov_expression0
32039 typedef typename
vococov_t::type0 node_type
;
32040 typedef typename
vococov_t::sf4_type sf4_type
;
32041 typedef typename
node_type::T0 T0
;
32042 typedef typename
node_type::T1 T1
;
32043 typedef typename
node_type::T2 T2
;
32044 typedef typename
node_type::T3 T3
;
32046 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32047 const details::operator_type
& operation
,
32048 expression_node_ptr (&branch
)[2])
32050 // (v0 o0 c0) o1 (c1 o2 v1)
32051 const details::voc_base_node
<Type
>* voc
= static_cast<details::voc_base_node
<Type
>*>(branch
[0]);
32052 const details::cov_base_node
<Type
>* cov
= static_cast<details::cov_base_node
<Type
>*>(branch
[1]);
32053 const Type c0
= voc
->c();
32054 const Type
& v0
= voc
->v();
32055 const Type c1
= cov
->c();
32056 const Type
& v1
= cov
->v();
32057 const details::operator_type o0
= voc
->operation();
32058 const details::operator_type o1
= operation
;
32059 const details::operator_type o2
= cov
->operation();
32061 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32062 binary_functor_t f1
= reinterpret_cast<binary_functor_t
>(0);
32063 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
32065 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
32066 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32068 expression_node_ptr result
= error_node();
32070 if (expr_gen
.parser_
->settings_
.strength_reduction_enabled())
32072 // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
32073 if ((details::e_add
== o0
) && (details::e_add
== o1
) && (details::e_add
== o2
))
32075 const bool synthesis_result
=
32076 synthesize_sf3ext_expression::
32077 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)+t", (c0
+ c1
), v0
, v1
, result
);
32079 exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
32081 return (synthesis_result
) ? result
: error_node();
32083 // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
32084 else if ((details::e_add
== o0
) && (details::e_sub
== o1
) && (details::e_add
== o2
))
32086 const bool synthesis_result
=
32087 synthesize_sf3ext_expression::
32088 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t+t)-t", (c0
- c1
), v0
, v1
, result
);
32090 exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
32092 return (synthesis_result
) ? result
: error_node();
32094 // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)
32095 else if ((details::e_sub
== o0
) && (details::e_sub
== o1
) && (details::e_sub
== o2
))
32097 const bool synthesis_result
=
32098 synthesize_sf3ext_expression::
32099 template compile
<vtype
,vtype
,ctype
>(expr_gen
, "(t+t)-t", v0
, v1
, (c1
+ c0
), result
);
32101 exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
32103 return (synthesis_result
) ? result
: error_node();
32105 // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
32106 else if ((details::e_mul
== o0
) && (details::e_mul
== o1
) && (details::e_mul
== o2
))
32108 const bool synthesis_result
=
32109 synthesize_sf3ext_expression::
32110 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)*t", (c0
* c1
), v0
, v1
, result
);
32112 exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
32114 return (synthesis_result
) ? result
: error_node();
32116 // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)
32117 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
32119 const bool synthesis_result
=
32120 synthesize_sf3ext_expression::
32121 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c0
/ c1
), v0
, v1
, result
);
32123 exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
32125 return (synthesis_result
) ? result
: error_node();
32127 // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)
32128 else if ((details::e_div
== o0
) && (details::e_mul
== o1
) && (details::e_div
== o2
))
32130 const bool synthesis_result
=
32131 synthesize_sf3ext_expression::
32132 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", (c1
/ c0
), v0
, v1
, result
);
32134 exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
32136 return (synthesis_result
) ? result
: error_node();
32138 // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
32139 else if ((details::e_mul
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
32141 const bool synthesis_result
=
32142 synthesize_sf3ext_expression::
32143 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)*t", (c0
/ c1
), v0
, v1
, result
);
32145 exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
32147 return (synthesis_result
) ? result
: error_node();
32149 // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)
32150 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_mul
== o2
))
32152 const bool synthesis_result
=
32153 synthesize_sf3ext_expression::
32154 template compile
<ctype
,vtype
,vtype
>(expr_gen
, "(t*t)/t", Type(1) / (c0
* c1
), v0
, v1
, result
);
32156 exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
32158 return (synthesis_result
) ? result
: error_node();
32160 // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))
32161 else if ((details::e_div
== o0
) && (details::e_div
== o1
) && (details::e_div
== o2
))
32163 const bool synthesis_result
=
32164 synthesize_sf3ext_expression::
32165 template compile
<vtype
,vtype
,ctype
>(expr_gen
, "(t*t)*t", v0
, v1
, Type(1) / (c0
* c1
), result
);
32167 exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
32169 return (synthesis_result
) ? result
: error_node();
32171 // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)
32173 (std::equal_to
<T
>()(c0
,c1
)) &&
32174 (details::e_mul
== o0
) &&
32175 (details::e_mul
== o2
) &&
32177 (details::e_add
== o1
) || (details::e_sub
== o1
)
32181 std::string specfunc
;
32185 case details::e_add
: specfunc
= "t*(t+t)"; break;
32186 case details::e_sub
: specfunc
= "t*(t-t)"; break;
32187 default : return error_node();
32190 const bool synthesis_result
=
32191 synthesize_sf3ext_expression::
32192 template compile
<ctype
,vtype
,vtype
>(expr_gen
, specfunc
, c0
, v0
, v1
, result
);
32194 exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
32196 return (synthesis_result
) ? result
: error_node();
32200 const bool synthesis_result
=
32201 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32202 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, c1
, v1
, result
);
32204 if (synthesis_result
)
32206 else if (!expr_gen
.valid_operator(o0
,f0
))
32207 return error_node();
32208 else if (!expr_gen
.valid_operator(o1
,f1
))
32209 return error_node();
32210 else if (!expr_gen
.valid_operator(o2
,f2
))
32211 return error_node();
32213 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, c1
, v1
, f0
, f1
, f2
);
32216 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32217 const details::operator_type o0
,
32218 const details::operator_type o1
,
32219 const details::operator_type o2
)
32221 return details::build_string()
32222 << "(t" << expr_gen
.to_str(o0
)
32223 << "t)" << expr_gen
.to_str(o1
)
32224 << "(t" << expr_gen
.to_str(o2
)
32229 struct synthesize_vovovov_expression1
32231 typedef typename
vovovov_t::type1 node_type
;
32232 typedef typename
vovovov_t::sf4_type sf4_type
;
32233 typedef typename
node_type::T0 T0
;
32234 typedef typename
node_type::T1 T1
;
32235 typedef typename
node_type::T2 T2
;
32236 typedef typename
node_type::T3 T3
;
32238 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32239 const details::operator_type
& operation
,
32240 expression_node_ptr (&branch
)[2])
32242 // v0 o0 (v1 o1 (v2 o2 v3))
32243 typedef typename
synthesize_vovov_expression1::node_type lcl_vovov_t
;
32245 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[1]);
32246 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32247 const Type
& v1
= vovov
->t0();
32248 const Type
& v2
= vovov
->t1();
32249 const Type
& v3
= vovov
->t2();
32250 const details::operator_type o0
= operation
;
32251 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f0());
32252 const details::operator_type o2
= expr_gen
.get_operator(vovov
->f1());
32254 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32255 binary_functor_t f1
= vovov
->f0();
32256 binary_functor_t f2
= vovov
->f1();
32258 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32260 expression_node_ptr result
= error_node();
32262 if (synthesize_sf4ext_expression::template compile
<T0
,T1
,T2
,T3
>(expr_gen
,id(expr_gen
,o0
,o1
,o2
),v0
,v1
,v2
,v3
,result
))
32264 else if (!expr_gen
.valid_operator(o0
,f0
))
32265 return error_node();
32267 exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n"));
32269 return node_type::allocate(*(expr_gen
.node_allocator_
),v0
,v1
,v2
,v3
,f0
,f1
,f2
);
32272 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32273 const details::operator_type o0
,
32274 const details::operator_type o1
,
32275 const details::operator_type o2
)
32277 return details::build_string()
32278 << "t" << expr_gen
.to_str(o0
)
32279 << "(t" << expr_gen
.to_str(o1
)
32280 << "(t" << expr_gen
.to_str(o2
)
32285 struct synthesize_vovovoc_expression1
32287 typedef typename
vovovoc_t::type1 node_type
;
32288 typedef typename
vovovoc_t::sf4_type sf4_type
;
32289 typedef typename
node_type::T0 T0
;
32290 typedef typename
node_type::T1 T1
;
32291 typedef typename
node_type::T2 T2
;
32292 typedef typename
node_type::T3 T3
;
32294 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32295 const details::operator_type
& operation
,
32296 expression_node_ptr (&branch
)[2])
32298 // v0 o0 (v1 o1 (v2 o2 c))
32299 typedef typename
synthesize_vovoc_expression1::node_type lcl_vovoc_t
;
32301 const lcl_vovoc_t
* vovoc
= static_cast<const lcl_vovoc_t
*>(branch
[1]);
32302 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32303 const Type
& v1
= vovoc
->t0();
32304 const Type
& v2
= vovoc
->t1();
32305 const Type c
= vovoc
->t2();
32306 const details::operator_type o0
= operation
;
32307 const details::operator_type o1
= expr_gen
.get_operator(vovoc
->f0());
32308 const details::operator_type o2
= expr_gen
.get_operator(vovoc
->f1());
32310 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32311 binary_functor_t f1
= vovoc
->f0();
32312 binary_functor_t f2
= vovoc
->f1();
32314 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32316 expression_node_ptr result
= error_node();
32318 const bool synthesis_result
=
32319 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32320 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, c
, result
);
32322 if (synthesis_result
)
32324 else if (!expr_gen
.valid_operator(o0
,f0
))
32325 return error_node();
32327 exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n"));
32329 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, c
, f0
, f1
, f2
);
32332 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32333 const details::operator_type o0
,
32334 const details::operator_type o1
,
32335 const details::operator_type o2
)
32337 return details::build_string()
32338 << "t" << expr_gen
.to_str(o0
)
32339 << "(t" << expr_gen
.to_str(o1
)
32340 << "(t" << expr_gen
.to_str(o2
)
32345 struct synthesize_vovocov_expression1
32347 typedef typename
vovocov_t::type1 node_type
;
32348 typedef typename
vovocov_t::sf4_type sf4_type
;
32349 typedef typename
node_type::T0 T0
;
32350 typedef typename
node_type::T1 T1
;
32351 typedef typename
node_type::T2 T2
;
32352 typedef typename
node_type::T3 T3
;
32354 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32355 const details::operator_type
& operation
,
32356 expression_node_ptr (&branch
)[2])
32358 // v0 o0 (v1 o1 (c o2 v2))
32359 typedef typename
synthesize_vocov_expression1::node_type lcl_vocov_t
;
32361 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[1]);
32362 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32363 const Type
& v1
= vocov
->t0();
32364 const Type c
= vocov
->t1();
32365 const Type
& v2
= vocov
->t2();
32366 const details::operator_type o0
= operation
;
32367 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f0());
32368 const details::operator_type o2
= expr_gen
.get_operator(vocov
->f1());
32370 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32371 binary_functor_t f1
= vocov
->f0();
32372 binary_functor_t f2
= vocov
->f1();
32374 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32376 expression_node_ptr result
= error_node();
32378 const bool synthesis_result
=
32379 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32380 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, c
, v2
, result
);
32382 if (synthesis_result
)
32384 if (!expr_gen
.valid_operator(o0
,f0
))
32385 return error_node();
32387 exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n"));
32389 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, c
, v2
, f0
, f1
, f2
);
32392 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32393 const details::operator_type o0
,
32394 const details::operator_type o1
,
32395 const details::operator_type o2
)
32397 return details::build_string()
32398 << "t" << expr_gen
.to_str(o0
)
32399 << "(t" << expr_gen
.to_str(o1
)
32400 << "(t" << expr_gen
.to_str(o2
)
32405 struct synthesize_vocovov_expression1
32407 typedef typename
vocovov_t::type1 node_type
;
32408 typedef typename
vocovov_t::sf4_type sf4_type
;
32409 typedef typename
node_type::T0 T0
;
32410 typedef typename
node_type::T1 T1
;
32411 typedef typename
node_type::T2 T2
;
32412 typedef typename
node_type::T3 T3
;
32414 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32415 const details::operator_type
& operation
,
32416 expression_node_ptr (&branch
)[2])
32418 // v0 o0 (c o1 (v1 o2 v2))
32419 typedef typename
synthesize_covov_expression1::node_type lcl_covov_t
;
32421 const lcl_covov_t
* covov
= static_cast<const lcl_covov_t
*>(branch
[1]);
32422 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32423 const Type c
= covov
->t0();
32424 const Type
& v1
= covov
->t1();
32425 const Type
& v2
= covov
->t2();
32426 const details::operator_type o0
= operation
;
32427 const details::operator_type o1
= expr_gen
.get_operator(covov
->f0());
32428 const details::operator_type o2
= expr_gen
.get_operator(covov
->f1());
32430 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32431 binary_functor_t f1
= covov
->f0();
32432 binary_functor_t f2
= covov
->f1();
32434 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32436 expression_node_ptr result
= error_node();
32438 const bool synthesis_result
=
32439 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32440 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c
, v1
, v2
, result
);
32442 if (synthesis_result
)
32444 else if (!expr_gen
.valid_operator(o0
,f0
))
32445 return error_node();
32447 exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n"));
32449 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c
, v1
, v2
, f0
, f1
, f2
);
32452 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32453 const details::operator_type o0
,
32454 const details::operator_type o1
,
32455 const details::operator_type o2
)
32457 return details::build_string()
32458 << "t" << expr_gen
.to_str(o0
)
32459 << "(t" << expr_gen
.to_str(o1
)
32460 << "(t" << expr_gen
.to_str(o2
)
32465 struct synthesize_covovov_expression1
32467 typedef typename
covovov_t::type1 node_type
;
32468 typedef typename
covovov_t::sf4_type sf4_type
;
32469 typedef typename
node_type::T0 T0
;
32470 typedef typename
node_type::T1 T1
;
32471 typedef typename
node_type::T2 T2
;
32472 typedef typename
node_type::T3 T3
;
32474 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32475 const details::operator_type
& operation
,
32476 expression_node_ptr (&branch
)[2])
32478 // c o0 (v0 o1 (v1 o2 v2))
32479 typedef typename
synthesize_vovov_expression1::node_type lcl_vovov_t
;
32481 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[1]);
32482 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
32483 const Type
& v0
= vovov
->t0();
32484 const Type
& v1
= vovov
->t1();
32485 const Type
& v2
= vovov
->t2();
32486 const details::operator_type o0
= operation
;
32487 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f0());
32488 const details::operator_type o2
= expr_gen
.get_operator(vovov
->f1());
32490 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32491 binary_functor_t f1
= vovov
->f0();
32492 binary_functor_t f2
= vovov
->f1();
32494 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
32495 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32497 expression_node_ptr result
= error_node();
32499 const bool synthesis_result
=
32500 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32501 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c
, v0
, v1
, v2
, result
);
32503 if (synthesis_result
)
32505 if (!expr_gen
.valid_operator(o0
,f0
))
32506 return error_node();
32508 exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n"));
32510 return node_type::allocate(*(expr_gen
.node_allocator_
), c
, v0
, v1
, v2
, f0
, f1
, f2
);
32513 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32514 const details::operator_type o0
,
32515 const details::operator_type o1
,
32516 const details::operator_type o2
)
32518 return details::build_string()
32519 << "t" << expr_gen
.to_str(o0
)
32520 << "(t" << expr_gen
.to_str(o1
)
32521 << "(t" << expr_gen
.to_str(o2
)
32526 struct synthesize_covocov_expression1
32528 typedef typename
covocov_t::type1 node_type
;
32529 typedef typename
covocov_t::sf4_type sf4_type
;
32530 typedef typename
node_type::T0 T0
;
32531 typedef typename
node_type::T1 T1
;
32532 typedef typename
node_type::T2 T2
;
32533 typedef typename
node_type::T3 T3
;
32535 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32536 const details::operator_type
& operation
,
32537 expression_node_ptr (&branch
)[2])
32539 // c0 o0 (v0 o1 (c1 o2 v1))
32540 typedef typename
synthesize_vocov_expression1::node_type lcl_vocov_t
;
32542 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[1]);
32543 const Type c0
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
32544 const Type
& v0
= vocov
->t0();
32545 const Type c1
= vocov
->t1();
32546 const Type
& v1
= vocov
->t2();
32547 const details::operator_type o0
= operation
;
32548 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f0());
32549 const details::operator_type o2
= expr_gen
.get_operator(vocov
->f1());
32551 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32552 binary_functor_t f1
= vocov
->f0();
32553 binary_functor_t f2
= vocov
->f1();
32555 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
32556 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32558 expression_node_ptr result
= error_node();
32560 const bool synthesis_result
=
32561 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32562 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, c1
, v1
, result
);
32564 if (synthesis_result
)
32566 else if (!expr_gen
.valid_operator(o0
,f0
))
32567 return error_node();
32569 exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n"));
32571 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, c1
, v1
, f0
, f1
, f2
);
32574 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32575 const details::operator_type o0
,
32576 const details::operator_type o1
,
32577 const details::operator_type o2
)
32579 return details::build_string()
32580 << "t" << expr_gen
.to_str(o0
)
32581 << "(t" << expr_gen
.to_str(o1
)
32582 << "(t" << expr_gen
.to_str(o2
)
32587 struct synthesize_vocovoc_expression1
32589 typedef typename
vocovoc_t::type1 node_type
;
32590 typedef typename
vocovoc_t::sf4_type sf4_type
;
32591 typedef typename
node_type::T0 T0
;
32592 typedef typename
node_type::T1 T1
;
32593 typedef typename
node_type::T2 T2
;
32594 typedef typename
node_type::T3 T3
;
32596 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32597 const details::operator_type
& operation
,
32598 expression_node_ptr (&branch
)[2])
32600 // v0 o0 (c0 o1 (v1 o2 c2))
32601 typedef typename
synthesize_covoc_expression1::node_type lcl_covoc_t
;
32603 const lcl_covoc_t
* covoc
= static_cast<const lcl_covoc_t
*>(branch
[1]);
32604 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32605 const Type c0
= covoc
->t0();
32606 const Type
& v1
= covoc
->t1();
32607 const Type c1
= covoc
->t2();
32608 const details::operator_type o0
= operation
;
32609 const details::operator_type o1
= expr_gen
.get_operator(covoc
->f0());
32610 const details::operator_type o2
= expr_gen
.get_operator(covoc
->f1());
32612 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32613 binary_functor_t f1
= covoc
->f0();
32614 binary_functor_t f2
= covoc
->f1();
32616 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32618 expression_node_ptr result
= error_node();
32620 const bool synthesis_result
=
32621 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32622 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, v1
, c1
, result
);
32624 if (synthesis_result
)
32626 else if (!expr_gen
.valid_operator(o0
,f0
))
32627 return error_node();
32629 exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n"));
32631 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, v1
, c1
, f0
, f1
, f2
);
32634 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32635 const details::operator_type o0
,
32636 const details::operator_type o1
,
32637 const details::operator_type o2
)
32639 return details::build_string()
32640 << "t" << expr_gen
.to_str(o0
)
32641 << "(t" << expr_gen
.to_str(o1
)
32642 << "(t" << expr_gen
.to_str(o2
)
32647 struct synthesize_covovoc_expression1
32649 typedef typename
covovoc_t::type1 node_type
;
32650 typedef typename
covovoc_t::sf4_type sf4_type
;
32651 typedef typename
node_type::T0 T0
;
32652 typedef typename
node_type::T1 T1
;
32653 typedef typename
node_type::T2 T2
;
32654 typedef typename
node_type::T3 T3
;
32655 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32656 const details::operator_type
& operation
,
32657 expression_node_ptr (&branch
)[2])
32659 // c0 o0 (v0 o1 (v1 o2 c1))
32660 typedef typename
synthesize_vovoc_expression1::node_type lcl_vovoc_t
;
32662 const lcl_vovoc_t
* vovoc
= static_cast<const lcl_vovoc_t
*>(branch
[1]);
32663 const Type c0
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
32664 const Type
& v0
= vovoc
->t0();
32665 const Type
& v1
= vovoc
->t1();
32666 const Type c1
= vovoc
->t2();
32667 const details::operator_type o0
= operation
;
32668 const details::operator_type o1
= expr_gen
.get_operator(vovoc
->f0());
32669 const details::operator_type o2
= expr_gen
.get_operator(vovoc
->f1());
32671 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32672 binary_functor_t f1
= vovoc
->f0();
32673 binary_functor_t f2
= vovoc
->f1();
32675 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
32676 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32678 expression_node_ptr result
= error_node();
32680 const bool synthesis_result
=
32681 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32682 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, v1
, c1
, result
);
32684 if (synthesis_result
)
32686 else if (!expr_gen
.valid_operator(o0
,f0
))
32687 return error_node();
32689 exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n"));
32691 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, v1
, c1
, f0
, f1
, f2
);
32694 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32695 const details::operator_type o0
,
32696 const details::operator_type o1
,
32697 const details::operator_type o2
)
32699 return details::build_string()
32700 << "t" << expr_gen
.to_str(o0
)
32701 << "(t" << expr_gen
.to_str(o1
)
32702 << "(t" << expr_gen
.to_str(o2
)
32707 struct synthesize_vococov_expression1
32709 typedef typename
vococov_t::type1 node_type
;
32710 typedef typename
vococov_t::sf4_type sf4_type
;
32711 typedef typename
node_type::T0 T0
;
32712 typedef typename
node_type::T1 T1
;
32713 typedef typename
node_type::T2 T2
;
32714 typedef typename
node_type::T3 T3
;
32716 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32717 const details::operator_type
& operation
,
32718 expression_node_ptr (&branch
)[2])
32720 // v0 o0 (c0 o1 (c1 o2 v1))
32721 typedef typename
synthesize_cocov_expression1::node_type lcl_cocov_t
;
32723 const lcl_cocov_t
* cocov
= static_cast<const lcl_cocov_t
*>(branch
[1]);
32724 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32725 const Type c0
= cocov
->t0();
32726 const Type c1
= cocov
->t1();
32727 const Type
& v1
= cocov
->t2();
32728 const details::operator_type o0
= operation
;
32729 const details::operator_type o1
= expr_gen
.get_operator(cocov
->f0());
32730 const details::operator_type o2
= expr_gen
.get_operator(cocov
->f1());
32732 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32733 binary_functor_t f1
= cocov
->f0();
32734 binary_functor_t f2
= cocov
->f1();
32736 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32738 expression_node_ptr result
= error_node();
32740 const bool synthesis_result
=
32741 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32742 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, c1
, v1
, result
);
32744 if (synthesis_result
)
32746 else if (!expr_gen
.valid_operator(o0
,f0
))
32747 return error_node();
32749 exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n"));
32751 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, c1
, v1
, f0
, f1
, f2
);
32754 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32755 const details::operator_type o0
,
32756 const details::operator_type o1
,
32757 const details::operator_type o2
)
32759 return details::build_string()
32760 << "t" << expr_gen
.to_str(o0
)
32761 << "(t" << expr_gen
.to_str(o1
)
32762 << "(t" << expr_gen
.to_str(o2
)
32767 struct synthesize_vovovov_expression2
32769 typedef typename
vovovov_t::type2 node_type
;
32770 typedef typename
vovovov_t::sf4_type sf4_type
;
32771 typedef typename
node_type::T0 T0
;
32772 typedef typename
node_type::T1 T1
;
32773 typedef typename
node_type::T2 T2
;
32774 typedef typename
node_type::T3 T3
;
32776 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32777 const details::operator_type
& operation
,
32778 expression_node_ptr (&branch
)[2])
32780 // v0 o0 ((v1 o1 v2) o2 v3)
32781 typedef typename
synthesize_vovov_expression0::node_type lcl_vovov_t
;
32783 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[1]);
32784 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32785 const Type
& v1
= vovov
->t0();
32786 const Type
& v2
= vovov
->t1();
32787 const Type
& v3
= vovov
->t2();
32788 const details::operator_type o0
= operation
;
32789 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f0());
32790 const details::operator_type o2
= expr_gen
.get_operator(vovov
->f1());
32792 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32793 binary_functor_t f1
= vovov
->f0();
32794 binary_functor_t f2
= vovov
->f1();
32796 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32798 expression_node_ptr result
= error_node();
32800 const bool synthesis_result
=
32801 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32802 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, v3
, result
);
32804 if (synthesis_result
)
32806 else if (!expr_gen
.valid_operator(o0
,f0
))
32807 return error_node();
32809 exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n"));
32811 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, v3
, f0
, f1
, f2
);
32814 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32815 const details::operator_type o0
,
32816 const details::operator_type o1
,
32817 const details::operator_type o2
)
32819 return details::build_string()
32820 << "t" << expr_gen
.to_str(o0
)
32821 << "((t" << expr_gen
.to_str(o1
)
32822 << "t)" << expr_gen
.to_str(o2
)
32827 struct synthesize_vovovoc_expression2
32829 typedef typename
vovovoc_t::type2 node_type
;
32830 typedef typename
vovovoc_t::sf4_type sf4_type
;
32831 typedef typename
node_type::T0 T0
;
32832 typedef typename
node_type::T1 T1
;
32833 typedef typename
node_type::T2 T2
;
32834 typedef typename
node_type::T3 T3
;
32836 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32837 const details::operator_type
& operation
,
32838 expression_node_ptr (&branch
)[2])
32840 // v0 o0 ((v1 o1 v2) o2 c)
32841 typedef typename
synthesize_vovoc_expression0::node_type lcl_vovoc_t
;
32843 const lcl_vovoc_t
* vovoc
= static_cast<const lcl_vovoc_t
*>(branch
[1]);
32844 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32845 const Type
& v1
= vovoc
->t0();
32846 const Type
& v2
= vovoc
->t1();
32847 const Type c
= vovoc
->t2();
32848 const details::operator_type o0
= operation
;
32849 const details::operator_type o1
= expr_gen
.get_operator(vovoc
->f0());
32850 const details::operator_type o2
= expr_gen
.get_operator(vovoc
->f1());
32852 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32853 binary_functor_t f1
= vovoc
->f0();
32854 binary_functor_t f2
= vovoc
->f1();
32856 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32858 expression_node_ptr result
= error_node();
32860 const bool synthesis_result
=
32861 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32862 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, c
, result
);
32864 if (synthesis_result
)
32866 else if (!expr_gen
.valid_operator(o0
,f0
))
32867 return error_node();
32869 exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n"));
32871 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, c
, f0
, f1
, f2
);
32874 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32875 const details::operator_type o0
,
32876 const details::operator_type o1
,
32877 const details::operator_type o2
)
32879 return details::build_string()
32880 << "t" << expr_gen
.to_str(o0
)
32881 << "((t" << expr_gen
.to_str(o1
)
32882 << "t)" << expr_gen
.to_str(o2
)
32887 struct synthesize_vovocov_expression2
32889 typedef typename
vovocov_t::type2 node_type
;
32890 typedef typename
vovocov_t::sf4_type sf4_type
;
32891 typedef typename
node_type::T0 T0
;
32892 typedef typename
node_type::T1 T1
;
32893 typedef typename
node_type::T2 T2
;
32894 typedef typename
node_type::T3 T3
;
32896 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32897 const details::operator_type
& operation
,
32898 expression_node_ptr (&branch
)[2])
32900 // v0 o0 ((v1 o1 c) o2 v2)
32901 typedef typename
synthesize_vocov_expression0::node_type lcl_vocov_t
;
32903 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[1]);
32904 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32905 const Type
& v1
= vocov
->t0();
32906 const Type c
= vocov
->t1();
32907 const Type
& v2
= vocov
->t2();
32908 const details::operator_type o0
= operation
;
32909 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f0());
32910 const details::operator_type o2
= expr_gen
.get_operator(vocov
->f1());
32912 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32913 binary_functor_t f1
= vocov
->f0();
32914 binary_functor_t f2
= vocov
->f1();
32916 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32918 expression_node_ptr result
= error_node();
32920 const bool synthesis_result
=
32921 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32922 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, c
, v2
, result
);
32924 if (synthesis_result
)
32926 else if (!expr_gen
.valid_operator(o0
,f0
))
32927 return error_node();
32929 exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n"));
32931 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, c
, v2
, f0
, f1
, f2
);
32934 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32935 const details::operator_type o0
,
32936 const details::operator_type o1
,
32937 const details::operator_type o2
)
32939 return details::build_string()
32940 << "t" << expr_gen
.to_str(o0
)
32941 << "((t" << expr_gen
.to_str(o1
)
32942 << "t)" << expr_gen
.to_str(o2
)
32947 struct synthesize_vocovov_expression2
32949 typedef typename
vocovov_t::type2 node_type
;
32950 typedef typename
vocovov_t::sf4_type sf4_type
;
32951 typedef typename
node_type::T0 T0
;
32952 typedef typename
node_type::T1 T1
;
32953 typedef typename
node_type::T2 T2
;
32954 typedef typename
node_type::T3 T3
;
32956 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
32957 const details::operator_type
& operation
,
32958 expression_node_ptr (&branch
)[2])
32960 // v0 o0 ((c o1 v1) o2 v2)
32961 typedef typename
synthesize_covov_expression0::node_type lcl_covov_t
;
32963 const lcl_covov_t
* covov
= static_cast<const lcl_covov_t
*>(branch
[1]);
32964 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
32965 const Type c
= covov
->t0();
32966 const Type
& v1
= covov
->t1();
32967 const Type
& v2
= covov
->t2();
32968 const details::operator_type o0
= operation
;
32969 const details::operator_type o1
= expr_gen
.get_operator(covov
->f0());
32970 const details::operator_type o2
= expr_gen
.get_operator(covov
->f1());
32972 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
32973 binary_functor_t f1
= covov
->f0();
32974 binary_functor_t f2
= covov
->f1();
32976 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
32978 expression_node_ptr result
= error_node();
32980 const bool synthesis_result
=
32981 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
32982 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c
, v1
, v2
, result
);
32984 if (synthesis_result
)
32986 else if (!expr_gen
.valid_operator(o0
,f0
))
32987 return error_node();
32989 exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n"));
32991 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c
, v1
, v2
, f0
, f1
, f2
);
32994 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
32995 const details::operator_type o0
,
32996 const details::operator_type o1
,
32997 const details::operator_type o2
)
32999 return details::build_string()
33000 << "t" << expr_gen
.to_str(o0
)
33001 << "((t" << expr_gen
.to_str(o1
)
33002 << "t)" << expr_gen
.to_str(o2
)
33007 struct synthesize_covovov_expression2
33009 typedef typename
covovov_t::type2 node_type
;
33010 typedef typename
covovov_t::sf4_type sf4_type
;
33011 typedef typename
node_type::T0 T0
;
33012 typedef typename
node_type::T1 T1
;
33013 typedef typename
node_type::T2 T2
;
33014 typedef typename
node_type::T3 T3
;
33016 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33017 const details::operator_type
& operation
,
33018 expression_node_ptr (&branch
)[2])
33020 // c o0 ((v1 o1 v2) o2 v3)
33021 typedef typename
synthesize_vovov_expression0::node_type lcl_vovov_t
;
33023 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[1]);
33024 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
33025 const Type
& v0
= vovov
->t0();
33026 const Type
& v1
= vovov
->t1();
33027 const Type
& v2
= vovov
->t2();
33028 const details::operator_type o0
= operation
;
33029 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f0());
33030 const details::operator_type o2
= expr_gen
.get_operator(vovov
->f1());
33032 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
33033 binary_functor_t f1
= vovov
->f0();
33034 binary_functor_t f2
= vovov
->f1();
33036 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33037 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33039 expression_node_ptr result
= error_node();
33041 const bool synthesis_result
=
33042 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33043 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c
, v0
, v1
, v2
, result
);
33045 if (synthesis_result
)
33047 else if (!expr_gen
.valid_operator(o0
,f0
))
33048 return error_node();
33050 exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n"));
33052 return node_type::allocate(*(expr_gen
.node_allocator_
), c
, v0
, v1
, v2
, f0
, f1
, f2
);
33055 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33056 const details::operator_type o0
,
33057 const details::operator_type o1
,
33058 const details::operator_type o2
)
33060 return details::build_string()
33061 << "t" << expr_gen
.to_str(o0
)
33062 << "((t" << expr_gen
.to_str(o1
)
33063 << "t)" << expr_gen
.to_str(o2
)
33068 struct synthesize_covocov_expression2
33070 typedef typename
covocov_t::type2 node_type
;
33071 typedef typename
covocov_t::sf4_type sf4_type
;
33072 typedef typename
node_type::T0 T0
;
33073 typedef typename
node_type::T1 T1
;
33074 typedef typename
node_type::T2 T2
;
33075 typedef typename
node_type::T3 T3
;
33077 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33078 const details::operator_type
& operation
,
33079 expression_node_ptr (&branch
)[2])
33081 // c0 o0 ((v0 o1 c1) o2 v1)
33082 typedef typename
synthesize_vocov_expression0::node_type lcl_vocov_t
;
33084 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[1]);
33085 const Type c0
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
33086 const Type
& v0
= vocov
->t0();
33087 const Type c1
= vocov
->t1();
33088 const Type
& v1
= vocov
->t2();
33089 const details::operator_type o0
= operation
;
33090 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f0());
33091 const details::operator_type o2
= expr_gen
.get_operator(vocov
->f1());
33093 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
33094 binary_functor_t f1
= vocov
->f0();
33095 binary_functor_t f2
= vocov
->f1();
33097 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33098 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33100 expression_node_ptr result
= error_node();
33102 const bool synthesis_result
=
33103 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33104 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, c1
, v1
, result
);
33106 if (synthesis_result
)
33108 else if (!expr_gen
.valid_operator(o0
,f0
))
33109 return error_node();
33111 exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n"));
33113 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, c1
, v1
, f0
, f1
, f2
);
33116 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33117 const details::operator_type o0
,
33118 const details::operator_type o1
,
33119 const details::operator_type o2
)
33121 return details::build_string()
33122 << "t" << expr_gen
.to_str(o0
)
33123 << "((t" << expr_gen
.to_str(o1
)
33124 << "t)" << expr_gen
.to_str(o2
)
33129 struct synthesize_vocovoc_expression2
33131 typedef typename
vocovoc_t::type2 node_type
;
33132 typedef typename
vocovoc_t::sf4_type sf4_type
;
33133 typedef typename
node_type::T0 T0
;
33134 typedef typename
node_type::T1 T1
;
33135 typedef typename
node_type::T2 T2
;
33136 typedef typename
node_type::T3 T3
;
33138 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33139 const details::operator_type
& operation
,
33140 expression_node_ptr (&branch
)[2])
33142 // v0 o0 ((c0 o1 v1) o2 c1)
33143 typedef typename
synthesize_covoc_expression0::node_type lcl_covoc_t
;
33145 const lcl_covoc_t
* covoc
= static_cast<const lcl_covoc_t
*>(branch
[1]);
33146 const Type
& v0
= static_cast<details::variable_node
<Type
>*>(branch
[0])->ref();
33147 const Type c0
= covoc
->t0();
33148 const Type
& v1
= covoc
->t1();
33149 const Type c1
= covoc
->t2();
33150 const details::operator_type o0
= operation
;
33151 const details::operator_type o1
= expr_gen
.get_operator(covoc
->f0());
33152 const details::operator_type o2
= expr_gen
.get_operator(covoc
->f1());
33154 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
33155 binary_functor_t f1
= covoc
->f0();
33156 binary_functor_t f2
= covoc
->f1();
33158 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33160 expression_node_ptr result
= error_node();
33162 const bool synthesis_result
=
33163 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33164 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, v1
, c1
, result
);
33166 if (synthesis_result
)
33168 else if (!expr_gen
.valid_operator(o0
,f0
))
33169 return error_node();
33171 exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n"));
33173 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, v1
, c1
, f0
, f1
, f2
);
33176 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33177 const details::operator_type o0
,
33178 const details::operator_type o1
,
33179 const details::operator_type o2
)
33181 return details::build_string()
33182 << "t" << expr_gen
.to_str(o0
)
33183 << "((t" << expr_gen
.to_str(o1
)
33184 << "t)" << expr_gen
.to_str(o2
)
33189 struct synthesize_covovoc_expression2
33191 typedef typename
covovoc_t::type2 node_type
;
33192 typedef typename
covovoc_t::sf4_type sf4_type
;
33193 typedef typename
node_type::T0 T0
;
33194 typedef typename
node_type::T1 T1
;
33195 typedef typename
node_type::T2 T2
;
33196 typedef typename
node_type::T3 T3
;
33198 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33199 const details::operator_type
& operation
,
33200 expression_node_ptr (&branch
)[2])
33202 // c0 o0 ((v0 o1 v1) o2 c1)
33203 typedef typename
synthesize_vovoc_expression0::node_type lcl_vovoc_t
;
33205 const lcl_vovoc_t
* vovoc
= static_cast<const lcl_vovoc_t
*>(branch
[1]);
33206 const Type c0
= static_cast<details::literal_node
<Type
>*>(branch
[0])->value();
33207 const Type
& v0
= vovoc
->t0();
33208 const Type
& v1
= vovoc
->t1();
33209 const Type c1
= vovoc
->t2();
33210 const details::operator_type o0
= operation
;
33211 const details::operator_type o1
= expr_gen
.get_operator(vovoc
->f0());
33212 const details::operator_type o2
= expr_gen
.get_operator(vovoc
->f1());
33214 binary_functor_t f0
= reinterpret_cast<binary_functor_t
>(0);
33215 binary_functor_t f1
= vovoc
->f0();
33216 binary_functor_t f2
= vovoc
->f1();
33218 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33219 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33221 expression_node_ptr result
= error_node();
33223 const bool synthesis_result
=
33224 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33225 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, v1
, c1
, result
);
33227 if (synthesis_result
)
33229 else if (!expr_gen
.valid_operator(o0
,f0
))
33230 return error_node();
33232 exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n"));
33234 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, v1
, c1
, f0
, f1
, f2
);
33237 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33238 const details::operator_type o0
,
33239 const details::operator_type o1
,
33240 const details::operator_type o2
)
33242 return details::build_string()
33243 << "t" << expr_gen
.to_str(o0
)
33244 << "((t" << expr_gen
.to_str(o1
)
33245 << "t)" << expr_gen
.to_str(o2
)
33250 struct synthesize_vococov_expression2
33252 typedef typename
vococov_t::type2 node_type
;
33253 static inline expression_node_ptr
process(expression_generator
<Type
>&, const details::operator_type
&, expression_node_ptr (&)[2])
33255 // v0 o0 ((c0 o1 c1) o2 v1) - Not possible
33256 exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
33257 return error_node();
33260 static inline std::string
id(expression_generator
<Type
>&,
33261 const details::operator_type
, const details::operator_type
, const details::operator_type
)
33267 struct synthesize_vovovov_expression3
33269 typedef typename
vovovov_t::type3 node_type
;
33270 typedef typename
vovovov_t::sf4_type sf4_type
;
33271 typedef typename
node_type::T0 T0
;
33272 typedef typename
node_type::T1 T1
;
33273 typedef typename
node_type::T2 T2
;
33274 typedef typename
node_type::T3 T3
;
33276 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33277 const details::operator_type
& operation
,
33278 expression_node_ptr (&branch
)[2])
33280 // ((v0 o0 v1) o1 v2) o2 v3
33281 typedef typename
synthesize_vovov_expression0::node_type lcl_vovov_t
;
33283 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[0]);
33284 const Type
& v0
= vovov
->t0();
33285 const Type
& v1
= vovov
->t1();
33286 const Type
& v2
= vovov
->t2();
33287 const Type
& v3
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33288 const details::operator_type o0
= expr_gen
.get_operator(vovov
->f0());
33289 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f1());
33290 const details::operator_type o2
= operation
;
33292 binary_functor_t f0
= vovov
->f0();
33293 binary_functor_t f1
= vovov
->f1();
33294 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33296 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33298 expression_node_ptr result
= error_node();
33300 const bool synthesis_result
=
33301 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33302 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, v3
, result
);
33304 if (synthesis_result
)
33306 else if (!expr_gen
.valid_operator(o2
,f2
))
33307 return error_node();
33309 exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n"));
33311 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, v3
, f0
, f1
, f2
);
33314 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33315 const details::operator_type o0
,
33316 const details::operator_type o1
,
33317 const details::operator_type o2
)
33319 return details::build_string()
33320 << "((t" << expr_gen
.to_str(o0
)
33321 << "t)" << expr_gen
.to_str(o1
)
33322 << "t)" << expr_gen
.to_str(o2
)
33327 struct synthesize_vovovoc_expression3
33329 typedef typename
vovovoc_t::type3 node_type
;
33330 typedef typename
vovovoc_t::sf4_type sf4_type
;
33331 typedef typename
node_type::T0 T0
;
33332 typedef typename
node_type::T1 T1
;
33333 typedef typename
node_type::T2 T2
;
33334 typedef typename
node_type::T3 T3
;
33336 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33337 const details::operator_type
& operation
,
33338 expression_node_ptr (&branch
)[2])
33340 // ((v0 o0 v1) o1 v2) o2 c
33341 typedef typename
synthesize_vovov_expression0::node_type lcl_vovov_t
;
33343 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[0]);
33344 const Type
& v0
= vovov
->t0();
33345 const Type
& v1
= vovov
->t1();
33346 const Type
& v2
= vovov
->t2();
33347 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
33348 const details::operator_type o0
= expr_gen
.get_operator(vovov
->f0());
33349 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f1());
33350 const details::operator_type o2
= operation
;
33352 binary_functor_t f0
= vovov
->f0();
33353 binary_functor_t f1
= vovov
->f1();
33354 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33356 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33357 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33359 expression_node_ptr result
= error_node();
33361 const bool synthesis_result
=
33362 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33363 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, c
, result
);
33365 if (synthesis_result
)
33367 else if (!expr_gen
.valid_operator(o2
,f2
))
33368 return error_node();
33370 exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n"));
33372 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, c
, f0
, f1
, f2
);
33375 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33376 const details::operator_type o0
,
33377 const details::operator_type o1
,
33378 const details::operator_type o2
)
33380 return details::build_string()
33381 << "((t" << expr_gen
.to_str(o0
)
33382 << "t)" << expr_gen
.to_str(o1
)
33383 << "t)" << expr_gen
.to_str(o2
)
33388 struct synthesize_vovocov_expression3
33390 typedef typename
vovocov_t::type3 node_type
;
33391 typedef typename
vovocov_t::sf4_type sf4_type
;
33392 typedef typename
node_type::T0 T0
;
33393 typedef typename
node_type::T1 T1
;
33394 typedef typename
node_type::T2 T2
;
33395 typedef typename
node_type::T3 T3
;
33397 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33398 const details::operator_type
& operation
,
33399 expression_node_ptr (&branch
)[2])
33401 // ((v0 o0 v1) o1 c) o2 v2
33402 typedef typename
synthesize_vovoc_expression0::node_type lcl_vovoc_t
;
33404 const lcl_vovoc_t
* vovoc
= static_cast<const lcl_vovoc_t
*>(branch
[0]);
33405 const Type
& v0
= vovoc
->t0();
33406 const Type
& v1
= vovoc
->t1();
33407 const Type c
= vovoc
->t2();
33408 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33409 const details::operator_type o0
= expr_gen
.get_operator(vovoc
->f0());
33410 const details::operator_type o1
= expr_gen
.get_operator(vovoc
->f1());
33411 const details::operator_type o2
= operation
;
33413 binary_functor_t f0
= vovoc
->f0();
33414 binary_functor_t f1
= vovoc
->f1();
33415 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33417 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33419 expression_node_ptr result
= error_node();
33421 const bool synthesis_result
=
33422 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33423 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, c
, v2
, result
);
33425 if (synthesis_result
)
33427 else if (!expr_gen
.valid_operator(o2
,f2
))
33428 return error_node();
33430 exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n"));
33432 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, c
, v2
, f0
, f1
, f2
);
33435 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33436 const details::operator_type o0
,
33437 const details::operator_type o1
,
33438 const details::operator_type o2
)
33440 return details::build_string()
33441 << "((t" << expr_gen
.to_str(o0
)
33442 << "t)" << expr_gen
.to_str(o1
)
33443 << "t)" << expr_gen
.to_str(o2
)
33448 struct synthesize_vocovov_expression3
33450 typedef typename
vocovov_t::type3 node_type
;
33451 typedef typename
vocovov_t::sf4_type sf4_type
;
33452 typedef typename
node_type::T0 T0
;
33453 typedef typename
node_type::T1 T1
;
33454 typedef typename
node_type::T2 T2
;
33455 typedef typename
node_type::T3 T3
;
33457 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33458 const details::operator_type
& operation
,
33459 expression_node_ptr (&branch
)[2])
33461 // ((v0 o0 c) o1 v1) o2 v2
33462 typedef typename
synthesize_vocov_expression0::node_type lcl_vocov_t
;
33464 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[0]);
33465 const Type
& v0
= vocov
->t0();
33466 const Type c
= vocov
->t1();
33467 const Type
& v1
= vocov
->t2();
33468 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33469 const details::operator_type o0
= expr_gen
.get_operator(vocov
->f0());
33470 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f1());
33471 const details::operator_type o2
= operation
;
33473 binary_functor_t f0
= vocov
->f0();
33474 binary_functor_t f1
= vocov
->f1();
33475 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33477 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33479 expression_node_ptr result
= error_node();
33481 const bool synthesis_result
=
33482 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33483 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c
, v1
, v2
, result
);
33485 if (synthesis_result
)
33487 else if (!expr_gen
.valid_operator(o2
,f2
))
33488 return error_node();
33490 exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n"));
33492 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c
, v1
, v2
, f0
, f1
, f2
);
33495 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33496 const details::operator_type o0
,
33497 const details::operator_type o1
,
33498 const details::operator_type o2
)
33500 return details::build_string()
33501 << "((t" << expr_gen
.to_str(o0
)
33502 << "t)" << expr_gen
.to_str(o1
)
33503 << "t)" << expr_gen
.to_str(o2
)
33508 struct synthesize_covovov_expression3
33510 typedef typename
covovov_t::type3 node_type
;
33511 typedef typename
covovov_t::sf4_type sf4_type
;
33512 typedef typename
node_type::T0 T0
;
33513 typedef typename
node_type::T1 T1
;
33514 typedef typename
node_type::T2 T2
;
33515 typedef typename
node_type::T3 T3
;
33517 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33518 const details::operator_type
& operation
,
33519 expression_node_ptr (&branch
)[2])
33521 // ((c o0 v0) o1 v1) o2 v2
33522 typedef typename
synthesize_covov_expression0::node_type lcl_covov_t
;
33524 const lcl_covov_t
* covov
= static_cast<const lcl_covov_t
*>(branch
[0]);
33525 const Type c
= covov
->t0();
33526 const Type
& v0
= covov
->t1();
33527 const Type
& v1
= covov
->t2();
33528 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33529 const details::operator_type o0
= expr_gen
.get_operator(covov
->f0());
33530 const details::operator_type o1
= expr_gen
.get_operator(covov
->f1());
33531 const details::operator_type o2
= operation
;
33533 binary_functor_t f0
= covov
->f0();
33534 binary_functor_t f1
= covov
->f1();
33535 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33537 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33539 expression_node_ptr result
= error_node();
33541 const bool synthesis_result
=
33542 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33543 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c
, v0
, v1
, v2
, result
);
33545 if (synthesis_result
)
33547 else if (!expr_gen
.valid_operator(o2
,f2
))
33548 return error_node();
33550 exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n"));
33552 return node_type::allocate(*(expr_gen
.node_allocator_
), c
, v0
, v1
, v2
, f0
, f1
, f2
);
33555 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33556 const details::operator_type o0
,
33557 const details::operator_type o1
,
33558 const details::operator_type o2
)
33560 return details::build_string()
33561 << "((t" << expr_gen
.to_str(o0
)
33562 << "t)" << expr_gen
.to_str(o1
)
33563 << "t)" << expr_gen
.to_str(o2
)
33568 struct synthesize_covocov_expression3
33570 typedef typename
covocov_t::type3 node_type
;
33571 typedef typename
covocov_t::sf4_type sf4_type
;
33572 typedef typename
node_type::T0 T0
;
33573 typedef typename
node_type::T1 T1
;
33574 typedef typename
node_type::T2 T2
;
33575 typedef typename
node_type::T3 T3
;
33577 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33578 const details::operator_type
& operation
,
33579 expression_node_ptr (&branch
)[2])
33581 // ((c0 o0 v0) o1 c1) o2 v1
33582 typedef typename
synthesize_covoc_expression0::node_type lcl_covoc_t
;
33584 const lcl_covoc_t
* covoc
= static_cast<const lcl_covoc_t
*>(branch
[0]);
33585 const Type c0
= covoc
->t0();
33586 const Type
& v0
= covoc
->t1();
33587 const Type c1
= covoc
->t2();
33588 const Type
& v1
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33589 const details::operator_type o0
= expr_gen
.get_operator(covoc
->f0());
33590 const details::operator_type o1
= expr_gen
.get_operator(covoc
->f1());
33591 const details::operator_type o2
= operation
;
33593 binary_functor_t f0
= covoc
->f0();
33594 binary_functor_t f1
= covoc
->f1();
33595 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33597 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33599 expression_node_ptr result
= error_node();
33601 const bool synthesis_result
=
33602 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33603 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, c1
, v1
, result
);
33605 if (synthesis_result
)
33607 else if (!expr_gen
.valid_operator(o2
,f2
))
33608 return error_node();
33610 exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n"));
33612 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, c1
, v1
, f0
, f1
, f2
);
33615 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33616 const details::operator_type o0
,
33617 const details::operator_type o1
,
33618 const details::operator_type o2
)
33620 return details::build_string()
33621 << "((t" << expr_gen
.to_str(o0
)
33622 << "t)" << expr_gen
.to_str(o1
)
33623 << "t)" << expr_gen
.to_str(o2
)
33628 struct synthesize_vocovoc_expression3
33630 typedef typename
vocovoc_t::type3 node_type
;
33631 typedef typename
vocovoc_t::sf4_type sf4_type
;
33632 typedef typename
node_type::T0 T0
;
33633 typedef typename
node_type::T1 T1
;
33634 typedef typename
node_type::T2 T2
;
33635 typedef typename
node_type::T3 T3
;
33637 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33638 const details::operator_type
& operation
,
33639 expression_node_ptr (&branch
)[2])
33641 // ((v0 o0 c0) o1 v1) o2 c1
33642 typedef typename
synthesize_vocov_expression0::node_type lcl_vocov_t
;
33644 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[0]);
33645 const Type
& v0
= vocov
->t0();
33646 const Type c0
= vocov
->t1();
33647 const Type
& v1
= vocov
->t2();
33648 const Type c1
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
33649 const details::operator_type o0
= expr_gen
.get_operator(vocov
->f0());
33650 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f1());
33651 const details::operator_type o2
= operation
;
33653 binary_functor_t f0
= vocov
->f0();
33654 binary_functor_t f1
= vocov
->f1();
33655 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33657 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33658 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33660 expression_node_ptr result
= error_node();
33662 const bool synthesis_result
=
33663 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33664 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, v1
, c1
, result
);
33666 if (synthesis_result
)
33668 else if (!expr_gen
.valid_operator(o2
,f2
))
33669 return error_node();
33671 exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n"));
33673 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, v1
, c1
, f0
, f1
, f2
);
33676 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33677 const details::operator_type o0
,
33678 const details::operator_type o1
,
33679 const details::operator_type o2
)
33681 return details::build_string()
33682 << "((t" << expr_gen
.to_str(o0
)
33683 << "t)" << expr_gen
.to_str(o1
)
33684 << "t)" << expr_gen
.to_str(o2
)
33689 struct synthesize_covovoc_expression3
33691 typedef typename
covovoc_t::type3 node_type
;
33692 typedef typename
covovoc_t::sf4_type sf4_type
;
33693 typedef typename
node_type::T0 T0
;
33694 typedef typename
node_type::T1 T1
;
33695 typedef typename
node_type::T2 T2
;
33696 typedef typename
node_type::T3 T3
;
33698 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33699 const details::operator_type
& operation
,
33700 expression_node_ptr (&branch
)[2])
33702 // ((c0 o0 v0) o1 v1) o2 c1
33703 typedef typename
synthesize_covov_expression0::node_type lcl_covov_t
;
33705 const lcl_covov_t
* covov
= static_cast<const lcl_covov_t
*>(branch
[0]);
33706 const Type c0
= covov
->t0();
33707 const Type
& v0
= covov
->t1();
33708 const Type
& v1
= covov
->t2();
33709 const Type c1
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
33710 const details::operator_type o0
= expr_gen
.get_operator(covov
->f0());
33711 const details::operator_type o1
= expr_gen
.get_operator(covov
->f1());
33712 const details::operator_type o2
= operation
;
33714 binary_functor_t f0
= covov
->f0();
33715 binary_functor_t f1
= covov
->f1();
33716 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33718 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33719 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33721 expression_node_ptr result
= error_node();
33723 const bool synthesis_result
=
33724 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33725 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, v1
, c1
, result
);
33727 if (synthesis_result
)
33729 else if (!expr_gen
.valid_operator(o2
,f2
))
33730 return error_node();
33732 exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n"));
33734 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, v1
, c1
, f0
, f1
, f2
);
33737 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33738 const details::operator_type o0
,
33739 const details::operator_type o1
,
33740 const details::operator_type o2
)
33742 return details::build_string()
33743 << "((t" << expr_gen
.to_str(o0
)
33744 << "t)" << expr_gen
.to_str(o1
)
33745 << "t)" << expr_gen
.to_str(o2
)
33750 struct synthesize_vococov_expression3
33752 typedef typename
vococov_t::type3 node_type
;
33753 typedef typename
vococov_t::sf4_type sf4_type
;
33754 typedef typename
node_type::T0 T0
;
33755 typedef typename
node_type::T1 T1
;
33756 typedef typename
node_type::T2 T2
;
33757 typedef typename
node_type::T3 T3
;
33759 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33760 const details::operator_type
& operation
,
33761 expression_node_ptr (&branch
)[2])
33763 // ((v0 o0 c0) o1 c1) o2 v1
33764 typedef typename
synthesize_vococ_expression0::node_type lcl_vococ_t
;
33766 const lcl_vococ_t
* vococ
= static_cast<const lcl_vococ_t
*>(branch
[0]);
33767 const Type
& v0
= vococ
->t0();
33768 const Type c0
= vococ
->t1();
33769 const Type c1
= vococ
->t2();
33770 const Type
& v1
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33771 const details::operator_type o0
= expr_gen
.get_operator(vococ
->f0());
33772 const details::operator_type o1
= expr_gen
.get_operator(vococ
->f1());
33773 const details::operator_type o2
= operation
;
33775 binary_functor_t f0
= vococ
->f0();
33776 binary_functor_t f1
= vococ
->f1();
33777 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33779 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33781 expression_node_ptr result
= error_node();
33783 const bool synthesis_result
=
33784 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33785 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, c1
, v1
, result
);
33787 if (synthesis_result
)
33789 else if (!expr_gen
.valid_operator(o2
,f2
))
33790 return error_node();
33792 exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n"));
33794 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, c1
, v1
, f0
, f1
, f2
);
33797 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33798 const details::operator_type o0
,
33799 const details::operator_type o1
,
33800 const details::operator_type o2
)
33802 return details::build_string()
33803 << "((t" << expr_gen
.to_str(o0
)
33804 << "t)" << expr_gen
.to_str(o1
)
33805 << "t)" << expr_gen
.to_str(o2
)
33810 struct synthesize_vovovov_expression4
33812 typedef typename
vovovov_t::type4 node_type
;
33813 typedef typename
vovovov_t::sf4_type sf4_type
;
33814 typedef typename
node_type::T0 T0
;
33815 typedef typename
node_type::T1 T1
;
33816 typedef typename
node_type::T2 T2
;
33817 typedef typename
node_type::T3 T3
;
33819 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33820 const details::operator_type
& operation
,
33821 expression_node_ptr (&branch
)[2])
33823 // (v0 o0 (v1 o1 v2)) o2 v3
33824 typedef typename
synthesize_vovov_expression1::node_type lcl_vovov_t
;
33826 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[0]);
33827 const Type
& v0
= vovov
->t0();
33828 const Type
& v1
= vovov
->t1();
33829 const Type
& v2
= vovov
->t2();
33830 const Type
& v3
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33831 const details::operator_type o0
= expr_gen
.get_operator(vovov
->f0());
33832 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f1());
33833 const details::operator_type o2
= operation
;
33835 binary_functor_t f0
= vovov
->f0();
33836 binary_functor_t f1
= vovov
->f1();
33837 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33839 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33841 expression_node_ptr result
= error_node();
33843 const bool synthesis_result
=
33844 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33845 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, v3
, result
);
33847 if (synthesis_result
)
33849 else if (!expr_gen
.valid_operator(o2
,f2
))
33850 return error_node();
33852 exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n"));
33854 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, v3
, f0
, f1
, f2
);
33857 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33858 const details::operator_type o0
,
33859 const details::operator_type o1
,
33860 const details::operator_type o2
)
33862 return details::build_string()
33863 << "(t" << expr_gen
.to_str(o0
)
33864 << "(t" << expr_gen
.to_str(o1
)
33865 << "t)" << expr_gen
.to_str(o2
)
33870 struct synthesize_vovovoc_expression4
33872 typedef typename
vovovoc_t::type4 node_type
;
33873 typedef typename
vovovoc_t::sf4_type sf4_type
;
33874 typedef typename
node_type::T0 T0
;
33875 typedef typename
node_type::T1 T1
;
33876 typedef typename
node_type::T2 T2
;
33877 typedef typename
node_type::T3 T3
;
33879 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33880 const details::operator_type
& operation
,
33881 expression_node_ptr (&branch
)[2])
33883 // ((v0 o0 (v1 o1 v2)) o2 c)
33884 typedef typename
synthesize_vovov_expression1::node_type lcl_vovov_t
;
33886 const lcl_vovov_t
* vovov
= static_cast<const lcl_vovov_t
*>(branch
[0]);
33887 const Type
& v0
= vovov
->t0();
33888 const Type
& v1
= vovov
->t1();
33889 const Type
& v2
= vovov
->t2();
33890 const Type c
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
33891 const details::operator_type o0
= expr_gen
.get_operator(vovov
->f0());
33892 const details::operator_type o1
= expr_gen
.get_operator(vovov
->f1());
33893 const details::operator_type o2
= operation
;
33895 binary_functor_t f0
= vovov
->f0();
33896 binary_functor_t f1
= vovov
->f1();
33897 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33899 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33900 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
33902 expression_node_ptr result
= error_node();
33904 const bool synthesis_result
=
33905 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33906 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, v2
, c
, result
);
33908 if (synthesis_result
)
33910 else if (!expr_gen
.valid_operator(o2
,f2
))
33911 return error_node();
33913 exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n"));
33915 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, v2
, c
, f0
, f1
, f2
);
33918 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33919 const details::operator_type o0
,
33920 const details::operator_type o1
,
33921 const details::operator_type o2
)
33923 return details::build_string()
33924 << "(t" << expr_gen
.to_str(o0
)
33925 << "(t" << expr_gen
.to_str(o1
)
33926 << "t)" << expr_gen
.to_str(o2
)
33931 struct synthesize_vovocov_expression4
33933 typedef typename
vovocov_t::type4 node_type
;
33934 typedef typename
vovocov_t::sf4_type sf4_type
;
33935 typedef typename
node_type::T0 T0
;
33936 typedef typename
node_type::T1 T1
;
33937 typedef typename
node_type::T2 T2
;
33938 typedef typename
node_type::T3 T3
;
33940 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
33941 const details::operator_type
& operation
,
33942 expression_node_ptr (&branch
)[2])
33944 // ((v0 o0 (v1 o1 c)) o2 v1)
33945 typedef typename
synthesize_vovoc_expression1::node_type lcl_vovoc_t
;
33947 const lcl_vovoc_t
* vovoc
= static_cast<const lcl_vovoc_t
*>(branch
[0]);
33948 const Type
& v0
= vovoc
->t0();
33949 const Type
& v1
= vovoc
->t1();
33950 const Type c
= vovoc
->t2();
33951 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
33952 const details::operator_type o0
= expr_gen
.get_operator(vovoc
->f0());
33953 const details::operator_type o1
= expr_gen
.get_operator(vovoc
->f1());
33954 const details::operator_type o2
= operation
;
33956 binary_functor_t f0
= vovoc
->f0();
33957 binary_functor_t f1
= vovoc
->f1();
33958 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
33960 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
33962 expression_node_ptr result
= error_node();
33964 const bool synthesis_result
=
33965 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
33966 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, v1
, c
, v2
, result
);
33968 if (synthesis_result
)
33970 else if (!expr_gen
.valid_operator(o2
,f2
))
33971 return error_node();
33973 exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n"));
33975 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, v1
, c
, v2
, f0
, f1
, f2
);
33978 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
33979 const details::operator_type o0
,
33980 const details::operator_type o1
,
33981 const details::operator_type o2
)
33983 return details::build_string()
33984 << "(t" << expr_gen
.to_str(o0
)
33985 << "(t" << expr_gen
.to_str(o1
)
33986 << "t)" << expr_gen
.to_str(o2
)
33991 struct synthesize_vocovov_expression4
33993 typedef typename
vocovov_t::type4 node_type
;
33994 typedef typename
vocovov_t::sf4_type sf4_type
;
33995 typedef typename
node_type::T0 T0
;
33996 typedef typename
node_type::T1 T1
;
33997 typedef typename
node_type::T2 T2
;
33998 typedef typename
node_type::T3 T3
;
34000 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
34001 const details::operator_type
& operation
,
34002 expression_node_ptr (&branch
)[2])
34004 // ((v0 o0 (c o1 v1)) o2 v2)
34005 typedef typename
synthesize_vocov_expression1::node_type lcl_vocov_t
;
34007 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[0]);
34008 const Type
& v0
= vocov
->t0();
34009 const Type c
= vocov
->t1();
34010 const Type
& v1
= vocov
->t2();
34011 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
34012 const details::operator_type o0
= expr_gen
.get_operator(vocov
->f0());
34013 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f1());
34014 const details::operator_type o2
= operation
;
34016 binary_functor_t f0
= vocov
->f0();
34017 binary_functor_t f1
= vocov
->f1();
34018 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
34020 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
34021 expression_node_ptr result
= error_node();
34023 const bool synthesis_result
=
34024 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
34025 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c
, v1
, v2
, result
);
34027 if (synthesis_result
)
34029 else if (!expr_gen
.valid_operator(o2
,f2
))
34030 return error_node();
34032 exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n"));
34034 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c
, v1
, v2
, f0
, f1
, f2
);
34037 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
34038 const details::operator_type o0
,
34039 const details::operator_type o1
,
34040 const details::operator_type o2
)
34042 return details::build_string()
34043 << "(t" << expr_gen
.to_str(o0
)
34044 << "(t" << expr_gen
.to_str(o1
)
34045 << "t)" << expr_gen
.to_str(o2
)
34050 struct synthesize_covovov_expression4
34052 typedef typename
covovov_t::type4 node_type
;
34053 typedef typename
covovov_t::sf4_type sf4_type
;
34054 typedef typename
node_type::T0 T0
;
34055 typedef typename
node_type::T1 T1
;
34056 typedef typename
node_type::T2 T2
;
34057 typedef typename
node_type::T3 T3
;
34059 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
34060 const details::operator_type
& operation
,
34061 expression_node_ptr (&branch
)[2])
34063 // ((c o0 (v0 o1 v1)) o2 v2)
34064 typedef typename
synthesize_covov_expression1::node_type lcl_covov_t
;
34066 const lcl_covov_t
* covov
= static_cast<const lcl_covov_t
*>(branch
[0]);
34067 const Type c
= covov
->t0();
34068 const Type
& v0
= covov
->t1();
34069 const Type
& v1
= covov
->t2();
34070 const Type
& v2
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
34071 const details::operator_type o0
= expr_gen
.get_operator(covov
->f0());
34072 const details::operator_type o1
= expr_gen
.get_operator(covov
->f1());
34073 const details::operator_type o2
= operation
;
34075 binary_functor_t f0
= covov
->f0();
34076 binary_functor_t f1
= covov
->f1();
34077 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
34079 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
34081 expression_node_ptr result
= error_node();
34083 const bool synthesis_result
=
34084 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
34085 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c
, v0
, v1
, v2
, result
);
34087 if (synthesis_result
)
34089 else if (!expr_gen
.valid_operator(o2
,f2
))
34090 return error_node();
34092 exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n"));
34094 return node_type::allocate(*(expr_gen
.node_allocator_
), c
, v0
, v1
, v2
, f0
, f1
, f2
);
34097 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
34098 const details::operator_type o0
,
34099 const details::operator_type o1
,
34100 const details::operator_type o2
)
34102 return details::build_string()
34103 << "(t" << expr_gen
.to_str(o0
)
34104 << "(t" << expr_gen
.to_str(o1
)
34105 << "t)" << expr_gen
.to_str(o2
)
34110 struct synthesize_covocov_expression4
34112 typedef typename
covocov_t::type4 node_type
;
34113 typedef typename
covocov_t::sf4_type sf4_type
;
34114 typedef typename
node_type::T0 T0
;
34115 typedef typename
node_type::T1 T1
;
34116 typedef typename
node_type::T2 T2
;
34117 typedef typename
node_type::T3 T3
;
34119 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
34120 const details::operator_type
& operation
,
34121 expression_node_ptr (&branch
)[2])
34123 // ((c0 o0 (v0 o1 c1)) o2 v1)
34124 typedef typename
synthesize_covoc_expression1::node_type lcl_covoc_t
;
34126 const lcl_covoc_t
* covoc
= static_cast<const lcl_covoc_t
*>(branch
[0]);
34127 const Type c0
= covoc
->t0();
34128 const Type
& v0
= covoc
->t1();
34129 const Type c1
= covoc
->t2();
34130 const Type
& v1
= static_cast<details::variable_node
<Type
>*>(branch
[1])->ref();
34131 const details::operator_type o0
= expr_gen
.get_operator(covoc
->f0());
34132 const details::operator_type o1
= expr_gen
.get_operator(covoc
->f1());
34133 const details::operator_type o2
= operation
;
34135 binary_functor_t f0
= covoc
->f0();
34136 binary_functor_t f1
= covoc
->f1();
34137 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
34139 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
34141 expression_node_ptr result
= error_node();
34143 const bool synthesis_result
=
34144 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
34145 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, c1
, v1
, result
);
34147 if (synthesis_result
)
34149 else if (!expr_gen
.valid_operator(o2
,f2
))
34150 return error_node();
34152 exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n"));
34154 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, c1
, v1
, f0
, f1
, f2
);
34157 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
34158 const details::operator_type o0
,
34159 const details::operator_type o1
,
34160 const details::operator_type o2
)
34162 return details::build_string()
34163 << "(t" << expr_gen
.to_str(o0
)
34164 << "(t" << expr_gen
.to_str(o1
)
34165 << "t)" << expr_gen
.to_str(o2
)
34170 struct synthesize_vocovoc_expression4
34172 typedef typename
vocovoc_t::type4 node_type
;
34173 typedef typename
vocovoc_t::sf4_type sf4_type
;
34174 typedef typename
node_type::T0 T0
;
34175 typedef typename
node_type::T1 T1
;
34176 typedef typename
node_type::T2 T2
;
34177 typedef typename
node_type::T3 T3
;
34179 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
34180 const details::operator_type
& operation
,
34181 expression_node_ptr (&branch
)[2])
34183 // ((v0 o0 (c0 o1 v1)) o2 c1)
34184 typedef typename
synthesize_vocov_expression1::node_type lcl_vocov_t
;
34186 const lcl_vocov_t
* vocov
= static_cast<const lcl_vocov_t
*>(branch
[0]);
34187 const Type
& v0
= vocov
->t0();
34188 const Type c0
= vocov
->t1();
34189 const Type
& v1
= vocov
->t2();
34190 const Type c1
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
34191 const details::operator_type o0
= expr_gen
.get_operator(vocov
->f0());
34192 const details::operator_type o1
= expr_gen
.get_operator(vocov
->f1());
34193 const details::operator_type o2
= operation
;
34195 binary_functor_t f0
= vocov
->f0();
34196 binary_functor_t f1
= vocov
->f1();
34197 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
34199 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
34200 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
34202 expression_node_ptr result
= error_node();
34204 const bool synthesis_result
=
34205 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
34206 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), v0
, c0
, v1
, c1
, result
);
34208 if (synthesis_result
)
34210 else if (!expr_gen
.valid_operator(o2
,f2
))
34211 return error_node();
34213 exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n"));
34215 return node_type::allocate(*(expr_gen
.node_allocator_
), v0
, c0
, v1
, c1
, f0
, f1
, f2
);
34218 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
34219 const details::operator_type o0
,
34220 const details::operator_type o1
,
34221 const details::operator_type o2
)
34223 return details::build_string()
34224 << "(t" << expr_gen
.to_str(o0
)
34225 << "(t" << expr_gen
.to_str(o1
)
34226 << "t)" << expr_gen
.to_str(o2
)
34231 struct synthesize_covovoc_expression4
34233 typedef typename
covovoc_t::type4 node_type
;
34234 typedef typename
covovoc_t::sf4_type sf4_type
;
34235 typedef typename
node_type::T0 T0
;
34236 typedef typename
node_type::T1 T1
;
34237 typedef typename
node_type::T2 T2
;
34238 typedef typename
node_type::T3 T3
;
34240 static inline expression_node_ptr
process(expression_generator
<Type
>& expr_gen
,
34241 const details::operator_type
& operation
,
34242 expression_node_ptr (&branch
)[2])
34244 // ((c0 o0 (v0 o1 v1)) o2 c1)
34245 typedef typename
synthesize_covov_expression1::node_type lcl_covov_t
;
34247 const lcl_covov_t
* covov
= static_cast<const lcl_covov_t
*>(branch
[0]);
34248 const Type c0
= covov
->t0();
34249 const Type
& v0
= covov
->t1();
34250 const Type
& v1
= covov
->t2();
34251 const Type c1
= static_cast<details::literal_node
<Type
>*>(branch
[1])->value();
34252 const details::operator_type o0
= expr_gen
.get_operator(covov
->f0());
34253 const details::operator_type o1
= expr_gen
.get_operator(covov
->f1());
34254 const details::operator_type o2
= operation
;
34256 binary_functor_t f0
= covov
->f0();
34257 binary_functor_t f1
= covov
->f1();
34258 binary_functor_t f2
= reinterpret_cast<binary_functor_t
>(0);
34260 details::free_node(*(expr_gen
.node_allocator_
),branch
[0]);
34261 details::free_node(*(expr_gen
.node_allocator_
),branch
[1]);
34263 expression_node_ptr result
= error_node();
34265 const bool synthesis_result
=
34266 synthesize_sf4ext_expression::template compile
<T0
, T1
, T2
, T3
>
34267 (expr_gen
, id(expr_gen
, o0
, o1
, o2
), c0
, v0
, v1
, c1
, result
);
34269 if (synthesis_result
)
34271 else if (!expr_gen
.valid_operator(o2
,f2
))
34272 return error_node();
34274 exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n"));
34276 return node_type::allocate(*(expr_gen
.node_allocator_
), c0
, v0
, v1
, c1
, f0
, f1
, f2
);
34279 static inline std::string
id(expression_generator
<Type
>& expr_gen
,
34280 const details::operator_type o0
,
34281 const details::operator_type o1
,
34282 const details::operator_type o2
)
34284 return details::build_string()
34285 << "(t" << expr_gen
.to_str(o0
)
34286 << "(t" << expr_gen
.to_str(o1
)
34287 << "t)" << expr_gen
.to_str(o2
)
34292 struct synthesize_vococov_expression4
34294 typedef typename
vococov_t::type4 node_type
;
34295 static inline expression_node_ptr
process(expression_generator
<Type
>&, const details::operator_type
&, expression_node_ptr (&)[2])
34297 // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible
34298 exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
34299 return error_node();
34302 static inline std::string
id(expression_generator
<Type
>&,
34303 const details::operator_type
, const details::operator_type
, const details::operator_type
)
34310 inline expression_node_ptr
synthesize_uvouv_expression(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2])
34312 // Definition: uv o uv
34313 details::operator_type o0
= static_cast<details::uv_base_node
<Type
>*>(branch
[0])->operation();
34314 details::operator_type o1
= static_cast<details::uv_base_node
<Type
>*>(branch
[1])->operation();
34315 const Type
& v0
= static_cast<details::uv_base_node
<Type
>*>(branch
[0])->v();
34316 const Type
& v1
= static_cast<details::uv_base_node
<Type
>*>(branch
[1])->v();
34317 unary_functor_t u0
= reinterpret_cast<unary_functor_t
> (0);
34318 unary_functor_t u1
= reinterpret_cast<unary_functor_t
> (0);
34319 binary_functor_t f
= reinterpret_cast<binary_functor_t
>(0);
34321 if (!valid_operator(o0
,u0
))
34322 return error_node();
34323 else if (!valid_operator(o1
,u1
))
34324 return error_node();
34325 else if (!valid_operator(operation
,f
))
34326 return error_node();
34328 expression_node_ptr result
= error_node();
34331 (details::e_neg
== o0
) &&
34332 (details::e_neg
== o1
)
34337 // (-v0 + -v1) --> -(v0 + v1)
34338 case details::e_add
: result
= (*this)(details::e_neg
,
34340 allocate_rr
<typename
details::
34341 vov_node
<Type
,details::add_op
<Type
> > >(v0
, v1
));
34342 exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n"));
34345 // (-v0 - -v1) --> (v1 - v0)
34346 case details::e_sub
: result
= node_allocator_
->
34347 allocate_rr
<typename
details::
34348 vov_node
<Type
,details::sub_op
<Type
> > >(v1
, v0
);
34349 exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n"));
34352 // (-v0 * -v1) --> (v0 * v1)
34353 case details::e_mul
: result
= node_allocator_
->
34354 allocate_rr
<typename
details::
34355 vov_node
<Type
,details::mul_op
<Type
> > >(v0
, v1
);
34356 exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n"));
34359 // (-v0 / -v1) --> (v0 / v1)
34360 case details::e_div
: result
= node_allocator_
->
34361 allocate_rr
<typename
details::
34362 vov_node
<Type
,details::div_op
<Type
> > >(v0
, v1
);
34363 exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n"));
34372 result
= node_allocator_
->
34373 allocate_rrrrr
<typename
details::uvouv_node
<Type
> >(v0
, v1
, u0
, u1
, f
);
34376 details::free_all_nodes(*node_allocator_
,branch
);
34380 #undef basic_opr_switch_statements
34381 #undef extended_opr_switch_statements
34382 #undef unary_opr_switch_statements
34384 #ifndef exprtk_disable_string_capabilities
34386 #define string_opr_switch_statements \
34387 case_stmt(details:: e_lt ,details:: lt_op) \
34388 case_stmt(details:: e_lte ,details:: lte_op) \
34389 case_stmt(details:: e_gt ,details:: gt_op) \
34390 case_stmt(details:: e_gte ,details:: gte_op) \
34391 case_stmt(details:: e_eq ,details:: eq_op) \
34392 case_stmt(details:: e_ne ,details:: ne_op) \
34393 case_stmt(details::e_in ,details:: in_op) \
34394 case_stmt(details::e_like ,details:: like_op) \
34395 case_stmt(details::e_ilike,details::ilike_op) \
34397 template <typename T0, typename T1>
34398 inline expression_node_ptr
synthesize_str_xrox_expression_impl(const details::operator_type
& opr
,
34404 #define case_stmt(op0,op1) \
34405 case op0 : return node_allocator_-> \
34406 allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
34409 string_opr_switch_statements
34411 default : return error_node();
34415 template <typename T0
, typename T1
>
34416 inline expression_node_ptr
synthesize_str_xoxr_expression_impl(const details::operator_type
& opr
,
34422 #define case_stmt(op0,op1) \
34423 case op0 : return node_allocator_-> \
34424 allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
34427 string_opr_switch_statements
34429 default : return error_node();
34433 template <typename T0
, typename T1
>
34434 inline expression_node_ptr
synthesize_str_xroxr_expression_impl(const details::operator_type
& opr
,
34436 range_t rp0
, range_t rp1
)
34440 #define case_stmt(op0,op1) \
34441 case op0 : return node_allocator_-> \
34442 allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
34443 (s0, s1, rp0, rp1); \
34445 string_opr_switch_statements
34447 default : return error_node();
34451 template <typename T0
, typename T1
>
34452 inline expression_node_ptr
synthesize_sos_expression_impl(const details::operator_type
& opr
, T0 s0
, T1 s1
)
34456 #define case_stmt(op0,op1) \
34457 case op0 : return node_allocator_-> \
34458 allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \
34460 string_opr_switch_statements
34462 default : return error_node();
34466 inline expression_node_ptr
synthesize_sos_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34468 std::string
& s0
= static_cast<details::stringvar_node
<Type
>*>(branch
[0])->ref();
34469 std::string
& s1
= static_cast<details::stringvar_node
<Type
>*>(branch
[1])->ref();
34471 return synthesize_sos_expression_impl
<std::string
&,std::string
&>(opr
, s0
, s1
);
34474 inline expression_node_ptr
synthesize_sros_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34476 std::string
& s0
= static_cast<details::string_range_node
<Type
>*>(branch
[0])->ref ();
34477 std::string
& s1
= static_cast<details::stringvar_node
<Type
>*> (branch
[1])->ref ();
34478 range_t rp0
= static_cast<details::string_range_node
<Type
>*>(branch
[0])->range();
34480 static_cast<details::string_range_node
<Type
>*>(branch
[0])->range_ref().clear();
34482 free_node(*node_allocator_
,branch
[0]);
34484 return synthesize_str_xrox_expression_impl
<std::string
&,std::string
&>(opr
, s0
, s1
, rp0
);
34487 inline expression_node_ptr
synthesize_sosr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34489 std::string
& s0
= static_cast<details::stringvar_node
<Type
>*> (branch
[0])->ref ();
34490 std::string
& s1
= static_cast<details::string_range_node
<Type
>*>(branch
[1])->ref ();
34491 range_t rp1
= static_cast<details::string_range_node
<Type
>*>(branch
[1])->range();
34493 static_cast<details::string_range_node
<Type
>*>(branch
[1])->range_ref().clear();
34495 free_node(*node_allocator_
,branch
[1]);
34497 return synthesize_str_xoxr_expression_impl
<std::string
&,std::string
&>(opr
, s0
, s1
, rp1
);
34500 inline expression_node_ptr
synthesize_socsr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34502 std::string
& s0
= static_cast<details::stringvar_node
<Type
>*> (branch
[0])->ref ();
34503 std::string s1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->str ();
34504 range_t rp1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range();
34506 static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range_ref().clear();
34508 free_node(*node_allocator_
,branch
[1]);
34510 return synthesize_str_xoxr_expression_impl
<std::string
&, const std::string
>(opr
, s0
, s1
, rp1
);
34513 inline expression_node_ptr
synthesize_srosr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34515 std::string
& s0
= static_cast<details::string_range_node
<Type
>*>(branch
[0])->ref ();
34516 std::string
& s1
= static_cast<details::string_range_node
<Type
>*>(branch
[1])->ref ();
34517 range_t rp0
= static_cast<details::string_range_node
<Type
>*>(branch
[0])->range();
34518 range_t rp1
= static_cast<details::string_range_node
<Type
>*>(branch
[1])->range();
34520 static_cast<details::string_range_node
<Type
>*>(branch
[0])->range_ref().clear();
34521 static_cast<details::string_range_node
<Type
>*>(branch
[1])->range_ref().clear();
34523 details::free_node(*node_allocator_
,branch
[0]);
34524 details::free_node(*node_allocator_
,branch
[1]);
34526 return synthesize_str_xroxr_expression_impl
<std::string
&,std::string
&>(opr
, s0
, s1
, rp0
, rp1
);
34529 inline expression_node_ptr
synthesize_socs_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34531 std::string
& s0
= static_cast< details::stringvar_node
<Type
>*>(branch
[0])->ref();
34532 std::string s1
= static_cast<details::string_literal_node
<Type
>*>(branch
[1])->str();
34534 details::free_node(*node_allocator_
,branch
[1]);
34536 return synthesize_sos_expression_impl
<std::string
&, const std::string
>(opr
, s0
, s1
);
34539 inline expression_node_ptr
synthesize_csos_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34541 std::string s0
= static_cast<details::string_literal_node
<Type
>*>(branch
[0])->str();
34542 std::string
& s1
= static_cast< details::stringvar_node
<Type
>*>(branch
[1])->ref();
34544 details::free_node(*node_allocator_
,branch
[0]);
34546 return synthesize_sos_expression_impl
<const std::string
,std::string
&>(opr
, s0
, s1
);
34549 inline expression_node_ptr
synthesize_csosr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34551 std::string s0
= static_cast<details::string_literal_node
<Type
>*>(branch
[0])->str ();
34552 std::string
& s1
= static_cast<details::string_range_node
<Type
>*> (branch
[1])->ref ();
34553 range_t rp1
= static_cast<details::string_range_node
<Type
>*> (branch
[1])->range();
34555 static_cast<details::string_range_node
<Type
>*>(branch
[1])->range_ref().clear();
34557 details::free_node(*node_allocator_
,branch
[0]);
34558 details::free_node(*node_allocator_
,branch
[1]);
34560 return synthesize_str_xoxr_expression_impl
<const std::string
,std::string
&>(opr
, s0
, s1
, rp1
);
34563 inline expression_node_ptr
synthesize_srocs_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34565 std::string
& s0
= static_cast<details::string_range_node
<Type
>*> (branch
[0])->ref ();
34566 std::string s1
= static_cast<details::string_literal_node
<Type
>*>(branch
[1])->str ();
34567 range_t rp0
= static_cast<details::string_range_node
<Type
>*> (branch
[0])->range();
34569 static_cast<details::string_range_node
<Type
>*>(branch
[0])->range_ref().clear();
34571 details::free_node(*node_allocator_
,branch
[0]);
34572 details::free_node(*node_allocator_
,branch
[1]);
34574 return synthesize_str_xrox_expression_impl
<std::string
&, const std::string
>(opr
, s0
, s1
, rp0
);
34577 inline expression_node_ptr
synthesize_srocsr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34579 std::string
& s0
= static_cast<details::string_range_node
<Type
>*> (branch
[0])->ref ();
34580 std::string s1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->str ();
34581 range_t rp0
= static_cast<details::string_range_node
<Type
>*> (branch
[0])->range();
34582 range_t rp1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range();
34584 static_cast<details::string_range_node
<Type
>*> (branch
[0])->range_ref().clear();
34585 static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range_ref().clear();
34587 details::free_node(*node_allocator_
,branch
[0]);
34588 details::free_node(*node_allocator_
,branch
[1]);
34590 return synthesize_str_xroxr_expression_impl
<std::string
&, const std::string
>(opr
, s0
, s1
, rp0
, rp1
);
34593 inline expression_node_ptr
synthesize_csocs_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34595 const std::string s0
= static_cast<details::string_literal_node
<Type
>*>(branch
[0])->str();
34596 const std::string s1
= static_cast<details::string_literal_node
<Type
>*>(branch
[1])->str();
34598 expression_node_ptr result
= error_node();
34600 if (details::e_add
== opr
)
34601 result
= node_allocator_
->allocate_c
<details::string_literal_node
<Type
> >(s0
+ s1
);
34602 else if (details::e_in
== opr
)
34603 result
= node_allocator_
->allocate_c
<details::literal_node
<Type
> >(details::in_op
<Type
>::process(s0
,s1
));
34604 else if (details::e_like
== opr
)
34605 result
= node_allocator_
->allocate_c
<details::literal_node
<Type
> >(details::like_op
<Type
>::process(s0
,s1
));
34606 else if (details::e_ilike
== opr
)
34607 result
= node_allocator_
->allocate_c
<details::literal_node
<Type
> >(details::ilike_op
<Type
>::process(s0
,s1
));
34610 expression_node_ptr temp
= synthesize_sos_expression_impl
<const std::string
, const std::string
>(opr
, s0
, s1
);
34612 const Type v
= temp
->value();
34614 details::free_node(*node_allocator_
,temp
);
34616 result
= node_allocator_
->allocate
<literal_node_t
>(v
);
34619 details::free_all_nodes(*node_allocator_
,branch
);
34624 inline expression_node_ptr
synthesize_csocsr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34626 const std::string s0
= static_cast<details::string_literal_node
<Type
>*> (branch
[0])->str ();
34627 std::string s1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->str ();
34628 range_t rp1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range();
34630 static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range_ref().clear();
34632 free_node(*node_allocator_
,branch
[0]);
34633 free_node(*node_allocator_
,branch
[1]);
34635 return synthesize_str_xoxr_expression_impl
<const std::string
, const std::string
>(opr
, s0
, s1
, rp1
);
34638 inline expression_node_ptr
synthesize_csros_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34640 std::string s0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->str ();
34641 std::string
& s1
= static_cast<details::stringvar_node
<Type
>*> (branch
[1])->ref ();
34642 range_t rp0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range();
34644 static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range_ref().clear();
34646 free_node(*node_allocator_
,branch
[0]);
34648 return synthesize_str_xrox_expression_impl
<const std::string
,std::string
&>(opr
, s0
, s1
, rp0
);
34651 inline expression_node_ptr
synthesize_csrosr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34653 const std::string s0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->str ();
34654 std::string
& s1
= static_cast<details::string_range_node
<Type
>*> (branch
[1])->ref ();
34655 const range_t rp0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range();
34656 const range_t rp1
= static_cast<details::string_range_node
<Type
>*> (branch
[1])->range();
34658 static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range_ref().clear();
34659 static_cast<details::string_range_node
<Type
>*> (branch
[1])->range_ref().clear();
34661 free_node(*node_allocator_
,branch
[0]);
34662 free_node(*node_allocator_
,branch
[1]);
34664 return synthesize_str_xroxr_expression_impl
<const std::string
,std::string
&>(opr
, s0
, s1
, rp0
, rp1
);
34667 inline expression_node_ptr
synthesize_csrocs_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34669 const std::string s0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->str ();
34670 const std::string s1
= static_cast<details::string_literal_node
<Type
>*> (branch
[1])->str ();
34671 const range_t rp0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range();
34673 static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range_ref().clear();
34675 details::free_all_nodes(*node_allocator_
,branch
);
34677 return synthesize_str_xrox_expression_impl
<const std::string
,std::string
>(opr
, s0
, s1
, rp0
);
34680 inline expression_node_ptr
synthesize_csrocsr_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34682 const std::string s0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->str ();
34683 const std::string s1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->str ();
34684 const range_t rp0
= static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range();
34685 const range_t rp1
= static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range();
34687 static_cast<details::const_string_range_node
<Type
>*>(branch
[0])->range_ref().clear();
34688 static_cast<details::const_string_range_node
<Type
>*>(branch
[1])->range_ref().clear();
34690 details::free_all_nodes(*node_allocator_
,branch
);
34692 return synthesize_str_xroxr_expression_impl
<const std::string
, const std::string
>(opr
, s0
, s1
, rp0
, rp1
);
34695 inline expression_node_ptr
synthesize_strogen_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34699 #define case_stmt(op0,op1) \
34700 case op0 : return node_allocator_-> \
34701 allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
34702 (opr, branch[0], branch[1]); \
34704 string_opr_switch_statements
34706 default : return error_node();
34711 #ifndef exprtk_disable_string_capabilities
34712 inline expression_node_ptr
synthesize_string_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[2])
34714 if ((0 == branch
[0]) || (0 == branch
[1]))
34716 details::free_all_nodes(*node_allocator_
,branch
);
34718 return error_node();
34721 const bool b0_is_s
= details::is_string_node (branch
[0]);
34722 const bool b0_is_cs
= details::is_const_string_node (branch
[0]);
34723 const bool b0_is_sr
= details::is_string_range_node (branch
[0]);
34724 const bool b0_is_csr
= details::is_const_string_range_node(branch
[0]);
34726 const bool b1_is_s
= details::is_string_node (branch
[1]);
34727 const bool b1_is_cs
= details::is_const_string_node (branch
[1]);
34728 const bool b1_is_sr
= details::is_string_range_node (branch
[1]);
34729 const bool b1_is_csr
= details::is_const_string_range_node(branch
[1]);
34731 const bool b0_is_gen
= details::is_string_assignment_node (branch
[0]) ||
34732 details::is_genricstring_range_node(branch
[0]) ||
34733 details::is_string_concat_node (branch
[0]) ||
34734 details::is_string_function_node (branch
[0]) ||
34735 details::is_string_condition_node (branch
[0]) ||
34736 details::is_string_ccondition_node (branch
[0]) ||
34737 details::is_string_vararg_node (branch
[0]) ;
34739 const bool b1_is_gen
= details::is_string_assignment_node (branch
[1]) ||
34740 details::is_genricstring_range_node(branch
[1]) ||
34741 details::is_string_concat_node (branch
[1]) ||
34742 details::is_string_function_node (branch
[1]) ||
34743 details::is_string_condition_node (branch
[1]) ||
34744 details::is_string_ccondition_node (branch
[1]) ||
34745 details::is_string_vararg_node (branch
[1]) ;
34747 if (details::e_add
== opr
)
34749 if (!b0_is_cs
|| !b1_is_cs
)
34751 return synthesize_expression
<string_concat_node_t
,2>(opr
,branch
);
34755 if (b0_is_gen
|| b1_is_gen
)
34757 return synthesize_strogen_expression(opr
,branch
);
34761 if (b1_is_s
) return synthesize_sos_expression (opr
,branch
);
34762 else if (b1_is_cs
) return synthesize_socs_expression (opr
,branch
);
34763 else if (b1_is_sr
) return synthesize_sosr_expression (opr
,branch
);
34764 else if (b1_is_csr
) return synthesize_socsr_expression (opr
,branch
);
34768 if (b1_is_s
) return synthesize_csos_expression (opr
,branch
);
34769 else if (b1_is_cs
) return synthesize_csocs_expression (opr
,branch
);
34770 else if (b1_is_sr
) return synthesize_csosr_expression (opr
,branch
);
34771 else if (b1_is_csr
) return synthesize_csocsr_expression(opr
,branch
);
34775 if (b1_is_s
) return synthesize_sros_expression (opr
,branch
);
34776 else if (b1_is_sr
) return synthesize_srosr_expression (opr
,branch
);
34777 else if (b1_is_cs
) return synthesize_srocs_expression (opr
,branch
);
34778 else if (b1_is_csr
) return synthesize_srocsr_expression(opr
,branch
);
34780 else if (b0_is_csr
)
34782 if (b1_is_s
) return synthesize_csros_expression (opr
,branch
);
34783 else if (b1_is_sr
) return synthesize_csrosr_expression (opr
,branch
);
34784 else if (b1_is_cs
) return synthesize_csrocs_expression (opr
,branch
);
34785 else if (b1_is_csr
) return synthesize_csrocsr_expression(opr
,branch
);
34788 return error_node();
34791 inline expression_node_ptr
synthesize_string_expression(const details::operator_type
&, expression_node_ptr (&branch
)[2])
34793 details::free_all_nodes(*node_allocator_
,branch
);
34794 return error_node();
34798 #ifndef exprtk_disable_string_capabilities
34799 inline expression_node_ptr
synthesize_string_expression(const details::operator_type
& opr
, expression_node_ptr (&branch
)[3])
34801 if (details::e_inrange
!= opr
)
34802 return error_node();
34803 else if ((0 == branch
[0]) || (0 == branch
[1]) || (0 == branch
[2]))
34805 details::free_all_nodes(*node_allocator_
,branch
);
34807 return error_node();
34810 details::is_const_string_node(branch
[0]) &&
34811 details::is_const_string_node(branch
[1]) &&
34812 details::is_const_string_node(branch
[2])
34815 const std::string s0
= static_cast<details::string_literal_node
<Type
>*>(branch
[0])->str();
34816 const std::string s1
= static_cast<details::string_literal_node
<Type
>*>(branch
[1])->str();
34817 const std::string s2
= static_cast<details::string_literal_node
<Type
>*>(branch
[2])->str();
34819 const Type v
= (((s0
<= s1
) && (s1
<= s2
)) ? Type(1) : Type(0));
34821 details::free_all_nodes(*node_allocator_
,branch
);
34823 return node_allocator_
->allocate_c
<details::literal_node
<Type
> >(v
);
34826 details::is_string_node(branch
[0]) &&
34827 details::is_string_node(branch
[1]) &&
34828 details::is_string_node(branch
[2])
34831 std::string
& s0
= static_cast<details::stringvar_node
<Type
>*>(branch
[0])->ref();
34832 std::string
& s1
= static_cast<details::stringvar_node
<Type
>*>(branch
[1])->ref();
34833 std::string
& s2
= static_cast<details::stringvar_node
<Type
>*>(branch
[2])->ref();
34835 typedef typename
details::sosos_node
<Type
, std::string
&, std::string
&, std::string
&, details::inrange_op
<Type
> > inrange_t
;
34837 return node_allocator_
->allocate_type
<inrange_t
, std::string
&, std::string
&, std::string
&>(s0
, s1
, s2
);
34840 details::is_const_string_node(branch
[0]) &&
34841 details::is_string_node(branch
[1]) &&
34842 details::is_const_string_node(branch
[2])
34845 std::string s0
= static_cast<details::string_literal_node
<Type
>*>(branch
[0])->str();
34846 std::string
& s1
= static_cast< details::stringvar_node
<Type
>*>(branch
[1])->ref();
34847 std::string s2
= static_cast<details::string_literal_node
<Type
>*>(branch
[2])->str();
34849 typedef typename
details::sosos_node
<Type
, std::string
, std::string
&, std::string
, details::inrange_op
<Type
> > inrange_t
;
34851 details::free_node(*node_allocator_
,branch
[0]);
34852 details::free_node(*node_allocator_
,branch
[2]);
34854 return node_allocator_
->allocate_type
<inrange_t
, std::string
, std::string
&, std::string
>(s0
, s1
, s2
);
34857 details::is_string_node(branch
[0]) &&
34858 details::is_const_string_node(branch
[1]) &&
34859 details::is_string_node(branch
[2])
34862 std::string
& s0
= static_cast< details::stringvar_node
<Type
>*>(branch
[0])->ref();
34863 std::string s1
= static_cast<details::string_literal_node
<Type
>*>(branch
[1])->str();
34864 std::string
& s2
= static_cast< details::stringvar_node
<Type
>*>(branch
[2])->ref();
34866 typedef typename
details::sosos_node
<Type
, std::string
&, std::string
, std::string
&, details::inrange_op
<Type
> > inrange_t
;
34868 details::free_node(*node_allocator_
,branch
[1]);
34870 return node_allocator_
->allocate_type
<inrange_t
, std::string
&, std::string
, std::string
&>(s0
, s1
, s2
);
34873 details::is_string_node(branch
[0]) &&
34874 details::is_string_node(branch
[1]) &&
34875 details::is_const_string_node(branch
[2])
34878 std::string
& s0
= static_cast< details::stringvar_node
<Type
>*>(branch
[0])->ref();
34879 std::string
& s1
= static_cast< details::stringvar_node
<Type
>*>(branch
[1])->ref();
34880 std::string s2
= static_cast<details::string_literal_node
<Type
>*>(branch
[2])->str();
34882 typedef typename
details::sosos_node
<Type
, std::string
&, std::string
&, std::string
, details::inrange_op
<Type
> > inrange_t
;
34884 details::free_node(*node_allocator_
,branch
[2]);
34886 return node_allocator_
->allocate_type
<inrange_t
, std::string
&, std::string
&, std::string
>(s0
, s1
, s2
);
34889 details::is_const_string_node(branch
[0]) &&
34890 details:: is_string_node(branch
[1]) &&
34891 details:: is_string_node(branch
[2])
34894 std::string s0
= static_cast<details::string_literal_node
<Type
>*>(branch
[0])->str();
34895 std::string
& s1
= static_cast< details::stringvar_node
<Type
>*>(branch
[1])->ref();
34896 std::string
& s2
= static_cast< details::stringvar_node
<Type
>*>(branch
[2])->ref();
34898 typedef typename
details::sosos_node
<Type
, std::string
, std::string
&, std::string
&, details::inrange_op
<Type
> > inrange_t
;
34900 details::free_node(*node_allocator_
,branch
[0]);
34902 return node_allocator_
->allocate_type
<inrange_t
, std::string
, std::string
&, std::string
&>(s0
, s1
, s2
);
34905 return error_node();
34908 inline expression_node_ptr
synthesize_string_expression(const details::operator_type
&, expression_node_ptr (&branch
)[3])
34910 details::free_all_nodes(*node_allocator_
,branch
);
34911 return error_node();
34915 inline expression_node_ptr
synthesize_null_expression(const details::operator_type
& operation
, expression_node_ptr (&branch
)[2])
34918 Note: The following are the type promotion rules
34919 that relate to operations that include 'null':
34920 0. null ==/!= null --> true false
34921 1. null operation null --> null
34922 2. x ==/!= null --> true/false
34923 3. null ==/!= x --> true/false
34924 4. x operation null --> x
34925 5. null operation x --> x
34928 typedef typename
details::null_eq_node
<T
> nulleq_node_t
;
34930 const bool b0_null
= details::is_null_node(branch
[0]);
34931 const bool b1_null
= details::is_null_node(branch
[1]);
34933 if (b0_null
&& b1_null
)
34935 expression_node_ptr result
= error_node();
34937 if (details::e_eq
== operation
)
34938 result
= node_allocator_
->allocate_c
<literal_node_t
>(T(1));
34939 else if (details::e_ne
== operation
)
34940 result
= node_allocator_
->allocate_c
<literal_node_t
>(T(0));
34944 details::free_node(*node_allocator_
,branch
[0]);
34945 details::free_node(*node_allocator_
,branch
[1]);
34950 details::free_node(*node_allocator_
,branch
[1]);
34954 else if (details::e_eq
== operation
)
34956 expression_node_ptr result
= node_allocator_
->
34957 allocate_rc
<nulleq_node_t
>(branch
[b0_null
? 0 : 1],true);
34959 details::free_node(*node_allocator_
,branch
[b0_null
? 1 : 0]);
34963 else if (details::e_ne
== operation
)
34965 expression_node_ptr result
= node_allocator_
->
34966 allocate_rc
<nulleq_node_t
>(branch
[b0_null
? 0 : 1],false);
34968 details::free_node(*node_allocator_
,branch
[b0_null
? 1 : 0]);
34974 details::free_node(*node_allocator_
,branch
[0]);
34975 branch
[0] = branch
[1];
34976 branch
[1] = error_node();
34980 details::free_node(*node_allocator_
,branch
[1]);
34981 branch
[1] = error_node();
34985 (details::e_add
== operation
) || (details::e_sub
== operation
) ||
34986 (details::e_mul
== operation
) || (details::e_div
== operation
) ||
34987 (details::e_mod
== operation
) || (details::e_pow
== operation
)
34993 (details::e_lt
== operation
) || (details::e_lte
== operation
) ||
34994 (details::e_gt
== operation
) || (details::e_gte
== operation
) ||
34995 (details::e_and
== operation
) || (details::e_nand
== operation
) ||
34996 (details::e_or
== operation
) || (details::e_nor
== operation
) ||
34997 (details::e_xor
== operation
) || (details::e_xnor
== operation
) ||
34998 (details::e_in
== operation
) || (details::e_like
== operation
) ||
34999 (details::e_ilike
== operation
)
35002 return node_allocator_
->allocate_c
<literal_node_t
>(T(0));
35005 details::free_node(*node_allocator_
,branch
[0]);
35007 return node_allocator_
->allocate
<details::null_node
<Type
> >();
35010 template <typename NodeType
, std::size_t N
>
35011 inline expression_node_ptr
synthesize_expression(const details::operator_type
& operation
, expression_node_ptr (&branch
)[N
])
35014 (details::e_in
== operation
) ||
35015 (details::e_like
== operation
) ||
35016 (details::e_ilike
== operation
)
35019 free_all_nodes(*node_allocator_
,branch
);
35021 return error_node();
35023 else if (!details::all_nodes_valid
<N
>(branch
))
35025 free_all_nodes(*node_allocator_
,branch
);
35027 return error_node();
35029 else if ((details::e_default
!= operation
))
35031 // Attempt simple constant folding optimisation.
35032 expression_node_ptr expression_point
= node_allocator_
->allocate
<NodeType
>(operation
,branch
);
35034 if (is_constant_foldable
<N
>(branch
))
35036 const Type v
= expression_point
->value();
35037 details::free_node(*node_allocator_
,expression_point
);
35039 return node_allocator_
->allocate
<literal_node_t
>(v
);
35042 return expression_point
;
35045 return error_node();
35048 template <typename NodeType
, std::size_t N
>
35049 inline expression_node_ptr
synthesize_expression(F
* f
, expression_node_ptr (&branch
)[N
])
35051 if (!details::all_nodes_valid
<N
>(branch
))
35053 free_all_nodes(*node_allocator_
,branch
);
35055 return error_node();
35058 typedef typename
details::function_N_node
<T
,ifunction_t
,N
> function_N_node_t
;
35060 // Attempt simple constant folding optimisation.
35062 expression_node_ptr expression_point
= node_allocator_
->allocate
<NodeType
>(f
);
35063 function_N_node_t
* func_node_ptr
= dynamic_cast<function_N_node_t
*>(expression_point
);
35065 if (0 == func_node_ptr
)
35067 free_all_nodes(*node_allocator_
,branch
);
35069 return error_node();
35072 func_node_ptr
->init_branches(branch
);
35074 if (is_constant_foldable
<N
>(branch
) && !f
->has_side_effects())
35076 Type v
= expression_point
->value();
35077 details::free_node(*node_allocator_
,expression_point
);
35079 return node_allocator_
->allocate
<literal_node_t
>(v
);
35082 parser_
->state_
.activate_side_effect("synthesize_expression(function<NT,N>)");
35084 return expression_point
;
35087 bool strength_reduction_enabled_
;
35088 details::node_allocator
* node_allocator_
;
35089 synthesize_map_t synthesize_map_
;
35090 unary_op_map_t
* unary_op_map_
;
35091 binary_op_map_t
* binary_op_map_
;
35092 inv_binary_op_map_t
* inv_binary_op_map_
;
35093 sf3_map_t
* sf3_map_
;
35094 sf4_map_t
* sf4_map_
;
35098 inline void set_error(const parser_error::type
& error_type
)
35100 error_list_
.push_back(error_type
);
35103 inline void remove_last_error()
35105 if (!error_list_
.empty())
35107 error_list_
.pop_back();
35111 inline void set_synthesis_error(const std::string
& synthesis_error_message
)
35113 if (synthesis_error_
.empty())
35115 synthesis_error_
= synthesis_error_message
;
35119 inline void register_local_vars(expression
<T
>& e
)
35121 for (std::size_t i
= 0; i
< sem_
.size(); ++i
)
35123 scope_element
& se
= sem_
.get_element(i
);
35126 (scope_element::e_variable
== se
.type
) ||
35127 (scope_element::e_vecelem
== se
.type
)
35132 e
.register_local_var(se
.var_node
);
35137 e
.register_local_data(se
.data
, 1, 0);
35140 else if (scope_element::e_vector
== se
.type
)
35144 e
.register_local_var(se
.vec_node
);
35149 e
.register_local_data(se
.data
, se
.size
, 1);
35152 #ifndef exprtk_disable_string_capabilities
35153 else if (scope_element::e_string
== se
.type
)
35157 e
.register_local_var(se
.str_node
);
35162 e
.register_local_data(se
.data
, se
.size
, 2);
35169 #ifndef exprtk_disable_string_capabilities
35178 inline void register_return_results(expression
<T
>& e
)
35180 e
.register_return_results(results_context_
);
35181 results_context_
= 0;
35184 inline void load_unary_operations_map(unary_op_map_t
& m
)
35186 #define register_unary_op(Op,UnaryFunctor) \
35187 m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
35189 register_unary_op(details:: e_abs, details:: abs_op)
35190 register_unary_op(details:: e_acos
, details:: acos_op
)
35191 register_unary_op(details::e_acosh
, details::acosh_op
)
35192 register_unary_op(details:: e_asin
, details:: asin_op
)
35193 register_unary_op(details::e_asinh
, details::asinh_op
)
35194 register_unary_op(details::e_atanh
, details::atanh_op
)
35195 register_unary_op(details:: e_ceil
, details:: ceil_op
)
35196 register_unary_op(details:: e_cos
, details:: cos_op
)
35197 register_unary_op(details:: e_cosh
, details:: cosh_op
)
35198 register_unary_op(details:: e_exp
, details:: exp_op
)
35199 register_unary_op(details::e_expm1
, details::expm1_op
)
35200 register_unary_op(details::e_floor
, details::floor_op
)
35201 register_unary_op(details:: e_log
, details:: log_op
)
35202 register_unary_op(details::e_log10
, details::log10_op
)
35203 register_unary_op(details:: e_log2
, details:: log2_op
)
35204 register_unary_op(details::e_log1p
, details::log1p_op
)
35205 register_unary_op(details:: e_neg
, details:: neg_op
)
35206 register_unary_op(details:: e_pos
, details:: pos_op
)
35207 register_unary_op(details::e_round
, details::round_op
)
35208 register_unary_op(details:: e_sin
, details:: sin_op
)
35209 register_unary_op(details:: e_sinc
, details:: sinc_op
)
35210 register_unary_op(details:: e_sinh
, details:: sinh_op
)
35211 register_unary_op(details:: e_sqrt
, details:: sqrt_op
)
35212 register_unary_op(details:: e_tan
, details:: tan_op
)
35213 register_unary_op(details:: e_tanh
, details:: tanh_op
)
35214 register_unary_op(details:: e_cot
, details:: cot_op
)
35215 register_unary_op(details:: e_sec
, details:: sec_op
)
35216 register_unary_op(details:: e_csc
, details:: csc_op
)
35217 register_unary_op(details:: e_r2d
, details:: r2d_op
)
35218 register_unary_op(details:: e_d2r
, details:: d2r_op
)
35219 register_unary_op(details:: e_d2g
, details:: d2g_op
)
35220 register_unary_op(details:: e_g2d
, details:: g2d_op
)
35221 register_unary_op(details:: e_notl
, details:: notl_op
)
35222 register_unary_op(details:: e_sgn
, details:: sgn_op
)
35223 register_unary_op(details:: e_erf
, details:: erf_op
)
35224 register_unary_op(details:: e_erfc
, details:: erfc_op
)
35225 register_unary_op(details:: e_ncdf
, details:: ncdf_op
)
35226 register_unary_op(details:: e_frac
, details:: frac_op
)
35227 register_unary_op(details::e_trunc
, details::trunc_op
)
35228 #undef register_unary_op
35231 inline void load_binary_operations_map(binary_op_map_t
& m
)
35233 typedef typename
binary_op_map_t::value_type value_type
;
35235 #define register_binary_op(Op,BinaryFunctor) \
35236 m.insert(value_type(Op,BinaryFunctor<T>::process)); \
35238 register_binary_op(details:: e_add, details:: add_op)
35239 register_binary_op(details:: e_sub
, details:: sub_op
)
35240 register_binary_op(details:: e_mul
, details:: mul_op
)
35241 register_binary_op(details:: e_div
, details:: div_op
)
35242 register_binary_op(details:: e_mod
, details:: mod_op
)
35243 register_binary_op(details:: e_pow
, details:: pow_op
)
35244 register_binary_op(details:: e_lt
, details:: lt_op
)
35245 register_binary_op(details:: e_lte
, details:: lte_op
)
35246 register_binary_op(details:: e_gt
, details:: gt_op
)
35247 register_binary_op(details:: e_gte
, details:: gte_op
)
35248 register_binary_op(details:: e_eq
, details:: eq_op
)
35249 register_binary_op(details:: e_ne
, details:: ne_op
)
35250 register_binary_op(details:: e_and
, details:: and_op
)
35251 register_binary_op(details::e_nand
, details::nand_op
)
35252 register_binary_op(details:: e_or
, details:: or_op
)
35253 register_binary_op(details:: e_nor
, details:: nor_op
)
35254 register_binary_op(details:: e_xor
, details:: xor_op
)
35255 register_binary_op(details::e_xnor
, details::xnor_op
)
35256 #undef register_binary_op
35259 inline void load_inv_binary_operations_map(inv_binary_op_map_t
& m
)
35261 typedef typename
inv_binary_op_map_t::value_type value_type
;
35263 #define register_binary_op(Op,BinaryFunctor) \
35264 m.insert(value_type(BinaryFunctor<T>::process,Op)); \
35266 register_binary_op(details:: e_add, details:: add_op)
35267 register_binary_op(details:: e_sub
, details:: sub_op
)
35268 register_binary_op(details:: e_mul
, details:: mul_op
)
35269 register_binary_op(details:: e_div
, details:: div_op
)
35270 register_binary_op(details:: e_mod
, details:: mod_op
)
35271 register_binary_op(details:: e_pow
, details:: pow_op
)
35272 register_binary_op(details:: e_lt
, details:: lt_op
)
35273 register_binary_op(details:: e_lte
, details:: lte_op
)
35274 register_binary_op(details:: e_gt
, details:: gt_op
)
35275 register_binary_op(details:: e_gte
, details:: gte_op
)
35276 register_binary_op(details:: e_eq
, details:: eq_op
)
35277 register_binary_op(details:: e_ne
, details:: ne_op
)
35278 register_binary_op(details:: e_and
, details:: and_op
)
35279 register_binary_op(details::e_nand
, details::nand_op
)
35280 register_binary_op(details:: e_or
, details:: or_op
)
35281 register_binary_op(details:: e_nor
, details:: nor_op
)
35282 register_binary_op(details:: e_xor
, details:: xor_op
)
35283 register_binary_op(details::e_xnor
, details::xnor_op
)
35284 #undef register_binary_op
35287 inline void load_sf3_map(sf3_map_t
& sf3_map
)
35289 typedef std::pair
<trinary_functor_t
,details::operator_type
> pair_t
;
35291 #define register_sf3(Op) \
35292 sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
35294 register_sf3(00) register_sf3(01) register_sf3(02) register_sf3(03)
35295 register_sf3(04) register_sf3(05) register_sf3(06) register_sf3(07)
35296 register_sf3(08) register_sf3(09) register_sf3(10) register_sf3(11)
35297 register_sf3(12) register_sf3(13) register_sf3(14) register_sf3(15)
35298 register_sf3(16) register_sf3(17) register_sf3(18) register_sf3(19)
35299 register_sf3(20) register_sf3(21) register_sf3(22) register_sf3(23)
35300 register_sf3(24) register_sf3(25) register_sf3(26) register_sf3(27)
35301 register_sf3(28) register_sf3(29) register_sf3(30)
35302 #undef register_sf3
35304 #define register_sf3_extid(Id, Op) \
35305 sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
35307 register_sf3_extid("(t-t)-t",23) // (t-t)-t --> t-(t+t)
35308 #undef register_sf3_extid
35311 inline void load_sf4_map(sf4_map_t
& sf4_map
)
35313 typedef std::pair
<quaternary_functor_t
,details::operator_type
> pair_t
;
35315 #define register_sf4(Op) \
35316 sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
35318 register_sf4(48) register_sf4(49) register_sf4(50) register_sf4(51)
35319 register_sf4(52) register_sf4(53) register_sf4(54) register_sf4(55)
35320 register_sf4(56) register_sf4(57) register_sf4(58) register_sf4(59)
35321 register_sf4(60) register_sf4(61) register_sf4(62) register_sf4(63)
35322 register_sf4(64) register_sf4(65) register_sf4(66) register_sf4(67)
35323 register_sf4(68) register_sf4(69) register_sf4(70) register_sf4(71)
35324 register_sf4(72) register_sf4(73) register_sf4(74) register_sf4(75)
35325 register_sf4(76) register_sf4(77) register_sf4(78) register_sf4(79)
35326 register_sf4(80) register_sf4(81) register_sf4(82) register_sf4(83)
35327 #undef register_sf4
35329 #define register_sf4ext(Op) \
35330 sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
35332 register_sf4ext(00) register_sf4ext(01) register_sf4ext(02) register_sf4ext(03)
35333 register_sf4ext(04) register_sf4ext(05) register_sf4ext(06) register_sf4ext(07)
35334 register_sf4ext(08) register_sf4ext(09) register_sf4ext(10) register_sf4ext(11)
35335 register_sf4ext(12) register_sf4ext(13) register_sf4ext(14) register_sf4ext(15)
35336 register_sf4ext(16) register_sf4ext(17) register_sf4ext(18) register_sf4ext(19)
35337 register_sf4ext(20) register_sf4ext(21) register_sf4ext(22) register_sf4ext(23)
35338 register_sf4ext(24) register_sf4ext(25) register_sf4ext(26) register_sf4ext(27)
35339 register_sf4ext(28) register_sf4ext(29) register_sf4ext(30) register_sf4ext(31)
35340 register_sf4ext(32) register_sf4ext(33) register_sf4ext(34) register_sf4ext(35)
35341 register_sf4ext(36) register_sf4ext(36) register_sf4ext(38) register_sf4ext(39)
35342 register_sf4ext(40) register_sf4ext(41) register_sf4ext(42) register_sf4ext(43)
35343 register_sf4ext(44) register_sf4ext(45) register_sf4ext(46) register_sf4ext(47)
35344 register_sf4ext(48) register_sf4ext(49) register_sf4ext(50) register_sf4ext(51)
35345 register_sf4ext(52) register_sf4ext(53) register_sf4ext(54) register_sf4ext(55)
35346 register_sf4ext(56) register_sf4ext(57) register_sf4ext(58) register_sf4ext(59)
35347 register_sf4ext(60) register_sf4ext(61)
35348 #undef register_sf4ext
35351 inline results_context_t
& results_ctx()
35353 if (0 == results_context_
)
35355 results_context_
= new results_context_t();
35358 return (*results_context_
);
35361 inline void return_cleanup()
35363 #ifndef exprtk_disable_return_statement
35364 if (results_context_
)
35366 delete results_context_
;
35367 results_context_
= 0;
35370 state_
.return_stmt_present
= false;
35376 parser(const parser
<T
>&);
35377 parser
<T
>& operator=(const parser
<T
>&);
35379 settings_store settings_
;
35380 expression_generator
<T
> expression_generator_
;
35381 details::node_allocator node_allocator_
;
35382 symtab_store symtab_store_
;
35383 dependent_entity_collector dec_
;
35384 std::deque
<parser_error::type
> error_list_
;
35385 std::deque
<bool> brkcnt_list_
;
35386 parser_state state_
;
35387 bool resolve_unknown_symbol_
;
35388 results_context_t
* results_context_
;
35389 unknown_symbol_resolver
* unknown_symbol_resolver_
;
35390 unknown_symbol_resolver default_usr_
;
35391 base_ops_map_t base_ops_map_
;
35392 unary_op_map_t unary_op_map_
;
35393 binary_op_map_t binary_op_map_
;
35394 inv_binary_op_map_t inv_binary_op_map_
;
35395 sf3_map_t sf3_map_
;
35396 sf4_map_t sf4_map_
;
35397 std::string synthesis_error_
;
35398 scope_element_manager sem_
;
35400 lexer::helper::helper_assembly helper_assembly_
;
35402 lexer::helper::commutative_inserter commutative_inserter_
;
35403 lexer::helper::operator_joiner operator_joiner_2_
;
35404 lexer::helper::operator_joiner operator_joiner_3_
;
35405 lexer::helper::symbol_replacer symbol_replacer_
;
35406 lexer::helper::bracket_checker bracket_checker_
;
35407 lexer::helper::numeric_checker numeric_checker_
;
35408 lexer::helper::sequence_validator sequence_validator_
;
35409 lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_
;
35411 template <typename ParserType
>
35412 friend void details::disable_type_checking(ParserType
& p
);
35417 template <typename T
>
35418 struct collector_helper
35420 typedef exprtk::symbol_table
<T
> symbol_table_t
;
35421 typedef exprtk::expression
<T
> expression_t
;
35422 typedef exprtk::parser
<T
> parser_t
;
35423 typedef typename
parser_t::dependent_entity_collector::symbol_t symbol_t
;
35424 typedef typename
parser_t::unknown_symbol_resolver usr_t
;
35426 struct resolve_as_vector
: public parser_t::unknown_symbol_resolver
35428 typedef exprtk::parser
<T
> parser_t
;
35430 resolve_as_vector()
35431 : usr_t(usr_t::e_usrmode_extended
)
35434 virtual bool process(const std::string
& unknown_symbol
,
35435 symbol_table_t
& symbol_table
,
35439 symbol_table
.add_vector(unknown_symbol
,v
);
35444 static inline bool collection_pass(const std::string
& expression_string
,
35445 std::set
<std::string
>& symbol_set
,
35446 const bool collect_variables
,
35447 const bool collect_functions
,
35448 const bool vector_pass
,
35449 symbol_table_t
& ext_symbol_table
)
35451 symbol_table_t symbol_table
;
35452 expression_t expression
;
35455 resolve_as_vector vect_resolver
;
35457 expression
.register_symbol_table(symbol_table
);
35458 expression
.register_symbol_table(ext_symbol_table
);
35461 parser
.enable_unknown_symbol_resolver(&vect_resolver
);
35463 parser
.enable_unknown_symbol_resolver();
35465 if (collect_variables
)
35466 parser
.dec().collect_variables() = true;
35468 if (collect_functions
)
35469 parser
.dec().collect_functions() = true;
35471 bool pass_result
= false;
35473 details::disable_type_checking(parser
);
35475 if (parser
.compile(expression_string
, expression
))
35477 pass_result
= true;
35479 std::deque
<symbol_t
> symb_list
;
35480 parser
.dec().symbols(symb_list
);
35482 for (std::size_t i
= 0; i
< symb_list
.size(); ++i
)
35484 symbol_set
.insert(symb_list
[i
].first
);
35488 return pass_result
;
35493 template <typename Allocator
,
35494 template <typename
, typename
> class Sequence
>
35495 inline bool collect_variables(const std::string
& expression
,
35496 Sequence
<std::string
, Allocator
>& symbol_list
)
35499 typedef details::collector_helper
<T
> collect_t
;
35501 collect_t::symbol_table_t null_symbol_table
;
35503 std::set
<std::string
> symbol_set
;
35505 const bool variable_pass
= collect_t::collection_pass
35506 (expression
, symbol_set
, true, false, false, null_symbol_table
);
35507 const bool vector_pass
= collect_t::collection_pass
35508 (expression
, symbol_set
, true, false, true, null_symbol_table
);
35510 if (!variable_pass
&& !vector_pass
)
35513 std::set
<std::string
>::iterator itr
= symbol_set
.begin();
35515 while (symbol_set
.end() != itr
)
35517 symbol_list
.push_back(*itr
);
35524 template <typename T
,
35525 typename Allocator
,
35526 template <typename
, typename
> class Sequence
>
35527 inline bool collect_variables(const std::string
& expression
,
35528 exprtk::symbol_table
<T
>& extrnl_symbol_table
,
35529 Sequence
<std::string
, Allocator
>& symbol_list
)
35531 typedef details::collector_helper
<T
> collect_t
;
35533 std::set
<std::string
> symbol_set
;
35535 const bool variable_pass
= collect_t::collection_pass
35536 (expression
, symbol_set
, true, false, false, extrnl_symbol_table
);
35537 const bool vector_pass
= collect_t::collection_pass
35538 (expression
, symbol_set
, true, false, true, extrnl_symbol_table
);
35540 if (!variable_pass
&& !vector_pass
)
35543 std::set
<std::string
>::iterator itr
= symbol_set
.begin();
35545 while (symbol_set
.end() != itr
)
35547 symbol_list
.push_back(*itr
);
35554 template <typename Allocator
,
35555 template <typename
, typename
> class Sequence
>
35556 inline bool collect_functions(const std::string
& expression
,
35557 Sequence
<std::string
, Allocator
>& symbol_list
)
35560 typedef details::collector_helper
<T
> collect_t
;
35562 collect_t::symbol_table_t null_symbol_table
;
35564 std::set
<std::string
> symbol_set
;
35566 const bool variable_pass
= collect_t::collection_pass
35567 (expression
, symbol_set
, false, true, false, null_symbol_table
);
35568 const bool vector_pass
= collect_t::collection_pass
35569 (expression
, symbol_set
, false, true, true, null_symbol_table
);
35571 if (!variable_pass
&& !vector_pass
)
35574 std::set
<std::string
>::iterator itr
= symbol_set
.begin();
35576 while (symbol_set
.end() != itr
)
35578 symbol_list
.push_back(*itr
);
35585 template <typename T
,
35586 typename Allocator
,
35587 template <typename
, typename
> class Sequence
>
35588 inline bool collect_functions(const std::string
& expression
,
35589 exprtk::symbol_table
<T
>& extrnl_symbol_table
,
35590 Sequence
<std::string
, Allocator
>& symbol_list
)
35592 typedef details::collector_helper
<T
> collect_t
;
35594 std::set
<std::string
> symbol_set
;
35596 const bool variable_pass
= collect_t::collection_pass
35597 (expression
, symbol_set
, false, true, false, extrnl_symbol_table
);
35598 const bool vector_pass
= collect_t::collection_pass
35599 (expression
, symbol_set
, false, true, true, extrnl_symbol_table
);
35601 if (!variable_pass
&& !vector_pass
)
35604 std::set
<std::string
>::iterator itr
= symbol_set
.begin();
35606 while (symbol_set
.end() != itr
)
35608 symbol_list
.push_back(*itr
);
35615 template <typename T
>
35616 inline T
integrate(const expression
<T
>& e
,
35618 const T
& r0
, const T
& r1
,
35619 const std::size_t number_of_intervals
= 1000000)
35624 const T h
= (r1
- r0
) / (T(2) * number_of_intervals
);
35625 T total_area
= T(0);
35627 for (std::size_t i
= 0; i
< number_of_intervals
; ++i
)
35629 x
= r0
+ T(2) * i
* h
;
35630 const T y0
= e
.value(); x
+= h
;
35631 const T y1
= e
.value(); x
+= h
;
35632 const T y2
= e
.value(); x
+= h
;
35633 total_area
+= h
* (y0
+ T(4) * y1
+ y2
) / T(3);
35639 template <typename T
>
35640 inline T
integrate(const expression
<T
>& e
,
35641 const std::string
& variable_name
,
35642 const T
& r0
, const T
& r1
,
35643 const std::size_t number_of_intervals
= 1000000)
35645 const symbol_table
<T
>& sym_table
= e
.get_symbol_table();
35647 if (!sym_table
.valid())
35648 return std::numeric_limits
<T
>::quiet_NaN();
35650 details::variable_node
<T
>* var
= sym_table
.get_variable(variable_name
);
35656 T result
= integrate(e
, x
, r0
, r1
, number_of_intervals
);
35662 return std::numeric_limits
<T
>::quiet_NaN();
35665 template <typename T
>
35666 inline T
derivative(const expression
<T
>& e
,
35668 const T
& h
= T(0.00000001))
35670 const T x_init
= x
;
35671 const T _2h
= T(2) * h
;
35674 const T y0
= e
.value();
35676 const T y1
= e
.value();
35678 const T y2
= e
.value();
35680 const T y3
= e
.value();
35683 return (-y0
+ T(8) * (y1
- y2
) + y3
) / (T(12) * h
);
35686 template <typename T
>
35687 inline T
second_derivative(const expression
<T
>& e
,
35689 const T
& h
= T(0.00001))
35691 const T x_init
= x
;
35692 const T _2h
= T(2) * h
;
35694 const T y
= e
.value();
35696 const T y0
= e
.value();
35698 const T y1
= e
.value();
35700 const T y2
= e
.value();
35702 const T y3
= e
.value();
35705 return (-y0
+ T(16) * (y1
+ y2
) - T(30) * y
- y3
) / (T(12) * h
* h
);
35708 template <typename T
>
35709 inline T
third_derivative(const expression
<T
>& e
,
35711 const T
& h
= T(0.0001))
35713 const T x_init
= x
;
35714 const T _2h
= T(2) * h
;
35717 const T y0
= e
.value();
35719 const T y1
= e
.value();
35721 const T y2
= e
.value();
35723 const T y3
= e
.value();
35726 return (y0
+ T(2) * (y2
- y1
) - y3
) / (T(2) * h
* h
* h
);
35729 template <typename T
>
35730 inline T
derivative(const expression
<T
>& e
,
35731 const std::string
& variable_name
,
35732 const T
& h
= T(0.00000001))
35734 const symbol_table
<T
>& sym_table
= e
.get_symbol_table();
35736 if (!sym_table
.valid())
35738 return std::numeric_limits
<T
>::quiet_NaN();
35741 details::variable_node
<T
>* var
= sym_table
.get_variable(variable_name
);
35747 T result
= derivative(e
, x
, h
);
35753 return std::numeric_limits
<T
>::quiet_NaN();
35756 template <typename T
>
35757 inline T
second_derivative(const expression
<T
>& e
,
35758 const std::string
& variable_name
,
35759 const T
& h
= T(0.00001))
35761 const symbol_table
<T
>& sym_table
= e
.get_symbol_table();
35763 if (!sym_table
.valid())
35765 return std::numeric_limits
<T
>::quiet_NaN();
35768 details::variable_node
<T
>* var
= sym_table
.get_variable(variable_name
);
35773 const T x_original
= x
;
35774 const T result
= second_derivative(e
, x
, h
);
35780 return std::numeric_limits
<T
>::quiet_NaN();
35783 template <typename T
>
35784 inline T
third_derivative(const expression
<T
>& e
,
35785 const std::string
& variable_name
,
35786 const T
& h
= T(0.0001))
35788 const symbol_table
<T
>& sym_table
= e
.get_symbol_table();
35790 if (!sym_table
.valid())
35792 return std::numeric_limits
<T
>::quiet_NaN();
35795 details::variable_node
<T
>* var
= sym_table
.get_variable(variable_name
);
35800 const T x_original
= x
;
35801 const T result
= third_derivative(e
, x
, h
);
35807 return std::numeric_limits
<T
>::quiet_NaN();
35811 Note: The following 'compute' routines are simple helpers,
35812 for quickly setting up the required pieces of code in order
35813 to evaluate an expression. By virtue of how they operate
35814 there will be an overhead with regards to their setup and
35815 teardown and hence should not be used in time critical
35817 Furthermore they only assume a small sub set of variables,
35818 no string variables or user defined functions.
35820 template <typename T
>
35821 inline bool compute(const std::string
& expression_string
, T
& result
)
35824 symbol_table
<T
> symbol_table
;
35825 symbol_table
.add_constants();
35827 expression
<T
> expression
;
35828 expression
.register_symbol_table(symbol_table
);
35832 if (parser
.compile(expression_string
,expression
))
35834 result
= expression
.value();
35842 template <typename T
>
35843 inline bool compute(const std::string
& expression_string
,
35848 static const std::string
x_var("x");
35850 symbol_table
<T
> symbol_table
;
35851 symbol_table
.add_constants();
35852 symbol_table
.add_constant(x_var
,x
);
35854 expression
<T
> expression
;
35855 expression
.register_symbol_table(symbol_table
);
35859 if (parser
.compile(expression_string
,expression
))
35861 result
= expression
.value();
35869 template <typename T
>
35870 inline bool compute(const std::string
& expression_string
,
35871 const T
&x
, const T
& y
,
35874 // Only 'x' and 'y'
35875 static const std::string
x_var("x");
35876 static const std::string
y_var("y");
35878 symbol_table
<T
> symbol_table
;
35879 symbol_table
.add_constants();
35880 symbol_table
.add_constant(x_var
,x
);
35881 symbol_table
.add_constant(y_var
,y
);
35883 expression
<T
> expression
;
35884 expression
.register_symbol_table(symbol_table
);
35888 if (parser
.compile(expression_string
,expression
))
35890 result
= expression
.value();
35898 template <typename T
>
35899 inline bool compute(const std::string
& expression_string
,
35900 const T
& x
, const T
& y
, const T
& z
,
35903 // Only 'x', 'y' or 'z'
35904 static const std::string
x_var("x");
35905 static const std::string
y_var("y");
35906 static const std::string
z_var("z");
35908 symbol_table
<T
> symbol_table
;
35909 symbol_table
.add_constants();
35910 symbol_table
.add_constant(x_var
,x
);
35911 symbol_table
.add_constant(y_var
,y
);
35912 symbol_table
.add_constant(z_var
,z
);
35914 expression
<T
> expression
;
35915 expression
.register_symbol_table(symbol_table
);
35919 if (parser
.compile(expression_string
,expression
))
35921 result
= expression
.value();
35929 template <typename T
, std::size_t N
>
35930 class polynomial
: public ifunction
<T
>
35934 template <typename Type
, std::size_t NumberOfCoefficients
>
35935 struct poly_impl
{ };
35937 template <typename Type
>
35938 struct poly_impl
<Type
,12>
35940 static inline T
evaluate(const Type x
,
35941 const Type c12
, const Type c11
, const Type c10
, const Type c9
, const Type c8
,
35942 const Type c7
, const Type c6
, const Type c5
, const Type c4
, const Type c3
,
35943 const Type c2
, const Type c1
, const Type c0
)
35945 // p(x) = c_12x^12 + c_11x^11 + c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35946 return ((((((((((((c12
* x
+ c11
) * x
+ c10
) * x
+ c9
) * x
+ c8
) * x
+ c7
) * x
+ c6
) * x
+ c5
) * x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
35950 template <typename Type
>
35951 struct poly_impl
<Type
,11>
35953 static inline T
evaluate(const Type x
,
35954 const Type c11
, const Type c10
, const Type c9
, const Type c8
, const Type c7
,
35955 const Type c6
, const Type c5
, const Type c4
, const Type c3
, const Type c2
,
35956 const Type c1
, const Type c0
)
35958 // p(x) = c_11x^11 + c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35959 return (((((((((((c11
* x
+ c10
) * x
+ c9
) * x
+ c8
) * x
+ c7
) * x
+ c6
) * x
+ c5
) * x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
35963 template <typename Type
>
35964 struct poly_impl
<Type
,10>
35966 static inline T
evaluate(const Type x
,
35967 const Type c10
, const Type c9
, const Type c8
, const Type c7
, const Type c6
,
35968 const Type c5
, const Type c4
, const Type c3
, const Type c2
, const Type c1
,
35971 // p(x) = c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35972 return ((((((((((c10
* x
+ c9
) * x
+ c8
) * x
+ c7
) * x
+ c6
) * x
+ c5
) * x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
35976 template <typename Type
>
35977 struct poly_impl
<Type
,9>
35979 static inline T
evaluate(const Type x
,
35980 const Type c9
, const Type c8
, const Type c7
, const Type c6
, const Type c5
,
35981 const Type c4
, const Type c3
, const Type c2
, const Type c1
, const Type c0
)
35983 // p(x) = c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35984 return (((((((((c9
* x
+ c8
) * x
+ c7
) * x
+ c6
) * x
+ c5
) * x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
35988 template <typename Type
>
35989 struct poly_impl
<Type
,8>
35991 static inline T
evaluate(const Type x
,
35992 const Type c8
, const Type c7
, const Type c6
, const Type c5
, const Type c4
,
35993 const Type c3
, const Type c2
, const Type c1
, const Type c0
)
35995 // p(x) = c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35996 return ((((((((c8
* x
+ c7
) * x
+ c6
) * x
+ c5
) * x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
36000 template <typename Type
>
36001 struct poly_impl
<Type
,7>
36003 static inline T
evaluate(const Type x
,
36004 const Type c7
, const Type c6
, const Type c5
, const Type c4
, const Type c3
,
36005 const Type c2
, const Type c1
, const Type c0
)
36007 // p(x) = c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
36008 return (((((((c7
* x
+ c6
) * x
+ c5
) * x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
36012 template <typename Type
>
36013 struct poly_impl
<Type
,6>
36015 static inline T
evaluate(const Type x
,
36016 const Type c6
, const Type c5
, const Type c4
, const Type c3
, const Type c2
,
36017 const Type c1
, const Type c0
)
36019 // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
36020 return ((((((c6
* x
+ c5
) * x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
36024 template <typename Type
>
36025 struct poly_impl
<Type
,5>
36027 static inline T
evaluate(const Type x
,
36028 const Type c5
, const Type c4
, const Type c3
, const Type c2
,
36029 const Type c1
, const Type c0
)
36031 // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
36032 return (((((c5
* x
+ c4
) * x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
36036 template <typename Type
>
36037 struct poly_impl
<Type
,4>
36039 static inline T
evaluate(const Type x
, const Type c4
, const Type c3
, const Type c2
, const Type c1
, const Type c0
)
36041 // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
36042 return ((((c4
* x
+ c3
) * x
+ c2
) * x
+ c1
) * x
+ c0
);
36046 template <typename Type
>
36047 struct poly_impl
<Type
,3>
36049 static inline T
evaluate(const Type x
, const Type c3
, const Type c2
, const Type c1
, const Type c0
)
36051 // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
36052 return (((c3
* x
+ c2
) * x
+ c1
) * x
+ c0
);
36056 template <typename Type
>
36057 struct poly_impl
<Type
,2>
36059 static inline T
evaluate(const Type x
, const Type c2
, const Type c1
, const Type c0
)
36061 // p(x) = c_2x^2 + c_1x^1 + c_0x^0
36062 return ((c2
* x
+ c1
) * x
+ c0
);
36066 template <typename Type
>
36067 struct poly_impl
<Type
,1>
36069 static inline T
evaluate(const Type x
, const Type c1
, const Type c0
)
36071 // p(x) = c_1x^1 + c_0x^0
36072 return (c1
* x
+ c0
);
36078 using ifunction
<T
>::operator();
36081 : ifunction
<T
>((N
+2 <= 20) ? (N
+ 2) : std::numeric_limits
<std::size_t>::max())
36083 disable_has_side_effects(*this);
36086 virtual ~polynomial()
36089 #define poly_rtrn(NN) \
36090 return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
36092 inline virtual T
operator() (const T
& x
, const T
& c1
, const T
& c0
)
36094 poly_rtrn(1) poly_impl
<T
,1>::evaluate(x
, c1
, c0
);
36097 inline virtual T
operator() (const T
& x
, const T
& c2
, const T
& c1
, const T
& c0
)
36099 poly_rtrn(2) poly_impl
<T
,2>::evaluate(x
, c2
, c1
, c0
);
36102 inline virtual T
operator() (const T
& x
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36104 poly_rtrn(3) poly_impl
<T
,3>::evaluate(x
, c3
, c2
, c1
, c0
);
36107 inline virtual T
operator() (const T
& x
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36109 poly_rtrn(4) poly_impl
<T
,4>::evaluate(x
, c4
, c3
, c2
, c1
, c0
);
36112 inline virtual T
operator() (const T
& x
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36114 poly_rtrn(5) poly_impl
<T
,5>::evaluate(x
, c5
, c4
, c3
, c2
, c1
, c0
);
36117 inline virtual T
operator() (const T
& x
, const T
& c6
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36119 poly_rtrn(6) poly_impl
<T
,6>::evaluate(x
, c6
, c5
, c4
, c3
, c2
, c1
, c0
);
36122 inline virtual T
operator() (const T
& x
, const T
& c7
, const T
& c6
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36124 poly_rtrn(7) poly_impl
<T
,7>::evaluate(x
, c7
, c6
, c5
, c4
, c3
, c2
, c1
, c0
);
36127 inline virtual T
operator() (const T
& x
, const T
& c8
, const T
& c7
, const T
& c6
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36129 poly_rtrn(8) poly_impl
<T
,8>::evaluate(x
, c8
, c7
, c6
, c5
, c4
, c3
, c2
, c1
, c0
);
36132 inline virtual T
operator() (const T
& x
, const T
& c9
, const T
& c8
, const T
& c7
, const T
& c6
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36134 poly_rtrn(9) poly_impl
<T
,9>::evaluate(x
, c9
, c8
, c7
, c6
, c5
, c4
, c3
, c2
, c1
, c0
);
36137 inline virtual T
operator() (const T
& x
, const T
& c10
, const T
& c9
, const T
& c8
, const T
& c7
, const T
& c6
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36139 poly_rtrn(10) poly_impl
<T
,10>::evaluate(x
, c10
, c9
, c8
, c7
, c6
, c5
, c4
, c3
, c2
, c1
, c0
);
36142 inline virtual T
operator() (const T
& x
, const T
& c11
, const T
& c10
, const T
& c9
, const T
& c8
, const T
& c7
, const T
& c6
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36144 poly_rtrn(11) poly_impl
<T
,11>::evaluate(x
, c11
, c10
, c9
, c8
, c7
, c6
, c5
, c4
, c3
, c2
, c1
, c0
);
36147 inline virtual T
operator() (const T
& x
, const T
& c12
, const T
& c11
, const T
& c10
, const T
& c9
, const T
& c8
, const T
& c7
, const T
& c6
, const T
& c5
, const T
& c4
, const T
& c3
, const T
& c2
, const T
& c1
, const T
& c0
)
36149 poly_rtrn(12) poly_impl
<T
,12>::evaluate(x
, c12
, c11
, c10
, c9
, c8
, c7
, c6
, c5
, c4
, c3
, c2
, c1
, c0
);
36154 inline virtual T
operator() ()
36156 return std::numeric_limits
<T
>::quiet_NaN();
36159 inline virtual T
operator() (const T
&)
36161 return std::numeric_limits
<T
>::quiet_NaN();
36164 inline virtual T
operator() (const T
&, const T
&)
36166 return std::numeric_limits
<T
>::quiet_NaN();
36170 template <typename T
>
36171 class function_compositor
36175 typedef exprtk::expression
<T
> expression_t
;
36176 typedef exprtk::symbol_table
<T
> symbol_table_t
;
36177 typedef exprtk::parser
<T
> parser_t
;
36178 typedef typename
parser_t::settings_store settings_t
;
36185 function(const std::string
& n
)
36189 function(const std::string
& name
,
36190 const std::string
& expression
)
36192 expression_(expression
)
36195 function(const std::string
& name
,
36196 const std::string
& expression
,
36197 const std::string
& v0
)
36199 expression_(expression
)
36204 function(const std::string
& name
,
36205 const std::string
& expression
,
36206 const std::string
& v0
, const std::string
& v1
)
36208 expression_(expression
)
36210 v_
.push_back(v0
); v_
.push_back(v1
);
36213 function(const std::string
& name
,
36214 const std::string
& expression
,
36215 const std::string
& v0
, const std::string
& v1
,
36216 const std::string
& v2
)
36218 expression_(expression
)
36220 v_
.push_back(v0
); v_
.push_back(v1
);
36224 function(const std::string
& name
,
36225 const std::string
& expression
,
36226 const std::string
& v0
, const std::string
& v1
,
36227 const std::string
& v2
, const std::string
& v3
)
36229 expression_(expression
)
36231 v_
.push_back(v0
); v_
.push_back(v1
);
36232 v_
.push_back(v2
); v_
.push_back(v3
);
36235 function(const std::string
& name
,
36236 const std::string
& expression
,
36237 const std::string
& v0
, const std::string
& v1
,
36238 const std::string
& v2
, const std::string
& v3
,
36239 const std::string
& v4
)
36241 expression_(expression
)
36243 v_
.push_back(v0
); v_
.push_back(v1
);
36244 v_
.push_back(v2
); v_
.push_back(v3
);
36248 inline function
& name(const std::string
& n
)
36254 inline function
& expression(const std::string
& e
)
36260 inline function
& var(const std::string
& v
)
36267 std::string expression_
;
36268 std::deque
<std::string
> v_
;
36273 struct base_func
: public exprtk::ifunction
<T
>
36275 typedef const T
& type
;
36276 typedef exprtk::ifunction
<T
> function_t
;
36277 typedef std::vector
<T
*> varref_t
;
36278 typedef std::vector
<T
> var_t
;
36279 typedef std::pair
<T
*,std::size_t> lvarref_t
;
36280 typedef std::vector
<lvarref_t
> lvr_vec_t
;
36282 using exprtk::ifunction
<T
>::operator();
36284 base_func(const std::size_t& pc
= 0)
36285 : exprtk::ifunction
<T
>(pc
),
36286 local_var_stack_size(0),
36292 virtual ~base_func()
36295 inline void update(const T
& v0
)
36300 inline void update(const T
& v0
, const T
& v1
)
36302 (*v
[0]) = v0
; (*v
[1]) = v1
;
36305 inline void update(const T
& v0
, const T
& v1
, const T
& v2
)
36307 (*v
[0]) = v0
; (*v
[1]) = v1
;
36311 inline void update(const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
)
36313 (*v
[0]) = v0
; (*v
[1]) = v1
;
36314 (*v
[2]) = v2
; (*v
[3]) = v3
;
36317 inline void update(const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
)
36319 (*v
[0]) = v0
; (*v
[1]) = v1
;
36320 (*v
[2]) = v2
; (*v
[3]) = v3
;
36324 inline void update(const T
& v0
, const T
& v1
, const T
& v2
, const T
& v3
, const T
& v4
, const T
& v5
)
36326 (*v
[0]) = v0
; (*v
[1]) = v1
;
36327 (*v
[2]) = v2
; (*v
[3]) = v3
;
36328 (*v
[4]) = v4
; (*v
[5]) = v5
;
36331 inline function_t
& setup(expression_t
& expr
)
36335 typedef typename
expression_t::control_block::local_data_list_t ldl_t
;
36337 ldl_t ldl
= expr
.local_data_list();
36339 std::vector
<std::size_t> index_list
;
36341 for (std::size_t i
= 0; i
< ldl
.size(); ++i
)
36345 index_list
.push_back(i
);
36349 std::size_t input_param_count
= 0;
36351 for (std::size_t i
= 0; i
< index_list
.size(); ++i
)
36353 const std::size_t index
= index_list
[i
];
36355 if (i
< (index_list
.size() - v
.size()))
36359 reinterpret_cast<T
*>(ldl
[index
].pointer
),
36362 local_var_stack_size
+= ldl
[index
].size
;
36365 v
[input_param_count
++] = reinterpret_cast<T
*>(ldl
[index
].pointer
);
36379 var_t
var_stack(v
.size(),T(0));
36381 param_stack
.push_back(var_stack
);
36386 var_t
local_var_stack(local_var_stack_size
,T(0));
36387 copy(lv
,local_var_stack
);
36388 local_stack
.push_back(local_var_stack
);
36399 copy(param_stack
.back(),v
);
36400 param_stack
.pop_back();
36405 copy(local_stack
.back(),lv
);
36406 local_stack
.pop_back();
36411 void copy(const varref_t
& src_v
, var_t
& dest_v
)
36413 for (std::size_t i
= 0; i
< src_v
.size(); ++i
)
36415 dest_v
[i
] = (*src_v
[i
]);
36419 void copy(const var_t
& src_v
, varref_t
& dest_v
)
36421 for (std::size_t i
= 0; i
< src_v
.size(); ++i
)
36423 (*dest_v
[i
]) = src_v
[i
];
36427 void copy(const lvr_vec_t
& src_v
, var_t
& dest_v
)
36429 typename
var_t::iterator itr
= dest_v
.begin();
36430 typedef typename
std::iterator_traits
<typename
var_t::iterator
>::difference_type diff_t
;
36432 for (std::size_t i
= 0; i
< src_v
.size(); ++i
)
36434 lvarref_t vr
= src_v
[i
];
36436 if (1 == vr
.second
)
36437 *itr
++ = (*vr
.first
);
36440 std::copy(vr
.first
, vr
.first
+ vr
.second
, itr
);
36441 itr
+= static_cast<diff_t
>(vr
.second
);
36446 void copy(const var_t
& src_v
, lvr_vec_t
& dest_v
)
36448 typename
var_t::const_iterator itr
= src_v
.begin();
36449 typedef typename
std::iterator_traits
<typename
var_t::iterator
>::difference_type diff_t
;
36451 for (std::size_t i
= 0; i
< src_v
.size(); ++i
)
36453 lvarref_t vr
= dest_v
[i
];
36455 if (1 == vr
.second
)
36456 (*vr
.first
) = *itr
++;
36459 std::copy(itr
, itr
+ static_cast<diff_t
>(vr
.second
), vr
.first
);
36460 itr
+= static_cast<diff_t
>(vr
.second
);
36465 inline void clear_stack()
36467 for (std::size_t i
= 0; i
< v
.size(); ++i
)
36473 inline virtual T
value(expression_t
& e
)
36478 expression_t expression
;
36481 std::size_t local_var_stack_size
;
36482 std::size_t stack_depth
;
36483 std::deque
<var_t
> param_stack
;
36484 std::deque
<var_t
> local_stack
;
36487 typedef std::map
<std::string
,base_func
*> funcparam_t
;
36489 struct func_0param
: public base_func
36491 using exprtk::ifunction
<T
>::operator();
36493 func_0param() : base_func(0) {}
36495 inline T
operator() ()
36497 return this->value(base_func::expression
);
36501 typedef const T
& type
;
36503 template <typename BaseFuncType
>
36506 scoped_bft(BaseFuncType
& bft
) : bft_(bft
) { bft_
.pre (); }
36507 ~scoped_bft() { bft_
.post(); }
36509 BaseFuncType
& bft_
;
36513 scoped_bft(scoped_bft
&);
36514 scoped_bft
& operator=(scoped_bft
&);
36517 struct func_1param
: public base_func
36519 using exprtk::ifunction
<T
>::operator();
36521 func_1param() : base_func(1) {}
36523 inline T
operator() (type v0
)
36525 scoped_bft
<func_1param
> sb(*this);
36526 base_func::update(v0
);
36527 return this->value(base_func::expression
);
36531 struct func_2param
: public base_func
36533 using exprtk::ifunction
<T
>::operator();
36535 func_2param() : base_func(2) {}
36537 inline T
operator() (type v0
, type v1
)
36539 scoped_bft
<func_2param
> sb(*this);
36540 base_func::update(v0
, v1
);
36541 return this->value(base_func::expression
);
36545 struct func_3param
: public base_func
36547 using exprtk::ifunction
<T
>::operator();
36549 func_3param() : base_func(3) {}
36551 inline T
operator() (type v0
, type v1
, type v2
)
36553 scoped_bft
<func_3param
> sb(*this);
36554 base_func::update(v0
, v1
, v2
);
36555 return this->value(base_func::expression
);
36559 struct func_4param
: public base_func
36561 using exprtk::ifunction
<T
>::operator();
36563 func_4param() : base_func(4) {}
36565 inline T
operator() (type v0
, type v1
, type v2
, type v3
)
36567 scoped_bft
<func_4param
> sb(*this);
36568 base_func::update(v0
, v1
, v2
, v3
);
36569 return this->value(base_func::expression
);
36573 struct func_5param
: public base_func
36575 using exprtk::ifunction
<T
>::operator();
36577 func_5param() : base_func(5) {}
36579 inline T
operator() (type v0
, type v1
, type v2
, type v3
, type v4
)
36581 scoped_bft
<func_5param
> sb(*this);
36582 base_func::update(v0
, v1
, v2
, v3
, v4
);
36583 return this->value(base_func::expression
);
36587 struct func_6param
: public base_func
36589 using exprtk::ifunction
<T
>::operator();
36591 func_6param() : base_func(6) {}
36593 inline T
operator() (type v0
, type v1
, type v2
, type v3
, type v4
, type v5
)
36595 scoped_bft
<func_6param
> sb(*this);
36596 base_func::update(v0
, v1
, v2
, v3
, v4
, v5
);
36597 return this->value(base_func::expression
);
36601 static T
return_value(expression_t
& e
)
36603 typedef exprtk::results_context
<T
> results_context_t
;
36604 typedef typename
results_context_t::type_store_t type_t
;
36605 typedef typename
type_t::scalar_view scalar_t
;
36607 T result
= e
.value();
36609 if (e
.return_invoked())
36611 // Due to the post compilation checks, it can be safely
36612 // assumed that there will be at least one parameter
36613 // and that the first parameter will always be scalar.
36614 return scalar_t(e
.results()[0])();
36620 #define def_fp_retval(N) \
36621 struct func_##N##param_retval : public func_##N##param \
36623 inline T value(expression_t& e) \
36625 return return_value(e); \
36637 template <typename Allocator
,
36638 template <typename
, typename
> class Sequence
>
36639 inline bool add(const std::string
& name
,
36640 const std::string
& expression
,
36641 const Sequence
<std::string
,Allocator
>& var_list
,
36642 const bool override
= false)
36644 const typename
std::map
<std::string
,expression_t
>::iterator itr
= expr_map_
.find(name
);
36646 if (expr_map_
.end() != itr
)
36650 exprtk_debug(("Compositor error(add): function '%s' already defined\n",
36656 remove(name
, var_list
.size());
36659 if (compile_expression(name
,expression
,var_list
))
36661 const std::size_t n
= var_list
.size();
36663 fp_map_
[n
][name
]->setup(expr_map_
[name
]);
36669 exprtk_debug(("Compositor error(add): Failed to compile function '%s'\n",
36678 function_compositor()
36679 : parser_(settings_t::compile_all_opts
+
36680 settings_t::e_disable_zero_return
),
36684 function_compositor(const symbol_table_t
& st
)
36685 : symbol_table_(st
),
36686 parser_(settings_t::compile_all_opts
+
36687 settings_t::e_disable_zero_return
),
36691 ~function_compositor()
36696 inline symbol_table_t
& symbol_table()
36698 return symbol_table_
;
36701 inline void add_auxiliary_symtab(symbol_table_t
& symtab
)
36703 auxiliary_symtab_list_
.push_back(&symtab
);
36708 symbol_table_
.clear();
36709 expr_map_
.clear();
36711 for (std::size_t i
= 0; i
< fp_map_
.size(); ++i
)
36713 typename
funcparam_t::iterator itr
= fp_map_
[i
].begin();
36714 typename
funcparam_t::iterator end
= fp_map_
[i
].end ();
36718 delete itr
->second
;
36722 fp_map_
[i
].clear();
36726 inline bool add(const function
& f
, const bool override
= false)
36728 return add(f
.name_
, f
.expression_
, f
.v_
,override
);
36733 template <typename Allocator
,
36734 template <typename
, typename
> class Sequence
>
36735 bool compile_expression(const std::string
& name
,
36736 const std::string
& expression
,
36737 const Sequence
<std::string
,Allocator
>& input_var_list
,
36738 bool return_present
= false)
36740 expression_t compiled_expression
;
36741 symbol_table_t local_symbol_table
;
36743 local_symbol_table
.load_from(symbol_table_
);
36744 local_symbol_table
.add_constants();
36746 if (!valid(name
,input_var_list
.size()))
36750 input_var_list
.size(),
36751 local_symbol_table
,
36755 compiled_expression
.register_symbol_table(local_symbol_table
);
36757 for (std::size_t i
= 0; i
< auxiliary_symtab_list_
.size(); ++i
)
36759 compiled_expression
.register_symbol_table((*auxiliary_symtab_list_
[i
]));
36762 std::string mod_expression
;
36764 for (std::size_t i
= 0; i
< input_var_list
.size(); ++i
)
36766 mod_expression
+= " var " + input_var_list
[i
] + "{};\n";
36770 ('{' == details::front(expression
)) &&
36771 ('}' == details::back (expression
))
36773 mod_expression
+= "~" + expression
+ ";";
36775 mod_expression
+= "~{" + expression
+ "};";
36777 if (!parser_
.compile(mod_expression
,compiled_expression
))
36779 exprtk_debug(("Compositor Error: %s\n",parser_
.error().c_str()));
36780 exprtk_debug(("Compositor modified expression: \n%s\n",mod_expression
.c_str()));
36782 remove(name
,input_var_list
.size());
36787 if (!return_present
&& parser_
.dec().return_present())
36789 remove(name
,input_var_list
.size());
36791 return compile_expression(name
, expression
, input_var_list
, true);
36794 // Make sure every return point has a scalar as its first parameter
36795 if (parser_
.dec().return_present())
36797 typedef std::vector
<std::string
> str_list_t
;
36799 str_list_t ret_param_list
= parser_
.dec().return_param_type_list();
36801 for (std::size_t i
= 0; i
< ret_param_list
.size(); ++i
)
36803 const std::string
& params
= ret_param_list
[i
];
36805 if (params
.empty() || ('T' != params
[0]))
36807 exprtk_debug(("Compositor Error: Return statement in function '%s' is invalid\n",
36810 remove(name
,input_var_list
.size());
36817 expr_map_
[name
] = compiled_expression
;
36819 exprtk::ifunction
<T
>& ifunc
= (*(fp_map_
[input_var_list
.size()])[name
]);
36821 if (symbol_table_
.add_function(name
,ifunc
))
36825 exprtk_debug(("Compositor Error: Failed to add function '%s' to symbol table\n",
36831 inline bool symbol_used(const std::string
& symbol
) const
36834 symbol_table_
.is_variable (symbol
) ||
36835 symbol_table_
.is_stringvar (symbol
) ||
36836 symbol_table_
.is_function (symbol
) ||
36837 symbol_table_
.is_vector (symbol
) ||
36838 symbol_table_
.is_vararg_function(symbol
)
36842 inline bool valid(const std::string
& name
,
36843 const std::size_t& arg_count
) const
36847 else if (symbol_used(name
))
36849 else if (fp_map_
[arg_count
].end() != fp_map_
[arg_count
].find(name
))
36855 inline bool forward(const std::string
& name
,
36856 const std::size_t& arg_count
,
36857 symbol_table_t
& sym_table
,
36858 const bool ret_present
= false)
36862 #define case_stmt(N) \
36863 case N : (fp_map_[arg_count])[name] = \
36864 (!ret_present) ? static_cast<base_func*> \
36865 (new func_##N##param) : \
36866 static_cast<base_func*> \
36867 (new func_##N##param_retval) ; \
36870 case_stmt(0) case_stmt(1) case_stmt(2)
36871 case_stmt(3) case_stmt(4) case_stmt(5)
36876 exprtk::ifunction
<T
>& ifunc
= (*(fp_map_
[arg_count
])[name
]);
36878 return sym_table
.add_function(name
,ifunc
);
36881 inline void remove(const std::string
& name
, const std::size_t& arg_count
)
36886 const typename
std::map
<std::string
,expression_t
>::iterator em_itr
= expr_map_
.find(name
);
36888 if (expr_map_
.end() != em_itr
)
36890 expr_map_
.erase(em_itr
);
36893 const typename
funcparam_t::iterator fp_itr
= fp_map_
[arg_count
].find(name
);
36895 if (fp_map_
[arg_count
].end() != fp_itr
)
36897 delete fp_itr
->second
;
36898 fp_map_
[arg_count
].erase(fp_itr
);
36901 symbol_table_
.remove_function(name
);
36906 symbol_table_t symbol_table_
;
36908 std::map
<std::string
,expression_t
> expr_map_
;
36909 std::vector
<funcparam_t
> fp_map_
;
36910 std::vector
<symbol_table_t
*> auxiliary_symtab_list_
;
36913 template <typename T
>
36914 inline bool pgo_primer()
36916 static const std::string expression_list
[] =
36921 "(y + x / y) * (x - y / x)",
36922 "x / ((x + y) * (x - y)) / y",
36923 "1 - ((x * y) + (y / x)) - 3",
36924 "sin(2 * x) + cos(pi / y)",
36925 "1 - sin(2 * x) + cos(pi / y)",
36926 "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)",
36927 "(x^2 / sin(2 * pi / y)) -x / 2",
36928 "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
36929 "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
36930 "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
36931 "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
36932 "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x",
36933 "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55",
36936 "(2 * yy + 2 * xx)",
36937 "(yy + xx / yy) * (xx - yy / xx)",
36938 "xx / ((xx + yy) * (xx - yy)) / yy",
36939 "1 - ((xx * yy) + (yy / xx)) - 3",
36940 "sin(2 * xx) + cos(pi / yy)",
36941 "1 - sin(2 * xx) + cos(pi / yy)",
36942 "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)",
36943 "(xx^2 / sin(2 * pi / yy)) -xx / 2",
36944 "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy",
36945 "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)",
36946 "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))",
36947 "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx",
36948 "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55",
36949 "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))",
36950 "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)",
36951 "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)",
36952 "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)",
36953 "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)",
36954 "(x + 2) * 3", "x + (2 * 3)",
36955 "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)",
36956 "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)",
36957 "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))",
36958 "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))",
36959 "2 + (x * (y / 3))", "x + (2 * (3 / y))",
36960 "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)",
36961 "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)",
36962 "x + ((2 * 3) / y)", "(((x + y) * z) / w)",
36963 "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)",
36964 "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)",
36965 "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)",
36966 "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)",
36967 "((x + (2 * 3)) / y)",
36968 "(xx + yy) * zz", "xx + (yy * zz)",
36969 "(xx + yy) * 7", "xx + (yy * 7)",
36970 "(xx + 7) * yy", "xx + (7 * yy)",
36971 "(7 + xx) * yy", "7 + (xx * yy)",
36972 "(2 + x) * 3", "2 + (x * 3)",
36973 "(2 + 3) * x", "2 + (3 * x)",
36974 "(x + 2) * 3", "x + (2 * 3)",
36975 "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)",
36976 "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)",
36977 "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)",
36978 "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)",
36979 "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))",
36980 "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))",
36981 "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))",
36982 "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))",
36983 "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))",
36984 "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)",
36985 "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)",
36986 "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)",
36987 "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)",
36988 "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)",
36989 "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)",
36990 "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)",
36991 "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)",
36992 "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)",
36993 "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)",
36994 "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)",
36995 "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)",
36996 "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)",
36997 "((xx + (2 * 3)) / yy)"
37000 static const std::size_t expression_list_size
= sizeof(expression_list
) / sizeof(std::string
);
37011 exprtk::symbol_table
<T
> symbol_table
;
37012 symbol_table
.add_constants();
37013 symbol_table
.add_variable( "x", x
);
37014 symbol_table
.add_variable( "y", y
);
37015 symbol_table
.add_variable( "z", z
);
37016 symbol_table
.add_variable( "w", w
);
37017 symbol_table
.add_variable("xx",xx
);
37018 symbol_table
.add_variable("yy",yy
);
37019 symbol_table
.add_variable("zz",zz
);
37020 symbol_table
.add_variable("ww",ww
);
37022 typedef typename
std::deque
<exprtk::expression
<T
> > expr_list_t
;
37023 expr_list_t expr_list
;
37025 const std::size_t rounds
= 50;
37028 for (std::size_t r
= 0; r
< rounds
; ++r
)
37031 exprtk::parser
<T
> parser
;
37033 for (std::size_t i
= 0; i
< expression_list_size
; ++i
)
37035 exprtk::expression
<T
> expression
;
37036 expression
.register_symbol_table(symbol_table
);
37038 if (!parser
.compile(expression_list
[i
],expression
))
37043 expr_list
.push_back(expression
);
37050 static inline T
process(T
& x
, T
& y
, expression
<T
>& expression
)
37052 static const T lower_bound
= T(-20);
37053 static const T upper_bound
= T(+20);
37054 static const T delta
= T(0.1);
37058 for (x
= lower_bound
; x
<= upper_bound
; x
+= delta
)
37060 for (y
= lower_bound
; y
<= upper_bound
; y
+= delta
)
37062 total
+= expression
.value();
37070 for (std::size_t i
= 0; i
< expr_list
.size(); ++i
)
37072 execute::process( x
, y
, expr_list
[i
]);
37073 execute::process(xx
, yy
, expr_list
[i
]);
37077 for (std::size_t i
= 0; i
< 10000; ++i
)
37079 const T v
= T(123.456 + i
);
37081 if (details::is_true(details::numeric::nequal(details::numeric::fast_exp
<T
, 1>::result(v
),details::numeric::pow(v
,T( 1)))))
37084 #define else_stmt(N) \
37085 else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,N>::result(v),details::numeric::pow(v,T(N))))) \
37088 else_stmt( 2) else_stmt( 3) else_stmt( 4) else_stmt( 5)
37089 else_stmt( 6) else_stmt( 7) else_stmt( 8) else_stmt( 9)
37090 else_stmt(10) else_stmt(11) else_stmt(12) else_stmt(13)
37091 else_stmt(14) else_stmt(15) else_stmt(16) else_stmt(17)
37092 else_stmt(18) else_stmt(19) else_stmt(20) else_stmt(21)
37093 else_stmt(22) else_stmt(23) else_stmt(24) else_stmt(25)
37094 else_stmt(26) else_stmt(27) else_stmt(28) else_stmt(29)
37095 else_stmt(30) else_stmt(31) else_stmt(32) else_stmt(33)
37096 else_stmt(34) else_stmt(35) else_stmt(36) else_stmt(37)
37097 else_stmt(38) else_stmt(39) else_stmt(40) else_stmt(41)
37098 else_stmt(42) else_stmt(43) else_stmt(44) else_stmt(45)
37099 else_stmt(46) else_stmt(47) else_stmt(48) else_stmt(49)
37100 else_stmt(50) else_stmt(51) else_stmt(52) else_stmt(53)
37101 else_stmt(54) else_stmt(55) else_stmt(56) else_stmt(57)
37102 else_stmt(58) else_stmt(59) else_stmt(60) else_stmt(61)
37110 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
37114 # ifndef WIN32_LEAN_AND_MEAN
37115 # define WIN32_LEAN_AND_MEAN
37118 # define NORESOURCE
37119 # include <windows.h>
37123 # include <sys/time.h>
37124 # include <sys/types.h>
37133 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
37137 QueryPerformanceFrequency(&clock_frequency_
);
37140 inline void start()
37143 QueryPerformanceCounter(&start_time_
);
37148 QueryPerformanceCounter(&stop_time_
);
37152 inline double time() const
37154 return (1.0 * (stop_time_
.QuadPart
- start_time_
.QuadPart
)) / (1.0 * clock_frequency_
.QuadPart
);
37162 start_time_
.tv_sec
= 0;
37163 start_time_
.tv_usec
= 0;
37164 stop_time_
.tv_sec
= 0;
37165 stop_time_
.tv_usec
= 0;
37168 inline void start()
37171 gettimeofday(&start_time_
,0);
37176 gettimeofday(&stop_time_
, 0);
37180 inline unsigned long long int usec_time() const
37184 if (stop_time_
.tv_sec
>= start_time_
.tv_sec
)
37186 return 1000000LLU * static_cast<details::_uint64_t
>(stop_time_
.tv_sec
- start_time_
.tv_sec
) +
37187 static_cast<details::_uint64_t
>(stop_time_
.tv_usec
- start_time_
.tv_usec
) ;
37190 return std::numeric_limits
<details::_uint64_t
>::max();
37193 return std::numeric_limits
<details::_uint64_t
>::max();
37196 inline double time() const
37198 return usec_time() * 0.000001;
37203 inline bool in_use() const
37212 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
37213 LARGE_INTEGER start_time_
;
37214 LARGE_INTEGER stop_time_
;
37215 LARGE_INTEGER clock_frequency_
;
37217 struct timeval start_time_
;
37218 struct timeval stop_time_
;
37222 } // namespace exprtk
37224 #ifndef exprtk_disable_rtl_io
37227 namespace rtl
{ namespace io
{ namespace details
37229 template <typename T
>
37230 inline void print_type(const std::string
& fmt
,
37232 exprtk::details::numeric::details::real_type_tag
)
37234 printf(fmt
.c_str(),v
);
37237 template <typename T
>
37240 typedef typename igeneric_function
<T
>::generic_type generic_type
;
37241 typedef typename igeneric_function
<T
>::parameter_list_t parameter_list_t
;
37242 typedef typename
generic_type::scalar_view scalar_t
;
37243 typedef typename
generic_type::vector_view vector_t
;
37244 typedef typename
generic_type::string_view string_t
;
37245 typedef typename
exprtk::details::numeric::details::number_type
<T
>::type num_type
;
37247 static void process(const std::string
& scalar_format
, parameter_list_t parameters
)
37249 for (std::size_t i
= 0; i
< parameters
.size(); ++i
)
37251 generic_type
& gt
= parameters
[i
];
37255 case generic_type::e_scalar
: print(scalar_format
,scalar_t(gt
));
37258 case generic_type::e_vector
: print(scalar_format
,vector_t(gt
));
37261 case generic_type::e_string
: print(string_t(gt
));
37264 default : continue;
37269 static inline void print(const std::string
& scalar_format
, const scalar_t
& s
)
37271 print_type(scalar_format
,s(),num_type());
37274 static inline void print(const std::string
& scalar_format
, const vector_t
& v
)
37276 for (std::size_t i
= 0; i
< v
.size(); ++i
)
37278 print_type(scalar_format
,v
[i
],num_type());
37280 if ((i
+ 1) < v
.size())
37285 static inline void print(const string_t
& s
)
37287 printf("%s",to_str(s
).c_str());
37291 } // namespace exprtk::rtl::io::details
37293 template <typename T
>
37294 struct print
: public exprtk::igeneric_function
<T
>
37296 typedef typename igeneric_function
<T
>::parameter_list_t parameter_list_t
;
37298 using exprtk::igeneric_function
<T
>::operator();
37300 print(const std::string
& scalar_format
= "%10.5f")
37301 : scalar_format_(scalar_format
)
37303 exprtk::enable_zero_parameters(*this);
37306 inline T
operator() (parameter_list_t parameters
)
37308 details::print_impl
<T
>::process(scalar_format_
,parameters
);
37312 std::string scalar_format_
;
37315 template <typename T
>
37316 struct println
: public exprtk::igeneric_function
<T
>
37318 typedef typename igeneric_function
<T
>::parameter_list_t parameter_list_t
;
37320 using exprtk::igeneric_function
<T
>::operator();
37322 println(const std::string
& scalar_format
= "%10.5f")
37323 : scalar_format_(scalar_format
)
37325 exprtk::enable_zero_parameters(*this);
37328 inline T
operator() (parameter_list_t parameters
)
37330 details::print_impl
<T
>::process(scalar_format_
,parameters
);
37335 std::string scalar_format_
;
37338 template <typename T
>
37344 bool register_package(exprtk::symbol_table
<T
>& symtab
)
37346 #define exprtk_register_function(FunctionName,FunctionType) \
37347 if (!symtab.add_function(FunctionName,FunctionType)) \
37350 "exprtk::rtl::io::register_package - Failed to add function: %s\n", \
37355 exprtk_register_function("print" , p)
37356 exprtk_register_function("println", pl
)
37357 #undef exprtk_register_function
37363 } // namespace exprtk::rtl::io
37364 } // namespace exprtk::rtl
37365 } // namespace exprtk
37368 #ifndef exprtk_disable_rtl_io_file
37372 namespace rtl
{ namespace io
{ namespace file
{ namespace details
37382 struct file_descriptor
37384 file_descriptor(const std::string
& fname
, const std::string
& access
)
37386 mode(get_file_mode(access
)),
37392 std::string file_name
;
37396 if (e_read
== mode
)
37398 std::ifstream
* stream
= new std::ifstream(file_name
.c_str(),std::ios::binary
);
37408 stream_ptr
= stream
;
37412 else if (e_write
== mode
)
37414 std::ofstream
* stream
= new std::ofstream(file_name
.c_str(),std::ios::binary
);
37424 stream_ptr
= stream
;
37428 else if (e_rdwrt
== mode
)
37430 std::fstream
* stream
= new std::fstream(file_name
.c_str(),std::ios::binary
);
37440 stream_ptr
= stream
;
37448 template <typename Stream
, typename Ptr
>
37451 Stream
* stream
= reinterpret_cast<Stream
*>(p
);
37454 p
= reinterpret_cast<Ptr
>(0);
37461 case e_read
: close
<std::ifstream
>(stream_ptr
);
37464 case e_write
: close
<std::ofstream
>(stream_ptr
);
37467 case e_rdwrt
: close
<std::fstream
> (stream_ptr
);
37470 default : return false;
37476 template <typename View
>
37477 bool write(const View
& view
, const std::size_t amount
, const std::size_t offset
= 0)
37481 case e_write
: reinterpret_cast<std::ofstream
*>(stream_ptr
)->
37482 write(reinterpret_cast<const char*>(view
.begin() + offset
), amount
* sizeof(typename
View::value_t
));
37485 case e_rdwrt
: reinterpret_cast<std::fstream
*>(stream_ptr
)->
37486 write(reinterpret_cast<const char*>(view
.begin() + offset
) , amount
* sizeof(typename
View::value_t
));
37489 default : return false;
37495 template <typename View
>
37496 bool read(View
& view
, const std::size_t amount
, const std::size_t offset
= 0)
37500 case e_read
: reinterpret_cast<std::ifstream
*>(stream_ptr
)->
37501 read(reinterpret_cast<char*>(view
.begin() + offset
), amount
* sizeof(typename
View::value_t
));
37504 case e_rdwrt
: reinterpret_cast<std::fstream
*>(stream_ptr
)->
37505 read(reinterpret_cast<char*>(view
.begin() + offset
) , amount
* sizeof(typename
View::value_t
));
37508 default : return false;
37514 bool getline(std::string
& s
)
37518 case e_read
: return (!!std::getline(*reinterpret_cast<std::ifstream
*>(stream_ptr
),s
));
37519 case e_rdwrt
: return (!!std::getline(*reinterpret_cast<std::fstream
* >(stream_ptr
),s
));
37520 default : return false;
37528 case e_read
: return reinterpret_cast<std::ifstream
*>(stream_ptr
)->eof();
37529 case e_write
: return reinterpret_cast<std::ofstream
*>(stream_ptr
)->eof();
37530 case e_rdwrt
: return reinterpret_cast<std::fstream
* >(stream_ptr
)->eof();
37531 default : return true;
37535 file_mode
get_file_mode(const std::string
& access
) const
37537 if (access
.empty() || access
.size() > 2)
37540 std::size_t w_cnt
= 0;
37541 std::size_t r_cnt
= 0;
37543 for (std::size_t i
= 0; i
< access
.size(); ++i
)
37545 switch (std::tolower(access
[i
]))
37547 case 'r' : r_cnt
++; break;
37548 case 'w' : w_cnt
++; break;
37549 default : return e_error
;
37553 if ((0 == r_cnt
) && (0 == w_cnt
))
37555 else if ((r_cnt
> 1) || (w_cnt
> 1))
37557 else if ((1 == r_cnt
) && (1 == w_cnt
))
37559 else if (1 == r_cnt
)
37566 template <typename T
>
37567 file_descriptor
* make_handle(T v
)
37569 file_descriptor
* fd
= reinterpret_cast<file_descriptor
*>(0);
37571 std::memcpy(reinterpret_cast<char*>(&fd
),
37572 reinterpret_cast<const char*>(&v
),
37577 template <typename T
>
37578 void perform_check()
37581 #pragma warning(push)
37582 #pragma warning(disable: 4127)
37584 if (sizeof(T
) < sizeof(void*))
37586 throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder.");
37589 #pragma warning(pop)
37593 } // namespace exprtk::rtl::io::file::details
37595 template <typename T
>
37596 class open
: public exprtk::igeneric_function
<T
>
37600 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
37601 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
37602 typedef typename
igfun_t::generic_type generic_type
;
37603 typedef typename
generic_type::string_view string_t
;
37605 using exprtk::igeneric_function
<T
>::operator();
37608 : exprtk::igeneric_function
<T
>("S|SS")
37609 { details::perform_check
<T
>(); }
37611 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
37613 std::string file_name
= to_str(string_t(parameters
[0]));
37614 std::string access
;
37616 if (file_name
.empty())
37621 else if (0 == string_t(parameters
[1]).size())
37624 access
= to_str(string_t(parameters
[1]));
37626 details::file_descriptor
* fd
= new details::file_descriptor(file_name
,access
);
37632 std::memcpy(reinterpret_cast<char*>(&t
),
37633 reinterpret_cast<char*>(&fd
),
37645 template <typename T
>
37646 struct close
: public exprtk::ifunction
<T
>
37648 using exprtk::ifunction
<T
>::operator();
37651 : exprtk::ifunction
<T
>(1)
37652 { details::perform_check
<T
>(); }
37654 inline T
operator() (const T
& v
)
37656 details::file_descriptor
* fd
= details::make_handle(v
);
37667 template <typename T
>
37668 class write
: public exprtk::igeneric_function
<T
>
37672 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
37673 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
37674 typedef typename
igfun_t::generic_type generic_type
;
37675 typedef typename
generic_type::string_view string_t
;
37676 typedef typename
generic_type::scalar_view scalar_t
;
37677 typedef typename
generic_type::vector_view vector_t
;
37679 using exprtk::igeneric_function
<T
>::operator();
37682 : igfun_t("TS|TST|TV|TVT")
37683 { details::perform_check
<T
>(); }
37685 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
37687 details::file_descriptor
* fd
= details::make_handle(scalar_t(parameters
[0])());
37689 std::size_t amount
= 0;
37694 const string_t
buffer(parameters
[1]);
37695 amount
= buffer
.size();
37696 return T(fd
->write(buffer
, amount
) ? 1 : 0);
37700 const string_t
buffer(parameters
[1]);
37701 amount
= std::min(buffer
.size(),
37702 static_cast<std::size_t>(scalar_t(parameters
[2])()));
37703 return T(fd
->write(buffer
, amount
) ? 1 : 0);
37707 const vector_t
vec(parameters
[1]);
37708 amount
= vec
.size();
37709 return T(fd
->write(vec
, amount
) ? 1 : 0);
37713 const vector_t
vec(parameters
[1]);
37714 amount
= std::min(vec
.size(),
37715 static_cast<std::size_t>(scalar_t(parameters
[2])()));
37716 return T(fd
->write(vec
, amount
) ? 1 : 0);
37724 template <typename T
>
37725 class read
: public exprtk::igeneric_function
<T
>
37729 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
37730 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
37731 typedef typename
igfun_t::generic_type generic_type
;
37732 typedef typename
generic_type::string_view string_t
;
37733 typedef typename
generic_type::scalar_view scalar_t
;
37734 typedef typename
generic_type::vector_view vector_t
;
37736 using exprtk::igeneric_function
<T
>::operator();
37739 : igfun_t("TS|TST|TV|TVT")
37740 { details::perform_check
<T
>(); }
37742 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
37744 details::file_descriptor
* fd
= details::make_handle(scalar_t(parameters
[0])());
37746 std::size_t amount
= 0;
37751 string_t
buffer(parameters
[1]);
37752 amount
= buffer
.size();
37753 return T(fd
->read(buffer
,amount
) ? 1 : 0);
37757 string_t
buffer(parameters
[1]);
37758 amount
= std::min(buffer
.size(),
37759 static_cast<std::size_t>(scalar_t(parameters
[2])()));
37760 return T(fd
->read(buffer
,amount
) ? 1 : 0);
37764 vector_t
vec(parameters
[1]);
37765 amount
= vec
.size();
37766 return T(fd
->read(vec
,amount
) ? 1 : 0);
37770 vector_t
vec(parameters
[1]);
37771 amount
= std::min(vec
.size(),
37772 static_cast<std::size_t>(scalar_t(parameters
[2])()));
37773 return T(fd
->read(vec
,amount
) ? 1 : 0);
37781 template <typename T
>
37782 class getline
: public exprtk::igeneric_function
<T
>
37786 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
37787 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
37788 typedef typename
igfun_t::generic_type generic_type
;
37789 typedef typename
generic_type::string_view string_t
;
37790 typedef typename
generic_type::scalar_view scalar_t
;
37792 using exprtk::igeneric_function
<T
>::operator();
37795 : igfun_t("T",igfun_t::e_rtrn_string
)
37796 { details::perform_check
<T
>(); }
37798 inline T
operator() (std::string
& result
,
37799 parameter_list_t parameters
)
37801 details::file_descriptor
* fd
= details::make_handle(scalar_t(parameters
[0])());
37802 return T(fd
->getline(result
) ? 1 : 0);
37806 template <typename T
>
37807 struct eof
: public exprtk::ifunction
<T
>
37809 using exprtk::ifunction
<T
>::operator();
37812 : exprtk::ifunction
<T
>(1)
37813 { details::perform_check
<T
>(); }
37815 inline T
operator() (const T
& v
)
37817 details::file_descriptor
* fd
= details::make_handle(v
);
37819 return (fd
->eof() ? T(1) : T(0));
37823 template <typename T
>
37833 bool register_package(exprtk::symbol_table
<T
>& symtab
)
37835 #define exprtk_register_function(FunctionName,FunctionType) \
37836 if (!symtab.add_function(FunctionName,FunctionType)) \
37839 "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
37844 exprtk_register_function("open" ,o)
37845 exprtk_register_function("close" ,c
)
37846 exprtk_register_function("write" ,w
)
37847 exprtk_register_function("read" ,r
)
37848 exprtk_register_function("getline",g
)
37849 exprtk_register_function("eof" ,e
)
37850 #undef exprtk_register_function
37856 } // namespace exprtk::rtl::io::file
37857 } // namespace exprtk::rtl::io
37858 } // namespace exprtk::rtl
37859 } // namespace exprtk
37862 #ifndef exprtk_disable_rtl_vecops
37865 namespace rtl
{ namespace vecops
{
37869 template <typename Vector
>
37870 inline bool invalid_range(const Vector
& v
, const std::size_t r0
, const std::size_t r1
)
37872 if (r0
> (v
.size() - 1))
37874 else if (r1
> (v
.size() - 1))
37882 template <typename T
>
37883 struct load_vector_range
37885 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
37886 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
37887 typedef typename
igfun_t::generic_type generic_type
;
37888 typedef typename
generic_type::scalar_view scalar_t
;
37889 typedef typename
generic_type::vector_view vector_t
;
37891 static inline bool process(parameter_list_t
& parameters
,
37892 std::size_t& r0
, std::size_t& r1
,
37893 const std::size_t& r0_prmidx
,
37894 const std::size_t& r1_prmidx
,
37895 const std::size_t vec_idx
= 0)
37897 if (r0_prmidx
>= parameters
.size())
37900 if (r1_prmidx
>= parameters
.size())
37903 if (!scalar_t(parameters
[r0_prmidx
]).to_uint(r0
))
37906 if (!scalar_t(parameters
[r1_prmidx
]).to_uint(r1
))
37909 return !invalid_range(vector_t(parameters
[vec_idx
]), r0
, r1
);
37916 template <typename T
>
37917 inline void kahan_sum(T
& sum
, T
& error
, const T v
)
37919 const T x
= v
- error
;
37920 const T y
= sum
+ x
;
37921 error
= (y
- sum
) - x
;
37925 } // namespace exprtk::rtl::details
37927 template <typename T
>
37928 class all_true
: public exprtk::igeneric_function
<T
>
37932 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
37933 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
37934 typedef typename
igfun_t::generic_type generic_type
;
37935 typedef typename
generic_type::vector_view vector_t
;
37937 using exprtk::igeneric_function
<T
>::operator();
37940 : exprtk::igeneric_function
<T
>("V|VTT")
37944 1. VTT - vector, r0, r1
37948 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
37950 const vector_t
vec(parameters
[0]);
37952 std::size_t r0
= 0;
37953 std::size_t r1
= vec
.size() - 1;
37957 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 1, 2, 0)
37959 return std::numeric_limits
<T
>::quiet_NaN();
37961 for (std::size_t i
= r0
; i
<= r1
; ++i
)
37963 if (vec
[i
] == T(0))
37973 template <typename T
>
37974 class all_false
: public exprtk::igeneric_function
<T
>
37978 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
37979 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
37980 typedef typename
igfun_t::generic_type generic_type
;
37981 typedef typename
generic_type::vector_view vector_t
;
37983 using exprtk::igeneric_function
<T
>::operator();
37986 : exprtk::igeneric_function
<T
>("V|VTT")
37990 1. VTT - vector, r0, r1
37994 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
37996 const vector_t
vec(parameters
[0]);
37998 std::size_t r0
= 0;
37999 std::size_t r1
= vec
.size() - 1;
38003 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 1, 2, 0)
38005 return std::numeric_limits
<T
>::quiet_NaN();
38007 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38009 if (vec
[i
] != T(0))
38019 template <typename T
>
38020 class any_true
: public exprtk::igeneric_function
<T
>
38024 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38025 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38026 typedef typename
igfun_t::generic_type generic_type
;
38027 typedef typename
generic_type::vector_view vector_t
;
38029 using exprtk::igeneric_function
<T
>::operator();
38032 : exprtk::igeneric_function
<T
>("V|VTT")
38036 1. VTT - vector, r0, r1
38040 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38042 const vector_t
vec(parameters
[0]);
38044 std::size_t r0
= 0;
38045 std::size_t r1
= vec
.size() - 1;
38049 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 1, 2, 0)
38051 return std::numeric_limits
<T
>::quiet_NaN();
38053 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38055 if (vec
[i
] != T(0))
38065 template <typename T
>
38066 class any_false
: public exprtk::igeneric_function
<T
>
38070 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38071 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38072 typedef typename
igfun_t::generic_type generic_type
;
38073 typedef typename
generic_type::vector_view vector_t
;
38075 using exprtk::igeneric_function
<T
>::operator();
38078 : exprtk::igeneric_function
<T
>("V|VTT")
38082 1. VTT - vector, r0, r1
38086 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38088 const vector_t
vec(parameters
[0]);
38090 std::size_t r0
= 0;
38091 std::size_t r1
= vec
.size() - 1;
38095 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 1, 2, 0)
38097 return std::numeric_limits
<T
>::quiet_NaN();
38099 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38101 if (vec
[i
] == T(0))
38111 template <typename T
>
38112 class count
: public exprtk::igeneric_function
<T
>
38116 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38117 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38118 typedef typename
igfun_t::generic_type generic_type
;
38119 typedef typename
generic_type::vector_view vector_t
;
38121 using exprtk::igeneric_function
<T
>::operator();
38124 : exprtk::igeneric_function
<T
>("V|VTT")
38128 1. VTT - vector, r0, r1
38132 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38134 const vector_t
vec(parameters
[0]);
38136 std::size_t r0
= 0;
38137 std::size_t r1
= vec
.size() - 1;
38141 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 1, 2, 0)
38143 return std::numeric_limits
<T
>::quiet_NaN();
38145 std::size_t cnt
= 0;
38147 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38149 if (vec
[i
] != T(0)) ++cnt
;
38156 template <typename T
>
38157 class copy
: public exprtk::igeneric_function
<T
>
38161 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38162 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38163 typedef typename
igfun_t::generic_type generic_type
;
38164 typedef typename
generic_type::scalar_view scalar_t
;
38165 typedef typename
generic_type::vector_view vector_t
;
38167 using exprtk::igeneric_function
<T
>::operator();
38170 : exprtk::igeneric_function
<T
>("VV|VTTVTT")
38173 0. VV - x(vector), y(vector)
38174 1. VTTVTT - x(vector), xr0, xr1, y(vector), yr0, yr1,
38178 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38180 const vector_t
x(parameters
[0]);
38181 vector_t
y(parameters
[(0 == ps_index
) ? 1 : 3]);
38183 std::size_t xr0
= 0;
38184 std::size_t xr1
= x
.size() - 1;
38186 std::size_t yr0
= 0;
38187 std::size_t yr1
= y
.size() - 1;
38192 !helper::load_vector_range
<T
>::process(parameters
, xr0
, xr1
, 1, 2, 0) ||
38193 !helper::load_vector_range
<T
>::process(parameters
, yr0
, yr1
, 4, 5, 3)
38198 const std::size_t n
= std::min(xr1
- xr0
+ 1, yr1
- yr0
+ 1);
38200 std::copy(x
.begin() + xr0
, x
.begin() + xr0
+ n
, y
.begin() + yr0
);
38206 template <typename T
>
38207 class rol
: public exprtk::igeneric_function
<T
>
38211 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38212 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38213 typedef typename
igfun_t::generic_type generic_type
;
38214 typedef typename
generic_type::scalar_view scalar_t
;
38215 typedef typename
generic_type::vector_view vector_t
;
38217 using exprtk::igeneric_function
<T
>::operator();
38220 : exprtk::igeneric_function
<T
>("VT|VTTT")
38224 1. VTTT - vector, N, r0, r1
38228 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38230 vector_t
vec(parameters
[0]);
38233 std::size_t r0
= 0;
38234 std::size_t r1
= vec
.size() - 1;
38236 if (!scalar_t(parameters
[1]).to_uint(n
))
38241 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0)
38245 std::size_t dist
= r1
- r0
+ 1;
38246 std::size_t shift
= n
% dist
;
38248 std::rotate(vec
.begin() + r0
, vec
.begin() + r0
+ shift
, vec
.begin() + r1
+ 1);
38254 template <typename T
>
38255 class ror
: public exprtk::igeneric_function
<T
>
38259 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38260 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38261 typedef typename
igfun_t::generic_type generic_type
;
38262 typedef typename
generic_type::scalar_view scalar_t
;
38263 typedef typename
generic_type::vector_view vector_t
;
38265 using exprtk::igeneric_function
<T
>::operator();
38268 : exprtk::igeneric_function
<T
>("VT|VTTT")
38272 1. VTTT - vector, N, r0, r1
38276 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38278 vector_t
vec(parameters
[0]);
38281 std::size_t r0
= 0;
38282 std::size_t r1
= vec
.size() - 1;
38284 if (!scalar_t(parameters
[1]).to_uint(n
))
38289 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0)
38293 std::size_t dist
= r1
- r0
+ 1;
38294 std::size_t shift
= (dist
- (n
% dist
)) % dist
;
38296 std::rotate(vec
.begin() + r0
, vec
.begin() + r0
+ shift
, vec
.begin() + r1
+ 1);
38302 template <typename T
>
38303 class shift_left
: public exprtk::igeneric_function
<T
>
38307 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38308 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38309 typedef typename
igfun_t::generic_type generic_type
;
38310 typedef typename
generic_type::scalar_view scalar_t
;
38311 typedef typename
generic_type::vector_view vector_t
;
38313 using exprtk::igeneric_function
<T
>::operator();
38316 : exprtk::igeneric_function
<T
>("VT|VTTT")
38320 1. VTTT - vector, N, r0, r1
38324 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38326 vector_t
vec(parameters
[0]);
38329 std::size_t r0
= 0;
38330 std::size_t r1
= vec
.size() - 1;
38332 if (!scalar_t(parameters
[1]).to_uint(n
))
38337 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0)
38341 std::size_t dist
= r1
- r0
+ 1;
38346 std::rotate(vec
.begin() + r0
, vec
.begin() + r0
+ n
, vec
.begin() + r1
+ 1);
38348 for (std::size_t i
= r1
- n
+ 1; i
<= r1
; ++i
)
38357 template <typename T
>
38358 class shift_right
: public exprtk::igeneric_function
<T
>
38362 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38363 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38364 typedef typename
igfun_t::generic_type generic_type
;
38365 typedef typename
generic_type::scalar_view scalar_t
;
38366 typedef typename
generic_type::vector_view vector_t
;
38368 using exprtk::igeneric_function
<T
>::operator();
38371 : exprtk::igeneric_function
<T
>("VT|VTTT")
38375 1. VTTT - vector, N, r0, r1
38379 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38381 vector_t
vec(parameters
[0]);
38384 std::size_t r0
= 0;
38385 std::size_t r1
= vec
.size() - 1;
38387 if (!scalar_t(parameters
[1]).to_uint(n
))
38392 !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0)
38396 std::size_t dist
= r1
- r0
+ 1;
38401 std::size_t shift
= (dist
- (n
% dist
)) % dist
;
38403 std::rotate(vec
.begin() + r0
, vec
.begin() + r0
+ shift
, vec
.begin() + r1
+ 1);
38405 for (std::size_t i
= r0
; i
< r0
+ n
; ++i
)
38414 template <typename T
>
38415 class sort
: public exprtk::igeneric_function
<T
>
38419 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38420 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38421 typedef typename
igfun_t::generic_type generic_type
;
38422 typedef typename
generic_type::string_view string_t
;
38423 typedef typename
generic_type::vector_view vector_t
;
38425 using exprtk::igeneric_function
<T
>::operator();
38428 : exprtk::igeneric_function
<T
>("V|VTT|VS|VSTT")
38432 1. VTT - vector, r0, r1
38433 2. VS - vector, string
38434 3. VSTT - vector, string, r0, r1
38438 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38440 vector_t
vec(parameters
[0]);
38442 std::size_t r0
= 0;
38443 std::size_t r1
= vec
.size() - 1;
38445 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 1, 2, 0))
38447 if ((3 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0))
38450 bool ascending
= true;
38452 if ((2 == ps_index
) || (3 == ps_index
))
38454 if (exprtk::details::imatch(to_str(string_t(parameters
[1])),"ascending"))
38456 else if (exprtk::details::imatch(to_str(string_t(parameters
[1])),"descending"))
38463 std::sort(vec
.begin() + r0
, vec
.begin() + r1
+ 1, std::less
<T
> ());
38465 std::sort(vec
.begin() + r0
, vec
.begin() + r1
+ 1, std::greater
<T
>());
38471 template <typename T
>
38472 class nthelement
: public exprtk::igeneric_function
<T
>
38476 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38477 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38478 typedef typename
igfun_t::generic_type generic_type
;
38479 typedef typename
generic_type::scalar_view scalar_t
;
38480 typedef typename
generic_type::vector_view vector_t
;
38482 using exprtk::igeneric_function
<T
>::operator();
38485 : exprtk::igeneric_function
<T
>("VT|VTTT")
38488 0. VT - vector, nth-element
38489 1. VTTT - vector, nth-element, r0, r1
38493 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38495 vector_t
vec(parameters
[0]);
38498 std::size_t r0
= 0;
38499 std::size_t r1
= vec
.size() - 1;
38501 if (!scalar_t(parameters
[1]).to_uint(n
))
38504 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0))
38505 return std::numeric_limits
<T
>::quiet_NaN();
38507 std::nth_element(vec
.begin() + r0
, vec
.begin() + r0
+ n
, vec
.begin() + r1
+ 1);
38513 template <typename T
>
38514 class iota
: public exprtk::igeneric_function
<T
>
38518 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38519 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38520 typedef typename
igfun_t::generic_type generic_type
;
38521 typedef typename
generic_type::scalar_view scalar_t
;
38522 typedef typename
generic_type::vector_view vector_t
;
38524 using exprtk::igeneric_function
<T
>::operator();
38527 : exprtk::igeneric_function
<T
>("VT|VTT|VTTT|VTTTT")
38530 0. VT - vector, increment
38531 1. VTT - vector, increment, base
38532 2. VTTTT - vector, increment, r0, r1
38533 3. VTTTT - vector, increment, base, r0, r1
38537 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38539 vector_t
vec(parameters
[0]);
38541 T increment
= scalar_t(parameters
[1])();
38542 T base
= ((1 == ps_index
) || (3 == ps_index
)) ? scalar_t(parameters
[2])() : T(0);
38544 std::size_t r0
= 0;
38545 std::size_t r1
= vec
.size() - 1;
38547 if ((2 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0))
38548 return std::numeric_limits
<T
>::quiet_NaN();
38549 else if ((3 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 3, 4, 0))
38550 return std::numeric_limits
<T
>::quiet_NaN();
38555 for (std::size_t i
= r0
; i
<= r1
; ++i
, ++j
)
38557 vec
[i
] = base
+ (increment
* j
);
38565 template <typename T
>
38566 class sumk
: public exprtk::igeneric_function
<T
>
38570 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38571 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38572 typedef typename
igfun_t::generic_type generic_type
;
38573 typedef typename
generic_type::vector_view vector_t
;
38575 using exprtk::igeneric_function
<T
>::operator();
38578 : exprtk::igeneric_function
<T
>("V|VTT")
38582 1. VTT - vector, r0, r1
38586 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38588 const vector_t
vec(parameters
[0]);
38590 std::size_t r0
= 0;
38591 std::size_t r1
= vec
.size() - 1;
38593 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 1, 2, 0))
38594 return std::numeric_limits
<T
>::quiet_NaN();
38599 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38601 details::kahan_sum(result
, error
, vec
[i
]);
38608 template <typename T
>
38609 class axpy
: public exprtk::igeneric_function
<T
>
38613 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38614 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38615 typedef typename
igfun_t::generic_type generic_type
;
38616 typedef typename
generic_type::scalar_view scalar_t
;
38617 typedef typename
generic_type::vector_view vector_t
;
38619 using exprtk::igeneric_function
<T
>::operator();
38622 : exprtk::igeneric_function
<T
>("TVV|TVVTT")
38626 0. TVV - a, x(vector), y(vector)
38627 1. TVVTT - a, x(vector), y(vector), r0, r1
38631 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38633 const vector_t
x(parameters
[1]);
38634 vector_t
y(parameters
[2]);
38636 std::size_t r0
= 0;
38637 std::size_t r1
= std::min(x
.size(),y
.size()) - 1;
38639 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 3, 4, 1))
38640 return std::numeric_limits
<T
>::quiet_NaN();
38641 else if (helper::invalid_range(y
, r0
, r1
))
38642 return std::numeric_limits
<T
>::quiet_NaN();
38644 const T a
= scalar_t(parameters
[0])();
38646 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38648 y
[i
] = (a
* x
[i
]) + y
[i
];
38655 template <typename T
>
38656 class axpby
: public exprtk::igeneric_function
<T
>
38660 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38661 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38662 typedef typename
igfun_t::generic_type generic_type
;
38663 typedef typename
generic_type::scalar_view scalar_t
;
38664 typedef typename
generic_type::vector_view vector_t
;
38666 using exprtk::igeneric_function
<T
>::operator();
38669 : exprtk::igeneric_function
<T
>("TVTV|TVTVTT")
38673 0. TVTV - a, x(vector), b, y(vector)
38674 1. TVTVTT - a, x(vector), b, y(vector), r0, r1
38678 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38680 const vector_t
x(parameters
[1]);
38681 vector_t
y(parameters
[3]);
38683 std::size_t r0
= 0;
38684 std::size_t r1
= std::min(x
.size(),y
.size()) - 1;
38686 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 4, 5, 1))
38687 return std::numeric_limits
<T
>::quiet_NaN();
38688 else if (helper::invalid_range(y
, r0
, r1
))
38689 return std::numeric_limits
<T
>::quiet_NaN();
38691 const T a
= scalar_t(parameters
[0])();
38692 const T b
= scalar_t(parameters
[2])();
38694 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38696 y
[i
] = (a
* x
[i
]) + (b
* y
[i
]);
38703 template <typename T
>
38704 class axpyz
: public exprtk::igeneric_function
<T
>
38708 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38709 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38710 typedef typename
igfun_t::generic_type generic_type
;
38711 typedef typename
generic_type::scalar_view scalar_t
;
38712 typedef typename
generic_type::vector_view vector_t
;
38714 using exprtk::igeneric_function
<T
>::operator();
38717 : exprtk::igeneric_function
<T
>("TVVV|TVVVTT")
38721 0. TVVV - a, x(vector), y(vector), z(vector)
38722 1. TVVVTT - a, x(vector), y(vector), z(vector), r0, r1
38726 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38728 const vector_t
x(parameters
[1]);
38729 const vector_t
y(parameters
[2]);
38730 vector_t
z(parameters
[3]);
38732 std::size_t r0
= 0;
38733 std::size_t r1
= std::min(x
.size(),y
.size()) - 1;
38735 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 3, 4, 1))
38736 return std::numeric_limits
<T
>::quiet_NaN();
38737 else if (helper::invalid_range(y
, r0
, r1
))
38738 return std::numeric_limits
<T
>::quiet_NaN();
38739 else if (helper::invalid_range(z
, r0
, r1
))
38740 return std::numeric_limits
<T
>::quiet_NaN();
38742 const T a
= scalar_t(parameters
[0])();
38744 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38746 z
[i
] = (a
* x
[i
]) + y
[i
];
38753 template <typename T
>
38754 class axpbyz
: public exprtk::igeneric_function
<T
>
38758 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38759 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38760 typedef typename
igfun_t::generic_type generic_type
;
38761 typedef typename
generic_type::scalar_view scalar_t
;
38762 typedef typename
generic_type::vector_view vector_t
;
38764 using exprtk::igeneric_function
<T
>::operator();
38767 : exprtk::igeneric_function
<T
>("TVTVV|TVTVVTT")
38771 0. TVTVV - a, x(vector), b, y(vector), z(vector)
38772 1. TVTVVTT - a, x(vector), b, y(vector), z(vector), r0, r1
38776 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38778 const vector_t
x(parameters
[1]);
38779 const vector_t
y(parameters
[3]);
38780 vector_t
z(parameters
[4]);
38782 std::size_t r0
= 0;
38783 std::size_t r1
= std::min(x
.size(),y
.size()) - 1;
38785 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 4, 5, 1))
38786 return std::numeric_limits
<T
>::quiet_NaN();
38787 else if (helper::invalid_range(y
, r0
, r1
))
38788 return std::numeric_limits
<T
>::quiet_NaN();
38789 else if (helper::invalid_range(z
, r0
, r1
))
38790 return std::numeric_limits
<T
>::quiet_NaN();
38792 const T a
= scalar_t(parameters
[0])();
38793 const T b
= scalar_t(parameters
[2])();
38795 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38797 z
[i
] = (a
* x
[i
]) + (b
* y
[i
]);
38804 template <typename T
>
38805 class axpbz
: public exprtk::igeneric_function
<T
>
38809 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38810 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38811 typedef typename
igfun_t::generic_type generic_type
;
38812 typedef typename
generic_type::scalar_view scalar_t
;
38813 typedef typename
generic_type::vector_view vector_t
;
38815 using exprtk::igeneric_function
<T
>::operator();
38818 : exprtk::igeneric_function
<T
>("TVTV|TVTVTT")
38822 0. TVTV - a, x(vector), b, z(vector)
38823 1. TVTVTT - a, x(vector), b, z(vector), r0, r1
38827 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38829 const vector_t
x(parameters
[1]);
38830 vector_t
z(parameters
[3]);
38832 std::size_t r0
= 0;
38833 std::size_t r1
= x
.size() - 1;
38835 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 4, 5, 1))
38836 return std::numeric_limits
<T
>::quiet_NaN();
38837 else if (helper::invalid_range(z
, r0
, r1
))
38838 return std::numeric_limits
<T
>::quiet_NaN();
38840 const T a
= scalar_t(parameters
[0])();
38841 const T b
= scalar_t(parameters
[2])();
38843 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38845 z
[i
] = (a
* x
[i
]) + b
;
38852 template <typename T
>
38853 class dot
: public exprtk::igeneric_function
<T
>
38857 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38858 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38859 typedef typename
igfun_t::generic_type generic_type
;
38860 typedef typename
generic_type::scalar_view scalar_t
;
38861 typedef typename
generic_type::vector_view vector_t
;
38863 using exprtk::igeneric_function
<T
>::operator();
38866 : exprtk::igeneric_function
<T
>("VV|VVTT")
38869 0. VV - x(vector), y(vector)
38870 1. VVTT - x(vector), y(vector), r0, r1
38874 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38876 const vector_t
x(parameters
[0]);
38877 const vector_t
y(parameters
[1]);
38879 std::size_t r0
= 0;
38880 std::size_t r1
= std::min(x
.size(),y
.size()) - 1;
38882 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0))
38883 return std::numeric_limits
<T
>::quiet_NaN();
38884 else if (helper::invalid_range(y
, r0
, r1
))
38885 return std::numeric_limits
<T
>::quiet_NaN();
38889 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38891 result
+= (x
[i
] * y
[i
]);
38898 template <typename T
>
38899 class dotk
: public exprtk::igeneric_function
<T
>
38903 typedef typename
exprtk::igeneric_function
<T
> igfun_t
;
38904 typedef typename
igfun_t::parameter_list_t parameter_list_t
;
38905 typedef typename
igfun_t::generic_type generic_type
;
38906 typedef typename
generic_type::scalar_view scalar_t
;
38907 typedef typename
generic_type::vector_view vector_t
;
38909 using exprtk::igeneric_function
<T
>::operator();
38912 : exprtk::igeneric_function
<T
>("VV|VVTT")
38915 0. VV - x(vector), y(vector)
38916 1. VVTT - x(vector), y(vector), r0, r1
38920 inline T
operator() (const std::size_t& ps_index
, parameter_list_t parameters
)
38922 const vector_t
x(parameters
[0]);
38923 const vector_t
y(parameters
[1]);
38925 std::size_t r0
= 0;
38926 std::size_t r1
= std::min(x
.size(),y
.size()) - 1;
38928 if ((1 == ps_index
) && !helper::load_vector_range
<T
>::process(parameters
, r0
, r1
, 2, 3, 0))
38929 return std::numeric_limits
<T
>::quiet_NaN();
38930 else if (helper::invalid_range(y
, r0
, r1
))
38931 return std::numeric_limits
<T
>::quiet_NaN();
38936 for (std::size_t i
= r0
; i
<= r1
; ++i
)
38938 details::kahan_sum(result
, error
, (x
[i
] * y
[i
]));
38945 template <typename T
>
38963 axpby
<T
> b1_axpby
;
38964 axpyz
<T
> b1_axpyz
;
38965 axpbyz
<T
> b1_axpbyz
;
38966 axpbz
<T
> b1_axpbz
;
38970 bool register_package(exprtk::symbol_table
<T
>& symtab
)
38972 #define exprtk_register_function(FunctionName,FunctionType) \
38973 if (!symtab.add_function(FunctionName,FunctionType)) \
38976 "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
38981 exprtk_register_function("all_true" ,at)
38982 exprtk_register_function("all_false" ,af
)
38983 exprtk_register_function("any_true" ,nt
)
38984 exprtk_register_function("any_false" ,nf
)
38985 exprtk_register_function("count" , c
)
38986 exprtk_register_function("copy" ,cp
)
38987 exprtk_register_function("rotate_left" ,rl
)
38988 exprtk_register_function("rol" ,rl
)
38989 exprtk_register_function("rotate_right" ,rr
)
38990 exprtk_register_function("ror" ,rr
)
38991 exprtk_register_function("shftl" ,sl
)
38992 exprtk_register_function("shftr" ,sr
)
38993 exprtk_register_function("sort" ,st
)
38994 exprtk_register_function("nth_element" ,ne
)
38995 exprtk_register_function("iota" ,ia
)
38996 exprtk_register_function("sumk" ,sk
)
38997 exprtk_register_function("axpy" ,b1_axpy
)
38998 exprtk_register_function("axpby" ,b1_axpby
)
38999 exprtk_register_function("axpyz" ,b1_axpyz
)
39000 exprtk_register_function("axpbyz",b1_axpbyz
)
39001 exprtk_register_function("axpbz" ,b1_axpbz
)
39002 exprtk_register_function("dot" ,dt
)
39003 exprtk_register_function("dotk" ,dtk
)
39004 #undef exprtk_register_function
39010 } // namespace exprtk::rtl::vecops
39011 } // namespace exprtk::rtl
39012 } // namespace exprtk
39017 namespace information
39019 static const char* library
= "Mathematical Expression Toolkit";
39020 static const char* version
= "2.7182818284590452353602874713526624977572470936999595749"
39021 "669676277240766303535475945713821785251664274274663919320";
39022 static const char* date
= "20200101";
39024 static inline std::string
data()
39026 static const std::string info_str
= std::string(library
) +
39027 std::string(" v") + std::string(version
) +
39028 std::string(" (") + date
+ std::string(")");
39032 } // namespace information
39034 #ifdef exprtk_debug
39035 #undef exprtk_debug
39038 #ifdef exprtk_error_location
39039 #undef exprtk_error_location
39042 #ifdef exprtk_disable_fallthrough_begin
39043 #undef exprtk_disable_fallthrough_begin
39046 #ifdef exprtk_disable_fallthrough_end
39047 #undef exprtk_disable_fallthrough_end
39050 } // namespace exprtk