C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
exprtk.hpp
Go to the documentation of this file.
1/*
2 ******************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * Author: Arash Partow (1999-2024) *
6 * URL: https://www.partow.net/programming/exprtk/index.html *
7 * *
8 * Copyright notice: *
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 * https://www.opensource.org/licenses/MIT *
13 * SPDX-License-Identifier: MIT *
14 * *
15 * Example expressions: *
16 * (00) (y + x / y) * (x - y / x) *
17 * (01) (x^2 / sin(2 * pi / y)) - x / 2 *
18 * (02) sqrt(1 - (x^2)) *
19 * (03) 1 - sin(2 * x) + cos(pi / y) *
20 * (04) a * exp(2 * t) + c *
21 * (05) if(((x + 2) == 3) and ((y + 5) <= 9), 1 + w, 2 / z) *
22 * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x *
23 * (07) z := x + sin(2 * pi / y) *
24 * (08) u := 2 * (pi * z) / (w := x + cos(y / pi)) *
25 * (09) clamp(-1, sin(2 * pi * x) + cos(y / 2 * pi), +1) *
26 * (10) inrange(-2, m, +2) == if(({-2 <= m} and [m <= +2]), 1, 0) *
27 * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) *
28 * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] *
29 * *
30 ******************************************************************
31*/
32
33
34#ifndef INCLUDE_EXPRTK_HPP
35#define INCLUDE_EXPRTK_HPP
36
37
38#include <algorithm>
39#include <cassert>
40#include <cctype>
41#include <cmath>
42#include <cstdio>
43#include <cstdlib>
44#include <cstring>
45#include <deque>
46#include <functional>
47#include <iterator>
48#include <limits>
49#include <list>
50#include <map>
51#include <set>
52#include <stack>
53#include <stdexcept>
54#include <string>
55#include <utility>
56#include <vector>
57
58
59namespace exprtk
60{
61 #ifdef exprtk_enable_debugging
62 #define exprtk_debug(params) printf params
63 #else
64 #define exprtk_debug(params) (void)0
65 #endif
66
67 #define exprtk_error_location \
68 "exprtk.hpp:" + details::to_str(__LINE__) \
69
70 #if __cplusplus >= 201103L
71 #define exprtk_override override
72 #define exprtk_final final
73 #define exprtk_delete = delete
74 #else
75 #define exprtk_override
76 #define exprtk_final
77 #define exprtk_delete
78 #endif
79
80 #if __cplusplus >= 201603L
81 #define exprtk_fallthrough [[fallthrough]];
82 #elif __cplusplus >= 201103L
83 #define exprtk_fallthrough [[gnu::fallthrough]];
84 #else
85 #ifndef _MSC_VER
86 #define exprtk_fallthrough __attribute__ ((fallthrough));
87 #else
88 #define exprtk_fallthrough
89 #endif
90 #endif
91
92 namespace details
93 {
94 typedef char char_t;
95 typedef char_t* char_ptr;
96 typedef char_t const* char_cptr;
97 typedef unsigned char uchar_t;
99 typedef uchar_t const* uchar_cptr;
100 typedef unsigned long long int _uint64_t;
101 typedef long long int _int64_t;
102
103 inline bool is_whitespace(const char_t c)
104 {
105 return (' ' == c) || ('\n' == c) ||
106 ('\r' == c) || ('\t' == c) ||
107 ('\b' == c) || ('\v' == c) ||
108 ('\f' == c) ;
109 }
110
111 inline bool is_operator_char(const char_t c)
112 {
113 return ('+' == c) || ('-' == c) ||
114 ('*' == c) || ('/' == c) ||
115 ('^' == c) || ('<' == c) ||
116 ('>' == c) || ('=' == c) ||
117 (',' == c) || ('!' == c) ||
118 ('(' == c) || (')' == c) ||
119 ('[' == c) || (']' == c) ||
120 ('{' == c) || ('}' == c) ||
121 ('%' == c) || (':' == c) ||
122 ('?' == c) || ('&' == c) ||
123 ('|' == c) || (';' == c) ;
124 }
125
126 inline bool is_letter(const char_t c)
127 {
128 return (('a' <= c) && (c <= 'z')) ||
129 (('A' <= c) && (c <= 'Z')) ;
130 }
131
132 inline bool is_digit(const char_t c)
133 {
134 return ('0' <= c) && (c <= '9');
135 }
136
137 inline bool is_letter_or_digit(const char_t c)
138 {
139 return is_letter(c) || is_digit(c);
140 }
141
142 inline bool is_left_bracket(const char_t c)
143 {
144 return ('(' == c) || ('[' == c) || ('{' == c);
145 }
146
147 inline bool is_right_bracket(const char_t c)
148 {
149 return (')' == c) || (']' == c) || ('}' == c);
150 }
151
152 inline bool is_bracket(const char_t c)
153 {
154 return is_left_bracket(c) || is_right_bracket(c);
155 }
156
157 inline bool is_sign(const char_t c)
158 {
159 return ('+' == c) || ('-' == c);
160 }
161
162 inline bool is_invalid(const char_t c)
163 {
164 return !is_whitespace (c) &&
165 !is_operator_char(c) &&
166 !is_letter (c) &&
167 !is_digit (c) &&
168 ('.' != c) &&
169 ('_' != c) &&
170 ('$' != c) &&
171 ('~' != c) &&
172 ('\'' != c);
173 }
174
175 inline bool is_valid_string_char(const char_t c)
176 {
177 return std::isprint(static_cast<uchar_t>(c)) ||
178 is_whitespace(c);
179 }
180
181 #ifndef exprtk_disable_caseinsensitivity
182 inline void case_normalise(std::string& s)
183 {
184 for (std::size_t i = 0; i < s.size(); ++i)
185 {
186 s[i] = static_cast<std::string::value_type>(std::tolower(s[i]));
187 }
188 }
189
190 inline bool imatch(const char_t c1, const char_t c2)
191 {
192 return std::tolower(c1) == std::tolower(c2);
193 }
194
195 inline bool imatch(const std::string& s1, const std::string& s2)
196 {
197 if (s1.size() == s2.size())
198 {
199 for (std::size_t i = 0; i < s1.size(); ++i)
200 {
201 if (std::tolower(s1[i]) != std::tolower(s2[i]))
202 {
203 return false;
204 }
205 }
206
207 return true;
208 }
209
210 return false;
211 }
212
214 {
215 inline bool operator() (const std::string& s1, const std::string& s2) const
216 {
217 const std::size_t length = std::min(s1.size(),s2.size());
218
219 for (std::size_t i = 0; i < length; ++i)
220 {
221 const char_t c1 = static_cast<char_t>(std::tolower(s1[i]));
222 const char_t c2 = static_cast<char_t>(std::tolower(s2[i]));
223
224 if (c1 < c2)
225 return true;
226 else if (c2 < c1)
227 return false;
228 }
229
230 return s1.size() < s2.size();
231 }
232 };
233
234 #else
235 inline void case_normalise(std::string&)
236 {}
237
238 inline bool imatch(const char_t c1, const char_t c2)
239 {
240 return c1 == c2;
241 }
242
243 inline bool imatch(const std::string& s1, const std::string& s2)
244 {
245 return s1 == s2;
246 }
247
248 struct ilesscompare
249 {
250 inline bool operator() (const std::string& s1, const std::string& s2) const
251 {
252 return s1 < s2;
253 }
254 };
255 #endif
256
257 inline bool is_valid_sf_symbol(const std::string& symbol)
258 {
259 // Special function: $f12 or $F34
260 return (4 == symbol.size()) &&
261 ('$' == symbol[0]) &&
262 imatch('f',symbol[1]) &&
263 is_digit(symbol[2]) &&
264 is_digit(symbol[3]);
265 }
266
267 inline const char_t& front(const std::string& s)
268 {
269 return s[0];
270 }
271
272 inline const char_t& back(const std::string& s)
273 {
274 return s[s.size() - 1];
275 }
276
277 inline std::string to_str(int i)
278 {
279 if (0 == i)
280 return std::string("0");
281
282 std::string result;
283
284 const int sign = (i < 0) ? -1 : 1;
285
286 for ( ; i; i /= 10)
287 {
288 result += '0' + static_cast<char_t>(sign * (i % 10));
289 }
290
291 if (sign < 0)
292 {
293 result += '-';
294 }
295
296 std::reverse(result.begin(), result.end());
297
298 return result;
299 }
300
301 inline std::string to_str(std::size_t i)
302 {
303 return to_str(static_cast<int>(i));
304 }
305
306 inline bool is_hex_digit(const uchar_t digit)
307 {
308 return (('0' <= digit) && (digit <= '9')) ||
309 (('A' <= digit) && (digit <= 'F')) ||
310 (('a' <= digit) && (digit <= 'f')) ;
311 }
312
314 {
315 if (('0' <= h) && (h <= '9'))
316 return (h - '0');
317 else
318 return static_cast<uchar_t>(std::toupper(h) - 'A');
319 }
320
321 template <typename Iterator>
322 inline bool parse_hex(Iterator& itr, Iterator end,
323 char_t& result)
324 {
325 if (
326 (end == (itr )) ||
327 (end == (itr + 1)) ||
328 (end == (itr + 2)) ||
329 (end == (itr + 3)) ||
330 ('0' != *(itr )) ||
331 ('X' != std::toupper(*(itr + 1))) ||
332 (!is_hex_digit(*(itr + 2))) ||
333 (!is_hex_digit(*(itr + 3)))
334 )
335 {
336 return false;
337 }
338
339 result = hex_to_bin(static_cast<uchar_t>(*(itr + 2))) << 4 |
340 hex_to_bin(static_cast<uchar_t>(*(itr + 3))) ;
341
342 return true;
343 }
344
345 inline bool cleanup_escapes(std::string& s)
346 {
347 typedef std::string::iterator str_itr_t;
348
349 str_itr_t itr1 = s.begin();
350 str_itr_t itr2 = s.begin();
351 str_itr_t end = s.end ();
352
353 std::size_t removal_count = 0;
354
355 while (end != itr1)
356 {
357 if ('\\' == (*itr1))
358 {
359 if (end == ++itr1)
360 {
361 return false;
362 }
363 else if (parse_hex(itr1, end, *itr2))
364 {
365 itr1 += 4;
366 itr2 += 1;
367 removal_count += 4;
368 }
369 else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; }
370 else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; }
371 else if ('f' == (*itr1)) { (*itr2++) = '\f'; ++itr1; ++removal_count; }
372 else if ('n' == (*itr1)) { (*itr2++) = '\n'; ++itr1; ++removal_count; }
373 else if ('r' == (*itr1)) { (*itr2++) = '\r'; ++itr1; ++removal_count; }
374 else if ('t' == (*itr1)) { (*itr2++) = '\t'; ++itr1; ++removal_count; }
375 else if ('v' == (*itr1)) { (*itr2++) = '\v'; ++itr1; ++removal_count; }
376 else if ('0' == (*itr1)) { (*itr2++) = '\0'; ++itr1; ++removal_count; }
377 else
378 {
379 (*itr2++) = (*itr1++);
380 ++removal_count;
381 }
382
383 continue;
384 }
385 else
386 (*itr2++) = (*itr1++);
387 }
388
389 if ((removal_count > s.size()) || (0 == removal_count))
390 return false;
391
392 s.resize(s.size() - removal_count);
393
394 return true;
395 }
396
398 {
399 public:
400
401 explicit build_string(const std::size_t& initial_size = 64)
402 {
403 data_.reserve(initial_size);
404 }
405
406 inline build_string& operator << (const std::string& s)
407 {
408 data_ += s;
409 return (*this);
410 }
411
413 {
414 data_ += std::string(s);
415 return (*this);
416 }
417
418 inline operator std::string () const
419 {
420 return data_;
421 }
422
423 inline std::string as_string() const
424 {
425 return data_;
426 }
427
428 private:
429
430 std::string data_;
431 };
432
433 static const std::string reserved_words[] =
434 {
435 "assert", "break", "case", "continue", "const", "default",
436 "false", "for", "if", "else", "ilike", "in", "like", "and",
437 "nand", "nor", "not", "null", "or", "repeat", "return",
438 "shl", "shr", "swap", "switch", "true", "until", "var",
439 "while", "xnor", "xor", "&", "|"
440 };
441
442 static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
443
444 static const std::string reserved_symbols[] =
445 {
446 "abs", "acos", "acosh", "and", "asin", "asinh", "assert",
447 "atan", "atanh", "atan2", "avg", "break", "case", "ceil",
448 "clamp", "continue", "const", "cos", "cosh", "cot", "csc",
449 "default", "deg2grad", "deg2rad", "equal", "erf", "erfc",
450 "exp", "expm1", "false", "floor", "for", "frac", "grad2deg",
451 "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
452 "like", "log", "log10", "log2", "logn", "log1p", "mand",
453 "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor",
454 "not", "not_equal", "null", "or", "pow", "rad2deg",
455 "repeat", "return", "root", "round", "roundn", "sec", "sgn",
456 "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap",
457 "switch", "tan", "tanh", "true", "trunc", "until", "var",
458 "while", "xnor", "xor", "&", "|"
459 };
460
461 static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
462
463 static const std::string base_function_list[] =
464 {
465 "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh",
466 "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot",
467 "csc", "equal", "erf", "erfc", "exp", "expm1", "floor",
468 "frac", "hypot", "iclamp", "like", "log", "log10", "log2",
469 "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul",
470 "ncdf", "pow", "root", "round", "roundn", "sec", "sgn",
471 "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
472 "trunc", "not_equal", "inrange", "deg2grad", "deg2rad",
473 "rad2deg", "grad2deg"
474 };
475
476 static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
477
478 static const std::string logic_ops_list[] =
479 {
480 "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|"
481 };
482
483 static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
484
485 static const std::string cntrl_struct_list[] =
486 {
487 "if", "switch", "for", "while", "repeat", "return"
488 };
489
490 static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
491
492 static const std::string arithmetic_ops_list[] =
493 {
494 "+", "-", "*", "/", "%", "^"
495 };
496
497 static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
498
499 static const std::string assignment_ops_list[] =
500 {
501 ":=", "+=", "-=",
502 "*=", "/=", "%="
503 };
504
505 static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
506
507 static const std::string inequality_ops_list[] =
508 {
509 "<", "<=", "==",
510 "=", "!=", "<>",
511 ">=", ">"
512 };
513
514 static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string);
515
516 inline bool is_reserved_word(const std::string& symbol)
517 {
518 for (std::size_t i = 0; i < reserved_words_size; ++i)
519 {
520 if (imatch(symbol, reserved_words[i]))
521 {
522 return true;
523 }
524 }
525
526 return false;
527 }
528
529 inline bool is_reserved_symbol(const std::string& symbol)
530 {
531 for (std::size_t i = 0; i < reserved_symbols_size; ++i)
532 {
533 if (imatch(symbol, reserved_symbols[i]))
534 {
535 return true;
536 }
537 }
538
539 return false;
540 }
541
542 inline bool is_base_function(const std::string& function_name)
543 {
544 for (std::size_t i = 0; i < base_function_list_size; ++i)
545 {
546 if (imatch(function_name, base_function_list[i]))
547 {
548 return true;
549 }
550 }
551
552 return false;
553 }
554
555 inline bool is_control_struct(const std::string& cntrl_strct)
556 {
557 for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
558 {
559 if (imatch(cntrl_strct, cntrl_struct_list[i]))
560 {
561 return true;
562 }
563 }
564
565 return false;
566 }
567
568 inline bool is_logic_opr(const std::string& lgc_opr)
569 {
570 for (std::size_t i = 0; i < logic_ops_list_size; ++i)
571 {
572 if (imatch(lgc_opr, logic_ops_list[i]))
573 {
574 return true;
575 }
576 }
577
578 return false;
579 }
580
581 struct cs_match
582 {
583 static inline bool cmp(const char_t c0, const char_t c1)
584 {
585 return (c0 == c1);
586 }
587 };
588
590 {
591 static inline bool cmp(const char_t c0, const char_t c1)
592 {
593 return (std::tolower(c0) == std::tolower(c1));
594 }
595 };
596
597 template <typename Iterator, typename Compare>
598 inline bool match_impl(const Iterator pattern_begin,
599 const Iterator pattern_end ,
600 const Iterator data_begin ,
601 const Iterator data_end ,
602 const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
603 const typename std::iterator_traits<Iterator>::value_type& exactly_one )
604 {
605 typedef typename std::iterator_traits<Iterator>::value_type type;
606
607 const Iterator null_itr(0);
608
609 Iterator p_itr = pattern_begin;
610 Iterator d_itr = data_begin;
611 Iterator np_itr = null_itr;
612 Iterator nd_itr = null_itr;
613
614 for ( ; ; )
615 {
616 if (p_itr != pattern_end)
617 {
618 const type c = *(p_itr);
619
620 if ((data_end != d_itr) && (Compare::cmp(c,*(d_itr)) || (exactly_one == c)))
621 {
622 ++d_itr;
623 ++p_itr;
624 continue;
625 }
626 else if (zero_or_more == c)
627 {
628 while ((pattern_end != p_itr) && (zero_or_more == *(p_itr)))
629 {
630 ++p_itr;
631 }
632
633 const type d = *(p_itr);
634
635 while ((data_end != d_itr) && !(Compare::cmp(d,*(d_itr)) || (exactly_one == d)))
636 {
637 ++d_itr;
638 }
639
640 // set backtrack iterators
641 np_itr = p_itr - 1;
642 nd_itr = d_itr + 1;
643
644 continue;
645 }
646 }
647 else if (data_end == d_itr)
648 break;
649
650 if ((data_end == d_itr) || (null_itr == nd_itr))
651 return false;
652
653 p_itr = np_itr;
654 d_itr = nd_itr;
655 }
656
657 return true;
658 }
659
660 inline bool wc_match(const std::string& wild_card,
661 const std::string& str)
662 {
664 (
665 wild_card.data(),
666 wild_card.data() + wild_card.size(),
667 str.data(),
668 str.data() + str.size(),
669 '*', '?'
670 );
671 }
672
673 inline bool wc_imatch(const std::string& wild_card,
674 const std::string& str)
675 {
677 (
678 wild_card.data(),
679 wild_card.data() + wild_card.size(),
680 str.data(),
681 str.data() + str.size(),
682 '*', '?'
683 );
684 }
685
686 inline bool sequence_match(const std::string& pattern,
687 const std::string& str,
688 std::size_t& diff_index,
690 {
691 if (str.empty())
692 {
693 return ("Z" == pattern);
694 }
695 else if ('*' == pattern[0])
696 return false;
697
698 typedef std::string::const_iterator itr_t;
699
700 itr_t p_itr = pattern.begin();
701 itr_t s_itr = str .begin();
702
703 const itr_t p_end = pattern.end();
704 const itr_t s_end = str .end();
705
706 while ((s_end != s_itr) && (p_end != p_itr))
707 {
708 if ('*' == (*p_itr))
709 {
710 const char_t target = static_cast<char_t>(std::toupper(*(p_itr - 1)));
711
712 if ('*' == target)
713 {
714 diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
715 diff_value = static_cast<char_t>(std::toupper(*p_itr));
716
717 return false;
718 }
719 else
720 ++p_itr;
721
722 while (s_itr != s_end)
723 {
724 if (target != std::toupper(*s_itr))
725 break;
726 else
727 ++s_itr;
728 }
729
730 continue;
731 }
732 else if (
733 ('?' != *p_itr) &&
734 std::toupper(*p_itr) != std::toupper(*s_itr)
735 )
736 {
737 diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
738 diff_value = static_cast<char_t>(std::toupper(*p_itr));
739
740 return false;
741 }
742
743 ++p_itr;
744 ++s_itr;
745 }
746
747 return (
748 (s_end == s_itr) &&
749 (
750 (p_end == p_itr) ||
751 ('*' == *p_itr)
752 )
753 );
754 }
755
756 template<typename T>
758 {
759 static inline void process(T* base_ptr, const std::size_t size)
760 {
761 const T zero = T(0);
762 for (std::size_t i = 0; i < size; ++i)
763 {
764 base_ptr[i] = zero;
765 }
766 }
767 };
768
769 #define pod_set_zero_value(T) \
770 template <> \
771 struct set_zero_value_impl<T> \
772 { \
773 static inline void process(T* base_ptr, const std::size_t size) \
774 { std::memset(base_ptr, 0x00, size * sizeof(T)); } \
775 }; \
776
780
781 #ifdef pod_set_zero_value
782 #undef pod_set_zero_value
783 #endif
784
785 template<typename T>
786 inline void set_zero_value(T* data, const std::size_t size)
787 {
789 }
790
791 template<typename T>
792 inline void set_zero_value(std::vector<T>& v)
793 {
794 set_zero_value(v.data(),v.size());
795 }
796
797 static const double pow10[] =
798 {
799 1.0,
800 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
801 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
802 1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
803 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
804 };
805
806 static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
807
808 namespace numeric
809 {
810 namespace constant
811 {
812 static const double e = 2.71828182845904523536028747135266249775724709369996;
813 static const double pi = 3.14159265358979323846264338327950288419716939937510;
814 static const double pi_2 = 1.57079632679489661923132169163975144209858469968755;
815 static const double pi_4 = 0.78539816339744830961566084581987572104929234984378;
816 static const double pi_180 = 0.01745329251994329576923690768488612713442871888542;
817 static const double _1_pi = 0.31830988618379067153776752674502872406891929148091;
818 static const double _2_pi = 0.63661977236758134307553505349005744813783858296183;
819 static const double _180_pi = 57.29577951308232087679815481410517033240547246656443;
820 static const double log2 = 0.69314718055994530941723212145817656807550013436026;
821 static const double sqrt2 = 1.41421356237309504880168872420969807856967187537695;
822 }
823
824 namespace details
825 {
827 struct real_type_tag { real_type_tag () {} };
828 struct int_type_tag { int_type_tag () {} };
829
830 template <typename T>
832 {
835 };
836
837 #define exprtk_register_real_type_tag(T) \
838 template <> struct number_type<T> \
839 { typedef real_type_tag type; number_type() {} }; \
840
841 #define exprtk_register_int_type_tag(T) \
842 template <> struct number_type<T> \
843 { typedef int_type_tag type; number_type() {} }; \
844
848
855
856 #undef exprtk_register_real_type_tag
857 #undef exprtk_register_int_type_tag
858
859 template <typename T>
860 struct epsilon_type {};
861
862 #define exprtk_define_epsilon_type(Type, Epsilon) \
863 template <> struct epsilon_type<Type> \
864 { \
865 static inline Type value() \
866 { \
867 const Type epsilon = static_cast<Type>(Epsilon); \
868 return epsilon; \
869 } \
870 }; \
871
872 exprtk_define_epsilon_type(float , 0.00000100000f)
873 exprtk_define_epsilon_type(double , 0.000000000100)
874 exprtk_define_epsilon_type(long double, 0.000000000001)
875
876 #undef exprtk_define_epsilon_type
877
878 template <typename T>
879 inline bool is_nan_impl(const T v, real_type_tag)
880 {
881 return std::not_equal_to<T>()(v,v);
882 }
883
884 template <typename T>
885 inline int to_int32_impl(const T v, real_type_tag)
886 {
887 return static_cast<int>(v);
888 }
889
890 template <typename T>
892 {
893 return static_cast<_int64_t>(v);
894 }
895
896 template <typename T>
898 {
899 return static_cast<_uint64_t>(v);
900 }
901
902 template <typename T>
903 inline bool is_true_impl(const T v)
904 {
905 return std::not_equal_to<T>()(T(0),v);
906 }
907
908 template <typename T>
909 inline bool is_false_impl(const T v)
910 {
911 return std::equal_to<T>()(T(0),v);
912 }
913
914 template <typename T>
915 inline T abs_impl(const T v, real_type_tag)
916 {
917 return ((v < T(0)) ? -v : v);
918 }
919
920 template <typename T>
921 inline T min_impl(const T v0, const T v1, real_type_tag)
922 {
923 return std::min<T>(v0,v1);
924 }
925
926 template <typename T>
927 inline T max_impl(const T v0, const T v1, real_type_tag)
928 {
929 return std::max<T>(v0,v1);
930 }
931
932 template <typename T>
933 inline T equal_impl(const T v0, const T v1, real_type_tag)
934 {
935 const T epsilon = epsilon_type<T>::value();
936 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);
937 }
938
939 inline float equal_impl(const float v0, const float v1, real_type_tag)
940 {
941 const float epsilon = epsilon_type<float>::value();
942 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;
943 }
944
945 template <typename T>
946 inline T equal_impl(const T v0, const T v1, int_type_tag)
947 {
948 return (v0 == v1) ? 1 : 0;
949 }
950
951 template <typename T>
952 inline T expm1_impl(const T v, real_type_tag)
953 {
954 // return std::expm1<T>(v);
955 if (abs_impl(v,real_type_tag()) < T(0.00001))
956 return v + (T(0.5) * v * v);
957 else
958 return std::exp(v) - T(1);
959 }
960
961 template <typename T>
962 inline T expm1_impl(const T v, int_type_tag)
963 {
964 return T(std::exp<double>(v)) - T(1);
965 }
966
967 template <typename T>
968 inline T nequal_impl(const T v0, const T v1, real_type_tag)
969 {
970 typedef real_type_tag rtg;
971 const T epsilon = epsilon_type<T>::value();
972 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);
973 }
974
975 inline float nequal_impl(const float v0, const float v1, real_type_tag)
976 {
977 typedef real_type_tag rtg;
978 const float epsilon = epsilon_type<float>::value();
979 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;
980 }
981
982 template <typename T>
983 inline T nequal_impl(const T v0, const T v1, int_type_tag)
984 {
985 return (v0 != v1) ? 1 : 0;
986 }
987
988 template <typename T>
989 inline T modulus_impl(const T v0, const T v1, real_type_tag)
990 {
991 return std::fmod(v0,v1);
992 }
993
994 template <typename T>
995 inline T modulus_impl(const T v0, const T v1, int_type_tag)
996 {
997 return v0 % v1;
998 }
999
1000 template <typename T>
1001 inline T pow_impl(const T v0, const T v1, real_type_tag)
1002 {
1003 return std::pow(v0,v1);
1004 }
1005
1006 template <typename T>
1007 inline T pow_impl(const T v0, const T v1, int_type_tag)
1008 {
1009 return std::pow(static_cast<double>(v0),static_cast<double>(v1));
1010 }
1011
1012 template <typename T>
1013 inline T logn_impl(const T v0, const T v1, real_type_tag)
1014 {
1015 return std::log(v0) / std::log(v1);
1016 }
1017
1018 template <typename T>
1019 inline T logn_impl(const T v0, const T v1, int_type_tag)
1020 {
1021 return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
1022 }
1023
1024 template <typename T>
1025 inline T log1p_impl(const T v, real_type_tag)
1026 {
1027 if (v > T(-1))
1028 {
1029 if (abs_impl(v,real_type_tag()) > T(0.0001))
1030 {
1031 return std::log(T(1) + v);
1032 }
1033 else
1034 return (T(-0.5) * v + T(1)) * v;
1035 }
1036
1037 return std::numeric_limits<T>::quiet_NaN();
1038 }
1039
1040 template <typename T>
1041 inline T log1p_impl(const T v, int_type_tag)
1042 {
1043 if (v > T(-1))
1044 {
1045 return std::log(T(1) + v);
1046 }
1047
1048 return std::numeric_limits<T>::quiet_NaN();
1049 }
1050
1051 template <typename T>
1052 inline T root_impl(const T v0, const T v1, real_type_tag)
1053 {
1054 if (v1 < T(0))
1055 return std::numeric_limits<T>::quiet_NaN();
1056
1057 const std::size_t n = static_cast<std::size_t>(v1);
1058
1059 if ((v0 < T(0)) && (0 == (n % 2)))
1060 return std::numeric_limits<T>::quiet_NaN();
1061
1062 return std::pow(v0, T(1) / n);
1063 }
1064
1065 template <typename T>
1066 inline T root_impl(const T v0, const T v1, int_type_tag)
1067 {
1068 return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
1069 }
1070
1071 template <typename T>
1072 inline T round_impl(const T v, real_type_tag)
1073 {
1074 return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5)));
1075 }
1076
1077 template <typename T>
1078 inline T roundn_impl(const T v0, const T v1, real_type_tag)
1079 {
1080 const int index = std::max<int>(0, std::min<int>(pow10_size - 1, static_cast<int>(std::floor(v1))));
1081 const T p10 = T(pow10[index]);
1082
1083 if (v0 < T(0))
1084 return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
1085 else
1086 return T(std::floor((v0 * p10) + T(0.5)) / p10);
1087 }
1088
1089 template <typename T>
1090 inline T roundn_impl(const T v0, const T, int_type_tag)
1091 {
1092 return v0;
1093 }
1094
1095 template <typename T>
1096 inline T hypot_impl(const T v0, const T v1, real_type_tag)
1097 {
1098 return std::sqrt((v0 * v0) + (v1 * v1));
1099 }
1100
1101 template <typename T>
1102 inline T hypot_impl(const T v0, const T v1, int_type_tag)
1103 {
1104 return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
1105 }
1106
1107 template <typename T>
1108 inline T atan2_impl(const T v0, const T v1, real_type_tag)
1109 {
1110 return std::atan2(v0,v1);
1111 }
1112
1113 template <typename T>
1114 inline T atan2_impl(const T, const T, int_type_tag)
1115 {
1116 return 0;
1117 }
1118
1119 template <typename T>
1120 inline T shr_impl(const T v0, const T v1, real_type_tag)
1121 {
1122 return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
1123 }
1124
1125 template <typename T>
1126 inline T shr_impl(const T v0, const T v1, int_type_tag)
1127 {
1128 return v0 >> v1;
1129 }
1130
1131 template <typename T>
1132 inline T shl_impl(const T v0, const T v1, real_type_tag)
1133 {
1134 return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
1135 }
1136
1137 template <typename T>
1138 inline T shl_impl(const T v0, const T v1, int_type_tag)
1139 {
1140 return v0 << v1;
1141 }
1142
1143 template <typename T>
1144 inline T sgn_impl(const T v, real_type_tag)
1145 {
1146 if (v > T(0)) return T(+1);
1147 else if (v < T(0)) return T(-1);
1148 else return T( 0);
1149 }
1150
1151 template <typename T>
1152 inline T sgn_impl(const T v, int_type_tag)
1153 {
1154 if (v > T(0)) return T(+1);
1155 else if (v < T(0)) return T(-1);
1156 else return T( 0);
1157 }
1158
1159 template <typename T>
1160 inline T and_impl(const T v0, const T v1, real_type_tag)
1161 {
1162 return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0);
1163 }
1164
1165 template <typename T>
1166 inline T and_impl(const T v0, const T v1, int_type_tag)
1167 {
1168 return v0 && v1;
1169 }
1170
1171 template <typename T>
1172 inline T nand_impl(const T v0, const T v1, real_type_tag)
1173 {
1174 return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0);
1175 }
1176
1177 template <typename T>
1178 inline T nand_impl(const T v0, const T v1, int_type_tag)
1179 {
1180 return !(v0 && v1);
1181 }
1182
1183 template <typename T>
1184 inline T or_impl(const T v0, const T v1, real_type_tag)
1185 {
1186 return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0);
1187 }
1188
1189 template <typename T>
1190 inline T or_impl(const T v0, const T v1, int_type_tag)
1191 {
1192 return (v0 || v1);
1193 }
1194
1195 template <typename T>
1196 inline T nor_impl(const T v0, const T v1, real_type_tag)
1197 {
1198 return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0);
1199 }
1200
1201 template <typename T>
1202 inline T nor_impl(const T v0, const T v1, int_type_tag)
1203 {
1204 return !(v0 || v1);
1205 }
1206
1207 template <typename T>
1208 inline T xor_impl(const T v0, const T v1, real_type_tag)
1209 {
1210 return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0);
1211 }
1212
1213 template <typename T>
1214 inline T xor_impl(const T v0, const T v1, int_type_tag)
1215 {
1216 return v0 ^ v1;
1217 }
1218
1219 template <typename T>
1220 inline T xnor_impl(const T v0, const T v1, real_type_tag)
1221 {
1222 const bool v0_true = is_true_impl(v0);
1223 const bool v1_true = is_true_impl(v1);
1224
1225 if ((v0_true && v1_true) || (!v0_true && !v1_true))
1226 return T(1);
1227 else
1228 return T(0);
1229 }
1230
1231 template <typename T>
1232 inline T xnor_impl(const T v0, const T v1, int_type_tag)
1233 {
1234 const bool v0_true = is_true_impl(v0);
1235 const bool v1_true = is_true_impl(v1);
1236
1237 if ((v0_true && v1_true) || (!v0_true && !v1_true))
1238 return T(1);
1239 else
1240 return T(0);
1241 }
1242
1243 #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1244 #define exprtk_define_erf(TT, impl) \
1245 inline TT erf_impl(const TT v) { return impl(v); } \
1246
1249 exprtk_define_erf(long double, ::erfl)
1250 #undef exprtk_define_erf
1251 #endif
1252
1253 template <typename T>
1254 inline T erf_impl(const T v, real_type_tag)
1255 {
1256 #if defined(_MSC_VER) && (_MSC_VER < 1900)
1257 // Credits: Abramowitz & Stegun Equations 7.1.25-28
1258 static const T c[] =
1259 {
1260 T( 1.26551223), T(1.00002368),
1261 T( 0.37409196), T(0.09678418),
1262 T(-0.18628806), T(0.27886807),
1263 T(-1.13520398), T(1.48851587),
1264 T(-0.82215223), T(0.17087277)
1265 };
1266
1267 const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
1268
1269 const T result = T(1) - t * std::exp((-v * v) -
1270 c[0] + t * (c[1] + t *
1271 (c[2] + t * (c[3] + t *
1272 (c[4] + t * (c[5] + t *
1273 (c[6] + t * (c[7] + t *
1274 (c[8] + t * (c[9]))))))))));
1275
1276 return (v >= T(0)) ? result : -result;
1277 #else
1278 return erf_impl(v);
1279 #endif
1280 }
1281
1282 template <typename T>
1283 inline T erf_impl(const T v, int_type_tag)
1284 {
1285 return erf_impl(static_cast<double>(v),real_type_tag());
1286 }
1287
1288 #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1289 #define exprtk_define_erfc(TT, impl) \
1290 inline TT erfc_impl(const TT v) { return impl(v); } \
1291
1295 #undef exprtk_define_erfc
1296 #endif
1297
1298 template <typename T>
1299 inline T erfc_impl(const T v, real_type_tag)
1300 {
1301 #if defined(_MSC_VER) && (_MSC_VER < 1900)
1302 return T(1) - erf_impl(v,real_type_tag());
1303 #else
1304 return erfc_impl(v);
1305 #endif
1306 }
1307
1308 template <typename T>
1309 inline T erfc_impl(const T v, int_type_tag)
1310 {
1311 return erfc_impl(static_cast<double>(v),real_type_tag());
1312 }
1313
1314 template <typename T>
1315 inline T ncdf_impl(const T v, real_type_tag)
1316 {
1317 return T(0.5) * erfc_impl(-(v / T(numeric::constant::sqrt2)),real_type_tag());
1318 }
1319
1320 template <typename T>
1321 inline T ncdf_impl(const T v, int_type_tag)
1322 {
1323 return ncdf_impl(static_cast<double>(v),real_type_tag());
1324 }
1325
1326 template <typename T>
1327 inline T sinc_impl(const T v, real_type_tag)
1328 {
1329 if (std::abs(v) >= std::numeric_limits<T>::epsilon())
1330 return(std::sin(v) / v);
1331 else
1332 return T(1);
1333 }
1334
1335 template <typename T>
1336 inline T sinc_impl(const T v, int_type_tag)
1337 {
1338 return sinc_impl(static_cast<double>(v),real_type_tag());
1339 }
1340
1341 #if __cplusplus >= 201103L
1342 template <typename T>
1343 inline T acosh_impl(const T v, real_type_tag)
1344 {
1345 return std::acosh(v);
1346 }
1347
1348 template <typename T>
1349 inline T asinh_impl(const T v, real_type_tag)
1350 {
1351 return std::asinh(v);
1352 }
1353
1354 template <typename T>
1355 inline T atanh_impl(const T v, real_type_tag)
1356 {
1357 return std::atanh(v);
1358 }
1359 #else
1360 template <typename T>
1361 inline T acosh_impl(const T v, real_type_tag)
1362 {
1363 return std::log(v + std::sqrt((v * v) - T(1)));
1364 }
1365
1366 template <typename T>
1367 inline T asinh_impl(const T v, real_type_tag)
1368 {
1369 return std::log(v + std::sqrt((v * v) + T(1)));
1370 }
1371
1372 template <typename T>
1373 inline T atanh_impl(const T v, real_type_tag)
1374 {
1375 return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2);
1376 }
1377 #endif
1378
1379 template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
1380 template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
1381 template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
1382 template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
1383 template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
1384 template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
1385 template <typename T> inline T exp_impl(const T v, real_type_tag) { return std::exp (v); }
1386 template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
1387 template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
1388 template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
1389 template <typename T> inline T log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1390 template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
1391 template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
1392 template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
1393 template <typename T> inline T sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
1394 template <typename T> inline T sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
1395 template <typename T> inline T tan_impl(const T v, real_type_tag) { return std::tan (v); }
1396 template <typename T> inline T tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
1397 template <typename T> inline T cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
1398 template <typename T> inline T sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
1399 template <typename T> inline T csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
1400 template <typename T> inline T r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
1401 template <typename T> inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
1402 template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(10.0/9.0)); }
1403 template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/10.0)); }
1404 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)); }
1405 template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
1406 template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); }
1407
1408 template <typename T> inline T const_pi_impl(real_type_tag) { return T(numeric::constant::pi); }
1409 template <typename T> inline T const_e_impl(real_type_tag) { return T(numeric::constant::e); }
1410 template <typename T> inline T const_qnan_impl(real_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1411
1412 template <typename T> inline T abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
1413 template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
1414 template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
1415 template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
1416 template <typename T> inline T log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1417 template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
1418 template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
1419 template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
1420 template <typename T> inline T floor_impl(const T v, int_type_tag) { return v; }
1421 template <typename T> inline T round_impl(const T v, int_type_tag) { return v; }
1422 template <typename T> inline T notl_impl(const T v, int_type_tag) { return !v; }
1423 template <typename T> inline T sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
1424 template <typename T> inline T frac_impl(const T , int_type_tag) { return T(0); }
1425 template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v; }
1426 template <typename T> inline T acos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1427 template <typename T> inline T acosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1428 template <typename T> inline T asin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1429 template <typename T> inline T asinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1430 template <typename T> inline T atan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1431 template <typename T> inline T atanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1432 template <typename T> inline T cos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1433 template <typename T> inline T cosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1434 template <typename T> inline T sin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1435 template <typename T> inline T sinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1436 template <typename T> inline T tan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1437 template <typename T> inline T tanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1438 template <typename T> inline T cot_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1439 template <typename T> inline T sec_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1440 template <typename T> inline T csc_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1441
1442 template <typename T>
1443 inline bool is_integer_impl(const T& v, real_type_tag)
1444 {
1445 return std::equal_to<T>()(T(0),std::fmod(v,T(1)));
1446 }
1447
1448 template <typename T>
1449 inline bool is_integer_impl(const T&, int_type_tag)
1450 {
1451 return true;
1452 }
1453 }
1454
1455 template <typename Type>
1456 struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
1457
1458 template <> struct numeric_info<int > { enum { length = 10, size = 16, bound_length = 9 }; };
1459 template <> struct numeric_info<float > { enum { min_exp = -38, max_exp = +38 }; };
1460 template <> struct numeric_info<double > { enum { min_exp = -308, max_exp = +308 }; };
1461 template <> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308 }; };
1462
1463 template <typename T>
1464 inline int to_int32(const T v)
1465 {
1466 const typename details::number_type<T>::type num_type;
1467 return to_int32_impl(v, num_type);
1468 }
1469
1470 template <typename T>
1471 inline _int64_t to_int64(const T v)
1472 {
1473 const typename details::number_type<T>::type num_type;
1474 return to_int64_impl(v, num_type);
1475 }
1476
1477 template <typename T>
1478 inline _uint64_t to_uint64(const T v)
1479 {
1480 const typename details::number_type<T>::type num_type;
1481 return to_uint64_impl(v, num_type);
1482 }
1483
1484 template <typename T>
1485 inline bool is_nan(const T v)
1486 {
1487 const typename details::number_type<T>::type num_type;
1488 return is_nan_impl(v, num_type);
1489 }
1490
1491 template <typename T>
1492 inline T min(const T v0, const T v1)
1493 {
1494 const typename details::number_type<T>::type num_type;
1495 return min_impl(v0, v1, num_type);
1496 }
1497
1498 template <typename T>
1499 inline T max(const T v0, const T v1)
1500 {
1501 const typename details::number_type<T>::type num_type;
1502 return max_impl(v0, v1, num_type);
1503 }
1504
1505 template <typename T>
1506 inline T equal(const T v0, const T v1)
1507 {
1508 const typename details::number_type<T>::type num_type;
1509 return equal_impl(v0, v1, num_type);
1510 }
1511
1512 template <typename T>
1513 inline T nequal(const T v0, const T v1)
1514 {
1515 const typename details::number_type<T>::type num_type;
1516 return nequal_impl(v0, v1, num_type);
1517 }
1518
1519 template <typename T>
1520 inline T modulus(const T v0, const T v1)
1521 {
1522 const typename details::number_type<T>::type num_type;
1523 return modulus_impl(v0, v1, num_type);
1524 }
1525
1526 template <typename T>
1527 inline T pow(const T v0, const T v1)
1528 {
1529 const typename details::number_type<T>::type num_type;
1530 return pow_impl(v0, v1, num_type);
1531 }
1532
1533 template <typename T>
1534 inline T logn(const T v0, const T v1)
1535 {
1536 const typename details::number_type<T>::type num_type;
1537 return logn_impl(v0, v1, num_type);
1538 }
1539
1540 template <typename T>
1541 inline T root(const T v0, const T v1)
1542 {
1543 const typename details::number_type<T>::type num_type;
1544 return root_impl(v0, v1, num_type);
1545 }
1546
1547 template <typename T>
1548 inline T roundn(const T v0, const T v1)
1549 {
1550 const typename details::number_type<T>::type num_type;
1551 return roundn_impl(v0, v1, num_type);
1552 }
1553
1554 template <typename T>
1555 inline T hypot(const T v0, const T v1)
1556 {
1557 const typename details::number_type<T>::type num_type;
1558 return hypot_impl(v0, v1, num_type);
1559 }
1560
1561 template <typename T>
1562 inline T atan2(const T v0, const T v1)
1563 {
1564 const typename details::number_type<T>::type num_type;
1565 return atan2_impl(v0, v1, num_type);
1566 }
1567
1568 template <typename T>
1569 inline T shr(const T v0, const T v1)
1570 {
1571 const typename details::number_type<T>::type num_type;
1572 return shr_impl(v0, v1, num_type);
1573 }
1574
1575 template <typename T>
1576 inline T shl(const T v0, const T v1)
1577 {
1578 const typename details::number_type<T>::type num_type;
1579 return shl_impl(v0, v1, num_type);
1580 }
1581
1582 template <typename T>
1583 inline T and_opr(const T v0, const T v1)
1584 {
1585 const typename details::number_type<T>::type num_type;
1586 return and_impl(v0, v1, num_type);
1587 }
1588
1589 template <typename T>
1590 inline T nand_opr(const T v0, const T v1)
1591 {
1592 const typename details::number_type<T>::type num_type;
1593 return nand_impl(v0, v1, num_type);
1594 }
1595
1596 template <typename T>
1597 inline T or_opr(const T v0, const T v1)
1598 {
1599 const typename details::number_type<T>::type num_type;
1600 return or_impl(v0, v1, num_type);
1601 }
1602
1603 template <typename T>
1604 inline T nor_opr(const T v0, const T v1)
1605 {
1606 const typename details::number_type<T>::type num_type;
1607 return nor_impl(v0, v1, num_type);
1608 }
1609
1610 template <typename T>
1611 inline T xor_opr(const T v0, const T v1)
1612 {
1613 const typename details::number_type<T>::type num_type;
1614 return xor_impl(v0, v1, num_type);
1615 }
1616
1617 template <typename T>
1618 inline T xnor_opr(const T v0, const T v1)
1619 {
1620 const typename details::number_type<T>::type num_type;
1621 return xnor_impl(v0, v1, num_type);
1622 }
1623
1624 template <typename T>
1625 inline bool is_integer(const T v)
1626 {
1627 const typename details::number_type<T>::type num_type;
1628 return is_integer_impl(v, num_type);
1629 }
1630
1631 template <typename T, unsigned int N>
1633 {
1634 static inline T result(T v)
1635 {
1636 unsigned int k = N;
1637 T l = T(1);
1638
1639 while (k)
1640 {
1641 if (1 == (k % 2))
1642 {
1643 l *= v;
1644 --k;
1645 }
1646
1647 v *= v;
1648 k /= 2;
1649 }
1650
1651 return l;
1652 }
1653 };
1654
1655 template <typename T> struct fast_exp<T,10> { static inline T result(const T v) { T v_5 = fast_exp<T,5>::result(v); return v_5 * v_5; } };
1656 template <typename T> struct fast_exp<T, 9> { static inline T result(const T v) { return fast_exp<T,8>::result(v) * v; } };
1657 template <typename T> struct fast_exp<T, 8> { static inline T result(const T v) { T v_4 = fast_exp<T,4>::result(v); return v_4 * v_4; } };
1658 template <typename T> struct fast_exp<T, 7> { static inline T result(const T v) { return fast_exp<T,6>::result(v) * v; } };
1659 template <typename T> struct fast_exp<T, 6> { static inline T result(const T v) { T v_3 = fast_exp<T,3>::result(v); return v_3 * v_3; } };
1660 template <typename T> struct fast_exp<T, 5> { static inline T result(const T v) { return fast_exp<T,4>::result(v) * v; } };
1661 template <typename T> struct fast_exp<T, 4> { static inline T result(const T v) { T v_2 = v * v; return v_2 * v_2; } };
1662 template <typename T> struct fast_exp<T, 3> { static inline T result(const T v) { return v * v * v; } };
1663 template <typename T> struct fast_exp<T, 2> { static inline T result(const T v) { return v * v; } };
1664 template <typename T> struct fast_exp<T, 1> { static inline T result(const T v) { return v; } };
1665 template <typename T> struct fast_exp<T, 0> { static inline T result(const T ) { return T(1); } };
1666
1667 #define exprtk_define_unary_function(FunctionName) \
1668 template <typename T> \
1669 inline T FunctionName (const T v) \
1670 { \
1671 const typename details::number_type<T>::type num_type; \
1672 return FunctionName##_impl(v,num_type); \
1673 } \
1674
1715 #undef exprtk_define_unary_function
1716 }
1717
1718 template <typename T>
1719 inline T compute_pow10(T d, const int exponent)
1720 {
1721 static const double fract10[] =
1722 {
1723 0.0,
1724 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,
1725 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,
1726 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,
1727 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,
1728 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,
1729 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,
1730 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,
1731 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,
1732 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,
1733 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,
1734 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,
1735 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,
1736 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,
1737 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,
1738 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,
1739 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,
1740 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,
1741 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,
1742 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,
1743 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,
1744 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,
1745 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,
1746 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,
1747 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,
1748 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,
1749 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,
1750 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,
1751 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,
1752 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,
1753 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,
1754 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
1755 };
1756
1757 static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
1758
1759 const int e = std::abs(exponent);
1760
1761 if (exponent >= std::numeric_limits<T>::min_exponent10)
1762 {
1763 if (e < fract10_size)
1764 {
1765 if (exponent > 0)
1766 return T(d * fract10[e]);
1767 else
1768 return T(d / fract10[e]);
1769 }
1770 else
1771 return T(d * std::pow(10.0, 10.0 * exponent));
1772 }
1773 else
1774 {
1775 d /= T(fract10[ -std::numeric_limits<T>::min_exponent10]);
1776 return T(d / fract10[-exponent + std::numeric_limits<T>::min_exponent10]);
1777 }
1778 }
1779
1780 template <typename Iterator, typename T>
1781 inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result)
1782 {
1783 if (itr == end)
1784 return false;
1785
1786 const bool negative = ('-' == (*itr));
1787
1788 if (negative || ('+' == (*itr)))
1789 {
1790 if (end == ++itr)
1791 return false;
1792 }
1793
1794 static const uchar_t zero = static_cast<uchar_t>('0');
1795
1796 while ((end != itr) && (zero == (*itr))) ++itr;
1797
1798 bool return_result = true;
1799 unsigned int digit = 0;
1800 const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
1801
1802 if (length <= 4)
1803 {
1804 switch (length)
1805 {
1806 #ifdef exprtk_use_lut
1807
1808 #define exprtk_process_digit \
1809 if ((digit = details::digit_table[(int)*itr++]) < 10) \
1810 result = result * 10 + (digit); \
1811 else \
1812 { \
1813 return_result = false; \
1814 break; \
1815 } \
1816 exprtk_fallthrough \
1817
1818 #else
1819
1820 #define exprtk_process_digit \
1821 if ((digit = (*itr++ - zero)) < 10) \
1822 result = result * T(10) + digit; \
1823 else \
1824 { \
1825 return_result = false; \
1826 break; \
1827 } \
1828 exprtk_fallthrough \
1829
1830 #endif
1831
1832 case 4 : exprtk_process_digit
1833 case 3 : exprtk_process_digit
1834 case 2 : exprtk_process_digit
1835 case 1 : if ((digit = (*itr - zero))>= 10)
1836 {
1837 digit = 0;
1838 return_result = false;
1839 }
1840
1841 #undef exprtk_process_digit
1842 }
1843 }
1844 else
1845 return_result = false;
1846
1847 if (length && return_result)
1848 {
1849 result = result * 10 + static_cast<T>(digit);
1850 ++itr;
1851 }
1852
1853 result = negative ? -result : result;
1854 return return_result;
1855 }
1856
1857 template <typename Iterator, typename T>
1858 static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
1859 {
1860 typedef typename std::iterator_traits<Iterator>::value_type type;
1861
1862 static const std::size_t nan_length = 3;
1863
1864 if (std::distance(itr,end) != static_cast<int>(nan_length))
1865 return false;
1866
1867 if (static_cast<type>('n') == (*itr))
1868 {
1869 if (
1870 (static_cast<type>('a') != *(itr + 1)) ||
1871 (static_cast<type>('n') != *(itr + 2))
1872 )
1873 {
1874 return false;
1875 }
1876 }
1877 else if (
1878 (static_cast<type>('A') != *(itr + 1)) ||
1879 (static_cast<type>('N') != *(itr + 2))
1880 )
1881 {
1882 return false;
1883 }
1884
1885 t = std::numeric_limits<T>::quiet_NaN();
1886
1887 return true;
1888 }
1889
1890 template <typename Iterator, typename T>
1891 static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, const bool negative)
1892 {
1893 static const char_t inf_uc[] = "INFINITY";
1894 static const char_t inf_lc[] = "infinity";
1895 static const std::size_t inf_length = 8;
1896
1897 const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
1898
1899 if ((3 != length) && (inf_length != length))
1900 return false;
1901
1902 char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
1903
1904 while (end != itr)
1905 {
1906 if (*inf_itr == static_cast<char_t>(*itr))
1907 {
1908 ++itr;
1909 ++inf_itr;
1910 continue;
1911 }
1912 else
1913 return false;
1914 }
1915
1916 if (negative)
1917 t = -std::numeric_limits<T>::infinity();
1918 else
1919 t = std::numeric_limits<T>::infinity();
1920
1921 return true;
1922 }
1923
1924 template <typename T>
1926 {
1927 using namespace details::numeric;
1928 return (numeric_info<T>::min_exp <= exponent) && (exponent <= numeric_info<T>::max_exp);
1929 }
1930
1931 template <typename Iterator, typename T>
1933 {
1934 if (end == itr_external) return false;
1935
1937
1938 T d = T(0);
1939
1940 const bool negative = ('-' == (*itr));
1941
1942 if (negative || '+' == (*itr))
1943 {
1944 if (end == ++itr)
1945 return false;
1946 }
1947
1948 bool instate = false;
1949
1950 static const char_t zero = static_cast<uchar_t>('0');
1951
1952 #define parse_digit_1(d) \
1953 if ((digit = (*itr - zero)) < 10) \
1954 { d = d * T(10) + digit; } \
1955 else \
1956 { break; } \
1957 if (end == ++itr) break; \
1958
1959 #define parse_digit_2(d) \
1960 if ((digit = (*itr - zero)) < 10) \
1961 { d = d * T(10) + digit; } \
1962 else \
1963 { break; } \
1964 ++itr; \
1965
1966 if ('.' != (*itr))
1967 {
1968 const Iterator curr = itr;
1969
1970 while ((end != itr) && (zero == (*itr))) ++itr;
1971
1972 while (end != itr)
1973 {
1974 unsigned int digit;
1978 }
1979
1980 if (curr != itr) instate = true;
1981 }
1982
1983 int exponent = 0;
1984
1985 if (end != itr)
1986 {
1987 if ('.' == (*itr))
1988 {
1989 const Iterator curr = ++itr;
1990 T tmp_d = T(0);
1991
1992 while (end != itr)
1993 {
1994 unsigned int digit;
1998 }
1999
2000 if (curr != itr)
2001 {
2002 instate = true;
2003
2004 const int frac_exponent = static_cast<int>(-std::distance(curr, itr));
2005
2007 return false;
2008
2010 }
2011
2012 #undef parse_digit_1
2013 #undef parse_digit_2
2014 }
2015
2016 if (end != itr)
2017 {
2018 typename std::iterator_traits<Iterator>::value_type c = (*itr);
2019
2020 if (('e' == c) || ('E' == c))
2021 {
2022 int exp = 0;
2023
2025 {
2026 if (end == itr)
2027 return false;
2028 else
2029 c = (*itr);
2030 }
2031
2032 exponent += exp;
2033 }
2034
2035 if (end != itr)
2036 {
2037 if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
2038 ++itr;
2039 else if ('#' == c)
2040 {
2041 if (end == ++itr)
2042 return false;
2043 else if (('I' <= (*itr)) && ((*itr) <= 'n'))
2044 {
2045 if (('i' == (*itr)) || ('I' == (*itr)))
2046 {
2047 return parse_inf(itr, end, t, negative);
2048 }
2049 else if (('n' == (*itr)) || ('N' == (*itr)))
2050 {
2051 return parse_nan(itr, end, t);
2052 }
2053 else
2054 return false;
2055 }
2056 else
2057 return false;
2058 }
2059 else if (('I' <= (*itr)) && ((*itr) <= 'n'))
2060 {
2061 if (('i' == (*itr)) || ('I' == (*itr)))
2062 {
2063 return parse_inf(itr, end, t, negative);
2064 }
2065 else if (('n' == (*itr)) || ('N' == (*itr)))
2066 {
2067 return parse_nan(itr, end, t);
2068 }
2069 else
2070 return false;
2071 }
2072 else
2073 return false;
2074 }
2075 }
2076 }
2077
2078 if ((end != itr) || (!instate))
2079 return false;
2081 return false;
2082 else if (exponent)
2084
2085 t = static_cast<T>((negative) ? -d : d);
2086 return true;
2087 }
2088
2089 template <typename T>
2090 inline bool string_to_real(const std::string& s, T& t)
2091 {
2092 const typename numeric::details::number_type<T>::type num_type;
2093
2094 char_cptr begin = s.data();
2095 char_cptr end = s.data() + s.size();
2096
2097 return string_to_real(begin, end, t, num_type);
2098 }
2099
2100 template <typename T>
2102 {
2103 /*
2104 Note: The following definitions for Type, may require tweaking
2105 based on the compiler and target architecture. The benchmark
2106 should provide enough information to make the right choice.
2107 */
2108 //typedef T Type;
2109 //typedef const T Type;
2110 typedef const T& Type;
2111 typedef T& RefType;
2112 typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3);
2113 typedef T (*tfunc_t)(Type t0, Type t1, Type t2);
2114 typedef T (*bfunc_t)(Type t0, Type t1);
2115 typedef T (*ufunc_t)(Type t0);
2116 };
2117
2118 } // namespace details
2119
2121 {
2130
2137
2139
2144
2146
2153
2154 virtual bool check()
2155 {
2156 return true;
2157 }
2158
2160 {
2161 throw std::runtime_error("ExprTk Loop runtime violation.");
2162 }
2163
2165 {}
2166 };
2167
2169
2171 {
2173 {
2175 void* end_ptr;
2177 std::size_t type_size;
2178 };
2179
2182
2184 {
2185 throw std::runtime_error("ExprTk runtime vector access violation.");
2186 #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
2187 return false;
2188 #endif
2189 }
2190 };
2191
2193
2195 {
2197 {
2198 std::string condition;
2199 std::string message;
2200 std::string id;
2201 std::size_t offet;
2202 };
2203
2205 {}
2206
2207 virtual void handle_assert(const assert_context& /*context*/)
2208 {
2209 }
2210 };
2211
2213
2215 {
2217 {
2218 std::string error_message;
2219 };
2220
2221 virtual bool continue_compilation(compilation_context& /*context*/) = 0;
2222
2224 {}
2225 };
2226
2228
2229 namespace lexer
2230 {
2231 struct token
2232 {
2234 {
2237 e_eof = 6, e_number = 7, e_symbol = 8,
2238 e_string = 9, e_assign = 10, e_addass = 11,
2239 e_subass = 12, e_mulass = 13, e_divass = 14,
2240 e_modass = 15, e_shr = 16, e_shl = 17,
2241 e_lte = 18, e_ne = 19, e_gte = 20,
2242 e_swap = 21, e_lt = '<', e_gt = '>',
2243 e_eq = '=', e_rbracket = ')', e_lbracket = '(',
2245 e_lcrlbracket = '{', e_comma = ',', e_add = '+',
2246 e_sub = '-', e_div = '/', e_mul = '*',
2247 e_mod = '%', e_pow = '^', e_colon = ':',
2248 e_ternary = '?'
2250
2252 : type(e_none)
2253 , value("")
2254 , position(std::numeric_limits<std::size_t>::max())
2255 {}
2256
2257 void clear()
2258 {
2259 type = e_none;
2260 value = "";
2261 position = std::numeric_limits<std::size_t>::max();
2262 }
2263
2264 template <typename Iterator>
2266 const Iterator begin, const Iterator end,
2267 const Iterator base_begin = Iterator(0))
2268 {
2269 type = tt;
2270 value.assign(begin,end);
2271 if (base_begin)
2272 position = static_cast<std::size_t>(std::distance(base_begin,begin));
2273 return (*this);
2274 }
2275
2276 template <typename Iterator>
2277 inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2278 {
2279 type = e_symbol;
2280 value.assign(begin,end);
2281 if (base_begin)
2282 position = static_cast<std::size_t>(std::distance(base_begin,begin));
2283 return (*this);
2284 }
2285
2286 template <typename Iterator>
2287 inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2288 {
2289 type = e_number;
2290 value.assign(begin,end);
2291 if (base_begin)
2292 position = static_cast<std::size_t>(std::distance(base_begin,begin));
2293 return (*this);
2294 }
2295
2296 template <typename Iterator>
2297 inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2298 {
2299 type = e_string;
2300 value.assign(begin,end);
2301 if (base_begin)
2302 position = static_cast<std::size_t>(std::distance(base_begin,begin));
2303 return (*this);
2304 }
2305
2306 inline token& set_string(const std::string& s, const std::size_t p)
2307 {
2308 type = e_string;
2309 value = s;
2310 position = p;
2311 return (*this);
2312 }
2313
2314 template <typename Iterator>
2315 inline token& set_error(const token_type et,
2316 const Iterator begin, const Iterator end,
2317 const Iterator base_begin = Iterator(0))
2318 {
2319 if (
2320 (e_error == et) ||
2321 (e_err_symbol == et) ||
2322 (e_err_number == et) ||
2323 (e_err_string == et) ||
2324 (e_err_sfunc == et)
2325 )
2326 {
2327 type = et;
2328 }
2329 else
2330 type = e_error;
2331
2332 value.assign(begin,end);
2333
2334 if (base_begin)
2335 position = static_cast<std::size_t>(std::distance(base_begin,begin));
2336
2337 return (*this);
2338 }
2339
2340 static inline std::string to_str(token_type t)
2341 {
2342 switch (t)
2343 {
2344 case e_none : return "NONE";
2345 case e_error : return "ERROR";
2346 case e_err_symbol : return "ERROR_SYMBOL";
2347 case e_err_number : return "ERROR_NUMBER";
2348 case e_err_string : return "ERROR_STRING";
2349 case e_eof : return "EOF";
2350 case e_number : return "NUMBER";
2351 case e_symbol : return "SYMBOL";
2352 case e_string : return "STRING";
2353 case e_assign : return ":=";
2354 case e_addass : return "+=";
2355 case e_subass : return "-=";
2356 case e_mulass : return "*=";
2357 case e_divass : return "/=";
2358 case e_modass : return "%=";
2359 case e_shr : return ">>";
2360 case e_shl : return "<<";
2361 case e_lte : return "<=";
2362 case e_ne : return "!=";
2363 case e_gte : return ">=";
2364 case e_lt : return "<";
2365 case e_gt : return ">";
2366 case e_eq : return "=";
2367 case e_rbracket : return ")";
2368 case e_lbracket : return "(";
2369 case e_rsqrbracket : return "]";
2370 case e_lsqrbracket : return "[";
2371 case e_rcrlbracket : return "}";
2372 case e_lcrlbracket : return "{";
2373 case e_comma : return ",";
2374 case e_add : return "+";
2375 case e_sub : return "-";
2376 case e_div : return "/";
2377 case e_mul : return "*";
2378 case e_mod : return "%";
2379 case e_pow : return "^";
2380 case e_colon : return ":";
2381 case e_ternary : return "?";
2382 case e_swap : return "<=>";
2383 default : return "UNKNOWN";
2384 }
2385 }
2386
2387 inline bool is_error() const
2388 {
2389 return (
2390 (e_error == type) ||
2391 (e_err_symbol == type) ||
2392 (e_err_number == type) ||
2393 (e_err_string == type) ||
2394 (e_err_sfunc == type)
2395 );
2396 }
2397
2399 std::string value;
2400 std::size_t position;
2401 };
2402
2404 {
2405 public:
2406
2408 typedef std::vector<token_t> token_list_t;
2409 typedef token_list_t::iterator token_list_itr_t;
2411
2413 : base_itr_(0)
2414 , s_itr_ (0)
2415 , s_end_ (0)
2416 {
2417 clear();
2418 }
2419
2420 inline void clear()
2421 {
2422 base_itr_ = 0;
2423 s_itr_ = 0;
2424 s_end_ = 0;
2425 token_list_.clear();
2426 token_itr_ = token_list_.end();
2428 }
2429
2430 inline bool process(const std::string& str)
2431 {
2432 base_itr_ = str.data();
2433 s_itr_ = str.data();
2434 s_end_ = str.data() + str.size();
2435
2438
2439 while (!is_end(s_itr_))
2440 {
2441 scan_token();
2442
2443 if (!token_list_.empty() && token_list_.back().is_error())
2444 return false;
2445 }
2446
2447 return true;
2448 }
2449
2450 inline bool empty() const
2451 {
2452 return token_list_.empty();
2453 }
2454
2455 inline std::size_t size() const
2456 {
2457 return token_list_.size();
2458 }
2459
2460 inline void begin()
2461 {
2462 token_itr_ = token_list_.begin();
2463 store_token_itr_ = token_list_.begin();
2464 }
2465
2466 inline void store()
2467 {
2469 }
2470
2471 inline void restore()
2472 {
2474 }
2475
2477 {
2478 if (token_list_.end() != token_itr_)
2479 {
2480 return *token_itr_++;
2481 }
2482 else
2483 return eof_token_;
2484 }
2485
2487 {
2488 if (token_list_.end() != token_itr_)
2489 {
2490 return *token_itr_;
2491 }
2492 else
2493 return eof_token_;
2494 }
2495
2496 inline token_t& operator[](const std::size_t& index)
2497 {
2498 if (index < token_list_.size())
2499 {
2500 return token_list_[index];
2501 }
2502 else
2503 return eof_token_;
2504 }
2505
2506 inline token_t operator[](const std::size_t& index) const
2507 {
2508 if (index < token_list_.size())
2509 {
2510 return token_list_[index];
2511 }
2512 else
2513 return eof_token_;
2514 }
2515
2516 inline bool finished() const
2517 {
2518 return (token_list_.end() == token_itr_);
2519 }
2520
2522 {
2523 if (
2524 !token_list_.empty() &&
2525 (token_list_.end() != token_itr_)
2526 )
2527 {
2528 token_t t = *token_itr_;
2529
2530 t.type = tk_type;
2531 token_itr_ = token_list_.insert(token_itr_,t);
2532 }
2533 }
2534
2535 inline std::string substr(const std::size_t& begin, const std::size_t& end) const
2536 {
2537 const details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
2538 const details::char_cptr end_itr = ((base_itr_ + end ) < s_end_) ? (base_itr_ + end ) : s_end_;
2539
2540 return std::string(begin_itr,end_itr);
2541 }
2542
2543 inline std::string remaining() const
2544 {
2545 if (finished())
2546 return "";
2547 else if (token_list_.begin() != token_itr_)
2548 return std::string(base_itr_ + (token_itr_ - 1)->position, s_end_);
2549 else
2550 return std::string(base_itr_ + token_itr_->position, s_end_);
2551 }
2552
2553 private:
2554
2555 inline bool is_end(details::char_cptr itr) const
2556 {
2557 return (s_end_ == itr);
2558 }
2559
2560 #ifndef exprtk_disable_comments
2562 {
2563 const char_t c0 = *(itr + 0);
2564 const char_t c1 = *(itr + 1);
2565
2566 if ('#' == c0)
2567 return true;
2568 else if (!is_end(itr + 1))
2569 {
2570 if (('/' == c0) && ('/' == c1)) return true;
2571 if (('/' == c0) && ('*' == c1)) return true;
2572 }
2573 return false;
2574 }
2575 #else
2576 inline bool is_comment_start(details::char_cptr) const
2577 {
2578 return false;
2579 }
2580 #endif
2581
2582 inline void skip_whitespace()
2583 {
2585 {
2586 ++s_itr_;
2587 }
2588 }
2589
2590 inline void skip_comments()
2591 {
2592 #ifndef exprtk_disable_comments
2593 // The following comment styles are supported:
2594 // 1. // .... \n
2595 // 2. # .... \n
2596 // 3. /* .... */
2597 struct test
2598 {
2599 static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr)
2600 {
2601 mode = 0;
2602 if ('#' == c0) { mode = 1; incr = 1; }
2603 else if ('/' == c0)
2604 {
2605 if ('/' == c1) { mode = 1; incr = 2; }
2606 else if ('*' == c1) { mode = 2; incr = 2; }
2607 }
2608 return (0 != mode);
2609 }
2610
2611 static inline bool comment_end(const char_t c0, const char_t c1, int& mode)
2612 {
2613 if (
2614 ((1 == mode) && ('\n' == c0)) ||
2615 ((2 == mode) && ( '*' == c0) && ('/' == c1))
2616 )
2617 {
2618 mode = 0;
2619 return true;
2620 }
2621 else
2622 return false;
2623 }
2624 };
2625
2626 int mode = 0;
2627 int increment = 0;
2628
2629 if (is_end(s_itr_))
2630 return;
2631 else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment))
2632 return;
2633
2634 details::char_cptr cmt_start = s_itr_;
2635
2636 s_itr_ += increment;
2637
2638 while (!is_end(s_itr_))
2639 {
2640 if ((1 == mode) && test::comment_end(*s_itr_, 0, mode))
2641 {
2642 ++s_itr_;
2643 return;
2644 }
2645
2646 if ((2 == mode))
2647 {
2648 if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode))
2649 {
2650 s_itr_ += 2;
2651 return;
2652 }
2653 }
2654
2655 ++s_itr_;
2656 }
2657
2658 if (2 == mode)
2659 {
2660 token_t t;
2661 t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_);
2662 token_list_.push_back(t);
2663 }
2664 #endif
2665 }
2666
2667 inline bool next_is_digit(const details::char_cptr itr) const
2668 {
2669 return ((itr + 1) != s_end_) &&
2670 details::is_digit(*(itr + 1));
2671 }
2672
2673 inline void scan_token()
2674 {
2675 const char_t c = *s_itr_;
2676
2678 {
2680 return;
2681 }
2682 else if (is_comment_start(s_itr_))
2683 {
2684 skip_comments();
2685 return;
2686 }
2687 else if (details::is_operator_char(c))
2688 {
2689 scan_operator();
2690 return;
2691 }
2692 else if (details::is_letter(c))
2693 {
2694 scan_symbol();
2695 return;
2696 }
2697 else if (('.' == c) && !next_is_digit(s_itr_))
2698 {
2699 scan_operator();
2700 return;
2701 }
2702 else if (details::is_digit(c) || ('.' == c))
2703 {
2704 scan_number();
2705 return;
2706 }
2707 else if ('$' == c)
2708 {
2710 return;
2711 }
2712 #ifndef exprtk_disable_string_capabilities
2713 else if ('\'' == c)
2714 {
2715 scan_string();
2716 return;
2717 }
2718 #endif
2719 else if ('~' == c)
2720 {
2721 token_t t;
2723 token_list_.push_back(t);
2724 ++s_itr_;
2725 return;
2726 }
2727 else
2728 {
2729 token_t t;
2731 token_list_.push_back(t);
2732 ++s_itr_;
2733 }
2734 }
2735
2736 inline void scan_operator()
2737 {
2738 token_t t;
2739
2740 const char_t c0 = s_itr_[0];
2741
2742 if (!is_end(s_itr_ + 1))
2743 {
2744 const char_t c1 = s_itr_[1];
2745
2746 if (!is_end(s_itr_ + 2))
2747 {
2748 const char_t c2 = s_itr_[2];
2749
2750 if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
2751 {
2753 token_list_.push_back(t);
2754 s_itr_ += 3;
2755 return;
2756 }
2757 }
2758
2760
2761 if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
2762 else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
2763 else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
2764 else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
2765 else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq;
2766 else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign;
2767 else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl;
2768 else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr;
2769 else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass;
2770 else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass;
2771 else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass;
2772 else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass;
2773 else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass;
2774
2775 if (token_t::e_none != ttype)
2776 {
2777 t.set_operator(ttype, s_itr_, s_itr_ + 2, base_itr_);
2778 token_list_.push_back(t);
2779 s_itr_ += 2;
2780 return;
2781 }
2782 }
2783
2784 if ('<' == c0)
2786 else if ('>' == c0)
2788 else if (';' == c0)
2790 else if ('&' == c0)
2792 else if ('|' == c0)
2794 else
2796
2797 token_list_.push_back(t);
2798 ++s_itr_;
2799 }
2800
2801 inline void scan_symbol()
2802 {
2803 details::char_cptr initial_itr = s_itr_;
2804
2805 while (!is_end(s_itr_))
2806 {
2807 if (!details::is_letter_or_digit(*s_itr_) && ('_' != (*s_itr_)))
2808 {
2809 if ('.' != (*s_itr_))
2810 break;
2811 /*
2812 Permit symbols that contain a 'dot'
2813 Allowed : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123
2814 Disallowed: .abc, abc.<white-space>, abc.<eof>, abc.<operator +,-,*,/...>
2815 */
2816 if (
2817 (s_itr_ != initial_itr) &&
2818 !is_end(s_itr_ + 1) &&
2820 ('_' != (*(s_itr_ + 1)))
2821 )
2822 break;
2823 }
2824
2825 ++s_itr_;
2826 }
2827
2828 token_t t;
2829 t.set_symbol(initial_itr, s_itr_, base_itr_);
2830 token_list_.push_back(t);
2831 }
2832
2833 inline void scan_number()
2834 {
2835 /*
2836 Attempt to match a valid numeric value in one of the following formats:
2837 (01) 123456
2838 (02) 123456.
2839 (03) 123.456
2840 (04) 123.456e3
2841 (05) 123.456E3
2842 (06) 123.456e+3
2843 (07) 123.456E+3
2844 (08) 123.456e-3
2845 (09) 123.456E-3
2846 (00) .1234
2847 (11) .1234e3
2848 (12) .1234E+3
2849 (13) .1234e+3
2850 (14) .1234E-3
2851 (15) .1234e-3
2852 */
2853
2854 details::char_cptr initial_itr = s_itr_;
2855 bool dot_found = false;
2856 bool e_found = false;
2857 bool post_e_sign_found = false;
2858 bool post_e_digit_found = false;
2859 token_t t;
2860
2861 while (!is_end(s_itr_))
2862 {
2863 if ('.' == (*s_itr_))
2864 {
2865 if (dot_found)
2866 {
2868 token_list_.push_back(t);
2869
2870 return;
2871 }
2872
2873 dot_found = true;
2874 ++s_itr_;
2875
2876 continue;
2877 }
2878 else if ('e' == std::tolower(*s_itr_))
2879 {
2880 const char_t& c = *(s_itr_ + 1);
2881
2882 if (is_end(s_itr_ + 1))
2883 {
2885 token_list_.push_back(t);
2886
2887 return;
2888 }
2889 else if (
2890 ('+' != c) &&
2891 ('-' != c) &&
2893 )
2894 {
2896 token_list_.push_back(t);
2897
2898 return;
2899 }
2900
2901 e_found = true;
2902 ++s_itr_;
2903
2904 continue;
2905 }
2906 else if (e_found && details::is_sign(*s_itr_) && !post_e_digit_found)
2907 {
2908 if (post_e_sign_found)
2909 {
2911 token_list_.push_back(t);
2912
2913 return;
2914 }
2915
2916 post_e_sign_found = true;
2917 ++s_itr_;
2918
2919 continue;
2920 }
2921 else if (e_found && details::is_digit(*s_itr_))
2922 {
2923 post_e_digit_found = true;
2924 ++s_itr_;
2925
2926 continue;
2927 }
2928 else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_))
2929 break;
2930 else
2931 ++s_itr_;
2932 }
2933
2934 t.set_numeric(initial_itr, s_itr_, base_itr_);
2935 token_list_.push_back(t);
2936
2937 return;
2938 }
2939
2941 {
2942 details::char_cptr initial_itr = s_itr_;
2943 token_t t;
2944
2945 // $fdd(x,x,x) = at least 11 chars
2946 if (std::distance(s_itr_,s_end_) < 11)
2947 {
2948 t.set_error(
2950 initial_itr, std::min(initial_itr + 11, s_end_),
2951 base_itr_);
2952 token_list_.push_back(t);
2953
2954 return;
2955 }
2956
2957 if (
2958 !(('$' == *s_itr_) &&
2959 (details::imatch ('f',*(s_itr_ + 1))) &&
2960 (details::is_digit(*(s_itr_ + 2))) &&
2961 (details::is_digit(*(s_itr_ + 3))))
2962 )
2963 {
2964 t.set_error(
2966 initial_itr, std::min(initial_itr + 4, s_end_),
2967 base_itr_);
2968 token_list_.push_back(t);
2969
2970 return;
2971 }
2972
2973 s_itr_ += 4; // $fdd = 4chars
2974
2975 t.set_symbol(initial_itr, s_itr_, base_itr_);
2976 token_list_.push_back(t);
2977
2978 return;
2979 }
2980
2981 #ifndef exprtk_disable_string_capabilities
2982 inline void scan_string()
2983 {
2984 details::char_cptr initial_itr = s_itr_ + 1;
2985 token_t t;
2986
2987 if (std::distance(s_itr_,s_end_) < 2)
2988 {
2990 token_list_.push_back(t);
2991
2992 return;
2993 }
2994
2995 ++s_itr_;
2996
2997 bool escaped_found = false;
2998 bool escaped = false;
2999
3000 while (!is_end(s_itr_))
3001 {
3003 {
3005 token_list_.push_back(t);
3006
3007 return;
3008 }
3009 else if (!escaped && ('\\' == *s_itr_))
3010 {
3011 escaped_found = true;
3012 escaped = true;
3013 ++s_itr_;
3014
3015 continue;
3016 }
3017 else if (!escaped)
3018 {
3019 if ('\'' == *s_itr_)
3020 break;
3021 }
3022 else if (escaped)
3023 {
3024 if (
3025 !is_end(s_itr_) && ('0' == *(s_itr_)) &&
3026 ((s_itr_ + 4) <= s_end_)
3027 )
3028 {
3029 const bool x_separator = ('X' == std::toupper(*(s_itr_ + 1)));
3030
3031 const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) &&
3033
3034 if (!(x_separator && both_digits))
3035 {
3037 token_list_.push_back(t);
3038
3039 return;
3040 }
3041 else
3042 s_itr_ += 3;
3043 }
3044
3045 escaped = false;
3046 }
3047
3048 ++s_itr_;
3049 }
3050
3051 if (is_end(s_itr_))
3052 {
3054 token_list_.push_back(t);
3055
3056 return;
3057 }
3058
3059 if (!escaped_found)
3060 t.set_string(initial_itr, s_itr_, base_itr_);
3061 else
3062 {
3063 std::string parsed_string(initial_itr,s_itr_);
3064
3065 if (!details::cleanup_escapes(parsed_string))
3066 {
3068 token_list_.push_back(t);
3069
3070 return;
3071 }
3072
3073 t.set_string(
3074 parsed_string,
3075 static_cast<std::size_t>(std::distance(base_itr_,initial_itr)));
3076 }
3077
3078 token_list_.push_back(t);
3079 ++s_itr_;
3080
3081 return;
3082 }
3083 #endif
3084
3085 private:
3086
3094
3095 friend class token_scanner;
3096 friend class token_modifier;
3097 friend class token_inserter;
3098 friend class token_joiner;
3099 }; // class generator
3100
3102 {
3103 public:
3104
3105 virtual void init() { }
3106 virtual void reset() { }
3107 virtual bool result() { return true; }
3108 virtual std::size_t process(generator&) { return 0; }
3109 virtual ~helper_interface() { }
3110 };
3111
3113 {
3114 public:
3115
3117 {}
3118
3119 explicit token_scanner(const std::size_t& stride)
3120 : stride_(stride)
3121 {
3122 if (stride > 4)
3123 {
3124 throw std::invalid_argument("token_scanner() - Invalid stride value");
3125 }
3126 }
3127
3128 inline std::size_t process(generator& g) exprtk_override
3129 {
3130 if (g.token_list_.size() >= stride_)
3131 {
3132 for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
3133 {
3134 token t;
3135
3136 switch (stride_)
3137 {
3138 case 1 :
3139 {
3140 const token& t0 = g.token_list_[i];
3141
3142 if (!operator()(t0))
3143 {
3144 return i;
3145 }
3146 }
3147 break;
3148
3149 case 2 :
3150 {
3151 const token& t0 = g.token_list_[i ];
3152 const token& t1 = g.token_list_[i + 1];
3153
3154 if (!operator()(t0, t1))
3155 {
3156 return i;
3157 }
3158 }
3159 break;
3160
3161 case 3 :
3162 {
3163 const token& t0 = g.token_list_[i ];
3164 const token& t1 = g.token_list_[i + 1];
3165 const token& t2 = g.token_list_[i + 2];
3166
3167 if (!operator()(t0, t1, t2))
3168 {
3169 return i;
3170 }
3171 }
3172 break;
3173
3174 case 4 :
3175 {
3176 const token& t0 = g.token_list_[i ];
3177 const token& t1 = g.token_list_[i + 1];
3178 const token& t2 = g.token_list_[i + 2];
3179 const token& t3 = g.token_list_[i + 3];
3180
3181 if (!operator()(t0, t1, t2, t3))
3182 {
3183 return i;
3184 }
3185 }
3186 break;
3187 }
3188 }
3189 }
3190
3191 return (g.token_list_.size() - stride_ + 1);
3192 }
3193
3194 virtual bool operator() (const token&)
3195 {
3196 return false;
3197 }
3198
3199 virtual bool operator() (const token&, const token&)
3200 {
3201 return false;
3202 }
3203
3204 virtual bool operator() (const token&, const token&, const token&)
3205 {
3206 return false;
3207 }
3208
3209 virtual bool operator() (const token&, const token&, const token&, const token&)
3210 {
3211 return false;
3212 }
3213
3214 private:
3215
3216 const std::size_t stride_;
3217 }; // class token_scanner
3218
3220 {
3221 public:
3222
3223 inline std::size_t process(generator& g) exprtk_override
3224 {
3225 std::size_t changes = 0;
3226
3227 for (std::size_t i = 0; i < g.token_list_.size(); ++i)
3228 {
3229 if (modify(g.token_list_[i])) changes++;
3230 }
3231
3232 return changes;
3233 }
3234
3235 virtual bool modify(token& t) = 0;
3236 };
3237
3239 {
3240 public:
3241
3242 explicit token_inserter(const std::size_t& stride)
3243 : stride_(stride)
3244 {
3245 if (stride > 5)
3246 {
3247 throw std::invalid_argument("token_inserter() - Invalid stride value");
3248 }
3249 }
3250
3251 inline std::size_t process(generator& g) exprtk_override
3252 {
3253 if (g.token_list_.empty())
3254 return 0;
3255 else if (g.token_list_.size() < stride_)
3256 return 0;
3257
3258 std::size_t changes = 0;
3259
3260 typedef std::pair<std::size_t, token> insert_t;
3261 std::vector<insert_t> insert_list;
3262 insert_list.reserve(10000);
3263
3264 for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
3265 {
3266 int insert_index = -1;
3267 token t;
3268
3269 switch (stride_)
3270 {
3271 case 1 : insert_index = insert(g.token_list_[i],t);
3272 break;
3273
3274 case 2 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], t);
3275 break;
3276
3277 case 3 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], g.token_list_[i + 2], t);
3278 break;
3279
3280 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);
3281 break;
3282
3283 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);
3284 break;
3285 }
3286
3287 if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1)))
3288 {
3289 insert_list.push_back(insert_t(i, t));
3290 changes++;
3291 }
3292 }
3293
3294 if (!insert_list.empty())
3295 {
3296 generator::token_list_t token_list;
3297
3298 std::size_t insert_index = 0;
3299
3300 for (std::size_t i = 0; i < g.token_list_.size(); ++i)
3301 {
3302 token_list.push_back(g.token_list_[i]);
3303
3304 if (
3305 (insert_index < insert_list.size()) &&
3306 (insert_list[insert_index].first == i)
3307 )
3308 {
3309 token_list.push_back(insert_list[insert_index].second);
3310 insert_index++;
3311 }
3312 }
3313
3314 std::swap(g.token_list_,token_list);
3315 }
3316
3317 return changes;
3318 }
3319
3320 #define token_inserter_empty_body \
3321 { \
3322 return -1; \
3323 } \
3324
3325 inline virtual int insert(const token&, token&)
3327
3328 inline virtual int insert(const token&, const token&, token&)
3330
3331 inline virtual int insert(const token&, const token&, const token&, token&)
3333
3334 inline virtual int insert(const token&, const token&, const token&, const token&, token&)
3336
3337 inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&)
3339
3340 #undef token_inserter_empty_body
3341
3342 private:
3343
3344 const std::size_t stride_;
3345 };
3346
3348 {
3349 public:
3350
3351 explicit token_joiner(const std::size_t& stride)
3352 : stride_(stride)
3353 {}
3354
3355 inline std::size_t process(generator& g) exprtk_override
3356 {
3357 if (g.token_list_.empty())
3358 return 0;
3359
3360 switch (stride_)
3361 {
3362 case 2 : return process_stride_2(g);
3363 case 3 : return process_stride_3(g);
3364 default : return 0;
3365 }
3366 }
3367
3368 virtual bool join(const token&, const token&, token&) { return false; }
3369 virtual bool join(const token&, const token&, const token&, token&) { return false; }
3370
3371 private:
3372
3373 inline std::size_t process_stride_2(generator& g)
3374 {
3375 if (g.token_list_.size() < 2)
3376 return 0;
3377
3378 std::size_t changes = 0;
3379
3380 generator::token_list_t token_list;
3381 token_list.reserve(10000);
3382
3383 for (int i = 0; i < static_cast<int>(g.token_list_.size() - 1); ++i)
3384 {
3385 token t;
3386
3387 for ( ; ; )
3388 {
3389 if (!join(g[i], g[i + 1], t))
3390 {
3391 token_list.push_back(g[i]);
3392 break;
3393 }
3394
3395 token_list.push_back(t);
3396
3397 ++changes;
3398
3399 i += 2;
3400
3401 if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1))
3402 break;
3403 }
3404 }
3405
3406 token_list.push_back(g.token_list_.back());
3407
3408 assert(token_list.size() <= g.token_list_.size());
3409
3410 std::swap(token_list, g.token_list_);
3411
3412 return changes;
3413 }
3414
3415 inline std::size_t process_stride_3(generator& g)
3416 {
3417 if (g.token_list_.size() < 3)
3418 return 0;
3419
3420 std::size_t changes = 0;
3421
3422 generator::token_list_t token_list;
3423 token_list.reserve(10000);
3424
3425 for (int i = 0; i < static_cast<int>(g.token_list_.size() - 2); ++i)
3426 {
3427 token t;
3428
3429 for ( ; ; )
3430 {
3431 if (!join(g[i], g[i + 1], g[i + 2], t))
3432 {
3433 token_list.push_back(g[i]);
3434 break;
3435 }
3436
3437 token_list.push_back(t);
3438
3439 ++changes;
3440
3441 i += 3;
3442
3443 if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2))
3444 break;
3445 }
3446 }
3447
3448 token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 2));
3449 token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 1));
3450
3451 assert(token_list.size() <= g.token_list_.size());
3452
3453 std::swap(token_list, g.token_list_);
3454
3455 return changes;
3456 }
3457
3458 const std::size_t stride_;
3459 };
3460
3461 namespace helper
3462 {
3463
3464 inline void dump(const lexer::generator& generator)
3465 {
3466 for (std::size_t i = 0; i < generator.size(); ++i)
3467 {
3468 const lexer::token& t = generator[i];
3469 printf("Token[%02d] @ %03d %6s --> '%s'\n",
3470 static_cast<int>(i),
3471 static_cast<int>(t.position),
3472 t.to_str(t.type).c_str(),
3473 t.value.c_str());
3474 }
3475 }
3476
3478 {
3479 public:
3480
3482
3484 : lexer::token_inserter(2)
3485 {}
3486
3487 inline void ignore_symbol(const std::string& symbol)
3488 {
3489 ignore_set_.insert(symbol);
3490 }
3491
3492 inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) exprtk_override
3493 {
3494 bool match = false;
3495 new_token.type = lexer::token::e_mul;
3496 new_token.value = "*";
3497 new_token.position = t1.position;
3498
3499 if (t0.type == lexer::token::e_symbol)
3500 {
3501 if (ignore_set_.end() != ignore_set_.find(t0.value))
3502 {
3503 return -1;
3504 }
3505 else if (!t0.value.empty() && ('$' == t0.value[0]))
3506 {
3507 return -1;
3508 }
3509 }
3510
3511 if (t1.type == lexer::token::e_symbol)
3512 {
3513 if (ignore_set_.end() != ignore_set_.find(t1.value))
3514 {
3515 return -1;
3516 }
3517 }
3518 if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
3519 else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lbracket )) match = true;
3520 else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
3521 else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
3522 else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_number )) match = true;
3523 else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_number )) match = true;
3524 else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number )) match = true;
3525 else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number )) match = true;
3526 else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_symbol )) match = true;
3527 else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol )) match = true;
3528 else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol )) match = true;
3529 else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_symbol )) match = true;
3530
3531 return (match) ? 1 : -1;
3532 }
3533
3534 private:
3535
3536 std::set<std::string,details::ilesscompare> ignore_set_;
3537 };
3538
3540 {
3541 public:
3542
3543 explicit operator_joiner(const std::size_t& stride)
3544 : token_joiner(stride)
3545 {}
3546
3547 inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) exprtk_override
3548 {
3549 // ': =' --> ':='
3550 if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
3551 {
3552 t.type = lexer::token::e_assign;
3553 t.value = ":=";
3554 t.position = t0.position;
3555
3556 return true;
3557 }
3558 // '+ =' --> '+='
3559 else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq))
3560 {
3561 t.type = lexer::token::e_addass;
3562 t.value = "+=";
3563 t.position = t0.position;
3564
3565 return true;
3566 }
3567 // '- =' --> '-='
3568 else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq))
3569 {
3570 t.type = lexer::token::e_subass;
3571 t.value = "-=";
3572 t.position = t0.position;
3573
3574 return true;
3575 }
3576 // '* =' --> '*='
3577 else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq))
3578 {
3579 t.type = lexer::token::e_mulass;
3580 t.value = "*=";
3581 t.position = t0.position;
3582
3583 return true;
3584 }
3585 // '/ =' --> '/='
3586 else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq))
3587 {
3588 t.type = lexer::token::e_divass;
3589 t.value = "/=";
3590 t.position = t0.position;
3591
3592 return true;
3593 }
3594 // '% =' --> '%='
3595 else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq))
3596 {
3597 t.type = lexer::token::e_modass;
3598 t.value = "%=";
3599 t.position = t0.position;
3600
3601 return true;
3602 }
3603 // '> =' --> '>='
3604 else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq))
3605 {
3606 t.type = lexer::token::e_gte;
3607 t.value = ">=";
3608 t.position = t0.position;
3609
3610 return true;
3611 }
3612 // '< =' --> '<='
3613 else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq))
3614 {
3615 t.type = lexer::token::e_lte;
3616 t.value = "<=";
3617 t.position = t0.position;
3618
3619 return true;
3620 }
3621 // '= =' --> '=='
3622 else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq))
3623 {
3624 t.type = lexer::token::e_eq;
3625 t.value = "==";
3626 t.position = t0.position;
3627
3628 return true;
3629 }
3630 // '! =' --> '!='
3631 else if ((static_cast<details::char_t>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
3632 {
3633 t.type = lexer::token::e_ne;
3634 t.value = "!=";
3635 t.position = t0.position;
3636
3637 return true;
3638 }
3639 // '< >' --> '<>'
3640 else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt))
3641 {
3642 t.type = lexer::token::e_ne;
3643 t.value = "<>";
3644 t.position = t0.position;
3645
3646 return true;
3647 }
3648 // '<= >' --> '<=>'
3649 else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt))
3650 {
3651 t.type = lexer::token::e_swap;
3652 t.value = "<=>";
3653 t.position = t0.position;
3654
3655 return true;
3656 }
3657 // '+ -' --> '-'
3658 else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_sub))
3659 {
3660 t.type = lexer::token::e_sub;
3661 t.value = "-";
3662 t.position = t0.position;
3663
3664 return true;
3665 }
3666 // '- +' --> '-'
3667 else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_add))
3668 {
3669 t.type = lexer::token::e_sub;
3670 t.value = "-";
3671 t.position = t0.position;
3672
3673 return true;
3674 }
3675 // '- -' --> '+'
3676 else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub))
3677 {
3678 /*
3679 Note: May need to reconsider this when wanting to implement
3680 pre/postfix decrement operator
3681 */
3682 t.type = lexer::token::e_add;
3683 t.value = "+";
3684 t.position = t0.position;
3685
3686 return true;
3687 }
3688 else
3689 return false;
3690 }
3691
3692 inline bool join(const lexer::token& t0,
3693 const lexer::token& t1,
3694 const lexer::token& t2,
3696 {
3697 // '[ * ]' --> '[*]'
3698 if (
3699 (t0.type == lexer::token::e_lsqrbracket) &&
3700 (t1.type == lexer::token::e_mul ) &&
3701 (t2.type == lexer::token::e_rsqrbracket)
3702 )
3703 {
3704 t.type = lexer::token::e_symbol;
3705 t.value = "[*]";
3706 t.position = t0.position;
3707
3708 return true;
3709 }
3710 else
3711 return false;
3712 }
3713 };
3714
3716 {
3717 public:
3718
3719 using lexer::token_scanner::operator();
3720
3722 : token_scanner(1)
3723 , state_(true)
3724 {}
3725
3727 {
3728 if (!stack_.empty())
3729 {
3730 lexer::token t;
3731 t.value = stack_.top().first;
3732 t.position = stack_.top().second;
3733 error_token_ = t;
3734 state_ = false;
3735
3736 return false;
3737 }
3738 else
3739 return state_;
3740 }
3741
3743 {
3744 return error_token_;
3745 }
3746
3748 {
3749 // Why? because msvc doesn't support swap properly.
3750 stack_ = std::stack<std::pair<char,std::size_t> >();
3751 state_ = true;
3753 }
3754
3756 {
3757 if (
3758 !t.value.empty() &&
3759 (lexer::token::e_string != t.type) &&
3760 (lexer::token::e_symbol != t.type) &&
3761 exprtk::details::is_bracket(t.value[0])
3762 )
3763 {
3764 details::char_t c = t.value[0];
3765
3766 if (t.type == lexer::token::e_lbracket ) stack_.push(std::make_pair(')',t.position));
3767 else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
3768 else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position));
3770 {
3771 if (stack_.empty())
3772 {
3773 state_ = false;
3774 error_token_ = t;
3775
3776 return false;
3777 }
3778 else if (c != stack_.top().first)
3779 {
3780 state_ = false;
3781 error_token_ = t;
3782
3783 return false;
3784 }
3785 else
3786 stack_.pop();
3787 }
3788 }
3789
3790 return true;
3791 }
3792
3793 private:
3794
3796 std::stack<std::pair<char,std::size_t> > stack_;
3798 };
3799
3800 template <typename T>
3802 {
3803 public:
3804
3805 using lexer::token_scanner::operator();
3806
3808 : token_scanner (1)
3809 , current_index_(0)
3810 {}
3811
3813 {
3814 return error_list_.empty();
3815 }
3816
3818 {
3819 error_list_.clear();
3820 current_index_ = 0;
3821 }
3822
3824 {
3825 if (token::e_number == t.type)
3826 {
3827 T v;
3828
3829 if (!exprtk::details::string_to_real(t.value,v))
3830 {
3831 error_list_.push_back(current_index_);
3832 }
3833 }
3834
3836
3837 return true;
3838 }
3839
3840 std::size_t error_count() const
3841 {
3842 return error_list_.size();
3843 }
3844
3845 std::size_t error_index(const std::size_t& i)
3846 {
3847 if (i < error_list_.size())
3848 return error_list_[i];
3849 else
3850 return std::numeric_limits<std::size_t>::max();
3851 }
3852
3854 {
3855 error_list_.clear();
3856 }
3857
3858 private:
3859
3860 std::size_t current_index_;
3861 std::vector<std::size_t> error_list_;
3862 };
3863
3865 {
3866 private:
3867
3868 typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t;
3869
3870 public:
3871
3872 bool remove(const std::string& target_symbol)
3873 {
3874 const replace_map_t::iterator itr = replace_map_.find(target_symbol);
3875
3876 if (replace_map_.end() == itr)
3877 return false;
3878
3879 replace_map_.erase(itr);
3880
3881 return true;
3882 }
3883
3884 bool add_replace(const std::string& target_symbol,
3885 const std::string& replace_symbol,
3887 {
3888 const replace_map_t::iterator itr = replace_map_.find(target_symbol);
3889
3890 if (replace_map_.end() != itr)
3891 {
3892 return false;
3893 }
3894
3895 replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type);
3896
3897 return true;
3898 }
3899
3900 void clear()
3901 {
3902 replace_map_.clear();
3903 }
3904
3905 private:
3906
3908 {
3909 if (lexer::token::e_symbol == t.type)
3910 {
3911 if (replace_map_.empty())
3912 return false;
3913
3914 const replace_map_t::iterator itr = replace_map_.find(t.value);
3915
3916 if (replace_map_.end() != itr)
3917 {
3918 t.value = itr->second.first;
3919 t.type = itr->second.second;
3920
3921 return true;
3922 }
3923 }
3924
3925 return false;
3926 }
3927
3929 };
3930
3932 {
3933 private:
3934
3935 typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t;
3936 typedef std::set<token_pair_t> set_t;
3937
3938 public:
3939
3940 using lexer::token_scanner::operator();
3941
3969
3971 {
3972 return error_list_.empty();
3973 }
3974
3976 {
3977 const set_t::value_type p = std::make_pair(t0.type,t1.type);
3978
3979 if (invalid_bracket_check(t0.type,t1.type))
3980 {
3981 error_list_.push_back(std::make_pair(t0,t1));
3982 }
3983 else if (invalid_comb_.find(p) != invalid_comb_.end())
3984 {
3985 error_list_.push_back(std::make_pair(t0,t1));
3986 }
3987
3988 return true;
3989 }
3990
3991 std::size_t error_count() const
3992 {
3993 return error_list_.size();
3994 }
3995
3996 std::pair<lexer::token,lexer::token> error(const std::size_t index)
3997 {
3998 if (index < error_list_.size())
3999 {
4000 return error_list_[index];
4001 }
4002 else
4003 {
4004 static const lexer::token error_token;
4005 return std::make_pair(error_token,error_token);
4006 }
4007 }
4008
4010 {
4011 error_list_.clear();
4012 }
4013
4014 private:
4015
4017 {
4018 invalid_comb_.insert(std::make_pair(base,t));
4019 }
4020
4039
4041 {
4042 if (details::is_right_bracket(static_cast<details::char_t>(base)))
4043 {
4044 switch (t)
4045 {
4046 case lexer::token::e_assign : return (']' != base);
4047 case lexer::token::e_string : return (')' != base);
4048 default : return false;
4049 }
4050 }
4051 else if (details::is_left_bracket(static_cast<details::char_t>(base)))
4052 {
4053 if (details::is_right_bracket(static_cast<details::char_t>(t)))
4054 return false;
4055 else if (details::is_left_bracket(static_cast<details::char_t>(t)))
4056 return false;
4057 else
4058 {
4059 switch (t)
4060 {
4061 case lexer::token::e_number : return false;
4062 case lexer::token::e_symbol : return false;
4063 case lexer::token::e_string : return false;
4064 case lexer::token::e_add : return false;
4065 case lexer::token::e_sub : return false;
4066 case lexer::token::e_colon : return false;
4067 case lexer::token::e_ternary : return false;
4068 default : return true ;
4069 }
4070 }
4071 }
4072 else if (details::is_right_bracket(static_cast<details::char_t>(t)))
4073 {
4074 switch (base)
4075 {
4076 case lexer::token::e_number : return false;
4077 case lexer::token::e_symbol : return false;
4078 case lexer::token::e_string : return false;
4079 case lexer::token::e_eof : return false;
4080 case lexer::token::e_colon : return false;
4081 case lexer::token::e_ternary : return false;
4082 default : return true ;
4083 }
4084 }
4085 else if (details::is_left_bracket(static_cast<details::char_t>(t)))
4086 {
4087 switch (base)
4088 {
4089 case lexer::token::e_rbracket : return true;
4090 case lexer::token::e_rsqrbracket : return true;
4091 case lexer::token::e_rcrlbracket : return true;
4092 default : return false;
4093 }
4094 }
4095
4096 return false;
4097 }
4098
4100 std::vector<std::pair<lexer::token,lexer::token> > error_list_;
4101 };
4102
4104 {
4105 private:
4106
4108 typedef std::pair<token_t,std::pair<token_t,token_t> > token_triplet_t;
4109 typedef std::set<token_triplet_t> set_t;
4110
4111 public:
4112
4113 using lexer::token_scanner::operator();
4114
4136
4138 {
4139 return error_list_.empty();
4140 }
4141
4143 {
4144 const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type));
4145
4146 if (invalid_comb_.find(p) != invalid_comb_.end())
4147 {
4148 error_list_.push_back(std::make_pair(t0,t1));
4149 }
4150
4151 return true;
4152 }
4153
4154 std::size_t error_count() const
4155 {
4156 return error_list_.size();
4157 }
4158
4159 std::pair<lexer::token,lexer::token> error(const std::size_t index)
4160 {
4161 if (index < error_list_.size())
4162 {
4163 return error_list_[index];
4164 }
4165 else
4166 {
4167 static const lexer::token error_token;
4168 return std::make_pair(error_token,error_token);
4169 }
4170 }
4171
4173 {
4174 error_list_.clear();
4175 }
4176
4177 private:
4178
4179 void add_invalid(const token_t t0, const token_t t1, const token_t t2)
4180 {
4181 invalid_comb_.insert(std::make_pair(t0,std::make_pair(t1,t2)));
4182 }
4183
4185 std::vector<std::pair<lexer::token,lexer::token> > error_list_;
4186 };
4187
4189 {
4191 {
4192 if (token_scanner_list.end() != std::find(token_scanner_list.begin(),
4193 token_scanner_list.end (),
4194 scanner))
4195 {
4196 return false;
4197 }
4198
4199 token_scanner_list.push_back(scanner);
4200
4201 return true;
4202 }
4203
4205 {
4206 if (token_modifier_list.end() != std::find(token_modifier_list.begin(),
4207 token_modifier_list.end (),
4208 modifier))
4209 {
4210 return false;
4211 }
4212
4213 token_modifier_list.push_back(modifier);
4214
4215 return true;
4216 }
4217
4219 {
4220 if (token_joiner_list.end() != std::find(token_joiner_list.begin(),
4221 token_joiner_list.end (),
4222 joiner))
4223 {
4224 return false;
4225 }
4226
4227 token_joiner_list.push_back(joiner);
4228
4229 return true;
4230 }
4231
4233 {
4234 if (token_inserter_list.end() != std::find(token_inserter_list.begin(),
4235 token_inserter_list.end (),
4236 inserter))
4237 {
4238 return false;
4239 }
4240
4241 token_inserter_list.push_back(inserter);
4242
4243 return true;
4244 }
4245
4247 {
4248 error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0);
4249
4250 for (std::size_t i = 0; i < token_modifier_list.size(); ++i)
4251 {
4253
4254 modifier.reset();
4255 modifier.process(g);
4256
4257 if (!modifier.result())
4258 {
4260
4261 return false;
4262 }
4263 }
4264
4265 return true;
4266 }
4267
4269 {
4270 error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
4271
4272 for (std::size_t i = 0; i < token_joiner_list.size(); ++i)
4273 {
4274 lexer::token_joiner& joiner = (*token_joiner_list[i]);
4275
4276 joiner.reset();
4277 joiner.process(g);
4278
4279 if (!joiner.result())
4280 {
4282
4283 return false;
4284 }
4285 }
4286
4287 return true;
4288 }
4289
4291 {
4292 error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
4293
4294 for (std::size_t i = 0; i < token_inserter_list.size(); ++i)
4295 {
4297
4298 inserter.reset();
4299 inserter.process(g);
4300
4301 if (!inserter.result())
4302 {
4304
4305 return false;
4306 }
4307 }
4308
4309 return true;
4310 }
4311
4313 {
4314 error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
4315
4316 for (std::size_t i = 0; i < token_scanner_list.size(); ++i)
4317 {
4319
4320 scanner.reset();
4321 scanner.process(g);
4322
4323 if (!scanner.result())
4324 {
4326
4327 return false;
4328 }
4329 }
4330
4331 return true;
4332 }
4333
4334 std::vector<lexer::token_scanner*> token_scanner_list;
4335 std::vector<lexer::token_modifier*> token_modifier_list;
4336 std::vector<lexer::token_joiner*> token_joiner_list;
4337 std::vector<lexer::token_inserter*> token_inserter_list;
4338
4343 };
4344 }
4345
4347 {
4348 public:
4349
4352
4353 inline bool init(const std::string& str)
4354 {
4355 if (!lexer_.process(str))
4356 {
4357 return false;
4358 }
4359
4360 lexer_.begin();
4361
4362 next_token();
4363
4364 return true;
4365 }
4366
4368 {
4369 return lexer_;
4370 }
4371
4372 inline const generator_t& lexer() const
4373 {
4374 return lexer_;
4375 }
4376
4377 inline void store_token()
4378 {
4379 lexer_.store();
4381 }
4382
4383 inline void restore_token()
4384 {
4385 lexer_.restore();
4387 }
4388
4389 inline void next_token()
4390 {
4392 }
4393
4394 inline const token_t& current_token() const
4395 {
4396 return current_token_;
4397 }
4398
4399 inline const token_t& peek_next_token()
4400 {
4401 return lexer_.peek_next_token();
4402 }
4403
4405 {
4407 e_advance = 1
4409
4410 inline void advance_token(const token_advance_mode mode)
4411 {
4412 if (e_advance == mode)
4413 {
4414 next_token();
4415 }
4416 }
4417
4418 inline bool token_is(const token_t::token_type& ttype, const token_advance_mode mode = e_advance)
4419 {
4420 if (current_token().type != ttype)
4421 {
4422 return false;
4423 }
4424
4425 advance_token(mode);
4426
4427 return true;
4428 }
4429
4430 inline bool token_is(const token_t::token_type& ttype,
4431 const std::string& value,
4432 const token_advance_mode mode = e_advance)
4433 {
4434 if (
4435 (current_token().type != ttype) ||
4437 )
4438 {
4439 return false;
4440 }
4441
4442 advance_token(mode);
4443
4444 return true;
4445 }
4446
4447 inline bool token_is(const std::string& value,
4448 const token_advance_mode mode = e_advance)
4449 {
4450 if (!exprtk::details::imatch(value,current_token().value))
4451 {
4452 return false;
4453 }
4454
4455 advance_token(mode);
4456
4457 return true;
4458 }
4459
4461 {
4462 switch (current_token().type)
4463 {
4464 case token_t::e_add :
4465 case token_t::e_sub :
4466 case token_t::e_div :
4467 case token_t::e_mul :
4468 case token_t::e_mod :
4469 case token_t::e_pow : break;
4470 default : return false;
4471 }
4472
4473 advance_token(mode);
4474
4475 return true;
4476 }
4477
4479 {
4480 switch (current_token().type)
4481 {
4482 case token_t::e_eq :
4483 case token_t::e_lte :
4484 case token_t::e_ne :
4485 case token_t::e_gte :
4486 case token_t::e_lt :
4487 case token_t::e_gt : break;
4488 default : return false;
4489 }
4490
4491 advance_token(mode);
4492
4493 return true;
4494 }
4495
4497 {
4498 switch (current_token().type)
4499 {
4500 case token_t::e_lbracket :
4502 case token_t::e_lsqrbracket : break;
4503 default : return false;
4504 }
4505
4506 advance_token(mode);
4507
4508 return true;
4509 }
4510
4512 {
4513 switch (current_token().type)
4514 {
4515 case token_t::e_rbracket :
4517 case token_t::e_rsqrbracket : break;
4518 default : return false;
4519 }
4520
4521 advance_token(mode);
4522
4523 return true;
4524 }
4525
4527 {
4528 return token_is("for" , mode) ||
4529 token_is("while" , mode) ||
4530 token_is("repeat", mode) ;
4531 }
4532
4533 inline bool peek_token_is(const token_t::token_type& ttype)
4534 {
4535 return (lexer_.peek_next_token().type == ttype);
4536 }
4537
4538 inline bool peek_token_is(const std::string& s)
4539 {
4541 }
4542
4543 private:
4544
4548 };
4549 }
4550
4551 template <typename T>
4553 {
4554 public:
4555
4556 typedef T* data_ptr_t;
4557
4558 vector_view(data_ptr_t data, const std::size_t& size)
4559 : base_size_(size)
4560 , size_(size)
4561 , data_(data)
4562 , data_ref_(0)
4563 {
4564 assert(size_ > 0);
4565 }
4566
4569 , size_(vv.size_)
4570 , data_(vv.data_)
4571 , data_ref_(0)
4572 {
4573 assert(size_ > 0);
4574 }
4575
4577 {
4578 data_ = data;
4579
4580 if (!data_ref_.empty())
4581 {
4582 for (std::size_t i = 0; i < data_ref_.size(); ++i)
4583 {
4584 (*data_ref_[i]) = data;
4585 }
4586 }
4587 }
4588
4589 inline data_ptr_t data() const
4590 {
4591 return data_;
4592 }
4593
4594 inline std::size_t base_size() const
4595 {
4596 return base_size_;
4597 }
4598
4599 inline std::size_t size() const
4600 {
4601 return size_;
4602 }
4603
4604 inline const T& operator[](const std::size_t index) const
4605 {
4606 assert(index < size_);
4607 return data_[index];
4608 }
4609
4610 inline T& operator[](const std::size_t index)
4611 {
4612 assert(index < size_);
4613 return data_[index];
4614 }
4615
4616 void set_ref(data_ptr_t* data_ref)
4617 {
4618 data_ref_.push_back(data_ref);
4619 exprtk_debug(("vector_view::set_ref() - data_ref: %p data_ref_.size(): %d\n",
4620 reinterpret_cast<void*>(data_ref),
4621 static_cast<int>(data_ref_.size())));
4622 }
4623
4624 void remove_ref(data_ptr_t* data_ref)
4625 {
4626 data_ref_.erase(
4627 std::remove(data_ref_.begin(), data_ref_.end(), data_ref),
4628 data_ref_.end());
4629 exprtk_debug(("vector_view::remove_ref() - data_ref: %p data_ref_.size(): %d\n",
4630 reinterpret_cast<void*>(data_ref),
4631 static_cast<int>(data_ref_.size())));
4632 }
4633
4634 bool set_size(const std::size_t new_size)
4635 {
4636 if ((new_size > 0) && (new_size <= base_size_))
4637 {
4638 size_ = new_size;
4639 exprtk_debug(("vector_view::set_size() - data_: %p size: %lu\n",
4640 reinterpret_cast<void*>(data_),
4641 size_));
4642 return true;
4643 }
4644
4645 exprtk_debug(("vector_view::set_size() - error invalid new_size: %lu base_size: %lu\n",
4646 new_size,
4647 base_size_));
4648 return false;
4649 }
4650
4651 private:
4652
4653 const std::size_t base_size_;
4654 std::size_t size_;
4656 std::vector<data_ptr_t*> data_ref_;
4657 };
4658
4659 template <typename T>
4661 const std::size_t size, const std::size_t offset = 0)
4662 {
4663 return vector_view<T>(data + offset, size);
4664 }
4665
4666 template <typename T>
4667 inline vector_view<T> make_vector_view(std::vector<T>& v,
4668 const std::size_t size, const std::size_t offset = 0)
4669 {
4670 return vector_view<T>(v.data() + offset, size);
4671 }
4672
4673 template <typename T> class results_context;
4674
4675 template <typename T>
4677 {
4685
4687 : data(0)
4688 , size(0)
4689 , type(e_unknown)
4690 {}
4691
4692 union
4693 {
4694 void* data;
4696 };
4697
4698 std::size_t size;
4700
4702 {
4703 public:
4704
4705 explicit parameter_list(std::vector<type_store>& pl)
4706 : parameter_list_(pl)
4707 {}
4708
4709 inline bool empty() const
4710 {
4711 return parameter_list_.empty();
4712 }
4713
4714 inline std::size_t size() const
4715 {
4716 return parameter_list_.size();
4717 }
4718
4719 inline type_store& operator[](const std::size_t& index)
4720 {
4721 return parameter_list_[index];
4722 }
4723
4724 inline const type_store& operator[](const std::size_t& index) const
4725 {
4726 return parameter_list_[index];
4727 }
4728
4730 {
4731 return parameter_list_[0];
4732 }
4733
4734 inline const type_store& front() const
4735 {
4736 return parameter_list_[0];
4737 }
4738
4740 {
4741 return parameter_list_.back();
4742 }
4743
4744 inline const type_store& back() const
4745 {
4746 return parameter_list_.back();
4747 }
4748
4749 private:
4750
4751 std::vector<type_store>& parameter_list_;
4752
4753 friend class results_context<T>;
4754 };
4755
4756 template <typename ViewType>
4758 {
4760 typedef ViewType value_t;
4761
4763 : ts_(ts)
4764 , data_(reinterpret_cast<value_t*>(ts_.data))
4765 {}
4766
4767 explicit type_view(const type_store_t& ts)
4768 : ts_(const_cast<type_store_t&>(ts))
4769 , data_(reinterpret_cast<value_t*>(ts_.data))
4770 {}
4771
4772 inline std::size_t size() const
4773 {
4774 return ts_.size;
4775 }
4776
4777 inline value_t& operator[](const std::size_t& i)
4778 {
4779 return data_[i];
4780 }
4781
4782 inline const value_t& operator[](const std::size_t& i) const
4783 {
4784 return data_[i];
4785 }
4786
4787 inline const value_t* begin() const { return data_; }
4788 inline value_t* begin() { return data_; }
4789
4790 inline const value_t* end() const
4791 {
4792 return static_cast<value_t*>(data_ + ts_.size);
4793 }
4794
4795 inline value_t* end()
4796 {
4797 return static_cast<value_t*>(data_ + ts_.size);
4798 }
4799
4802 };
4803
4806
4808 {
4810 typedef T value_t;
4811
4813 : v_(*reinterpret_cast<value_t*>(ts.data))
4814 {}
4815
4816 explicit scalar_view(const type_store_t& ts)
4817 : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
4818 {}
4819
4821 {
4822 return v_;
4823 }
4824
4825 inline const value_t& operator() () const
4826 {
4827 return v_;
4828 }
4829
4830 inline operator value_t() const
4831 {
4832 return v_;
4833 }
4834
4835 inline operator value_t()
4836 {
4837 return v_;
4838 }
4839
4840 template <typename IntType>
4841 inline bool to_int(IntType& i) const
4842 {
4844 return false;
4845
4846 i = static_cast<IntType>(v_);
4847
4848 return true;
4849 }
4850
4851 template <typename UIntType>
4852 inline bool to_uint(UIntType& u) const
4853 {
4854 if (v_ < T(0))
4855 return false;
4857 return false;
4858
4859 u = static_cast<UIntType>(v_);
4860
4861 return true;
4862 }
4863
4864 T& v_;
4865 };
4866 };
4867
4868 template <typename StringView>
4869 inline std::string to_str(const StringView& view)
4870 {
4871 return std::string(view.begin(),view.size());
4872 }
4873
4874 #ifndef exprtk_disable_return_statement
4875 namespace details
4876 {
4877 template <typename T> class return_node;
4878 template <typename T> class return_envelope_node;
4879 }
4880 #endif
4881
4882 template <typename T>
4884 {
4885 public:
4886
4891
4893 : results_available_(false)
4894 {}
4895
4896 inline std::size_t count() const
4897 {
4899 return parameter_list_.size();
4900 else
4901 return 0;
4902 }
4903
4904 inline type_store_t& operator[](const std::size_t& index)
4905 {
4906 return parameter_list_[index];
4907 }
4908
4909 inline const type_store_t& operator[](const std::size_t& index) const
4910 {
4911 return parameter_list_[index];
4912 }
4913
4914 inline bool get_scalar(const std::size_t& index, T& out) const
4915 {
4916 if (
4917 (index < parameter_list_.size()) &&
4919 )
4920 {
4921 const scalar_t scalar(parameter_list_[index]);
4922 out = scalar();
4923 return true;
4924 }
4925
4926 return false;
4927 }
4928
4929 template <typename OutputIterator>
4930 inline bool get_vector(const std::size_t& index, OutputIterator out_itr) const
4931 {
4932 if (
4933 (index < parameter_list_.size()) &&
4935 )
4936 {
4937 const vector_t vector(parameter_list_[index]);
4938 for (std::size_t i = 0; i < vector.size(); ++i)
4939 {
4940 *(out_itr++) = vector[i];
4941 }
4942
4943 return true;
4944 }
4945
4946 return false;
4947 }
4948
4949 inline bool get_vector(const std::size_t& index, std::vector<T>& out) const
4950 {
4951 return get_vector(index,std::back_inserter(out));
4952 }
4953
4954 inline bool get_string(const std::size_t& index, std::string& out) const
4955 {
4956 if (
4957 (index < parameter_list_.size()) &&
4959 )
4960 {
4961 const string_t str(parameter_list_[index]);
4962 out.assign(str.begin(),str.size());
4963 return true;
4964 }
4965
4966 return false;
4967 }
4968
4969 private:
4970
4971 inline void clear()
4972 {
4973 results_available_ = false;
4974 }
4975
4976 typedef std::vector<type_store_t> ts_list_t;
4978
4979 inline void assign(const parameter_list_t& pl)
4980 {
4982 results_available_ = true;
4983 }
4984
4987
4988 #ifndef exprtk_disable_return_statement
4989 friend class details::return_node<T>;
4990 friend class details::return_envelope_node<T>;
4991 #endif
4992 };
4993
4994 namespace details
4995 {
4997 {
5022
5023 // Do not add new functions/operators after this point.
5024 e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
5025 e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007,
5026 e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011,
5027 e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015,
5028 e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019,
5029 e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023,
5030 e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027,
5031 e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031,
5032 e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035,
5033 e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039,
5034 e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043,
5035 e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047,
5036 e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051,
5037 e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055,
5038 e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059,
5039 e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063,
5040 e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067,
5041 e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071,
5042 e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075,
5043 e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079,
5044 e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083,
5045 e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087,
5046 e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091,
5047 e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095,
5048 e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099,
5050 e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003,
5051 e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007,
5052 e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011,
5053 e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015,
5054 e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019,
5055 e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023,
5056 e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027,
5057 e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031,
5058 e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035,
5059 e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039,
5060 e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043,
5061 e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047,
5062 e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051,
5063 e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055,
5064 e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059,
5065 e_sf4ext60 = 2060, e_sf4ext61 = 2061
5067
5068 inline std::string to_str(const operator_type opr)
5069 {
5070 switch (opr)
5071 {
5072 case e_add : return "+" ;
5073 case e_sub : return "-" ;
5074 case e_mul : return "*" ;
5075 case e_div : return "/" ;
5076 case e_mod : return "%" ;
5077 case e_pow : return "^" ;
5078 case e_assign : return ":=" ;
5079 case e_addass : return "+=" ;
5080 case e_subass : return "-=" ;
5081 case e_mulass : return "*=" ;
5082 case e_divass : return "/=" ;
5083 case e_modass : return "%=" ;
5084 case e_lt : return "<" ;
5085 case e_lte : return "<=" ;
5086 case e_eq : return "==" ;
5087 case e_equal : return "=" ;
5088 case e_ne : return "!=" ;
5089 case e_nequal : return "<>" ;
5090 case e_gte : return ">=" ;
5091 case e_gt : return ">" ;
5092 case e_and : return "and" ;
5093 case e_or : return "or" ;
5094 case e_xor : return "xor" ;
5095 case e_nand : return "nand";
5096 case e_nor : return "nor" ;
5097 case e_xnor : return "xnor";
5098 default : return "N/A" ;
5099 }
5100 }
5101
5103 {
5104 base_operation_t(const operator_type t, const unsigned int& np)
5105 : type(t)
5106 , num_params(np)
5107 {}
5108
5110 unsigned int num_params;
5111 };
5112
5113 namespace loop_unroll
5114 {
5115 const unsigned int global_loop_batch_size =
5116 #ifndef exprtk_disable_superscalar_unroll
5117 16;
5118 #else
5119 4;
5120 #endif
5121
5122 struct details
5123 {
5124 explicit details(const std::size_t& vsize,
5125 const unsigned int loop_batch_size = global_loop_batch_size)
5129 {}
5130
5131 unsigned int batch_size;
5134 };
5135 }
5136
5137 #ifdef exprtk_enable_debugging
5138 inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0)
5139 {
5140 if (size)
5141 exprtk_debug(("%s - addr: %p size: %d\n",
5142 s.c_str(),
5143 ptr,
5144 static_cast<unsigned int>(size)));
5145 else
5146 exprtk_debug(("%s - addr: %p\n", s.c_str(), ptr));
5147 }
5148
5149 template <typename T>
5150 inline void dump_vector(const std::string& vec_name, const T* data, const std::size_t size)
5151 {
5152 printf("----- %s (%p) -----\n",
5153 vec_name.c_str(),
5154 static_cast<const void*>(data));
5155 printf("[ ");
5156 for (std::size_t i = 0; i < size; ++i)
5157 {
5158 printf("%8.3f\t", data[i]);
5159 }
5160 printf(" ]\n");
5161 printf("---------------------\n");
5162 }
5163 #else
5164 inline void dump_ptr(const std::string&, const void*) {}
5165 inline void dump_ptr(const std::string&, const void*, const std::size_t) {}
5166 template <typename T>
5167 inline void dump_vector(const std::string&, const T*, const std::size_t) {}
5168 #endif
5169
5170 template <typename T>
5172 {
5173 public:
5174
5176 typedef T* data_t;
5177
5178 private:
5179
5181 {
5183 : ref_count(1)
5184 , size (0)
5185 , data (0)
5186 , destruct (true)
5187 {}
5188
5189 explicit control_block(const std::size_t& dsize)
5190 : ref_count(1 )
5191 , size (dsize)
5192 , data (0 )
5193 , destruct (true )
5194 { create_data(); }
5195
5196 control_block(const std::size_t& dsize, data_t dptr, bool dstrct = false)
5197 : ref_count(1 )
5198 , size (dsize )
5199 , data (dptr )
5200 , destruct (dstrct)
5201 {}
5202
5204 {
5205 if (data && destruct && (0 == ref_count))
5206 {
5207 dump_ptr("~vec_data_store::control_block() data",data);
5208 delete[] data;
5209 data = reinterpret_cast<data_t>(0);
5210 }
5211 }
5212
5213 static inline control_block* create(const std::size_t& dsize, data_t data_ptr = data_t(0), bool dstrct = false)
5214 {
5215 if (dsize)
5216 {
5217 if (0 == data_ptr)
5218 return (new control_block(dsize));
5219 else
5220 return (new control_block(dsize, data_ptr, dstrct));
5221 }
5222 else
5223 return (new control_block);
5224 }
5225
5226 static inline void destroy(control_block*& cntrl_blck)
5227 {
5228 if (cntrl_blck)
5229 {
5230 if (
5231 (0 != cntrl_blck->ref_count) &&
5232 (0 == --cntrl_blck->ref_count)
5233 )
5234 {
5235 delete cntrl_blck;
5236 }
5237
5238 cntrl_blck = 0;
5239 }
5240 }
5241
5242 std::size_t ref_count;
5243 std::size_t size;
5246
5247 private:
5248
5251
5252 inline void create_data()
5253 {
5254 destruct = true;
5255 data = new T[size];
5256 std::fill_n(data, size, T(0));
5257 dump_ptr("control_block::create_data() - data", data, size);
5258 }
5259 };
5260
5261 public:
5262
5264 : control_block_(control_block::create(0))
5265 {}
5266
5267 explicit vec_data_store(const std::size_t& size)
5269 {}
5270
5271 vec_data_store(const std::size_t& size, data_t data, bool dstrct = false)
5273 {}
5274
5276 {
5279 }
5280
5285
5286 type& operator=(const type& vds)
5287 {
5288 if (this != &vds)
5289 {
5290 const std::size_t final_size = min_size(control_block_, vds.control_block_);
5291
5294
5296 {
5298
5301 }
5302 }
5303
5304 return (*this);
5305 }
5306
5307 inline data_t data()
5308 {
5309 return control_block_->data;
5310 }
5311
5312 inline data_t data() const
5313 {
5314 return control_block_->data;
5315 }
5316
5317 inline std::size_t size() const
5318 {
5319 return control_block_->size;
5320 }
5321
5322 inline data_t& ref()
5323 {
5324 return control_block_->data;
5325 }
5326
5327 inline void dump() const
5328 {
5329 #ifdef exprtk_enable_debugging
5330 exprtk_debug(("size: %d\taddress:%p\tdestruct:%c\n",
5331 size(),
5332 data(),
5333 (control_block_->destruct ? 'T' : 'F')));
5334
5335 for (std::size_t i = 0; i < size(); ++i)
5336 {
5337 if (5 == i)
5338 exprtk_debug(("\n"));
5339
5340 exprtk_debug(("%15.10f ", data()[i]));
5341 }
5342 exprtk_debug(("\n"));
5343 #endif
5344 }
5345
5346 static inline void match_sizes(type& vds0, type& vds1)
5347 {
5348 const std::size_t size = min_size(vds0.control_block_,vds1.control_block_);
5349 vds0.control_block_->size = size;
5350 vds1.control_block_->size = size;
5351 }
5352
5353 private:
5354
5355 static inline std::size_t min_size(const control_block* cb0, const control_block* cb1)
5356 {
5357 const std::size_t size0 = cb0->size;
5358 const std::size_t size1 = cb1->size;
5359
5360 if (size0 && size1)
5361 return std::min(size0,size1);
5362 else
5363 return (size0) ? size0 : size1;
5364 }
5365
5367 };
5368
5369 namespace numeric
5370 {
5371 namespace details
5372 {
5373 template <typename T>
5374 inline T process_impl(const operator_type operation, const T arg)
5375 {
5376 switch (operation)
5377 {
5378 case e_abs : return numeric::abs (arg);
5379 case e_acos : return numeric::acos (arg);
5380 case e_acosh : return numeric::acosh(arg);
5381 case e_asin : return numeric::asin (arg);
5382 case e_asinh : return numeric::asinh(arg);
5383 case e_atan : return numeric::atan (arg);
5384 case e_atanh : return numeric::atanh(arg);
5385 case e_ceil : return numeric::ceil (arg);
5386 case e_cos : return numeric::cos (arg);
5387 case e_cosh : return numeric::cosh (arg);
5388 case e_exp : return numeric::exp (arg);
5389 case e_expm1 : return numeric::expm1(arg);
5390 case e_floor : return numeric::floor(arg);
5391 case e_log : return numeric::log (arg);
5392 case e_log10 : return numeric::log10(arg);
5393 case e_log2 : return numeric::log2 (arg);
5394 case e_log1p : return numeric::log1p(arg);
5395 case e_neg : return numeric::neg (arg);
5396 case e_pos : return numeric::pos (arg);
5397 case e_round : return numeric::round(arg);
5398 case e_sin : return numeric::sin (arg);
5399 case e_sinc : return numeric::sinc (arg);
5400 case e_sinh : return numeric::sinh (arg);
5401 case e_sqrt : return numeric::sqrt (arg);
5402 case e_tan : return numeric::tan (arg);
5403 case e_tanh : return numeric::tanh (arg);
5404 case e_cot : return numeric::cot (arg);
5405 case e_sec : return numeric::sec (arg);
5406 case e_csc : return numeric::csc (arg);
5407 case e_r2d : return numeric::r2d (arg);
5408 case e_d2r : return numeric::d2r (arg);
5409 case e_d2g : return numeric::d2g (arg);
5410 case e_g2d : return numeric::g2d (arg);
5411 case e_notl : return numeric::notl (arg);
5412 case e_sgn : return numeric::sgn (arg);
5413 case e_erf : return numeric::erf (arg);
5414 case e_erfc : return numeric::erfc (arg);
5415 case e_ncdf : return numeric::ncdf (arg);
5416 case e_frac : return numeric::frac (arg);
5417 case e_trunc : return numeric::trunc(arg);
5418
5419 default : exprtk_debug(("numeric::details::process_impl<T> - Invalid unary operation.\n"));
5420 return std::numeric_limits<T>::quiet_NaN();
5421 }
5422 }
5423
5424 template <typename T>
5425 inline T process_impl(const operator_type operation, const T arg0, const T arg1)
5426 {
5427 switch (operation)
5428 {
5429 case e_add : return (arg0 + arg1);
5430 case e_sub : return (arg0 - arg1);
5431 case e_mul : return (arg0 * arg1);
5432 case e_div : return (arg0 / arg1);
5433 case e_mod : return modulus<T>(arg0,arg1);
5434 case e_pow : return pow<T>(arg0,arg1);
5435 case e_atan2 : return atan2<T>(arg0,arg1);
5436 case e_min : return std::min<T>(arg0,arg1);
5437 case e_max : return std::max<T>(arg0,arg1);
5438 case e_logn : return logn<T>(arg0,arg1);
5439 case e_lt : return (arg0 < arg1) ? T(1) : T(0);
5440 case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
5441 case e_eq : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0);
5442 case e_ne : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0);
5443 case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
5444 case e_gt : return (arg0 > arg1) ? T(1) : T(0);
5445 case e_and : return and_opr <T>(arg0,arg1);
5446 case e_nand : return nand_opr<T>(arg0,arg1);
5447 case e_or : return or_opr <T>(arg0,arg1);
5448 case e_nor : return nor_opr <T>(arg0,arg1);
5449 case e_xor : return xor_opr <T>(arg0,arg1);
5450 case e_xnor : return xnor_opr<T>(arg0,arg1);
5451 case e_root : return root <T>(arg0,arg1);
5452 case e_roundn : return roundn <T>(arg0,arg1);
5453 case e_equal : return equal <T>(arg0,arg1);
5454 case e_nequal : return nequal <T>(arg0,arg1);
5455 case e_hypot : return hypot <T>(arg0,arg1);
5456 case e_shr : return shr <T>(arg0,arg1);
5457 case e_shl : return shl <T>(arg0,arg1);
5458
5459 default : exprtk_debug(("numeric::details::process_impl<T> - Invalid binary operation.\n"));
5460 return std::numeric_limits<T>::quiet_NaN();
5461 }
5462 }
5463
5464 template <typename T>
5465 inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag)
5466 {
5467 switch (operation)
5468 {
5469 case e_add : return (arg0 + arg1);
5470 case e_sub : return (arg0 - arg1);
5471 case e_mul : return (arg0 * arg1);
5472 case e_div : return (arg0 / arg1);
5473 case e_mod : return arg0 % arg1;
5474 case e_pow : return pow<T>(arg0,arg1);
5475 case e_min : return std::min<T>(arg0,arg1);
5476 case e_max : return std::max<T>(arg0,arg1);
5477 case e_logn : return logn<T>(arg0,arg1);
5478 case e_lt : return (arg0 < arg1) ? T(1) : T(0);
5479 case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
5480 case e_eq : return (arg0 == arg1) ? T(1) : T(0);
5481 case e_ne : return (arg0 != arg1) ? T(1) : T(0);
5482 case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
5483 case e_gt : return (arg0 > arg1) ? T(1) : T(0);
5484 case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
5485 case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
5486 case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
5487 case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
5488 case e_xor : return arg0 ^ arg1;
5489 case e_xnor : return !(arg0 ^ arg1);
5490 case e_root : return root<T>(arg0,arg1);
5491 case e_equal : return arg0 == arg1;
5492 case e_nequal : return arg0 != arg1;
5493 case e_hypot : return hypot<T>(arg0,arg1);
5494 case e_shr : return arg0 >> arg1;
5495 case e_shl : return arg0 << arg1;
5496
5497 default : exprtk_debug(("numeric::details::process_impl<IntType> - Invalid binary operation.\n"));
5498 return std::numeric_limits<T>::quiet_NaN();
5499 }
5500 }
5501 }
5502
5503 template <typename T>
5504 inline T process(const operator_type operation, const T arg)
5505 {
5507 }
5508
5509 template <typename T>
5510 inline T process(const operator_type operation, const T arg0, const T arg1)
5511 {
5513 }
5514 }
5515
5516 template <typename Node>
5518 {
5520 typedef Node** node_pp_t;
5521 typedef std::vector<node_pp_t> noderef_list_t;
5522
5524 {}
5525
5527 {}
5528 };
5529
5530 template <typename Node>
5531 struct node_depth_base;
5532
5533 template <typename T>
5534 class expression_node : public node_collector_interface<expression_node<T> >
5535 , public node_depth_base<expression_node<T> >
5536 {
5537 public:
5538
5540 {
5579 e_assert
5581
5582 typedef T value_type;
5587
5589 {}
5590
5591 inline virtual T value() const
5592 {
5593 return std::numeric_limits<T>::quiet_NaN();
5594 }
5595
5596 inline virtual expression_node<T>* branch(const std::size_t& index = 0) const
5597 {
5598 return reinterpret_cast<expression_ptr>(index * 0);
5599 }
5600
5601 inline virtual node_type type() const
5602 {
5603 return e_none;
5604 }
5605
5606 inline virtual bool valid() const
5607 {
5608 return true;
5609 }
5610 }; // class expression_node
5611
5612 template <typename T>
5614
5615 inline bool is_true(const double v)
5616 {
5617 return std::not_equal_to<double>()(0.0,v);
5618 }
5619
5620 inline bool is_true(const long double v)
5621 {
5622 return std::not_equal_to<long double>()(0.0L,v);
5623 }
5624
5625 inline bool is_true(const float v)
5626 {
5627 return std::not_equal_to<float>()(0.0f,v);
5628 }
5629
5630 template <typename T>
5631 inline bool is_true(const expression_node<T>* node)
5632 {
5633 return std::not_equal_to<T>()(T(0),node->value());
5634 }
5635
5636 template <typename T>
5637 inline bool is_true(const std::pair<expression_node<T>*,bool>& node)
5638 {
5639 return std::not_equal_to<T>()(T(0),node.first->value());
5640 }
5641
5642 template <typename T>
5644 {
5645 return std::equal_to<T>()(T(0),node->value());
5646 }
5647
5648 template <typename T>
5649 inline bool is_false(const std::pair<expression_node<T>*,bool>& node)
5650 {
5651 return std::equal_to<T>()(T(0),node.first->value());
5652 }
5653
5654 template <typename T>
5656 {
5658 }
5659
5660 template <typename T>
5662 {
5664 }
5665
5666 template <typename T>
5668 {
5670 }
5671
5672 template <typename T>
5674 {
5676 }
5677
5678 template <typename T>
5680 {
5682 }
5683
5684 template <typename T>
5700
5701 template <typename T>
5703 {
5705 }
5706
5707 template <typename T>
5709 {
5711 }
5712
5713 template <typename T>
5718
5719 template <typename T>
5724
5725 template <typename T>
5730
5731 template <typename T>
5736
5737 template <typename T>
5742
5743 template <typename T>
5748
5749 template <typename T>
5751 {
5753 }
5754
5755 template <typename T>
5779
5780 template <typename T>
5782 {
5783 return node &&
5784 (
5787 );
5788 }
5789
5790 template <typename T>
5792 {
5794 }
5795
5796 template <typename T>
5798 {
5800 }
5801
5802 template <typename T>
5804 {
5806 }
5807
5808 template <typename T>
5810 {
5812 }
5813
5814 template <typename T>
5816 {
5818 }
5819
5820 template <typename T>
5822 {
5824 }
5825
5826 template <typename T>
5828 {
5830 }
5831
5832 template <typename T> class unary_node;
5833
5834 template <typename T>
5836 {
5837 if (node && is_unary_node(node))
5838 {
5839 return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation());
5840 }
5841 else
5842 return false;
5843 }
5844
5845 template <typename T>
5847 {
5849 }
5850
5851 template <typename T>
5853 {
5854 return (0 != node) &&
5856 !is_string_node (node) ;
5857 }
5858
5859 template <std::size_t N, typename T>
5860 inline bool all_nodes_valid(expression_node<T>* const (&b)[N])
5861 {
5862 for (std::size_t i = 0; i < N; ++i)
5863 {
5864 if (0 == b[i]) return false;
5865 }
5866
5867 return true;
5868 }
5869
5870 template <typename T,
5871 typename Allocator,
5872 template <typename, typename> class Sequence>
5874 {
5875 for (std::size_t i = 0; i < b.size(); ++i)
5876 {
5877 if (0 == b[i]) return false;
5878 }
5879
5880 return true;
5881 }
5882
5883 template <std::size_t N, typename T>
5884 inline bool all_nodes_variables(expression_node<T>* const (&b)[N])
5885 {
5886 for (std::size_t i = 0; i < N; ++i)
5887 {
5888 if (0 == b[i])
5889 return false;
5890 else if (!is_variable_node(b[i]))
5891 return false;
5892 }
5893
5894 return true;
5895 }
5896
5897 template <typename T,
5898 typename Allocator,
5899 template <typename, typename> class Sequence>
5901 {
5902 for (std::size_t i = 0; i < b.size(); ++i)
5903 {
5904 if (0 == b[i])
5905 return false;
5906 else if (!is_variable_node(b[i]))
5907 return false;
5908 }
5909
5910 return true;
5911 }
5912
5913 template <typename Node>
5915 {
5916 public:
5917
5919
5921 typedef typename nci_t::node_pp_t node_pp_t;
5923
5924 static void delete_nodes(node_ptr_t& root)
5925 {
5926 std::vector<node_pp_t> node_delete_list;
5927 node_delete_list.reserve(1000);
5928
5930
5931 for (std::size_t i = 0; i < node_delete_list.size(); ++i)
5932 {
5934 exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", reinterpret_cast<void*>(node)));
5935 delete node;
5936 node = reinterpret_cast<node_ptr_t>(0);
5937 }
5938 }
5939
5940 private:
5941
5943 {
5944 std::deque<node_ptr_t> node_list;
5945 node_list.push_back(root);
5946 node_delete_list.push_back(&root);
5947
5949 child_node_delete_list.reserve(1000);
5950
5951 while (!node_list.empty())
5952 {
5953 node_list.front()->collect_nodes(child_node_delete_list);
5954
5955 if (!child_node_delete_list.empty())
5956 {
5957 for (std::size_t i = 0; i < child_node_delete_list.size(); ++i)
5958 {
5960
5961 if (0 == (*node))
5962 {
5963 exprtk_debug(("ncd::collect_nodes() - null node encountered.\n"));
5964 }
5965
5966 node_list.push_back(*node);
5967 }
5968
5969 node_delete_list.insert(
5970 node_delete_list.end(),
5972
5973 child_node_delete_list.clear();
5974 }
5975
5976 node_list.pop_front();
5977 }
5978
5979 std::reverse(node_delete_list.begin(), node_delete_list.end());
5980 }
5981 };
5982
5983 template <typename NodeAllocator, typename T, std::size_t N>
5985 {
5986 for (std::size_t i = 0; i < N; ++i)
5987 {
5989 }
5990 }
5991
5992 template <typename NodeAllocator,
5993 typename T,
5994 typename Allocator,
5995 template <typename, typename> class Sequence>
5997 {
5998 for (std::size_t i = 0; i < b.size(); ++i)
5999 {
6001 }
6002
6003 b.clear();
6004 }
6005
6006 template <typename NodeAllocator, typename T>
6008 {
6009 if ((0 == node) || is_variable_node(node) || is_string_node(node))
6010 {
6011 return;
6012 }
6013
6015 ::delete_nodes(node);
6016 }
6017
6018 template <typename T>
6020 {
6021 if (0 != node)
6022 {
6024 ::delete_nodes(node);
6025 }
6026 }
6027
6028 template <typename Node>
6030 {
6032 typedef std::pair<node_ptr_t,bool> nb_pair_t;
6033
6035 : depth_set(false)
6036 , depth(0)
6037 {}
6038
6040 {}
6041
6042 virtual std::size_t node_depth() const { return 1; }
6043
6044 std::size_t compute_node_depth(const Node* const& node) const
6045 {
6046 if (!depth_set)
6047 {
6048 depth = 1 + (node ? node->node_depth() : 0);
6049 depth_set = true;
6050 }
6051
6052 return depth;
6053 }
6054
6055 std::size_t compute_node_depth(const nb_pair_t& branch) const
6056 {
6057 if (!depth_set)
6058 {
6059 depth = 1 + (branch.first ? branch.first->node_depth() : 0);
6060 depth_set = true;
6061 }
6062
6063 return depth;
6064 }
6065
6066 template <std::size_t N>
6067 std::size_t compute_node_depth(const nb_pair_t (&branch)[N]) const
6068 {
6069 if (!depth_set)
6070 {
6071 depth = 0;
6072
6073 for (std::size_t i = 0; i < N; ++i)
6074 {
6075 if (branch[i].first)
6076 {
6077 depth = std::max(depth,branch[i].first->node_depth());
6078 }
6079 }
6080
6081 depth += 1;
6082 depth_set = true;
6083 }
6084
6085 return depth;
6086 }
6087
6088 template <typename BranchType>
6089 std::size_t max_node_depth(const BranchType& n0, const BranchType& n1) const
6090 {
6091 return std::max(compute_node_depth(n0), compute_node_depth(n1));
6092 }
6093
6094 template <typename BranchType>
6095 std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, const BranchType& n2) const
6096 {
6097 return std::max(compute_node_depth(n0),
6099 }
6100
6101 template <typename BranchType>
6102 std::size_t max_node_depth(const BranchType& n0, const BranchType& n1,
6103 const BranchType& n2, const BranchType& n3) const
6104 {
6105 return std::max(
6108 }
6109
6110 template <typename BranchType>
6111 std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1) const
6112 {
6113 if (!depth_set)
6114 {
6115 depth = 1 + max_node_depth(n0, n1);
6116 depth_set = true;
6117 }
6118
6119 return depth;
6120 }
6121
6122 template <typename BranchType>
6123 std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1,
6124 const BranchType& n2) const
6125 {
6126 if (!depth_set)
6127 {
6128 depth = 1 + max_node_depth(n0, n1, n2);
6129 depth_set = true;
6130 }
6131
6132 return depth;
6133 }
6134
6135 template <typename BranchType>
6136 std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1,
6137 const BranchType& n2, const BranchType& n3) const
6138 {
6139 if (!depth_set)
6140 {
6141 depth = 1 + max_node_depth(n0, n1, n2, n3);
6142 depth_set = true;
6143 }
6144
6145 return depth;
6146 }
6147
6148 template <typename Allocator,
6149 template <typename, typename> class Sequence>
6151 {
6152 if (!depth_set)
6153 {
6154 for (std::size_t i = 0; i < branch_list.size(); ++i)
6155 {
6156 if (branch_list[i])
6157 {
6159 }
6160 }
6161
6162 depth_set = true;
6163 }
6164
6165 return depth;
6166 }
6167
6168 template <typename Allocator,
6169 template <typename, typename> class Sequence>
6171 {
6172 if (!depth_set)
6173 {
6174 for (std::size_t i = 0; i < branch_list.size(); ++i)
6175 {
6176 if (branch_list[i].first)
6177 {
6179 }
6180 }
6181
6182 depth_set = true;
6183 }
6184
6185 return depth;
6186 }
6187
6188 mutable bool depth_set;
6189 mutable std::size_t depth;
6190
6191 template <typename NodeSequence>
6193 const bool deletable,
6195 {
6196 if ((0 != node) && deletable)
6197 {
6198 delete_node_list.push_back(const_cast<node_ptr_t*>(&node));
6199 }
6200 }
6201
6202 template <typename NodeSequence>
6203 void collect(const nb_pair_t& branch,
6205 {
6206 collect(branch.first, branch.second, delete_node_list);
6207 }
6208
6209 template <typename NodeSequence>
6215
6216 template <std::size_t N, typename NodeSequence>
6217 void collect(const nb_pair_t(&branch)[N],
6219 {
6220 for (std::size_t i = 0; i < N; ++i)
6221 {
6222 collect(branch[i].first, branch[i].second, delete_node_list);
6223 }
6224 }
6225
6226 template <typename Allocator,
6227 template <typename, typename> class Sequence,
6228 typename NodeSequence>
6231 {
6232 for (std::size_t i = 0; i < branch.size(); ++i)
6233 {
6234 collect(branch[i].first, branch[i].second, delete_node_list);
6235 }
6236 }
6237
6238 template <typename Allocator,
6239 template <typename, typename> class Sequence,
6240 typename NodeSequence>
6243 {
6244 for (std::size_t i = 0; i < branch_list.size(); ++i)
6245 {
6247 }
6248 }
6249
6250 template <typename Boolean,
6251 typename AllocatorT,
6252 typename AllocatorB,
6253 template <typename, typename> class Sequence,
6254 typename NodeSequence>
6258 {
6259 for (std::size_t i = 0; i < branch_list.size(); ++i)
6260 {
6262 }
6263 }
6264 };
6265
6266 template <typename Type>
6268 {
6269 private:
6270
6271 typedef Type value_type;
6275
6277 {
6278 public:
6279
6281 {}
6282
6283 inline value_ptr operator[](const std::size_t& index) const
6284 {
6285 return value_at(index);
6286 }
6287
6288 inline std::size_t size() const
6289 {
6290 return vector_size();
6291 }
6292
6293 inline std::size_t base_size() const
6294 {
6295 return vector_base_size();
6296 }
6297
6298 inline value_ptr data() const
6299 {
6300 return value_at(0);
6301 }
6302
6303 virtual inline bool rebaseable() const
6304 {
6305 return false;
6306 }
6307
6308 virtual void set_ref(value_ptr*)
6309 {}
6310
6311 virtual void remove_ref(value_ptr*)
6312 {}
6313
6315 {
6316 return reinterpret_cast<vector_view<Type>*>(0);
6317 }
6318
6319 protected:
6320
6321 virtual value_ptr value_at(const std::size_t&) const = 0;
6322 virtual std::size_t vector_size() const = 0;
6323 virtual std::size_t vector_base_size() const = 0;
6324 };
6325
6327 {
6328 public:
6329
6330 array_vector_impl(const Type* vec, const std::size_t& vec_size)
6331 : vec_(vec)
6332 , size_(vec_size)
6333 {}
6334
6335 protected:
6336
6337 value_ptr value_at(const std::size_t& index) const exprtk_override
6338 {
6339 assert(index < size_);
6340 return const_cast<const_value_ptr>(vec_ + index);
6341 }
6342
6344 {
6345 return size_;
6346 }
6347
6349 {
6350 return vector_size();
6351 }
6352
6353 private:
6354
6357
6358 const Type* vec_;
6359 const std::size_t size_;
6360 };
6361
6362 template <typename Allocator,
6363 template <typename, typename> class Sequence>
6365 {
6366 public:
6367
6369
6373
6374 protected:
6375
6376 value_ptr value_at(const std::size_t& index) const exprtk_override
6377 {
6378 assert(index < sequence_.size());
6379 return (&sequence_[index]);
6380 }
6381
6383 {
6384 return sequence_.size();
6385 }
6386
6388 {
6389 return vector_size();
6390 }
6391
6392 private:
6393
6396
6398 };
6399
6401 {
6402 public:
6403
6405
6411
6413 {
6414 vec_view_.set_ref(ref);
6415 }
6416
6418 {
6419 vec_view_.remove_ref(ref);
6420 }
6421
6423 {
6424 return true;
6425 }
6426
6431
6432 protected:
6433
6434 value_ptr value_at(const std::size_t& index) const exprtk_override
6435 {
6436 assert(index < vec_view_.size());
6437 return (&vec_view_[index]);
6438 }
6439
6441 {
6442 return vec_view_.size();
6443 }
6444
6446 {
6447 return vec_view_.base_size();
6448 }
6449
6450 private:
6451
6454
6456 };
6457
6459 {
6460 public:
6461
6463 const Type* vec,
6464 const std::size_t& vec_size)
6465 : vec_(vec)
6466 , size_(vec_size)
6468 {
6469 assert(vec_view_holder.rebaseable_instance());
6471 }
6472
6474 {}
6475
6476 protected:
6477
6478 value_ptr value_at(const std::size_t& index) const exprtk_override
6479 {
6480 assert(index < vector_size());
6481 return const_cast<const_value_ptr>(vec_ + index);
6482 }
6483
6485 {
6486 return vec_view_holder_.size();
6487 }
6488
6490 {
6491 return vec_view_holder_.base_size();
6492 }
6493
6495 {
6496 return true;
6497 }
6498
6503
6504 private:
6505
6508
6509 const Type* vec_;
6510 const std::size_t size_;
6512 };
6513
6514 public:
6515
6517
6518 vector_holder(Type* vec, const std::size_t& vec_size)
6520 {}
6521
6522 explicit vector_holder(const vds_t& vds)
6524 {}
6525
6526 template <typename Allocator>
6527 explicit vector_holder(std::vector<Type,Allocator>& vec)
6529 {}
6530
6534
6535 explicit vector_holder(vector_holder_t& vec_holder, const vds_t& vds)
6536 : vector_holder_base_(new(buffer)resizable_vector_impl(vec_holder, vds.data(), vds.size()))
6537 {}
6538
6539 inline value_ptr operator[](const std::size_t& index) const
6540 {
6541 return (*vector_holder_base_)[index];
6542 }
6543
6544 inline std::size_t size() const
6545 {
6546 return vector_holder_base_->size();
6547 }
6548
6549 inline std::size_t base_size() const
6550 {
6552 }
6553
6554 inline value_ptr data() const
6555 {
6556 return vector_holder_base_->data();
6557 }
6558
6560 {
6561 if (rebaseable())
6562 {
6564 }
6565 }
6566
6568 {
6569 if (rebaseable())
6570 {
6572 }
6573 }
6574
6575 bool rebaseable() const
6576 {
6578 }
6579
6584
6585 private:
6586
6589
6592 };
6593
6594 template <typename T>
6596 {
6597 public:
6598
6600 {
6601 return std::numeric_limits<T>::quiet_NaN();
6602 }
6603
6608 };
6609
6610 template <typename T, std::size_t N>
6611 inline void construct_branch_pair(std::pair<expression_node<T>*,bool> (&branch)[N],
6613 const std::size_t& index)
6614 {
6615 if (b && (index < N))
6616 {
6617 branch[index] = std::make_pair(b,branch_deletable(b));
6618 }
6619 }
6620
6621 template <typename T>
6622 inline void construct_branch_pair(std::pair<expression_node<T>*,bool>& branch, expression_node<T>* b)
6623 {
6624 if (b)
6625 {
6626 branch = std::make_pair(b,branch_deletable(b));
6627 }
6628 }
6629
6630 template <std::size_t N, typename T>
6631 inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N],
6633 expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0),
6634 expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0),
6635 expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0),
6636 expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0),
6637 expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0),
6638 expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0),
6639 expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0),
6640 expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0),
6641 expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0))
6642 {
6643 construct_branch_pair(branch, b0, 0);
6644 construct_branch_pair(branch, b1, 1);
6645 construct_branch_pair(branch, b2, 2);
6646 construct_branch_pair(branch, b3, 3);
6647 construct_branch_pair(branch, b4, 4);
6648 construct_branch_pair(branch, b5, 5);
6649 construct_branch_pair(branch, b6, 6);
6650 construct_branch_pair(branch, b7, 7);
6651 construct_branch_pair(branch, b8, 8);
6652 construct_branch_pair(branch, b9, 9);
6653 }
6654
6655 template <typename T>
6657 {
6658 public:
6659
6661 typedef std::pair<expression_ptr,bool> branch_t;
6662
6663 explicit null_eq_node(expression_ptr branch, const bool equality = true)
6665 {
6667 assert(valid());
6668 }
6669
6671 {
6672 const T v = branch_.first->value();
6673 const bool result = details::numeric::is_nan(v);
6674
6675 if (result)
6676 return equality_ ? T(1) : T(0);
6677 else
6678 return equality_ ? T(0) : T(1);
6679 }
6680
6685
6686 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6687 {
6688 return branch_.first;
6689 }
6690
6692 {
6693 return branch_.first;
6694 }
6695
6700
6705
6706 private:
6707
6710 };
6711
6712 template <typename T>
6714 {
6715 public:
6716
6717 explicit literal_node(const T& v)
6718 : value_(v)
6719 {}
6720
6722 {
6723 return value_;
6724 }
6725
6730
6731 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6732 {
6733 return reinterpret_cast<expression_node<T>*>(0);
6734 }
6735
6736 private:
6737
6740
6741 const T value_;
6742 };
6743
6744 template <typename T>
6745 struct range_pack;
6746
6747 template <typename T>
6748 struct range_data_type;
6749
6750 template <typename T>
6752 {
6753 public:
6754
6756
6758 {}
6759
6760 virtual range_t& range_ref() = 0;
6761
6762 virtual const range_t& range_ref() const = 0;
6763 };
6764
6765 #ifndef exprtk_disable_string_capabilities
6766 template <typename T>
6768 {
6769 public:
6770
6772
6774 {}
6775
6776 virtual std::string str () const = 0;
6777
6778 virtual char_cptr base() const = 0;
6779
6780 virtual std::size_t size() const = 0;
6781 };
6782
6783 template <typename T>
6785 : public expression_node <T>
6786 , public string_base_node<T>
6787 , public range_interface <T>
6788 {
6789 public:
6790
6792
6793 explicit string_literal_node(const std::string& v)
6794 : value_(v)
6795 {
6796 rp_.n0_c = std::make_pair<bool,std::size_t>(true, 0);
6797 rp_.n1_c = std::make_pair<bool,std::size_t>(true, v.size());
6798 rp_.cache.first = rp_.n0_c.second;
6799 rp_.cache.second = rp_.n1_c.second;
6800 }
6801
6803 {
6804 return std::numeric_limits<T>::quiet_NaN();
6805 }
6806
6811
6812 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6813 {
6814 return reinterpret_cast<expression_node<T>*>(0);
6815 }
6816
6818 {
6819 return value_;
6820 }
6821
6823 {
6824 return value_.data();
6825 }
6826
6828 {
6829 return value_.size();
6830 }
6831
6833 {
6834 return rp_;
6835 }
6836
6838 {
6839 return rp_;
6840 }
6841
6842 private:
6843
6846
6847 const std::string value_;
6849 };
6850 #endif
6851
6852 template <typename T>
6853 class unary_node : public expression_node<T>
6854 {
6855 public:
6856
6858 typedef std::pair<expression_ptr,bool> branch_t;
6859
6866
6868 {
6869 return numeric::process<T>
6870 (operation_,branch_.first->value());
6871 }
6872
6877
6879 {
6880 return operation_;
6881 }
6882
6883 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6884 {
6885 return branch_.first;
6886 }
6887
6889 {
6890 return branch_.first && branch_.first->valid();
6891 }
6892
6893 inline void release()
6894 {
6895 branch_.second = false;
6896 }
6897
6902
6907
6908 private:
6909
6912 };
6913
6914 template <typename T>
6916 {
6917 public:
6918
6920 typedef std::pair<expression_ptr,bool> branch_t;
6921
6930
6932 {
6933 return numeric::process<T>
6934 (
6935 operation_,
6936 branch_[0].first->value(),
6937 branch_[1].first->value()
6938 );
6939 }
6940
6945
6947 {
6948 return operation_;
6949 }
6950
6951 inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
6952 {
6953 assert(index < 2);
6954 return branch_[index].first;
6955 }
6956
6958 {
6959 return
6960 branch_[0].first && branch_[0].first->valid() &&
6961 branch_[1].first && branch_[1].first->valid() ;
6962 }
6963
6968
6973
6974 private:
6975
6978 };
6979
6980 template <typename T, typename Operation>
6982 {
6983 public:
6984
6986 typedef std::pair<expression_ptr,bool> branch_t;
6987
6993
6995 {
6996 const T arg0 = branch_[0].first->value();
6997 const T arg1 = branch_[1].first->value();
6998 return Operation::process(arg0,arg1);
6999 }
7000
7005
7007 {
7008 return Operation::operation();
7009 }
7010
7011 inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
7012 {
7013 assert(index < 2);
7014 return branch_[index].first;
7015 }
7016
7018 {
7019 return
7020 branch_[0].first && branch_[0].first->valid() &&
7021 branch_[1].first && branch_[1].first->valid() ;
7022 }
7023
7028
7033
7034 protected:
7035
7037 };
7038
7039 template <typename T>
7041 {
7042 public:
7043
7045 typedef std::pair<expression_ptr,bool> branch_t;
7046
7056
7058 {
7059 const T arg0 = branch_[0].first->value();
7060 const T arg1 = branch_[1].first->value();
7061 const T arg2 = branch_[2].first->value();
7062
7063 switch (operation_)
7064 {
7065 case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1));
7066
7067 case e_clamp : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1);
7068
7069 case e_iclamp : if ((arg1 <= arg0) || (arg1 >= arg2))
7070 return arg1;
7071 else
7072 return ((T(2) * arg1 <= (arg2 + arg0)) ? arg0 : arg2);
7073
7074 default : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n"));
7075 return std::numeric_limits<T>::quiet_NaN();
7076 }
7077 }
7078
7083
7085 {
7086 return
7087 branch_[0].first && branch_[0].first->valid() &&
7088 branch_[1].first && branch_[1].first->valid() &&
7089 branch_[2].first && branch_[2].first->valid() ;
7090 }
7091
7096
7101
7102 protected:
7103
7106 };
7107
7108 template <typename T>
7110 {
7111 public:
7112
7114 typedef std::pair<expression_ptr,bool> branch_t;
7115
7125
7127 {
7128 return std::numeric_limits<T>::quiet_NaN();
7129 }
7130
7135
7140
7145
7147 {
7148 return
7149 branch_[0].first && branch_[0].first->valid() &&
7150 branch_[1].first && branch_[1].first->valid() &&
7151 branch_[2].first && branch_[2].first->valid() &&
7152 branch_[3].first && branch_[3].first->valid() ;
7153 }
7154
7155 protected:
7156
7159 };
7160
7161 template <typename T>
7163 {
7164 public:
7165
7167 typedef std::pair<expression_ptr,bool> branch_t;
7168
7178
7180 {
7181 if (is_true(condition_))
7182 return consequent_.first->value();
7183 else
7184 return alternative_.first->value();
7185 }
7186
7191
7193 {
7194 return
7195 condition_ .first && condition_ .first->valid() &&
7196 consequent_ .first && consequent_ .first->valid() &&
7197 alternative_.first && alternative_.first->valid() ;
7198 }
7199
7206
7212
7213 private:
7214
7218 };
7219
7220 template <typename T>
7222 {
7223 public:
7224
7225 // Consequent only conditional statement node
7227 typedef std::pair<expression_ptr,bool> branch_t;
7228
7236
7238 {
7239 if (is_true(condition_))
7240 return consequent_.first->value();
7241 else
7242 return std::numeric_limits<T>::quiet_NaN();
7243 }
7244
7249
7251 {
7252 return
7253 condition_ .first && condition_ .first->valid() &&
7254 consequent_.first && consequent_.first->valid() ;
7255 }
7256
7262
7268
7269 private:
7270
7273 };
7274
7275 #ifndef exprtk_disable_break_continue
7276 template <typename T>
7278 {
7279 public:
7280
7281 explicit break_exception(const T& v)
7282 : value(v)
7283 {}
7284
7286 };
7287
7289
7290 template <typename T>
7292 {
7293 public:
7294
7296 typedef std::pair<expression_ptr,bool> branch_t;
7297
7302
7304 {
7305 const T result = return_.first ?
7306 return_.first->value() :
7307 std::numeric_limits<T>::quiet_NaN();
7308
7309 throw break_exception<T>(result);
7310
7311 #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
7312 return std::numeric_limits<T>::quiet_NaN();
7313 #endif
7314 }
7315
7320
7325
7330
7331 private:
7332
7334 };
7335
7336 template <typename T>
7338 {
7339 public:
7340
7342 {
7343 throw continue_exception();
7344 #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
7345 return std::numeric_limits<T>::quiet_NaN();
7346 #endif
7347 }
7348
7353 };
7354 #endif
7355
7404
7405 template <typename T>
7407 {
7408 public:
7409
7411 typedef std::pair<expression_ptr,bool> branch_t;
7412
7420
7422 {
7423 T result = T(0);
7424
7425 while (is_true(condition_))
7426 {
7427 result = loop_body_.first->value();
7428 }
7429
7430 return result;
7431 }
7432
7437
7439 {
7440 return
7441 condition_.first && condition_.first->valid() &&
7442 loop_body_.first && loop_body_.first->valid() ;
7443 }
7444
7450
7455
7456 protected:
7457
7460 };
7461
7462 template <typename T>
7464 : public while_loop_node<T>
7465 , public loop_runtime_checker
7466 {
7467 public:
7468
7471
7480
7482 {
7483
7484 T result = T(0);
7485
7487
7489 {
7490 result = parent_t::loop_body_.first->value();
7491 }
7492
7493 return result;
7494 }
7495
7496 using parent_t::valid;
7497
7503 };
7504
7505 template <typename T>
7507 {
7508 public:
7509
7511 typedef std::pair<expression_ptr,bool> branch_t;
7512
7520
7522 {
7523 T result = T(0);
7524
7525 do
7526 {
7527 result = loop_body_.first->value();
7528 }
7529 while (is_false(condition_.first));
7530
7531 return result;
7532 }
7533
7538
7540 {
7541 return
7542 condition_.first && condition_.first->valid() &&
7543 loop_body_.first && loop_body_.first->valid() ;
7544 }
7545
7551
7556
7557 protected:
7558
7561 };
7562
7563 template <typename T>
7565 : public repeat_until_loop_node<T>
7566 , public loop_runtime_checker
7567 {
7568 public:
7569
7572
7581
7583 {
7584 T result = T(0);
7585
7587
7588 do
7589 {
7590 result = parent_t::loop_body_.first->value();
7591 }
7593
7594 return result;
7595 }
7596
7597 using parent_t::valid;
7598
7600 {
7601 return parent_t::valid() &&
7603 }
7604 };
7605
7606 template <typename T>
7608 {
7609 public:
7610
7612 typedef std::pair<expression_ptr,bool> branch_t;
7613
7625
7627 {
7628 T result = T(0);
7629
7630 if (initialiser_.first)
7631 initialiser_.first->value();
7632
7633 if (incrementor_.first)
7634 {
7635 while (is_true(condition_))
7636 {
7637 result = loop_body_.first->value();
7638 incrementor_.first->value();
7639 }
7640 }
7641 else
7642 {
7643 while (is_true(condition_))
7644 {
7645 result = loop_body_.first->value();
7646 }
7647 }
7648
7649 return result;
7650 }
7651
7656
7658 {
7659 return condition_.first && loop_body_.first;
7660 }
7661
7669
7675
7676 protected:
7677
7682 };
7683
7684 template <typename T>
7686 : public for_loop_node<T>
7687 , public loop_runtime_checker
7688 {
7689 public:
7690
7693
7704
7706 {
7707 T result = T(0);
7708
7710
7712 parent_t::initialiser_.first->value();
7713
7715 {
7717 {
7718 result = parent_t::loop_body_.first->value();
7719 parent_t::incrementor_.first->value();
7720 }
7721 }
7722 else
7723 {
7725 {
7726 result = parent_t::loop_body_.first->value();
7727 }
7728 }
7729
7730 return result;
7731 }
7732
7733 using parent_t::valid;
7734
7736 {
7737 return parent_t::valid() &&
7739 }
7740 };
7741
7742 #ifndef exprtk_disable_break_continue
7743 template <typename T>
7745 {
7746 public:
7747
7750
7753 : parent_t(condition, loop_body)
7754 {
7756 }
7757
7759 {
7760 T result = T(0);
7761
7762 while (is_true(parent_t::condition_))
7763 {
7764 try
7765 {
7766 result = parent_t::loop_body_.first->value();
7767 }
7768 catch(const break_exception<T>& e)
7769 {
7770 return e.value;
7771 }
7772 catch(const continue_exception&)
7773 {}
7774 }
7775
7776 return result;
7777 }
7778 };
7779
7780 template <typename T>
7782 : public while_loop_bc_node<T>
7783 , public loop_runtime_checker
7784 {
7785 public:
7786
7789
7798
7800 {
7801 T result = T(0);
7802
7804
7806 {
7807 try
7808 {
7809 result = parent_t::loop_body_.first->value();
7810 }
7811 catch(const break_exception<T>& e)
7812 {
7813 return e.value;
7814 }
7815 catch(const continue_exception&)
7816 {}
7817 }
7818
7819 return result;
7820 }
7821
7822 using parent_t::valid;
7823
7825 {
7826 return parent_t::valid() &&
7828 }
7829 };
7830
7831 template <typename T>
7833 {
7834 public:
7835
7838
7845
7847 {
7848 T result = T(0);
7849
7850 do
7851 {
7852 try
7853 {
7854 result = parent_t::loop_body_.first->value();
7855 }
7856 catch(const break_exception<T>& e)
7857 {
7858 return e.value;
7859 }
7860 catch(const continue_exception&)
7861 {}
7862 }
7864
7865 return result;
7866 }
7867 };
7868
7869 template <typename T>
7871 : public repeat_until_loop_bc_node<T>
7872 , public loop_runtime_checker
7873 {
7874 public:
7875
7878
7887
7889 {
7890 T result = T(0);
7891
7893
7894 do
7895 {
7896 try
7897 {
7898 result = parent_t::loop_body_.first->value();
7899 }
7900 catch(const break_exception<T>& e)
7901 {
7902 return e.value;
7903 }
7904 catch(const continue_exception&)
7905 {}
7906 }
7908
7909 return result;
7910 }
7911
7912 using parent_t::valid;
7913
7915 {
7916 return parent_t::valid() &&
7918 }
7919 };
7920
7921 template <typename T>
7923 {
7924 public:
7925
7928
7937
7939 {
7940 T result = T(0);
7941
7943 parent_t::initialiser_.first->value();
7944
7946 {
7947 while (is_true(parent_t::condition_))
7948 {
7949 try
7950 {
7951 result = parent_t::loop_body_.first->value();
7952 }
7953 catch(const break_exception<T>& e)
7954 {
7955 return e.value;
7956 }
7957 catch(const continue_exception&)
7958 {}
7959
7960 parent_t::incrementor_.first->value();
7961 }
7962 }
7963 else
7964 {
7965 while (is_true(parent_t::condition_))
7966 {
7967 try
7968 {
7969 result = parent_t::loop_body_.first->value();
7970 }
7971 catch(const break_exception<T>& e)
7972 {
7973 return e.value;
7974 }
7975 catch(const continue_exception&)
7976 {}
7977 }
7978 }
7979
7980 return result;
7981 }
7982 };
7983
7984 template <typename T>
7986 : public for_loop_bc_node<T>
7987 , public loop_runtime_checker
7988 {
7989 public:
7990
7993
8004
8006 {
8007 T result = T(0);
8008
8010
8012 parent_t::initialiser_.first->value();
8013
8015 {
8017 {
8018 try
8019 {
8020 result = parent_t::loop_body_.first->value();
8021 }
8022 catch(const break_exception<T>& e)
8023 {
8024 return e.value;
8025 }
8026 catch(const continue_exception&)
8027 {}
8028
8029 parent_t::incrementor_.first->value();
8030 }
8031 }
8032 else
8033 {
8035 {
8036 try
8037 {
8038 result = parent_t::loop_body_.first->value();
8039 }
8040 catch(const break_exception<T>& e)
8041 {
8042 return e.value;
8043 }
8044 catch(const continue_exception&)
8045 {}
8046 }
8047 }
8048
8049 return result;
8050 }
8051
8052 using parent_t::valid;
8053
8055 {
8056 return parent_t::valid() &&
8058 }
8059 };
8060 #endif
8061
8062 template <typename T>
8064 {
8065 public:
8066
8068 typedef std::pair<expression_ptr,bool> branch_t;
8069
8070 template <typename Allocator,
8071 template <typename, typename> class Sequence>
8073 {
8074 if (1 != (arg_list.size() & 1))
8075 return;
8076
8077 arg_list_.resize(arg_list.size());
8078
8079 for (std::size_t i = 0; i < arg_list.size(); ++i)
8080 {
8081 if (arg_list[i] && arg_list[i]->valid())
8082 {
8084 }
8085 else
8086 {
8087 arg_list_.clear();
8088 return;
8089 }
8090 }
8091
8092 assert(valid());
8093 }
8094
8096 {
8097 const std::size_t upper_bound = (arg_list_.size() - 1);
8098
8099 for (std::size_t i = 0; i < upper_bound; i += 2)
8100 {
8101 expression_ptr condition = arg_list_[i ].first;
8102 expression_ptr consequent = arg_list_[i + 1].first;
8103
8104 if (is_true(condition))
8105 {
8106 return consequent->value();
8107 }
8108 }
8109
8110 return arg_list_[upper_bound].first->value();
8111 }
8112
8117
8119 {
8120 return !arg_list_.empty();
8121 }
8122
8127
8132
8133 protected:
8134
8135 std::vector<branch_t> arg_list_;
8136 };
8137
8138 template <typename T, typename Switch_N>
8140 {
8141 public:
8142
8144
8145 template <typename Allocator,
8146 template <typename, typename> class Sequence>
8150
8152 {
8153 return Switch_N::process(switch_node<T>::arg_list_);
8154 }
8155 };
8156
8157 template <typename T>
8159 {
8160 public:
8161
8163 typedef std::pair<expression_ptr,bool> branch_t;
8164
8165 template <typename Allocator,
8166 template <typename, typename> class Sequence>
8168 {
8169 if (0 != (arg_list.size() & 1))
8170 return;
8171
8172 arg_list_.resize(arg_list.size());
8173
8174 for (std::size_t i = 0; i < arg_list.size(); ++i)
8175 {
8176 if (arg_list[i] && arg_list[i]->valid())
8177 {
8179 }
8180 else
8181 {
8182 arg_list_.clear();
8183 return;
8184 }
8185 }
8186
8187 assert(valid());
8188 }
8189
8191 {
8192 const std::size_t upper_bound = (arg_list_.size() - 1);
8193
8194 T result = T(0);
8195
8196 for (std::size_t i = 0; i < upper_bound; i += 2)
8197 {
8198 expression_ptr condition = arg_list_[i ].first;
8199 expression_ptr consequent = arg_list_[i + 1].first;
8200
8201 if (is_true(condition))
8202 {
8203 result = consequent->value();
8204 }
8205 }
8206
8207 return result;
8208 }
8209
8214
8216 {
8217 return !arg_list_.empty() && (0 == (arg_list_.size() % 2));
8218 }
8219
8224
8229
8230 private:
8231
8232 std::vector<branch_t> arg_list_;
8233 };
8234
8235 template <typename T>
8237 {
8238 public:
8239
8240 virtual ~ivariable()
8241 {}
8242
8243 virtual T& ref() = 0;
8244 virtual const T& ref() const = 0;
8245 };
8246
8247 template <typename T>
8249 : public expression_node<T>
8250 , public ivariable <T>
8251 {
8252 public:
8253
8255
8256 explicit variable_node()
8257 : value_(&null_value)
8258 {}
8259
8260 explicit variable_node(T& v)
8261 : value_(&v)
8262 {}
8263
8264 inline bool operator <(const variable_node<T>& v) const
8265 {
8266 return this < (&v);
8267 }
8268
8270 {
8271 return (*value_);
8272 }
8273
8275 {
8276 return (*value_);
8277 }
8278
8279 inline const T& ref() const exprtk_override
8280 {
8281 return (*value_);
8282 }
8283
8288
8289 private:
8290
8292 };
8293
8294 template <typename T>
8295 T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN());
8296
8297 template <typename T>
8299 {
8301 typedef std::pair<std::size_t,std::size_t> cached_range_t;
8302
8310
8311 void clear()
8312 {
8313 n0_e = std::make_pair(false,expression_node_ptr(0));
8314 n1_e = std::make_pair(false,expression_node_ptr(0));
8315 n0_c = std::make_pair(false,0);
8316 n1_c = std::make_pair(false,0);
8317 cache = std::make_pair(0,0);
8318 }
8319
8320 void free()
8321 {
8322 if (n0_e.first && n0_e.second)
8323 {
8324 n0_e.first = false;
8325
8326 if (
8327 !is_variable_node(n0_e.second) &&
8328 !is_string_node (n0_e.second)
8329 )
8330 {
8331 destroy_node(n0_e.second);
8332 }
8333 }
8334
8335 if (n1_e.first && n1_e.second)
8336 {
8337 n1_e.first = false;
8338
8339 if (
8340 !is_variable_node(n1_e.second) &&
8341 !is_string_node (n1_e.second)
8342 )
8343 {
8344 destroy_node(n1_e.second);
8345 }
8346 }
8347 }
8348
8349 bool const_range() const
8350 {
8351 return ( n0_c.first && n1_c.first) &&
8352 (!n0_e.first && !n1_e.first);
8353 }
8354
8355 bool var_range() const
8356 {
8357 return ( n0_e.first && n1_e.first) &&
8358 (!n0_c.first && !n1_c.first);
8359 }
8360
8361 bool operator() (std::size_t& r0, std::size_t& r1,
8362 const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
8363 {
8364 if (n0_c.first)
8365 r0 = n0_c.second;
8366 else if (n0_e.first)
8367 {
8368 r0 = static_cast<std::size_t>(details::numeric::to_int64(n0_e.second->value()));
8369 }
8370 else
8371 return false;
8372
8373 if (n1_c.first)
8374 r1 = n1_c.second;
8375 else if (n1_e.first)
8376 {
8377 r1 = static_cast<std::size_t>(details::numeric::to_int64(n1_e.second->value()));
8378 }
8379 else
8380 return false;
8381
8382 if (
8383 (std::numeric_limits<std::size_t>::max() != size) &&
8384 (std::numeric_limits<std::size_t>::max() == r1 )
8385 )
8386 {
8387 r1 = size;
8388 }
8389
8390 cache.first = r0;
8391 cache.second = r1;
8392
8393 #ifndef exprtk_enable_range_runtime_checks
8394 return (r0 <= r1);
8395 #else
8396 return range_runtime_check(r0, r1, size);
8397 #endif
8398 }
8399
8400 inline std::size_t const_size() const
8401 {
8402 return (n1_c.second - n0_c.second);
8403 }
8404
8405 inline std::size_t cache_size() const
8406 {
8407 return (cache.second - cache.first);
8408 }
8409
8410 std::pair<bool,expression_node_ptr> n0_e;
8411 std::pair<bool,expression_node_ptr> n1_e;
8412 std::pair<bool,std::size_t > n0_c;
8413 std::pair<bool,std::size_t > n1_c;
8415
8416 #ifdef exprtk_enable_range_runtime_checks
8417 bool range_runtime_check(const std::size_t r0,
8418 const std::size_t r1,
8419 const std::size_t size) const
8420 {
8421 if (r0 > size)
8422 {
8423 throw std::runtime_error("range error: (r0 < 0) || (r0 > size)");
8424 #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
8425 return false;
8426 #endif
8427 }
8428
8429 if (r1 > size)
8430 {
8431 throw std::runtime_error("range error: (r1 < 0) || (r1 > size)");
8432 #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
8433 return false;
8434 #endif
8435 }
8436
8437 return (r0 <= r1);
8438 }
8439 #endif
8440 };
8441
8442 template <typename T>
8443 class string_base_node;
8444
8445 template <typename T>
8447 {
8450
8452 : range(0)
8453 , data (0)
8454 , size (0)
8455 , type_size(0)
8456 , str_node (0)
8457 {}
8458
8460 void* data;
8461 std::size_t size;
8462 std::size_t type_size;
8464 };
8465
8466 template <typename T> class vector_node;
8467
8468 template <typename T>
8470 {
8471 public:
8472
8475
8477 {}
8478
8479 virtual std::size_t size () const = 0;
8480
8481 virtual std::size_t base_size() const = 0;
8482
8483 virtual vector_node_ptr vec () const = 0;
8484
8485 virtual vector_node_ptr vec () = 0;
8486
8487 virtual vds_t& vds () = 0;
8488
8489 virtual const vds_t& vds () const = 0;
8490
8491 virtual bool side_effect () const { return false; }
8492 };
8493
8494 template <typename T>
8496 : public expression_node <T>
8497 , public vector_interface<T>
8498 {
8499 public:
8500
8505
8509 {
8511 }
8512
8515 , vds_(vds)
8516 {}
8517
8519 {
8520 assert(valid());
8522 }
8523
8525 {
8526 return vds().data()[0];
8527 }
8528
8530 {
8531 return const_cast<vector_node_ptr>(this);
8532 }
8533
8535 {
8536 return this;
8537 }
8538
8543
8545 {
8546 return vector_holder_;
8547 }
8548
8550 {
8551 return vec_holder().size();
8552 }
8553
8555 {
8556 return vec_holder().base_size();
8557 }
8558
8560 {
8561 return vds_;
8562 }
8563
8565 {
8566 return vds_;
8567 }
8568
8570 {
8571 return (*vector_holder_);
8572 }
8573
8575 {
8576 return (*vector_holder_);
8577 }
8578
8579 private:
8580
8583 };
8584
8585 template <typename T>
8587 : public expression_node <T>
8588 {
8589 public:
8590
8593
8597
8599 {
8600 assert(valid());
8601 }
8602
8604 {
8606 return static_cast<T>(vector_holder_->size());
8607 }
8608
8613
8615 {
8616 return vector_holder_ && vector_holder_->size();
8617 }
8618
8620 {
8621 return vector_holder_;
8622 }
8623
8624 private:
8625
8627 };
8628
8629 template <typename T>
8631 : public expression_node<T>
8632 , public ivariable <T>
8633 {
8634 public:
8635
8639 typedef std::pair<expression_ptr,bool> branch_t;
8640
8651
8653 {
8654 return *access_vector();
8655 }
8656
8658 {
8659 return *access_vector();
8660 }
8661
8662 inline const T& ref() const exprtk_override
8663 {
8664 return *access_vector();
8665 }
8666
8671
8673 {
8674 return
8676 index_.first &&
8677 vector_node_.first &&
8678 index_.first->valid() &&
8679 vector_node_.first->valid();
8680 }
8681
8683 {
8684 return (*vector_holder_);
8685 }
8686
8692
8698
8699 private:
8700
8701 inline T* access_vector() const
8702 {
8703 vector_node_.first->value();
8704 return (vector_base_ + details::numeric::to_uint64(index_.first->value()));
8705 }
8706
8711 };
8712
8713 template <typename T>
8715 : public expression_node<T>
8716 , public ivariable <T>
8717 {
8718 public:
8719
8723 typedef std::pair<expression_ptr,bool> branch_t;
8724
8726 const std::size_t index,
8728 : index_(index)
8730 , vector_base_((*vec_holder)[0])
8731 {
8733 assert(valid());
8734 }
8735
8737 {
8738 return *access_vector();
8739 }
8740
8742 {
8743 return *access_vector();
8744 }
8745
8746 inline const T& ref() const exprtk_override
8747 {
8748 return *access_vector();
8749 }
8750
8755
8757 {
8758 return
8760 vector_node_.first &&
8761 vector_node_.first->valid();
8762 }
8763
8765 {
8766 return (*vector_holder_);
8767 }
8768
8773
8778
8779 private:
8780
8781 inline T* access_vector() const
8782 {
8783 vector_node_.first->value();
8784 return (vector_base_ + index_);
8785 }
8786
8787 const std::size_t index_;
8791 };
8792
8793 template <typename T>
8795 : public expression_node<T>
8796 , public ivariable <T>
8797 {
8798 public:
8799
8803 typedef std::pair<expression_ptr,bool> branch_t;
8804
8818
8820 {
8821 return *access_vector();
8822 }
8823
8825 {
8826 return *access_vector();
8827 }
8828
8829 inline const T& ref() const exprtk_override
8830 {
8831 return *access_vector();
8832 }
8833
8838
8840 {
8841 return
8843 index_.first &&
8844 vector_node_.first &&
8845 index_.first->valid() &&
8846 vector_node_.first->valid();
8847 }
8848
8850 {
8851 return (*vector_holder_);
8852 }
8853
8859
8865
8866 private:
8867
8868 inline T* access_vector() const
8869 {
8870 const _uint64_t index = details::numeric::to_uint64(index_.first->value());
8871 vector_node_.first->value();
8872
8873 if (index <= max_vector_index_)
8874 {
8875 return (vector_holder_->data() + index);
8876 }
8877
8879
8881 context.base_ptr = reinterpret_cast<void*>(vector_base_);
8882 context.end_ptr = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
8883 context.access_ptr = reinterpret_cast<void*>(vector_base_ + index);
8884 context.type_size = sizeof(T);
8885
8887 reinterpret_cast<T*>(context.access_ptr) :
8888 vector_base_ ;
8889 }
8890
8896 const std::size_t max_vector_index_;
8897 };
8898
8899 template <typename T>
8901 : public expression_node<T>
8902 , public ivariable <T>
8903 {
8904 public:
8905
8909 typedef std::pair<expression_ptr,bool> branch_t;
8910
8912 const std::size_t index,
8915 : index_(index)
8916 , max_vector_index_(vec_holder->size() - 1)
8918 , vector_base_((*vec_holder)[0])
8920 {
8922 assert(valid());
8923 }
8924
8926 {
8927 return *access_vector();
8928 }
8929
8931 {
8932 return *access_vector();
8933 }
8934
8935 inline const T& ref() const exprtk_override
8936 {
8937 return *access_vector();
8938 }
8939
8944
8946 {
8947 return
8949 vector_node_.first &&
8950 vector_node_.first->valid();
8951 }
8952
8954 {
8955 return (*vector_holder_);
8956 }
8957
8962
8967
8968 private:
8969
8970 inline T* access_vector() const
8971 {
8972 vector_node_.first->value();
8973
8975 {
8976 return (vector_holder_->data() + index_);
8977 }
8978
8980
8982 context.base_ptr = reinterpret_cast<void*>(vector_base_);
8983 context.end_ptr = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
8984 context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_);
8985 context.type_size = sizeof(T);
8986
8988 reinterpret_cast<T*>(context.access_ptr) :
8989 vector_base_ ;
8990 }
8991
8992 const std::size_t index_;
8993 const std::size_t max_vector_index_;
8998 };
8999
9000 template <typename T>
9002 : public expression_node<T>
9003 , public ivariable <T>
9004 {
9005 public:
9006
9011 typedef std::pair<expression_ptr,bool> branch_t;
9012
9022
9024 {
9025 return *access_vector();
9026 }
9027
9029 {
9030 return *access_vector();
9031 }
9032
9033 inline const T& ref() const exprtk_override
9034 {
9035 return *access_vector();
9036 }
9037
9042
9044 {
9045 return
9047 index_.first &&
9048 vector_node_.first &&
9049 index_.first->valid() &&
9050 vector_node_.first->valid();
9051 }
9052
9054 {
9055 return (*vector_holder_);
9056 }
9057
9063
9069
9070 private:
9071
9072 inline T* access_vector() const
9073 {
9074 vector_node_.first->value();
9075 return (vector_holder_->data() + details::numeric::to_uint64(index_.first->value()));
9076 }
9077
9081 };
9082
9083 template <typename T>
9085 : public expression_node<T>
9086 , public ivariable <T>
9087 {
9088 public:
9089
9093 typedef std::pair<expression_ptr,bool> branch_t;
9094
9096 const std::size_t index,
9098 : index_(index)
9100 {
9102 assert(valid());
9103 }
9104
9106 {
9107 vector_node_.first->value();
9108 return ref();;
9109 }
9110
9112 {
9113 return *(vector_holder_->data() + index_);
9114 }
9115
9116 inline const T& ref() const exprtk_override
9117 {
9118 return *(vector_holder_->data() + index_);
9119 }
9120
9125
9127 {
9128 return
9130 vector_node_.first &&
9131 vector_node_.first->valid();
9132 }
9133
9135 {
9136 return (*vector_holder_);
9137 }
9138
9143
9148
9149 private:
9150
9151 const std::size_t index_;
9154 };
9155
9156 template <typename T>
9158 : public expression_node<T>
9159 , public ivariable <T>
9160 {
9161 public:
9162
9166 typedef std::pair<expression_ptr,bool> branch_t;
9167
9179
9181 {
9182 return *access_vector();
9183 }
9184
9186 {
9187 return *access_vector();
9188 }
9189
9190 inline const T& ref() const exprtk_override
9191 {
9192 return *access_vector();
9193 }
9194
9199
9201 {
9202 return
9204 index_.first &&
9205 vector_node_.first &&
9206 index_.first->valid() &&
9207 vector_node_.first->valid();
9208 }
9209
9211 {
9212 return (*vector_holder_);
9213 }
9214
9220
9226
9227 private:
9228
9229 inline T* access_vector() const
9230 {
9231 vector_node_.first->value();
9232 const _uint64_t index = details::numeric::to_uint64(index_.first->value());
9233
9234 if (index <= (vector_holder_->size() - 1))
9235 {
9236 return (vector_holder_->data() + index);
9237 }
9238
9240
9242 context.base_ptr = reinterpret_cast<void*>(vector_holder_->data());
9243 context.end_ptr = reinterpret_cast<void*>(vector_holder_->data() + vector_holder_->size());
9244 context.access_ptr = reinterpret_cast<void*>(vector_holder_->data() + index);
9245 context.type_size = sizeof(T);
9246
9248 reinterpret_cast<T*>(context.access_ptr) :
9249 vector_holder_->data() ;
9250 }
9251
9256 };
9257
9258 template <typename T>
9260 : public expression_node<T>
9261 , public ivariable <T>
9262 {
9263 public:
9264
9268 typedef std::pair<expression_ptr,bool> branch_t;
9269
9271 const std::size_t index,
9274 : index_(index)
9276 , vector_base_((*vec_holder)[0])
9278 {
9280 assert(valid());
9281 }
9282
9284 {
9285 return *access_vector();
9286 }
9287
9289 {
9290 return *access_vector();
9291 }
9292
9293 inline const T& ref() const exprtk_override
9294 {
9295 return *access_vector();
9296 }
9297
9302
9304 {
9305 return
9307 vector_node_.first &&
9308 vector_node_.first->valid();
9309 }
9310
9312 {
9313 return (*vector_holder_);
9314 }
9315
9320
9325
9326 private:
9327
9328 inline T* access_vector() const
9329 {
9330 vector_node_.first->value();
9331
9332 if (index_ <= vector_holder_->size() - 1)
9333 {
9334 return (vector_holder_->data() + index_);
9335 }
9336
9338
9340 context.base_ptr = reinterpret_cast<void*>(vector_base_);
9341 context.end_ptr = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
9342 context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_);
9343 context.type_size = sizeof(T);
9344
9346 reinterpret_cast<T*>(context.access_ptr) :
9347 vector_base_ ;
9348 }
9349
9350 const std::size_t index_;
9355 };
9356
9357 template <typename T>
9359 {
9360 public:
9361
9363
9365 const std::size_t& size,
9366 const std::vector<expression_ptr>& initialiser_list,
9367 const bool single_value_initialse)
9370 , size_(size)
9375 {
9377 {
9378 if (initialiser_list_.empty())
9379 zero_value_initialse_ = true;
9380 else if (
9381 (initialiser_list_.size() == 1) &&
9383 (T(0) == initialiser_list_[0]->value())
9384 )
9385 {
9386 zero_value_initialse_ = true;
9387 }
9388 else
9389 {
9390 assert(initialiser_list_.size() == 1);
9391
9393 {
9397 }
9398 }
9399 }
9400 }
9401
9403 {
9405 {
9407 {
9409 }
9411 {
9412 for (std::size_t i = 0; i < size_; ++i)
9413 {
9415 }
9416 }
9417 else
9418 {
9419 for (std::size_t i = 0; i < size_; ++i)
9420 {
9422 }
9423 }
9424 }
9425 else
9426 {
9427 const std::size_t initialiser_list_size = initialiser_list_.size();
9428
9429 for (std::size_t i = 0; i < initialiser_list_size; ++i)
9430 {
9432 }
9433
9435 {
9439 }
9440 }
9441
9442 return *(vector_base_);
9443 }
9444
9449
9451 {
9452 return vector_base_;
9453 }
9454
9459
9464
9465 private:
9466
9469
9470 mutable T* vector_base_;
9471 std::vector<expression_ptr> initialiser_list_;
9472 const std::size_t size_;
9477 };
9478
9479 template <typename T>
9529
9530 template <typename T>
9532 {
9533 public:
9534
9536
9538 const std::size_t& size,
9539 const std::vector<expression_ptr>& initialiser_list)
9541 , size_(size)
9543 {
9545 assert(valid());
9546 }
9547
9549 {
9550 for (std::size_t i = 0; i < size_; ++i)
9551 {
9553 }
9554
9555 return *(vector_base_);
9556 }
9557
9562
9564 {
9565 return vector_base_ &&
9566 (initialiser_list_.size() == 1) &&
9569 }
9570
9575
9580
9581 private:
9582
9585
9586 mutable T* vector_base_;
9587 const std::size_t size_;
9588 std::vector<expression_ptr> initialiser_list_;
9590 };
9591
9592 template <typename T>
9594 {
9595 public:
9596
9598
9600 const std::size_t& size,
9601 const std::vector<expression_ptr>& initialiser_list)
9603 , size_(size)
9605 {
9606 assert(valid());
9607 }
9608
9610 {
9612
9613 for (std::size_t i = 0; i < size_; ++i)
9614 {
9615 *(vector_base_ + i) = node.value();
9616 }
9617
9618 return *(vector_base_);
9619 }
9620
9625
9627 {
9628 return vector_base_ &&
9629 (initialiser_list_.size() == 1) &&
9631 }
9632
9637
9642
9643 private:
9644
9647
9648 mutable T* vector_base_;
9649 const std::size_t size_;
9650 std::vector<expression_ptr> initialiser_list_;
9651 };
9652
9653 template <typename T>
9655 {
9656 public:
9657
9659
9661 const std::size_t& size,
9662 const std::vector<expression_ptr>& initialiser_list)
9664 , size_(size)
9666 {
9667 base_value_ = initialiser_list_[0]->value();
9668 increment_value_ = initialiser_list_[1]->value();
9669
9670 assert(valid());
9671 }
9672
9674 {
9676
9677 for (std::size_t i = 0; i < size_; ++i, value += increment_value_)
9678 {
9679 *(vector_base_ + i) = value;
9680 }
9681
9682 return *(vector_base_);
9683 }
9684
9689
9691 {
9692 return vector_base_ &&
9693 (initialiser_list_.size() == 2) &&
9696 }
9697
9702
9707
9708 private:
9709
9712
9713 mutable T* vector_base_;
9714 const std::size_t size_;
9715 std::vector<expression_ptr> initialiser_list_;
9718 };
9719
9720 template <typename T>
9722 {
9723 public:
9724
9726
9728 const std::size_t& size,
9729 const std::vector<expression_ptr>& initialiser_list)
9731 , size_(size)
9733 {
9734 assert(valid());
9735 base_value_ = initialiser_list_[0]->value();
9736 }
9737
9739 {
9742
9743 for (std::size_t i = 0; i < size_; ++i, value += increment.value())
9744 {
9745 *(vector_base_ + i) = value;
9746 }
9747
9748 return *(vector_base_);
9749 }
9750
9755
9757 {
9758 return vector_base_ &&
9759 (initialiser_list_.size() == 2) &&
9762 }
9763
9768
9773
9774 private:
9775
9778
9779 mutable T* vector_base_;
9780 const std::size_t size_;
9781 std::vector<expression_ptr> initialiser_list_;
9783 };
9784
9785 template <typename T>
9787 {
9788 public:
9789
9791
9793 const std::size_t& size,
9794 const std::vector<expression_ptr>& initialiser_list)
9796 , size_(size)
9798 {
9799 assert(valid());
9800 }
9801
9803 {
9804 T value = initialiser_list_[0]->value();
9805 const T increment = initialiser_list_[1]->value();
9806
9807 for (std::size_t i = 0; i < size_; ++i, value += increment)
9808 {
9809 *(vector_base_ + i) = value;
9810 }
9811
9812 return *(vector_base_);
9813 }
9814
9819
9821 {
9822 return vector_base_ &&
9823 (initialiser_list_.size() == 2) &&
9826 }
9827
9832
9837
9838 private:
9839
9842
9843 mutable T* vector_base_;
9844 const std::size_t size_;
9845 std::vector<expression_ptr> initialiser_list_;
9846 };
9847
9848 template <typename T>
9850 {
9851 public:
9852
9854
9856 const std::size_t& size,
9857 const std::vector<expression_ptr>& initialiser_list)
9859 , size_(size)
9861 {
9862 assert(valid());
9863 }
9864
9866 {
9867 T value = initialiser_list_[0]->value();
9869
9870 for (std::size_t i = 0; i < size_; ++i, value += increment.value())
9871 {
9872 *(vector_base_ + i) = value;
9873 }
9874
9875 return *(vector_base_);
9876 }
9877
9882
9884 {
9885 return vector_base_ &&
9886 (initialiser_list_.size() == 2) &&
9889 }
9890
9895
9900
9901 private:
9902
9905
9906 mutable T* vector_base_;
9907 const std::size_t size_;
9908 std::vector<expression_ptr> initialiser_list_;
9909 };
9910
9911 template <typename T>
9913 {
9914 public:
9915
9918
9923
9925 {
9926 std::swap(var0_->ref(),var1_->ref());
9927 return var1_->ref();
9928 }
9929
9934
9935 private:
9936
9939 };
9940
9941 template <typename T>
9943 {
9944 public:
9945
9948
9954
9956 {
9957 std::swap(var0_->ref(),var1_->ref());
9958 return var1_->ref();
9959 }
9960
9965
9966 private:
9967
9970 };
9971
9972 template <typename T>
9974 : public binary_node <T>
9975 , public vector_interface<T>
9976 {
9977 public:
9978
9982
9983 using binary_node<T>::branch;
9984
9987 : binary_node<T>(details::e_swap, branch0, branch1)
9988 , vec0_node_ptr_(0)
9989 , vec1_node_ptr_(0)
9991 {
9992 if (is_ivector_node(branch(0)))
9993 {
9994 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
9995
9996 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
9997 {
9998 vec0_node_ptr_ = vi->vec();
9999 vds() = vi->vds();
10000 }
10001 }
10002
10003 if (is_ivector_node(branch(1)))
10004 {
10005 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
10006
10007 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
10008 {
10009 vec1_node_ptr_ = vi->vec();
10010 }
10011 }
10012
10014 {
10015 initialised_ = size() <= base_size();
10016 }
10017
10018 assert(valid());
10019 }
10020
10022 {
10023 binary_node<T>::branch(0)->value();
10024 binary_node<T>::branch(1)->value();
10025
10026 T* vec0 = vec0_node_ptr_->vds().data();
10027 T* vec1 = vec1_node_ptr_->vds().data();
10028
10029 assert(size() <= base_size());
10030 const std::size_t n = size();
10031
10032 for (std::size_t i = 0; i < n; ++i)
10033 {
10034 std::swap(vec0[i],vec1[i]);
10035 }
10036
10037 return vec1_node_ptr_->value();
10038 }
10039
10041 {
10042 return vec0_node_ptr_;
10043 }
10044
10046 {
10047 return vec0_node_ptr_;
10048 }
10049
10054
10056 {
10058 }
10059
10061 {
10062 return std::min(
10063 vec0_node_ptr_->vec_holder().size(),
10064 vec1_node_ptr_->vec_holder().size());
10065 }
10066
10068 {
10069 return std::min(
10070 vec0_node_ptr_->vec_holder().base_size(),
10071 vec1_node_ptr_->vec_holder().base_size());
10072 }
10073
10075 {
10076 return vds_;
10077 }
10078
10080 {
10081 return vds_;
10082 }
10083
10084 private:
10085
10090 };
10091
10092 #ifndef exprtk_disable_string_capabilities
10093 template <typename T>
10095 : public expression_node <T>
10096 , public string_base_node<T>
10097 , public range_interface <T>
10098 {
10099 public:
10100
10102
10103 static std::string null_value;
10104
10106 : value_(&null_value)
10107 {}
10108
10109 explicit stringvar_node(std::string& v)
10110 : value_(&v)
10111 {
10112 rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
10113 rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size());
10114 rp_.cache.first = rp_.n0_c.second;
10115 rp_.cache.second = rp_.n1_c.second;
10116 }
10117
10118 inline bool operator <(const stringvar_node<T>& v) const
10119 {
10120 return this < (&v);
10121 }
10122
10124 {
10125 rp_.n1_c.second = (*value_).size();
10126 rp_.cache.second = rp_.n1_c.second;
10127
10128 return std::numeric_limits<T>::quiet_NaN();
10129 }
10130
10132 {
10133 return ref();
10134 }
10135
10137 {
10138 return &(*value_)[0];
10139 }
10140
10142 {
10143 return ref().size();
10144 }
10145
10146 std::string& ref()
10147 {
10148 return (*value_);
10149 }
10150
10151 const std::string& ref() const
10152 {
10153 return (*value_);
10154 }
10155
10157 {
10158 return rp_;
10159 }
10160
10162 {
10163 return rp_;
10164 }
10165
10170
10171 void rebase(std::string& s)
10172 {
10173 value_ = &s;
10174 rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
10175 rp_.n1_c = std::make_pair<bool,std::size_t>(true,value_->size() - 1);
10176 rp_.cache.first = rp_.n0_c.second;
10177 rp_.cache.second = rp_.n1_c.second;
10178 }
10179
10180 private:
10181
10182 std::string* value_;
10183 mutable range_t rp_;
10184 };
10185
10186 template <typename T>
10187 std::string stringvar_node<T>::null_value = std::string("");
10188
10189 template <typename T>
10191 : public expression_node <T>
10192 , public string_base_node<T>
10193 , public range_interface <T>
10194 {
10195 public:
10196
10198
10199 static std::string null_value;
10200
10201 explicit string_range_node(std::string& v, const range_t& rp)
10202 : value_(&v)
10203 , rp_(rp)
10204 {}
10205
10207 {
10208 rp_.free();
10209 }
10210
10211 inline bool operator <(const string_range_node<T>& v) const
10212 {
10213 return this < (&v);
10214 }
10215
10217 {
10218 return std::numeric_limits<T>::quiet_NaN();
10219 }
10220
10221 inline std::string str() const exprtk_override
10222 {
10223 return (*value_);
10224 }
10225
10227 {
10228 return &(*value_)[0];
10229 }
10230
10232 {
10233 return ref().size();
10234 }
10235
10236 inline range_t range() const
10237 {
10238 return rp_;
10239 }
10240
10241 inline virtual std::string& ref()
10242 {
10243 return (*value_);
10244 }
10245
10246 inline virtual const std::string& ref() const
10247 {
10248 return (*value_);
10249 }
10250
10252 {
10253 return rp_;
10254 }
10255
10257 {
10258 return rp_;
10259 }
10260
10265
10266 private:
10267
10268 std::string* value_;
10270 };
10271
10272 template <typename T>
10273 std::string string_range_node<T>::null_value = std::string("");
10274
10275 template <typename T>
10277 : public expression_node <T>
10278 , public string_base_node<T>
10279 , public range_interface <T>
10280 {
10281 public:
10282
10284
10285 explicit const_string_range_node(const std::string& v, const range_t& rp)
10286 : value_(v)
10287 , rp_(rp)
10288 {}
10289
10291 {
10292 rp_.free();
10293 }
10294
10296 {
10297 return std::numeric_limits<T>::quiet_NaN();
10298 }
10299
10301 {
10302 return value_;
10303 }
10304
10306 {
10307 return value_.data();
10308 }
10309
10311 {
10312 return value_.size();
10313 }
10314
10316 {
10317 return rp_;
10318 }
10319
10321 {
10322 return rp_;
10323 }
10324
10326 {
10327 return rp_;
10328 }
10329
10334
10335 private:
10336
10339
10340 const std::string value_;
10342 };
10343
10344 template <typename T>
10346 : public expression_node <T>
10347 , public string_base_node<T>
10348 , public range_interface <T>
10349 {
10350 public:
10351
10359 typedef std::pair<expression_ptr,bool> branch_t;
10360
10363 , str_base_ptr_ (0)
10364 , str_range_ptr_(0)
10366 {
10367 range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
10368 range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
10369 range_.cache.first = range_.n0_c.second;
10370 range_.cache.second = range_.n1_c.second;
10371
10373
10375 {
10376 str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first);
10377
10378 if (0 == str_base_ptr_)
10379 return;
10380
10381 str_range_ptr_ = dynamic_cast<irange_ptr>(branch_.first);
10382
10383 if (0 == str_range_ptr_)
10384 return;
10385 }
10386
10388 assert(valid());
10389 }
10390
10392 {
10393 base_range_.free();
10394 }
10395
10397 {
10398 branch_.first->value();
10399
10400 std::size_t str_r0 = 0;
10401 std::size_t str_r1 = 0;
10402
10403 std::size_t r0 = 0;
10404 std::size_t r1 = 0;
10405
10406 const range_t& range = str_range_ptr_->range_ref();
10407
10408 const std::size_t base_str_size = str_base_ptr_->size();
10409
10410 if (
10411 range (str_r0, str_r1, base_str_size ) &&
10413 )
10414 {
10415 const std::size_t size = r1 - r0;
10416
10417 range_.n1_c.second = size;
10418 range_.cache.second = range_.n1_c.second;
10419
10420 value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
10421 }
10422
10423 return std::numeric_limits<T>::quiet_NaN();
10424 }
10425
10427 {
10428 return value_;
10429 }
10430
10432 {
10433 return &value_[0];
10434 }
10435
10437 {
10438 return value_.size();
10439 }
10440
10442 {
10443 return range_;
10444 }
10445
10447 {
10448 return range_;
10449 }
10450
10455
10457 {
10458 return initialised_ && branch_.first;
10459 }
10460
10465
10470
10471 private:
10472
10479 mutable std::string value_;
10480 };
10481
10482 template <typename T>
10484 : public binary_node <T>
10485 , public string_base_node<T>
10486 , public range_interface <T>
10487 {
10488 public:
10489
10496
10497 using binary_node<T>::branch;
10498
10504 , str0_base_ptr_ (0)
10505 , str1_base_ptr_ (0)
10506 , str0_range_ptr_(0)
10507 , str1_range_ptr_(0)
10508 {
10509 range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
10510 range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
10511
10512 range_.cache.first = range_.n0_c.second;
10513 range_.cache.second = range_.n1_c.second;
10514
10516 {
10517 str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
10518
10519 if (0 == str0_base_ptr_)
10520 return;
10521
10522 str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0));
10523
10524 if (0 == str0_range_ptr_)
10525 return;
10526 }
10527
10529 {
10530 str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
10531
10532 if (0 == str1_base_ptr_)
10533 return;
10534
10535 str1_range_ptr_ = dynamic_cast<irange_ptr>(branch(1));
10536
10537 if (0 == str1_range_ptr_)
10538 return;
10539 }
10540
10545
10546 assert(valid());
10547 }
10548
10550 {
10551 branch(0)->value();
10552 branch(1)->value();
10553
10554 std::size_t str0_r0 = 0;
10555 std::size_t str0_r1 = 0;
10556
10557 std::size_t str1_r0 = 0;
10558 std::size_t str1_r1 = 0;
10559
10562
10563 if (
10566 )
10567 {
10568 const std::size_t size0 = (str0_r1 - str0_r0);
10569 const std::size_t size1 = (str1_r1 - str1_r0);
10570
10571 value_.assign(str0_base_ptr_->base() + str0_r0, size0);
10572 value_.append(str1_base_ptr_->base() + str1_r0, size1);
10573
10574 range_.n1_c.second = value_.size();
10575 range_.cache.second = range_.n1_c.second;
10576 }
10577
10578 return std::numeric_limits<T>::quiet_NaN();
10579 }
10580
10582 {
10583 return value_;
10584 }
10585
10587 {
10588 return &value_[0];
10589 }
10590
10592 {
10593 return value_.size();
10594 }
10595
10597 {
10598 return range_;
10599 }
10600
10602 {
10603 return range_;
10604 }
10605
10610
10612 {
10614 }
10615
10616 private:
10617
10624 mutable std::string value_;
10625 };
10626
10627 template <typename T>
10629 : public binary_node <T>
10630 , public string_base_node<T>
10631 , public range_interface <T>
10632 {
10633 public:
10634
10642
10643 using binary_node<T>::branch;
10644
10646 : binary_node<T>(details::e_swap, branch0, branch1)
10648 , str0_node_ptr_(0)
10649 , str1_node_ptr_(0)
10650 {
10651 if (is_string_node(branch(0)))
10652 {
10653 str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0));
10654 }
10655
10656 if (is_string_node(branch(1)))
10657 {
10658 str1_node_ptr_ = static_cast<strvar_node_ptr>(branch(1));
10659 }
10660
10662 assert(valid());
10663 }
10664
10666 {
10667 branch(0)->value();
10668 branch(1)->value();
10669
10670 std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref());
10671
10672 return std::numeric_limits<T>::quiet_NaN();
10673 }
10674
10676 {
10677 return str0_node_ptr_->str();
10678 }
10679
10681 {
10682 return str0_node_ptr_->base();
10683 }
10684
10686 {
10687 return str0_node_ptr_->size();
10688 }
10689
10691 {
10692 return str0_node_ptr_->range_ref();
10693 }
10694
10696 {
10697 return str0_node_ptr_->range_ref();
10698 }
10699
10704
10706 {
10708 }
10709
10710 private:
10711
10715 };
10716
10717 template <typename T>
10719 {
10720 public:
10721
10728
10729 using binary_node<T>::branch;
10730
10733 : binary_node<T>(details::e_default, branch0, branch1)
10734 , str0_base_ptr_ (0)
10735 , str1_base_ptr_ (0)
10736 , str0_range_ptr_(0)
10737 , str1_range_ptr_(0)
10739 {
10741 {
10742 str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
10743
10744 if (0 == str0_base_ptr_)
10745 return;
10746
10747 irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
10748
10749 if (0 == range)
10750 return;
10751
10752 str0_range_ptr_ = &(range->range_ref());
10753 }
10754
10756 {
10757 str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
10758
10759 if (0 == str1_base_ptr_)
10760 return;
10761
10762 irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
10763
10764 if (0 == range)
10765 return;
10766
10767 str1_range_ptr_ = &(range->range_ref());
10768 }
10769
10774
10775 assert(valid());
10776 }
10777
10779 {
10780 branch(0)->value();
10781 branch(1)->value();
10782
10783 std::size_t str0_r0 = 0;
10784 std::size_t str0_r1 = 0;
10785
10786 std::size_t str1_r0 = 0;
10787 std::size_t str1_r1 = 0;
10788
10789 const range_t& range0 = (*str0_range_ptr_);
10790 const range_t& range1 = (*str1_range_ptr_);
10791
10792 if (
10795 )
10796 {
10797 const std::size_t size0 = range0.cache_size();
10798 const std::size_t size1 = range1.cache_size();
10799 const std::size_t max_size = std::min(size0,size1);
10800
10801 char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0);
10802 char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0);
10803
10805 char_cptr upper_bound = s0 + lud.upper_bound;
10806
10807 while (s0 < upper_bound)
10808 {
10809 #define exprtk_loop(N) \
10810 std::swap(s0[N], s1[N]); \
10811
10812 exprtk_loop( 0) exprtk_loop( 1)
10813 exprtk_loop( 2) exprtk_loop( 3)
10814 #ifndef exprtk_disable_superscalar_unroll
10815 exprtk_loop( 4) exprtk_loop( 5)
10816 exprtk_loop( 6) exprtk_loop( 7)
10817 exprtk_loop( 8) exprtk_loop( 9)
10818 exprtk_loop(10) exprtk_loop(11)
10819 exprtk_loop(12) exprtk_loop(13)
10820 exprtk_loop(14) exprtk_loop(15)
10821 #endif
10822
10823 s0 += lud.batch_size;
10824 s1 += lud.batch_size;
10825 }
10826
10827 int i = 0;
10828
10829 switch (lud.remainder)
10830 {
10831 #define case_stmt(N) \
10832 case N : { std::swap(s0[i], s1[i]); ++i; } \
10833 exprtk_fallthrough \
10834
10835 #ifndef exprtk_disable_superscalar_unroll
10836 case_stmt(15) case_stmt(14)
10837 case_stmt(13) case_stmt(12)
10838 case_stmt(11) case_stmt(10)
10839 case_stmt( 9) case_stmt( 8)
10840 case_stmt( 7) case_stmt( 6)
10841 case_stmt( 5) case_stmt( 4)
10842 #endif
10843 case_stmt( 3) case_stmt( 2)
10844 case_stmt( 1)
10845 default: break;
10846 }
10847
10848 #undef exprtk_loop
10849 #undef case_stmt
10850 }
10851
10852 return std::numeric_limits<T>::quiet_NaN();
10853 }
10854
10859
10861 {
10863 }
10864
10865 private:
10866
10869
10875 };
10876
10877 template <typename T>
10879 {
10880 public:
10881
10882 static const std::string null_value;
10883
10885 : value_(&null_value)
10886 {}
10887
10888 explicit stringvar_size_node(std::string& v)
10889 : value_(&v)
10890 {}
10891
10893 {
10894 return T((*value_).size());
10895 }
10896
10901
10902 private:
10903
10904 const std::string* value_;
10905 };
10906
10907 template <typename T>
10908 const std::string stringvar_size_node<T>::null_value = std::string("");
10909
10910 template <typename T>
10912 {
10913 public:
10914
10917 typedef std::pair<expression_ptr,bool> branch_t;
10918
10920 : str_base_ptr_(0)
10921 {
10923
10925 {
10926 str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first);
10927 }
10928
10929 assert(valid());
10930 }
10931
10933 {
10934 branch_.first->value();
10935 return T(str_base_ptr_->size());
10936 }
10937
10942
10944 {
10945 return str_base_ptr_;
10946 }
10947
10952
10957
10958 private:
10959
10962 };
10963
10965 {
10966 static inline void execute(std::string& s, char_cptr data, const std::size_t size)
10967 { s.assign(data,size); }
10968 };
10969
10971 {
10972 static inline void execute(std::string& s, char_cptr data, const std::size_t size)
10973 { s.append(data,size); }
10974 };
10975
10976 template <typename T, typename AssignmentProcess = asn_assignment>
10978 : public binary_node <T>
10979 , public string_base_node<T>
10980 , public range_interface <T>
10981 {
10982 public:
10983
10991
10992 using binary_node<T>::branch;
10993
10999 , str0_base_ptr_ (0)
11000 , str1_base_ptr_ (0)
11001 , str0_node_ptr_ (0)
11002 , str1_range_ptr_(0)
11003 {
11004 if (is_string_node(branch(0)))
11005 {
11006 str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0));
11007 str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
11008 }
11009
11011 {
11012 str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
11013
11014 if (0 == str1_base_ptr_)
11015 return;
11016
11017 irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
11018
11019 if (0 == range)
11020 return;
11021
11022 str1_range_ptr_ = &(range->range_ref());
11023 }
11024
11029
11030 assert(valid());
11031 }
11032
11034 {
11035 branch(1)->value();
11036
11037 std::size_t r0 = 0;
11038 std::size_t r1 = 0;
11039
11040 const range_t& range = (*str1_range_ptr_);
11041
11042 if (range(r0, r1, str1_base_ptr_->size()))
11043 {
11044 AssignmentProcess::execute(
11046 str1_base_ptr_->base() + r0, (r1 - r0));
11047
11048 branch(0)->value();
11049 }
11050
11051 return std::numeric_limits<T>::quiet_NaN();
11052 }
11053
11055 {
11056 return str0_node_ptr_->str();
11057 }
11058
11060 {
11061 return str0_node_ptr_->base();
11062 }
11063
11065 {
11066 return str0_node_ptr_->size();
11067 }
11068
11070 {
11071 return str0_node_ptr_->range_ref();
11072 }
11073
11075 {
11076 return str0_node_ptr_->range_ref();
11077 }
11078
11083
11085 {
11087 }
11088
11089 private:
11090
11096 };
11097
11098 template <typename T, typename AssignmentProcess = asn_assignment>
11100 : public binary_node <T>
11101 , public string_base_node<T>
11102 , public range_interface <T>
11103 {
11104 public:
11105
11114
11115 using binary_node<T>::branch;
11116
11122 , str0_base_ptr_ (0)
11123 , str1_base_ptr_ (0)
11125 , str0_range_ptr_ (0)
11126 , str1_range_ptr_ (0)
11127 {
11129 {
11130 str0_rng_node_ptr_ = static_cast<str_rng_node_ptr>(branch(0));
11131 str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
11132 irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
11133
11134 if (0 == range)
11135 return;
11136
11137 str0_range_ptr_ = &(range->range_ref());
11138 }
11139
11141 {
11142 str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
11143
11144 if (0 == str1_base_ptr_)
11145 return;
11146
11147 irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
11148
11149 if (0 == range)
11150 return;
11151
11152 str1_range_ptr_ = &(range->range_ref());
11153 }
11154
11160
11161 assert(valid());
11162 }
11163
11165 {
11166 branch(0)->value();
11167 branch(1)->value();
11168
11169 std::size_t s0_r0 = 0;
11170 std::size_t s0_r1 = 0;
11171
11172 std::size_t s1_r0 = 0;
11173 std::size_t s1_r1 = 0;
11174
11175 const range_t& range0 = (*str0_range_ptr_);
11176 const range_t& range1 = (*str1_range_ptr_);
11177
11178 if (
11181 )
11182 {
11183 const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0));
11184
11185 std::copy(
11188 const_cast<char_ptr>(base() + s0_r0));
11189 }
11190
11191 return std::numeric_limits<T>::quiet_NaN();
11192 }
11193
11195 {
11196 return str0_base_ptr_->str();
11197 }
11198
11200 {
11201 return str0_base_ptr_->base();
11202 }
11203
11205 {
11206 return str0_base_ptr_->size();
11207 }
11208
11210 {
11211 return str0_rng_node_ptr_->range_ref();
11212 }
11213
11215 {
11216 return str0_rng_node_ptr_->range_ref();
11217 }
11218
11223
11225 {
11227 }
11228
11229 private:
11230
11237 };
11238
11239 template <typename T>
11241 : public trinary_node <T>
11242 , public string_base_node<T>
11243 , public range_interface <T>
11244 {
11245 public:
11246
11253
11257 : trinary_node<T>(details::e_default, consequent, alternative, condition)
11259 , str0_base_ptr_ (0)
11260 , str1_base_ptr_ (0)
11261 , str0_range_ptr_(0)
11262 , str1_range_ptr_(0)
11263 , condition_ (condition )
11266 {
11267 range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
11268 range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
11269
11270 range_.cache.first = range_.n0_c.second;
11271 range_.cache.second = range_.n1_c.second;
11272
11274 {
11275 str0_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[0].first);
11276
11277 if (0 == str0_base_ptr_)
11278 return;
11279
11280 str0_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[0].first);
11281
11282 if (0 == str0_range_ptr_)
11283 return;
11284 }
11285
11287 {
11288 str1_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[1].first);
11289
11290 if (0 == str1_base_ptr_)
11291 return;
11292
11293 str1_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[1].first);
11294
11295 if (0 == str1_range_ptr_)
11296 return;
11297 }
11298
11303
11304 assert(valid());
11305 }
11306
11308 {
11309 std::size_t r0 = 0;
11310 std::size_t r1 = 0;
11311
11312 if (is_true(condition_))
11313 {
11314 consequent_->value();
11315
11316 const range_t& range = str0_range_ptr_->range_ref();
11317
11318 if (range(r0, r1, str0_base_ptr_->size()))
11319 {
11320 const std::size_t size = (r1 - r0);
11321
11322 value_.assign(str0_base_ptr_->base() + r0, size);
11323
11324 range_.n1_c.second = value_.size();
11325 range_.cache.second = range_.n1_c.second;
11326
11327 return T(1);
11328 }
11329 }
11330 else
11331 {
11333
11334 const range_t& range = str1_range_ptr_->range_ref();
11335
11336 if (range(r0, r1, str1_base_ptr_->size()))
11337 {
11338 const std::size_t size = (r1 - r0);
11339
11340 value_.assign(str1_base_ptr_->base() + r0, size);
11341
11342 range_.n1_c.second = value_.size();
11343 range_.cache.second = range_.n1_c.second;
11344
11345 return T(0);
11346 }
11347 }
11348
11349 return std::numeric_limits<T>::quiet_NaN();
11350 }
11351
11353 {
11354 return value_;
11355 }
11356
11358 {
11359 return &value_[0];
11360 }
11361
11363 {
11364 return value_.size();
11365 }
11366
11368 {
11369 return range_;
11370 }
11371
11373 {
11374 return range_;
11375 }
11376
11381
11383 {
11384 return
11385 initialised_ &&
11386 condition_ && condition_ ->valid() &&
11387 consequent_ && consequent_ ->valid() &&
11389 }
11390
11391 private:
11392
11399 mutable std::string value_;
11400
11404 };
11405
11406 template <typename T>
11408 : public binary_node <T>
11409 , public string_base_node<T>
11410 , public range_interface <T>
11411 {
11412 public:
11413
11420
11421 using binary_node<T>::branch;
11422
11425 : binary_node<T>(details::e_default, consequent, condition)
11427 , str0_base_ptr_ (0)
11428 , str0_range_ptr_(0)
11429 , condition_ (condition )
11431 {
11432 range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
11433 range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
11434
11435 range_.cache.first = range_.n0_c.second;
11436 range_.cache.second = range_.n1_c.second;
11437
11439 {
11440 str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
11441
11442 if (0 == str0_base_ptr_)
11443 return;
11444
11445 str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0));
11446
11447 if (0 == str0_range_ptr_)
11448 return;
11449 }
11450
11452 assert(valid());
11453 }
11454
11456 {
11457 if (is_true(condition_))
11458 {
11459 consequent_->value();
11460
11461 const range_t& range = str0_range_ptr_->range_ref();
11462
11463 std::size_t r0 = 0;
11464 std::size_t r1 = 0;
11465
11466 if (range(r0, r1, str0_base_ptr_->size()))
11467 {
11468 const std::size_t size = (r1 - r0);
11469
11470 value_.assign(str0_base_ptr_->base() + r0, size);
11471
11472 range_.n1_c.second = value_.size();
11473 range_.cache.second = range_.n1_c.second;
11474
11475 return T(1);
11476 }
11477 }
11478
11479 return std::numeric_limits<T>::quiet_NaN();
11480 }
11481
11482 std::string str() const
11483 {
11484 return value_;
11485 }
11486
11488 {
11489 return &value_[0];
11490 }
11491
11492 std::size_t size() const
11493 {
11494 return value_.size();
11495 }
11496
11498 {
11499 return range_;
11500 }
11501
11502 const range_t& range_ref() const
11503 {
11504 return range_;
11505 }
11506
11511
11513 {
11514 return
11515 initialised_ &&
11516 condition_ && condition_ ->valid() &&
11518 }
11519
11520 private:
11521
11526 mutable std::string value_;
11527
11530 };
11531
11532 template <typename T, typename VarArgFunction>
11534 : public expression_node <T>
11535 , public string_base_node<T>
11536 , public range_interface <T>
11537 {
11538 public:
11539
11546 typedef std::pair<expression_ptr,bool> branch_t;
11547
11548 template <typename Allocator,
11549 template <typename, typename> class Sequence>
11552 , str_base_ptr_ (0)
11553 , str_range_ptr_(0)
11554 {
11556
11557 if (0 == final_node_.first)
11558 return;
11559 else if (!is_generally_string_node(final_node_.first))
11560 return;
11561
11562 str_base_ptr_ = dynamic_cast<str_base_ptr>(final_node_.first);
11563
11564 if (0 == str_base_ptr_)
11565 return;
11566
11567 str_range_ptr_ = dynamic_cast<irange_ptr>(final_node_.first);
11568
11569 if (0 == str_range_ptr_)
11570 return;
11571
11572 if (arg_list.size() > 1)
11573 {
11574 const std::size_t arg_list_size = arg_list.size() - 1;
11575
11576 arg_list_.resize(arg_list_size);
11577
11578 for (std::size_t i = 0; i < arg_list_size; ++i)
11579 {
11580 if (arg_list[i] && arg_list[i]->valid())
11581 {
11583 }
11584 else
11585 {
11586 arg_list_.clear();
11587 return;
11588 }
11589 }
11590
11591 initialised_ = true;
11592 }
11593
11595 assert(valid());
11596 }
11597
11599 {
11600 if (!arg_list_.empty())
11601 {
11602 VarArgFunction::process(arg_list_);
11603 }
11604
11605 final_node_.first->value();
11606
11607 return std::numeric_limits<T>::quiet_NaN();
11608 }
11609
11611 {
11612 return str_base_ptr_->str();
11613 }
11614
11616 {
11617 return str_base_ptr_->base();
11618 }
11619
11621 {
11622 return str_base_ptr_->size();
11623 }
11624
11626 {
11627 return str_range_ptr_->range_ref();
11628 }
11629
11631 {
11632 return str_range_ptr_->range_ref();
11633 }
11634
11639
11641 {
11642 return
11643 initialised_ &&
11644 final_node_.first && final_node_.first->valid();
11645 }
11646
11652
11659
11660 private:
11661
11666 std::vector<branch_t> arg_list_;
11667 };
11668 #endif
11669
11670 template <typename T>
11672 {
11673 public:
11674
11676 typedef std::pair<expression_ptr,bool> branch_t;
11679
11703
11705 {
11706 if (details::is_true(assert_condition_node_.first->value()))
11707 {
11708 return T(1);
11709 }
11710
11711 #ifndef exprtk_disable_string_capabilities
11712 if (assert_message_node_.first)
11713 {
11714 assert_message_node_.first->value();
11717 }
11718 #endif
11719
11721 return T(0);
11722 }
11723
11728
11730 {
11731 return (
11732 assert_check_ &&
11733 assert_condition_node_.first &&
11734 assert_condition_node_.first->valid()
11735 ) &&
11736 (
11737 (0 == assert_message_node_.first) ||
11738 (
11739 assert_message_node_.first &&
11741 assert_message_node_.first->valid() &&
11743 )
11744 );
11745 }
11746
11752
11758
11759 private:
11760
11766 };
11767
11768 template <typename T, std::size_t N>
11769 inline T axn(const T a, const T x)
11770 {
11771 // a*x^n
11773 }
11774
11775 template <typename T, std::size_t N>
11776 inline T axnb(const T a, const T x, const T b)
11777 {
11778 // a*x^n+b
11780 }
11781
11782 template <typename T>
11792
11793 #define define_sfop3(NN, OP0, OP1) \
11794 template <typename T> \
11795 struct sf##NN##_op : public sf_base<T> \
11796 { \
11797 typedef typename sf_base<T>::Type const Type; \
11798 static inline T process(Type x, Type y, Type z) \
11799 { \
11800 return (OP0); \
11801 } \
11802 static inline std::string id() \
11803 { \
11804 return (OP1); \
11805 } \
11806 }; \
11807
11808 define_sfop3(00,(x + y) / z ,"(t+t)/t")
11809 define_sfop3(01,(x + y) * z ,"(t+t)*t")
11810 define_sfop3(02,(x + y) - z ,"(t+t)-t")
11811 define_sfop3(03,(x + y) + z ,"(t+t)+t")
11812 define_sfop3(04,(x - y) + z ,"(t-t)+t")
11813 define_sfop3(05,(x - y) / z ,"(t-t)/t")
11814 define_sfop3(06,(x - y) * z ,"(t-t)*t")
11815 define_sfop3(07,(x * y) + z ,"(t*t)+t")
11816 define_sfop3(08,(x * y) - z ,"(t*t)-t")
11817 define_sfop3(09,(x * y) / z ,"(t*t)/t")
11818 define_sfop3(10,(x * y) * z ,"(t*t)*t")
11819 define_sfop3(11,(x / y) + z ,"(t/t)+t")
11820 define_sfop3(12,(x / y) - z ,"(t/t)-t")
11821 define_sfop3(13,(x / y) / z ,"(t/t)/t")
11822 define_sfop3(14,(x / y) * z ,"(t/t)*t")
11823 define_sfop3(15,x / (y + z) ,"t/(t+t)")
11824 define_sfop3(16,x / (y - z) ,"t/(t-t)")
11825 define_sfop3(17,x / (y * z) ,"t/(t*t)")
11826 define_sfop3(18,x / (y / z) ,"t/(t/t)")
11827 define_sfop3(19,x * (y + z) ,"t*(t+t)")
11828 define_sfop3(20,x * (y - z) ,"t*(t-t)")
11829 define_sfop3(21,x * (y * z) ,"t*(t*t)")
11830 define_sfop3(22,x * (y / z) ,"t*(t/t)")
11831 define_sfop3(23,x - (y + z) ,"t-(t+t)")
11832 define_sfop3(24,x - (y - z) ,"t-(t-t)")
11833 define_sfop3(25,x - (y / z) ,"t-(t/t)")
11834 define_sfop3(26,x - (y * z) ,"t-(t*t)")
11835 define_sfop3(27,x + (y * z) ,"t+(t*t)")
11836 define_sfop3(28,x + (y / z) ,"t+(t/t)")
11837 define_sfop3(29,x + (y + z) ,"t+(t+t)")
11838 define_sfop3(30,x + (y - z) ,"t+(t-t)")
11839 define_sfop3(31,(axnb<T,2>(x,y,z))," ")
11840 define_sfop3(32,(axnb<T,3>(x,y,z))," ")
11841 define_sfop3(33,(axnb<T,4>(x,y,z))," ")
11842 define_sfop3(34,(axnb<T,5>(x,y,z))," ")
11843 define_sfop3(35,(axnb<T,6>(x,y,z))," ")
11844 define_sfop3(36,(axnb<T,7>(x,y,z))," ")
11845 define_sfop3(37,(axnb<T,8>(x,y,z))," ")
11846 define_sfop3(38,(axnb<T,9>(x,y,z))," ")
11847 define_sfop3(39,x * numeric::log(y) + z,"")
11848 define_sfop3(40,x * numeric::log(y) - z,"")
11849 define_sfop3(41,x * numeric::log10(y) + z,"")
11850 define_sfop3(42,x * numeric::log10(y) - z,"")
11851 define_sfop3(43,x * numeric::sin(y) + z ,"")
11852 define_sfop3(44,x * numeric::sin(y) - z ,"")
11853 define_sfop3(45,x * numeric::cos(y) + z ,"")
11854 define_sfop3(46,x * numeric::cos(y) - z ,"")
11855 define_sfop3(47,details::is_true(x) ? y : z,"")
11856
11857 #define define_sfop4(NN, OP0, OP1) \
11858 template <typename T> \
11859 struct sf##NN##_op : public sf_base<T> \
11860 { \
11861 typedef typename sf_base<T>::Type const Type; \
11862 static inline T process(Type x, Type y, Type z, Type w) \
11863 { \
11864 return (OP0); \
11865 } \
11866 static inline std::string id() \
11867 { \
11868 return (OP1); \
11869 } \
11870 }; \
11871
11872 define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)")
11873 define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)")
11874 define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)")
11875 define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)")
11876 define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)")
11877 define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)")
11878 define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)")
11879 define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)")
11880 define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)")
11881 define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)")
11882 define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)")
11883 define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)")
11884 define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)")
11885 define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)")
11886 define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)")
11887 define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)")
11888 define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)")
11889 define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t")
11890 define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t")
11891 define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t")
11892 define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t")
11893 define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t")
11894 define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t")
11895 define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t")
11896 define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t")
11897 define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)")
11898 define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)")
11899 define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)")
11900 define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)")
11901 define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)")
11902 define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)")
11903 define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)")
11904 define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))")
11905 define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))")
11906 define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))")
11907 define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))")
11908
11909 define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"")
11910 define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"")
11911 define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"")
11912 define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"")
11913 define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"")
11914 define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"")
11915 define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"")
11916 define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"")
11917 define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"")
11918 define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"")
11919 define_sfop4(94,((x < y) ? z : w),"")
11920 define_sfop4(95,((x <= y) ? z : w),"")
11921 define_sfop4(96,((x > y) ? z : w),"")
11922 define_sfop4(97,((x >= y) ? z : w),"")
11923 define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"")
11924 define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"")
11925
11926 define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)")
11927 define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)")
11928 define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)")
11929 define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)")
11930 define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)")
11931 define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)")
11932 define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)")
11933 define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)")
11934 define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)")
11935 define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)")
11936 define_sfop4(ext10,((x + y) + (z + w)),"(t+t)+(t+t)")
11937 define_sfop4(ext11,((x + y) * (z - w)),"(t+t)*(t-t)")
11938 define_sfop4(ext12,((x + y) / (z - w)),"(t+t)/(t-t)")
11939 define_sfop4(ext13,((x - y) - (z + w)),"(t-t)-(t+t)")
11940 define_sfop4(ext14,((x - y) + (z + w)),"(t-t)+(t+t)")
11941 define_sfop4(ext15,((x - y) * (z + w)),"(t-t)*(t+t)")
11942 define_sfop4(ext16,((x - y) / (z + w)),"(t-t)/(t+t)")
11943 define_sfop4(ext17,((x * y) - (z + w)),"(t*t)-(t+t)")
11944 define_sfop4(ext18,((x / y) - (z + w)),"(t/t)-(t+t)")
11945 define_sfop4(ext19,((x * y) + (z + w)),"(t*t)+(t+t)")
11946 define_sfop4(ext20,((x / y) + (z + w)),"(t/t)+(t+t)")
11947 define_sfop4(ext21,((x * y) + (z - w)),"(t*t)+(t-t)")
11948 define_sfop4(ext22,((x / y) + (z - w)),"(t/t)+(t-t)")
11949 define_sfop4(ext23,((x * y) - (z - w)),"(t*t)-(t-t)")
11950 define_sfop4(ext24,((x / y) - (z - w)),"(t/t)-(t-t)")
11951 define_sfop4(ext25,((x + y) * (z * w)),"(t+t)*(t*t)")
11952 define_sfop4(ext26,((x + y) * (z / w)),"(t+t)*(t/t)")
11953 define_sfop4(ext27,((x + y) / (z * w)),"(t+t)/(t*t)")
11954 define_sfop4(ext28,((x + y) / (z / w)),"(t+t)/(t/t)")
11955 define_sfop4(ext29,((x - y) / (z * w)),"(t-t)/(t*t)")
11956 define_sfop4(ext30,((x - y) / (z / w)),"(t-t)/(t/t)")
11957 define_sfop4(ext31,((x - y) * (z * w)),"(t-t)*(t*t)")
11958 define_sfop4(ext32,((x - y) * (z / w)),"(t-t)*(t/t)")
11959 define_sfop4(ext33,((x * y) * (z + w)),"(t*t)*(t+t)")
11960 define_sfop4(ext34,((x / y) * (z + w)),"(t/t)*(t+t)")
11961 define_sfop4(ext35,((x * y) / (z + w)),"(t*t)/(t+t)")
11962 define_sfop4(ext36,((x / y) / (z + w)),"(t/t)/(t+t)")
11963 define_sfop4(ext37,((x * y) / (z - w)),"(t*t)/(t-t)")
11964 define_sfop4(ext38,((x / y) / (z - w)),"(t/t)/(t-t)")
11965 define_sfop4(ext39,((x * y) * (z - w)),"(t*t)*(t-t)")
11966 define_sfop4(ext40,((x * y) / (z * w)),"(t*t)/(t*t)")
11967 define_sfop4(ext41,((x / y) * (z / w)),"(t/t)*(t/t)")
11968 define_sfop4(ext42,((x / y) * (z - w)),"(t/t)*(t-t)")
11969 define_sfop4(ext43,((x * y) * (z * w)),"(t*t)*(t*t)")
11970 define_sfop4(ext44,(x + (y * (z / w))),"t+(t*(t/t))")
11971 define_sfop4(ext45,(x - (y * (z / w))),"t-(t*(t/t))")
11972 define_sfop4(ext46,(x + (y / (z * w))),"t+(t/(t*t))")
11973 define_sfop4(ext47,(x - (y / (z * w))),"t-(t/(t*t))")
11974 define_sfop4(ext48,(((x - y) - z) * w),"((t-t)-t)*t")
11975 define_sfop4(ext49,(((x - y) - z) / w),"((t-t)-t)/t")
11976 define_sfop4(ext50,(((x - y) + z) * w),"((t-t)+t)*t")
11977 define_sfop4(ext51,(((x - y) + z) / w),"((t-t)+t)/t")
11978 define_sfop4(ext52,((x + (y - z)) * w),"(t+(t-t))*t")
11979 define_sfop4(ext53,((x + (y - z)) / w),"(t+(t-t))/t")
11980 define_sfop4(ext54,((x + y) / (z + w)),"(t+t)/(t+t)")
11981 define_sfop4(ext55,((x - y) / (z - w)),"(t-t)/(t-t)")
11982 define_sfop4(ext56,((x + y) * (z + w)),"(t+t)*(t+t)")
11983 define_sfop4(ext57,((x - y) * (z - w)),"(t-t)*(t-t)")
11984 define_sfop4(ext58,((x - y) + (z - w)),"(t-t)+(t-t)")
11985 define_sfop4(ext59,((x - y) - (z - w)),"(t-t)-(t-t)")
11986 define_sfop4(ext60,((x / y) + (z * w)),"(t/t)+(t*t)")
11987 define_sfop4(ext61,(((x * y) * z) / w),"((t*t)*t)/t")
11988
11989 #undef define_sfop3
11990 #undef define_sfop4
11991
11992 template <typename T, typename SpecialFunction>
11994 {
11995 public:
11996
11998
12005
12007 {
12008 const T x = trinary_node<T>::branch_[0].first->value();
12009 const T y = trinary_node<T>::branch_[1].first->value();
12010 const T z = trinary_node<T>::branch_[2].first->value();
12011
12012 return SpecialFunction::process(x, y, z);
12013 }
12014 };
12015
12016 template <typename T, typename SpecialFunction>
12018 {
12019 public:
12020
12022
12030
12032 {
12033 const T x = quaternary_node<T>::branch_[0].first->value();
12034 const T y = quaternary_node<T>::branch_[1].first->value();
12035 const T z = quaternary_node<T>::branch_[2].first->value();
12036 const T w = quaternary_node<T>::branch_[3].first->value();
12037
12038 return SpecialFunction::process(x, y, z, w);
12039 }
12040 };
12041
12042 template <typename T, typename SpecialFunction>
12044 {
12045 public:
12046
12048
12049 sf3_var_node(const T& v0, const T& v1, const T& v2)
12050 : v0_(v0)
12051 , v1_(v1)
12052 , v2_(v2)
12053 {}
12054
12056 {
12057 return SpecialFunction::process(v0_, v1_, v2_);
12058 }
12059
12064
12065 private:
12066
12069
12070 const T& v0_;
12071 const T& v1_;
12072 const T& v2_;
12073 };
12074
12075 template <typename T, typename SpecialFunction>
12077 {
12078 public:
12079
12081
12082 sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
12083 : v0_(v0)
12084 , v1_(v1)
12085 , v2_(v2)
12086 , v3_(v3)
12087 {}
12088
12090 {
12091 return SpecialFunction::process(v0_, v1_, v2_, v3_);
12092 }
12093
12098
12099 private:
12100
12103
12104 const T& v0_;
12105 const T& v1_;
12106 const T& v2_;
12107 const T& v3_;
12108 };
12109
12110 template <typename T, typename VarArgFunction>
12112 {
12113 public:
12114
12116 typedef std::pair<expression_ptr,bool> branch_t;
12117
12118 template <typename Allocator,
12119 template <typename, typename> class Sequence>
12122 {
12123 arg_list_.resize(arg_list.size());
12124
12125 for (std::size_t i = 0; i < arg_list.size(); ++i)
12126 {
12127 if (arg_list[i] && arg_list[i]->valid())
12128 {
12130 }
12131 else
12132 {
12133 arg_list_.clear();
12134 return;
12135 }
12136 }
12137
12138 initialised_ = (arg_list_.size() == arg_list.size());
12139 assert(valid());
12140 }
12141
12143 {
12144 return VarArgFunction::process(arg_list_);
12145 }
12146
12151
12153 {
12154 return initialised_;
12155 }
12156
12161
12166
12167 std::size_t size() const
12168 {
12169 return arg_list_.size();
12170 }
12171
12172 expression_ptr operator[](const std::size_t& index) const
12173 {
12174 return arg_list_[index].first;
12175 }
12176
12177 private:
12178
12179 std::vector<branch_t> arg_list_;
12181 };
12182
12183 template <typename T, typename VarArgFunction>
12185 {
12186 public:
12187
12189
12190 template <typename Allocator,
12191 template <typename, typename> class Sequence>
12194 {
12195 arg_list_.resize(arg_list.size());
12196
12197 for (std::size_t i = 0; i < arg_list.size(); ++i)
12198 {
12200 {
12202 arg_list_[i] = (&var_node_ptr->ref());
12203 }
12204 else
12205 {
12206 arg_list_.clear();
12207 return;
12208 }
12209 }
12210
12211 initialised_ = (arg_list.size() == arg_list_.size());
12212 assert(valid());
12213 }
12214
12216 {
12217 return VarArgFunction::process(arg_list_);
12218 }
12219
12224
12226 {
12227 return initialised_;
12228 }
12229
12230 private:
12231
12232 std::vector<const T*> arg_list_;
12234 };
12235
12236 template <typename T, typename VecFunction>
12238 {
12239 public:
12240
12242 typedef std::pair<expression_ptr,bool> branch_t;
12243
12245 : ivec_ptr_(0)
12246 {
12248
12249 if (is_ivector_node(v_.first))
12250 {
12251 ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v_.first);
12252 }
12253 }
12254
12256 {
12257 v_.first->value();
12258 return VecFunction::process(ivec_ptr_);
12259 }
12260
12265
12267 {
12268 return ivec_ptr_ && v_.first && v_.first->valid();
12269 }
12270
12275
12280
12281 private:
12282
12285 };
12286
12287 template <typename T>
12289 {
12290 public:
12291
12293 using binary_node<T>::branch;
12294
12299 , var_node_ptr_(0)
12300 {
12301 if (is_variable_node(branch(0)))
12302 {
12303 var_node_ptr_ = static_cast<variable_node<T>*>(branch(0));
12304 }
12305 }
12306
12308 {
12309 T& result = var_node_ptr_->ref();
12310 result = branch(1)->value();
12311
12312 return result;
12313 }
12314
12316 {
12318 }
12319
12320 private:
12321
12323 };
12324
12325 template <typename T>
12327 {
12328 public:
12329
12331 using binary_node<T>::branch;
12332
12337 , vec_node_ptr_(0)
12338 {
12340 {
12341 vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
12342 }
12343
12344 assert(valid());
12345 }
12346
12348 {
12349 T& result = vec_node_ptr_->ref();
12350 result = branch(1)->value();
12351
12352 return result;
12353 }
12354
12356 {
12358 }
12359
12360 private:
12361
12363 };
12364
12365 template <typename T>
12367 {
12368 public:
12369
12371 using binary_node<T>::branch;
12372
12377 , vec_node_ptr_(0)
12378 {
12380 {
12381 vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
12382 }
12383
12384 assert(valid());
12385 }
12386
12388 {
12389 T& result = vec_node_ptr_->ref();
12390 result = branch(1)->value();
12391
12392 return result;
12393 }
12394
12396 {
12398 }
12399
12400 private:
12401
12403 };
12404
12405 template <typename T>
12407 {
12408 public:
12409
12412
12417 , rbvec_node_ptr_(0)
12418 {
12420 {
12422 }
12423
12424 assert(valid());
12425 }
12426
12428 {
12429 T& result = rbvec_node_ptr_->ref();
12430 result = branch(1)->value();
12431
12432 return result;
12433 }
12434
12436 {
12438 }
12439
12440 private:
12441
12443 };
12444
12445 template <typename T>
12447 {
12448 public:
12449
12452
12466
12468 {
12469 T& result = rbvec_node_ptr_->ref();
12470 result = branch(1)->value();
12471
12472 return result;
12473 }
12474
12476 {
12478 }
12479
12480 private:
12481
12483 };
12484
12485 template <typename T>
12487 {
12488 public:
12489
12491 using binary_node<T>::branch;
12492
12497 , rbvec_node_ptr_(0)
12498 {
12500 {
12502 }
12503
12504 assert(valid());
12505 }
12506
12508 {
12509 T& result = rbvec_node_ptr_->ref();
12510 result = branch(1)->value();
12511
12512 return result;
12513 }
12514
12516 {
12518 }
12519
12520 private:
12521
12523 };
12524
12525 template <typename T>
12527 : public binary_node <T>
12528 , public vector_interface<T>
12529 {
12530 public:
12531
12535
12536 using binary_node<T>::branch;
12537
12542 , vec_node_ptr_(0)
12543 {
12544 if (is_vector_node(branch(0)))
12545 {
12546 vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
12547 vds() = vec_node_ptr_->vds();
12548 }
12549
12550 assert(valid());
12551 }
12552
12554 {
12555 const T v = branch(1)->value();
12556
12557 T* vec = vds().data();
12558
12560 const T* upper_bound = vec + lud.upper_bound;
12561
12562 while (vec < upper_bound)
12563 {
12564 #define exprtk_loop(N) \
12565 vec[N] = v; \
12566
12567 exprtk_loop( 0) exprtk_loop( 1)
12568 exprtk_loop( 2) exprtk_loop( 3)
12569 #ifndef exprtk_disable_superscalar_unroll
12570 exprtk_loop( 4) exprtk_loop( 5)
12571 exprtk_loop( 6) exprtk_loop( 7)
12572 exprtk_loop( 8) exprtk_loop( 9)
12573 exprtk_loop(10) exprtk_loop(11)
12574 exprtk_loop(12) exprtk_loop(13)
12575 exprtk_loop(14) exprtk_loop(15)
12576 #endif
12577
12578 vec += lud.batch_size;
12579 }
12580
12581 switch (lud.remainder)
12582 {
12583 #define case_stmt(N) \
12584 case N : *vec++ = v; \
12585 exprtk_fallthrough \
12586
12587 #ifndef exprtk_disable_superscalar_unroll
12588 case_stmt(15) case_stmt(14)
12589 case_stmt(13) case_stmt(12)
12590 case_stmt(11) case_stmt(10)
12591 case_stmt( 9) case_stmt( 8)
12592 case_stmt( 7) case_stmt( 6)
12593 case_stmt( 5) case_stmt( 4)
12594 #endif
12595 case_stmt( 3) case_stmt( 2)
12596 case 1 : *vec++ = v;
12597 }
12598
12599 #undef exprtk_loop
12600 #undef case_stmt
12601
12602 return vec_node_ptr_->value();
12603 }
12604
12606 {
12607 return vec_node_ptr_;
12608 }
12609
12611 {
12612 return vec_node_ptr_;
12613 }
12614
12619
12621 {
12622 return
12623 vec_node_ptr_ &&
12624 (vds().size() <= vec_node_ptr_->vec_holder().base_size()) &&
12626 }
12627
12629 {
12630 return vec_node_ptr_->vec_holder().size();
12631 }
12632
12634 {
12635 return vec_node_ptr_->vec_holder().base_size();
12636 }
12637
12639 {
12640 return vds_;
12641 }
12642
12644 {
12645 return vds_;
12646 }
12647
12648 private:
12649
12652 };
12653
12654 template <typename T>
12656 : public binary_node <T>
12657 , public vector_interface<T>
12658 {
12659 public:
12660
12664
12665 using binary_node<T>::branch;
12666
12671 , vec0_node_ptr_(0)
12672 , vec1_node_ptr_(0)
12675 {
12676 if (is_vector_node(branch(0)))
12677 {
12678 vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
12679 vds() = vec0_node_ptr_->vds();
12680 }
12681
12682 if (is_vector_node(branch(1)))
12683 {
12684 vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1));
12686 }
12687 else if (is_ivector_node(branch(1)))
12688 {
12689 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
12690
12691 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
12692 {
12693 vec1_node_ptr_ = vi->vec();
12694
12695 if (!vi->side_effect())
12696 {
12697 vi->vds() = vds();
12698 src_is_ivec_ = true;
12699 }
12700 else
12701 vds_t::match_sizes(vds(),vi->vds());
12702 }
12703 }
12704
12705 initialised_ =
12708 (size() <= base_size()) &&
12709 (vds_.size() <= base_size()) &&
12711
12712 assert(valid());
12713 }
12714
12716 {
12717 branch(1)->value();
12718
12719 if (src_is_ivec_)
12720 return vec0_node_ptr_->value();
12721
12722 T* vec0 = vec0_node_ptr_->vds().data();
12723 T* vec1 = vec1_node_ptr_->vds().data();
12724
12726 const T* upper_bound = vec0 + lud.upper_bound;
12727
12728 while (vec0 < upper_bound)
12729 {
12730 #define exprtk_loop(N) \
12731 vec0[N] = vec1[N]; \
12732
12733 exprtk_loop( 0) exprtk_loop( 1)
12734 exprtk_loop( 2) exprtk_loop( 3)
12735 #ifndef exprtk_disable_superscalar_unroll
12736 exprtk_loop( 4) exprtk_loop( 5)
12737 exprtk_loop( 6) exprtk_loop( 7)
12738 exprtk_loop( 8) exprtk_loop( 9)
12739 exprtk_loop(10) exprtk_loop(11)
12740 exprtk_loop(12) exprtk_loop(13)
12741 exprtk_loop(14) exprtk_loop(15)
12742 #endif
12743
12744 vec0 += lud.batch_size;
12745 vec1 += lud.batch_size;
12746 }
12747
12748 switch (lud.remainder)
12749 {
12750 #define case_stmt(N,fall_through) \
12751 case N : *vec0++ = *vec1++; \
12752 fall_through \
12753
12754 #ifndef exprtk_disable_superscalar_unroll
12761 #endif
12763 case_stmt( 1, (void)0;)
12764 }
12765
12766 #undef exprtk_loop
12767 #undef case_stmt
12768
12769 return vec0_node_ptr_->value();
12770 }
12771
12773 {
12774 return vec0_node_ptr_;
12775 }
12776
12778 {
12779 return vec0_node_ptr_;
12780 }
12781
12786
12788 {
12789 return initialised_;
12790 }
12791
12793 {
12794 return std::min(
12795 vec0_node_ptr_->vec_holder().size(),
12796 vec1_node_ptr_->vec_holder().size());
12797 }
12798
12800 {
12801 return std::min(
12802 vec0_node_ptr_->vec_holder().base_size(),
12803 vec1_node_ptr_->vec_holder().base_size());
12804 }
12805
12807 {
12808 return vds_;
12809 }
12810
12812 {
12813 return vds_;
12814 }
12815
12816 private:
12817
12823 };
12824
12825 template <typename T, typename Operation>
12827 {
12828 public:
12829
12831 using binary_node<T>::branch;
12832
12837 , var_node_ptr_(0)
12838 {
12839 if (is_variable_node(branch(0)))
12840 {
12841 var_node_ptr_ = static_cast<variable_node<T>*>(branch(0));
12842 }
12843
12844 assert(valid());
12845 }
12846
12848 {
12849 T& v = var_node_ptr_->ref();
12850 v = Operation::process(v,branch(1)->value());
12851
12852 return v;
12853 }
12854
12856 {
12858 }
12859
12860 private:
12861
12863 };
12864
12865 template <typename T, typename Operation>
12867 {
12868 public:
12869
12871 using binary_node<T>::branch;
12872
12877 , vec_node_ptr_(0)
12878 {
12880 {
12881 vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
12882 }
12883
12884 assert(valid());
12885 }
12886
12888 {
12889 T& v = vec_node_ptr_->ref();
12890 v = Operation::process(v,branch(1)->value());
12891
12892 return v;
12893 }
12894
12896 {
12898 }
12899
12900 private:
12901
12903 };
12904
12905 template <typename T, typename Operation>
12907 {
12908 public:
12909
12911 using binary_node<T>::branch;
12912
12917 , vec_node_ptr_(0)
12918 {
12920 {
12921 vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
12922 }
12923
12924 assert(valid());
12925 }
12926
12928 {
12929 T& v = vec_node_ptr_->ref();
12930 v = Operation::process(v,branch(1)->value());
12931
12932 return v;
12933 }
12934
12936 {
12938 }
12939
12940 private:
12941
12943 };
12944
12945 template <typename T, typename Operation>
12947 {
12948 public:
12949
12951 using binary_node<T>::branch;
12952
12957 , vec_node_ptr_(0)
12958 {
12960 {
12961 vec_node_ptr_ = static_cast<vector_celem_rtc_node<T>*>(branch(0));
12962 }
12963
12964 assert(valid());
12965 }
12966
12968 {
12969 T& v = vec_node_ptr_->ref();
12970 v = Operation::process(v,branch(1)->value());
12971
12972 return v;
12973 }
12974
12976 {
12978 }
12979
12980 private:
12981
12983 };
12984
12985 template <typename T, typename Operation>
12987 {
12988 public:
12989
12991 using binary_node<T>::branch;
12992
12997 , rbvec_node_ptr_(0)
12998 {
13000 {
13002 }
13003
13004 assert(valid());
13005 }
13006
13008 {
13009 T& v = rbvec_node_ptr_->ref();
13010 v = Operation::process(v,branch(1)->value());
13011
13012 return v;
13013 }
13014
13016 {
13018 }
13019
13020 private:
13021
13023 };
13024
13025 template <typename T, typename Operation>
13027 {
13028 public:
13029
13031 using binary_node<T>::branch;
13032
13037 , rbvec_node_ptr_(0)
13038 {
13040 {
13042 }
13043
13044 assert(valid());
13045 }
13046
13048 {
13049 T& v = rbvec_node_ptr_->ref();
13050 v = Operation::process(v,branch(1)->value());
13051
13052 return v;
13053 }
13054
13056 {
13058 }
13059
13060 private:
13061
13063 };
13064
13065 template <typename T, typename Operation>
13067 {
13068 public:
13069
13071 using binary_node<T>::branch;
13072
13086
13088 {
13089 T& v = rbvec_node_ptr_->ref();
13090 v = Operation::process(v,branch(1)->value());
13091
13092 return v;
13093 }
13094
13096 {
13098 }
13099
13100 private:
13101
13103 };
13104
13105 template <typename T, typename Operation>
13107 {
13108 public:
13109
13111 using binary_node<T>::branch;
13112
13126
13128 {
13129 T& v = rbvec_node_ptr_->ref();
13130 v = Operation::process(v,branch(1)->value());
13131
13132 return v;
13133 }
13134
13136 {
13138 }
13139
13140 private:
13141
13143 };
13144
13145 template <typename T, typename Operation>
13147 : public binary_node <T>
13148 , public vector_interface<T>
13149 {
13150 public:
13151
13155
13156 using binary_node<T>::branch;
13157
13162 , vec_node_ptr_(0)
13163 {
13164 if (is_vector_node(branch(0)))
13165 {
13166 vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
13167 vds() = vec_node_ptr_->vds();
13168 }
13169
13170 assert(valid());
13171 }
13172
13174 {
13175 const T v = branch(1)->value();
13176
13177 T* vec = vds().data();
13178
13180 const T* upper_bound = vec + lud.upper_bound;
13181
13182 while (vec < upper_bound)
13183 {
13184 #define exprtk_loop(N) \
13185 Operation::assign(vec[N],v); \
13186
13187 exprtk_loop( 0) exprtk_loop( 1)
13188 exprtk_loop( 2) exprtk_loop( 3)
13189 #ifndef exprtk_disable_superscalar_unroll
13190 exprtk_loop( 4) exprtk_loop( 5)
13191 exprtk_loop( 6) exprtk_loop( 7)
13192 exprtk_loop( 8) exprtk_loop( 9)
13193 exprtk_loop(10) exprtk_loop(11)
13194 exprtk_loop(12) exprtk_loop(13)
13195 exprtk_loop(14) exprtk_loop(15)
13196 #endif
13197
13198 vec += lud.batch_size;
13199 }
13200
13201 switch (lud.remainder)
13202 {
13203 #define case_stmt(N,fall_through) \
13204 case N : Operation::assign(*vec++,v); \
13205 fall_through \
13206
13207 #ifndef exprtk_disable_superscalar_unroll
13214 #endif
13216 case_stmt( 1, (void)0;)
13217 }
13218
13219 #undef exprtk_loop
13220 #undef case_stmt
13221
13222 return vec_node_ptr_->value();
13223 }
13224
13226 {
13227 return vec_node_ptr_;
13228 }
13229
13231 {
13232 return vec_node_ptr_;
13233 }
13234
13239
13241 {
13242 return
13243 vec_node_ptr_ &&
13244 (size() <= base_size()) &&
13246 }
13247
13249 {
13250 return vec_node_ptr_->vec_holder().size();
13251 }
13252
13254 {
13255 return vec_node_ptr_->vec_holder().base_size();
13256 }
13257
13259 {
13260 return vds_;
13261 }
13262
13264 {
13265 return vds_;
13266 }
13267
13269 {
13270 return true;
13271 }
13272
13273 private:
13274
13277 };
13278
13279 template <typename T, typename Operation>
13281 : public binary_node <T>
13282 , public vector_interface<T>
13283 {
13284 public:
13285
13289
13290 using binary_node<T>::branch;
13291
13296 , vec0_node_ptr_(0)
13297 , vec1_node_ptr_(0)
13299 {
13300 if (is_vector_node(branch(0)))
13301 {
13302 vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
13303 vds() = vec0_node_ptr_->vds();
13304 }
13305
13306 if (is_vector_node(branch(1)))
13307 {
13308 vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1));
13309 vec1_node_ptr_->vds() = vds();
13310 }
13311 else if (is_ivector_node(branch(1)))
13312 {
13313 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13314
13315 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
13316 {
13317 vec1_node_ptr_ = vi->vec();
13318 vec1_node_ptr_->vds() = vi->vds();
13319 }
13320 else
13322 }
13323
13324 initialised_ =
13327 (size() <= base_size()) &&
13329
13330 assert(valid());
13331 }
13332
13334 {
13335 branch(0)->value();
13336 branch(1)->value();
13337
13338 T* vec0 = vec0_node_ptr_->vds().data();
13339 const T* vec1 = vec1_node_ptr_->vds().data();
13340
13342 const T* upper_bound = vec0 + lud.upper_bound;
13343
13344 while (vec0 < upper_bound)
13345 {
13346 #define exprtk_loop(N) \
13347 vec0[N] = Operation::process(vec0[N], vec1[N]); \
13348
13349 exprtk_loop( 0) exprtk_loop( 1)
13350 exprtk_loop( 2) exprtk_loop( 3)
13351 #ifndef exprtk_disable_superscalar_unroll
13352 exprtk_loop( 4) exprtk_loop( 5)
13353 exprtk_loop( 6) exprtk_loop( 7)
13354 exprtk_loop( 8) exprtk_loop( 9)
13355 exprtk_loop(10) exprtk_loop(11)
13356 exprtk_loop(12) exprtk_loop(13)
13357 exprtk_loop(14) exprtk_loop(15)
13358 #endif
13359
13360 vec0 += lud.batch_size;
13361 vec1 += lud.batch_size;
13362 }
13363
13364 int i = 0;
13365
13366 switch (lud.remainder)
13367 {
13368 #define case_stmt(N,fall_through) \
13369 case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
13370 fall_through \
13371
13372 #ifndef exprtk_disable_superscalar_unroll
13379 #endif
13381 case_stmt( 1, (void)0;)
13382 }
13383
13384 #undef exprtk_loop
13385 #undef case_stmt
13386
13387 return vec0_node_ptr_->value();
13388 }
13389
13391 {
13392 return vec0_node_ptr_;
13393 }
13394
13396 {
13397 return vec0_node_ptr_;
13398 }
13399
13404
13406 {
13407 return initialised_;
13408 }
13409
13411 {
13412 return std::min(
13413 vec0_node_ptr_->vec_holder().size(),
13414 vec1_node_ptr_->vec_holder().size());
13415 }
13416
13418 {
13419 return std::min(
13420 vec0_node_ptr_->vec_holder().base_size(),
13421 vec1_node_ptr_->vec_holder().base_size());
13422 }
13423
13425 {
13426 return vds_;
13427 }
13428
13430 {
13431 return vds_;
13432 }
13433
13435 {
13436 return true;
13437 }
13438
13439 private:
13440
13445 };
13446
13447 template <typename T>
13449 {
13453
13455 : temp_(0)
13456 , temp_vec_node_(0)
13457 {}
13458
13459 void clear()
13460 {
13461 delete temp_vec_node_;
13462 delete temp_;
13463 }
13464
13467 };
13468
13469 template <typename T>
13471 vec_data_store<T>& vds)
13472 {
13474 result_ctxt.temp_ = (vec_holder.rebaseable()) ?
13475 new vector_holder<T>(vec_holder,vds) :
13476 new vector_holder<T>(vds) ;
13477 result_ctxt.temp_vec_node_ = new vector_node <T>(vds,result_ctxt.temp_);
13478 return result_ctxt;
13479 }
13480
13481 template <typename T>
13484 vec_data_store<T>& vds)
13485 {
13487
13488 if (!vec_holder0.rebaseable() && !vec_holder1.rebaseable())
13490 else if (vec_holder0.rebaseable() && !vec_holder1.rebaseable())
13491 result_ctxt.temp_ = new vector_holder<T>(vec_holder0,vds);
13492 else if (!vec_holder0.rebaseable() && vec_holder1.rebaseable())
13493 result_ctxt.temp_ = new vector_holder<T>(vec_holder1,vds);
13494 else
13495 {
13496 result_ctxt.temp_ = (vec_holder0.base_size() >= vec_holder1.base_size()) ?
13497 new vector_holder<T>(vec_holder0, vds) :
13498 new vector_holder<T>(vec_holder1, vds) ;
13499 }
13500
13501 result_ctxt.temp_vec_node_ = new vector_node <T>(vds,result_ctxt.temp_);
13502 return result_ctxt;
13503 }
13504
13505 template <typename T, typename Operation>
13507 : public binary_node <T>
13508 , public vector_interface<T>
13509 {
13510 public:
13511
13518
13519 using binary_node<T>::branch;
13520
13525 , vec0_node_ptr_(0)
13526 , vec1_node_ptr_(0)
13528 {
13529 bool v0_is_ivec = false;
13530 bool v1_is_ivec = false;
13531
13532 if (is_vector_node(branch(0)))
13533 {
13534 vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
13535 }
13536 else if (is_ivector_node(branch(0)))
13537 {
13538 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13539
13540 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
13541 {
13542 vec0_node_ptr_ = vi->vec();
13543 v0_is_ivec = true;
13544 }
13545 }
13546
13547 if (is_vector_node(branch(1)))
13548 {
13549 vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1));
13550 }
13551 else if (is_ivector_node(branch(1)))
13552 {
13553 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13554
13555 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
13556 {
13557 vec1_node_ptr_ = vi->vec();
13558 v1_is_ivec = true;
13559 }
13560 }
13561
13563 {
13566
13567 if (v0_is_ivec && (vec0.base_size() <= vec1.base_size()))
13568 {
13570 }
13571 else if (v1_is_ivec && (vec1.base_size() <= vec0.base_size()))
13572 {
13574 }
13575 else
13576 {
13577 vds_ = vds_t(std::min(vec0.base_size(),vec1.base_size()));
13578 }
13579
13581
13582 initialised_ =
13583 (size() <= base_size()) &&
13585 }
13586
13587 assert(valid());
13588 }
13589
13591 {
13593 }
13594
13596 {
13597 branch(0)->value();
13598 branch(1)->value();
13599
13600 const T* vec0 = vec0_node_ptr_->vds().data();
13601 const T* vec1 = vec1_node_ptr_->vds().data();
13602 T* vec2 = vds().data();
13603
13605 const T* upper_bound = vec2 + lud.upper_bound;
13606
13607 while (vec2 < upper_bound)
13608 {
13609 #define exprtk_loop(N) \
13610 vec2[N] = Operation::process(vec0[N], vec1[N]); \
13611
13612 exprtk_loop( 0) exprtk_loop( 1)
13613 exprtk_loop( 2) exprtk_loop( 3)
13614 #ifndef exprtk_disable_superscalar_unroll
13615 exprtk_loop( 4) exprtk_loop( 5)
13616 exprtk_loop( 6) exprtk_loop( 7)
13617 exprtk_loop( 8) exprtk_loop( 9)
13618 exprtk_loop(10) exprtk_loop(11)
13619 exprtk_loop(12) exprtk_loop(13)
13620 exprtk_loop(14) exprtk_loop(15)
13621 #endif
13622
13623 vec0 += lud.batch_size;
13624 vec1 += lud.batch_size;
13625 vec2 += lud.batch_size;
13626 }
13627
13628 int i = 0;
13629
13630 switch (lud.remainder)
13631 {
13632 #define case_stmt(N) \
13633 case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
13634 exprtk_fallthrough \
13635
13636 #ifndef exprtk_disable_superscalar_unroll
13637 case_stmt(15) case_stmt(14)
13638 case_stmt(13) case_stmt(12)
13639 case_stmt(11) case_stmt(10)
13640 case_stmt( 9) case_stmt( 8)
13641 case_stmt( 7) case_stmt( 6)
13642 case_stmt( 5) case_stmt( 4)
13643 #endif
13644 case_stmt( 3) case_stmt( 2)
13645 case_stmt( 1)
13646 default: break;
13647 }
13648
13649 #undef exprtk_loop
13650 #undef case_stmt
13651
13652 return (vds().data())[0];
13653 }
13654
13659
13664
13669
13671 {
13672 return initialised_;
13673 }
13674
13676 {
13677 return std::min(
13680 }
13681
13683 {
13684 return std::min(
13687 }
13688
13690 {
13691 return vds_;
13692 }
13693
13695 {
13696 return vds_;
13697 }
13698
13699 private:
13700
13706 };
13707
13708 template <typename T, typename Operation>
13710 : public binary_node <T>
13711 , public vector_interface<T>
13712 {
13713 public:
13714
13721
13722 using binary_node<T>::branch;
13723
13728 , vec0_node_ptr_(0)
13729 {
13730 bool v0_is_ivec = false;
13731
13732 if (is_vector_node(branch(0)))
13733 {
13734 vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
13735 }
13736 else if (is_ivector_node(branch(0)))
13737 {
13738 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13739
13740 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
13741 {
13742 vec0_node_ptr_ = vi->vec();
13743 v0_is_ivec = true;
13744 }
13745 }
13746
13747 if (vec0_node_ptr_)
13748 {
13749 if (v0_is_ivec)
13750 vds() = vec0_node_ptr_->vds();
13751 else
13753
13755 }
13756
13757 assert(valid());
13758 }
13759
13761 {
13763 }
13764
13766 {
13767 branch(0)->value();
13768 const T v = branch(1)->value();
13769
13770 const T* vec0 = vec0_node_ptr_->vds().data();
13771 T* vec1 = vds().data();
13772
13774 const T* upper_bound = vec0 + lud.upper_bound;
13775
13776 while (vec0 < upper_bound)
13777 {
13778 #define exprtk_loop(N) \
13779 vec1[N] = Operation::process(vec0[N], v); \
13780
13781 exprtk_loop( 0) exprtk_loop( 1)
13782 exprtk_loop( 2) exprtk_loop( 3)
13783 #ifndef exprtk_disable_superscalar_unroll
13784 exprtk_loop( 4) exprtk_loop( 5)
13785 exprtk_loop( 6) exprtk_loop( 7)
13786 exprtk_loop( 8) exprtk_loop( 9)
13787 exprtk_loop(10) exprtk_loop(11)
13788 exprtk_loop(12) exprtk_loop(13)
13789 exprtk_loop(14) exprtk_loop(15)
13790 #endif
13791
13792 vec0 += lud.batch_size;
13793 vec1 += lud.batch_size;
13794 }
13795
13796 int i = 0;
13797
13798 switch (lud.remainder)
13799 {
13800 #define case_stmt(N,fall_through) \
13801 case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
13802 fall_through \
13803
13804 #ifndef exprtk_disable_superscalar_unroll
13811 #endif
13813 case_stmt( 1, (void)0;)
13814 }
13815
13816 #undef exprtk_loop
13817 #undef case_stmt
13818
13819 return (vds().data())[0];
13820 }
13821
13826
13831
13836
13838 {
13839 return
13841 (size() <= base_size()) &&
13843 }
13844
13846 {
13847 return vec0_node_ptr_->size();
13848 }
13849
13851 {
13853 }
13854
13856 {
13857 return vds_;
13858 }
13859
13861 {
13862 return vds_;
13863 }
13864
13865 private:
13866
13870 };
13871
13872 template <typename T, typename Operation>
13874 : public binary_node <T>
13875 , public vector_interface<T>
13876 {
13877 public:
13878
13885
13886 using binary_node<T>::branch;
13887
13892 , vec1_node_ptr_(0)
13893 {
13894 bool v1_is_ivec = false;
13895
13896 if (is_vector_node(branch(1)))
13897 {
13898 vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1));
13899 }
13900 else if (is_ivector_node(branch(1)))
13901 {
13902 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13903
13904 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
13905 {
13906 vec1_node_ptr_ = vi->vec();
13907 v1_is_ivec = true;
13908 }
13909 }
13910
13911 if (vec1_node_ptr_)
13912 {
13913 if (v1_is_ivec)
13914 vds() = vec1_node_ptr_->vds();
13915 else
13917
13919 }
13920
13921 assert(valid());
13922 }
13923
13925 {
13927 }
13928
13930 {
13931 const T v = branch(0)->value();
13932 branch(1)->value();
13933
13934 T* vec0 = vds().data();
13935 const T* vec1 = vec1_node_ptr_->vds().data();
13936
13938 const T* upper_bound = vec0 + lud.upper_bound;
13939
13940 while (vec0 < upper_bound)
13941 {
13942 #define exprtk_loop(N) \
13943 vec0[N] = Operation::process(v, vec1[N]); \
13944
13945 exprtk_loop( 0) exprtk_loop( 1)
13946 exprtk_loop( 2) exprtk_loop( 3)
13947 #ifndef exprtk_disable_superscalar_unroll
13948 exprtk_loop( 4) exprtk_loop( 5)
13949 exprtk_loop( 6) exprtk_loop( 7)
13950 exprtk_loop( 8) exprtk_loop( 9)
13951 exprtk_loop(10) exprtk_loop(11)
13952 exprtk_loop(12) exprtk_loop(13)
13953 exprtk_loop(14) exprtk_loop(15)
13954 #endif
13955
13956 vec0 += lud.batch_size;
13957 vec1 += lud.batch_size;
13958 }
13959
13960 int i = 0;
13961
13962 switch (lud.remainder)
13963 {
13964 #define case_stmt(N,fall_through) \
13965 case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
13966 fall_through \
13967
13968 #ifndef exprtk_disable_superscalar_unroll
13975 #endif
13977 case_stmt( 1, (void)0;)
13978 }
13979
13980 #undef exprtk_loop
13981 #undef case_stmt
13982
13983 return (vds().data())[0];
13984 }
13985
13990
13995
14000
14002 {
14003 return
14005 (size() <= base_size()) &&
14006 (vds_.size() <= base_size()) &&
14008 }
14009
14011 {
14012 return vec1_node_ptr_->vec_holder().size();
14013 }
14014
14016 {
14018 }
14019
14021 {
14022 return vds_;
14023 }
14024
14026 {
14027 return vds_;
14028 }
14029
14030 private:
14031
14035 };
14036
14037 template <typename T, typename Operation>
14039 : public unary_node <T>
14040 , public vector_interface<T>
14041 {
14042 public:
14043
14050
14052
14054 : unary_node<T>(opr, branch0)
14055 , vec0_node_ptr_(0)
14056 {
14057 bool vec0_is_ivec = false;
14058
14059 if (is_vector_node(branch(0)))
14060 {
14061 vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
14062 }
14063 else if (is_ivector_node(branch(0)))
14064 {
14065 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
14066
14067 if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
14068 {
14069 vec0_node_ptr_ = vi->vec();
14070 vec0_is_ivec = true;
14071 }
14072 }
14073
14074 if (vec0_node_ptr_)
14075 {
14076 if (vec0_is_ivec)
14077 vds_ = vec0_node_ptr_->vds();
14078 else
14080
14082 }
14083
14084 assert(valid());
14085 }
14086
14088 {
14090 }
14091
14093 {
14094 branch()->value();
14095
14096 const T* vec0 = vec0_node_ptr_->vds().data();
14097 T* vec1 = vds().data();
14098
14100 const T* upper_bound = vec0 + lud.upper_bound;
14101
14102 while (vec0 < upper_bound)
14103 {
14104 #define exprtk_loop(N) \
14105 vec1[N] = Operation::process(vec0[N]); \
14106
14107 exprtk_loop( 0) exprtk_loop( 1)
14108 exprtk_loop( 2) exprtk_loop( 3)
14109 #ifndef exprtk_disable_superscalar_unroll
14110 exprtk_loop( 4) exprtk_loop( 5)
14111 exprtk_loop( 6) exprtk_loop( 7)
14112 exprtk_loop( 8) exprtk_loop( 9)
14113 exprtk_loop(10) exprtk_loop(11)
14114 exprtk_loop(12) exprtk_loop(13)
14115 exprtk_loop(14) exprtk_loop(15)
14116 #endif
14117
14118 vec0 += lud.batch_size;
14119 vec1 += lud.batch_size;
14120 }
14121
14122 int i = 0;
14123
14124 switch (lud.remainder)
14125 {
14126 #define case_stmt(N) \
14127 case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
14128 exprtk_fallthrough \
14129
14130 #ifndef exprtk_disable_superscalar_unroll
14131 case_stmt(15) case_stmt(14)
14132 case_stmt(13) case_stmt(12)
14133 case_stmt(11) case_stmt(10)
14134 case_stmt( 9) case_stmt( 8)
14135 case_stmt( 7) case_stmt( 6)
14136 case_stmt( 5) case_stmt( 4)
14137 #endif
14138 case_stmt( 3) case_stmt( 2)
14139 case_stmt( 1)
14140 default: break;
14141 }
14142
14143 #undef exprtk_loop
14144 #undef case_stmt
14145
14146 return (vds().data())[0];
14147 }
14148
14153
14158
14163
14165 {
14167 }
14168
14170 {
14171 return vec0_node_ptr_->vec_holder().size();
14172 }
14173
14175 {
14177 }
14178
14180 {
14181 return vds_;
14182 }
14183
14185 {
14186 return vds_;
14187 }
14188
14189 private:
14190
14194 };
14195
14196 template <typename T>
14198 : public expression_node <T>
14199 , public vector_interface<T>
14200 {
14201 public:
14202
14210 typedef std::pair<expression_ptr,bool> branch_t;
14211
14217 , temp_vec_node_ (0)
14218 , temp_ (0)
14219 , result_vec_size_ (0)
14221 {
14222 construct_branch_pair(condition_ , condition );
14225
14227 {
14229
14230 if (0 != ivec_ptr)
14231 {
14233 }
14234 }
14235
14237 {
14239
14240 if (0 != ivec_ptr)
14241 {
14243 }
14244 }
14245
14247 {
14248 const std::size_t vec_size =
14249 std::max(consequent_node_ptr_ ->vec_holder().base_size(),
14251
14252 vds_ = vds_t(vec_size);
14254 consequent_node_ptr_ ->vec_holder(),
14256 vds());
14257
14258 initialised_ = (vec_size > 0);
14259 }
14260
14262 }
14263
14268
14270 {
14271 T result = T(0);
14272 T* source_vector = 0;
14273 T* result_vector = vds().data();
14274
14275 if (is_true(condition_))
14276 {
14277 result = consequent_.first->value();
14280 }
14281 else
14282 {
14283 result = alternative_.first->value();
14286 }
14287
14288 for (std::size_t i = 0; i < result_vec_size_; ++i)
14289 {
14291 }
14292
14293 return result;
14294 }
14295
14300
14305
14310
14312 {
14313 return
14314 initialised_ &&
14315 condition_ .first && condition_ .first->valid() &&
14316 consequent_ .first && consequent_ .first->valid() &&
14317 alternative_.first && alternative_.first->valid() &&
14318 size() <= base_size();
14319 }
14320
14322 {
14323 return result_vec_size_;
14324 }
14325
14327 {
14328 return std::min(
14329 consequent_node_ptr_ ->vec_holder().base_size(),
14331 }
14332
14334 {
14335 return vds_;
14336 }
14337
14339 {
14340 return vds_;
14341 }
14342
14349
14355
14356 private:
14357
14366 mutable std::size_t result_vec_size_;
14369 };
14370
14371 template <typename T>
14373 {
14374 public:
14375
14377 using binary_node<T>::branch;
14378
14386
14388 {
14389 return (
14390 std::not_equal_to<T>()
14391 (T(0),branch(0)->value()) &&
14392 std::not_equal_to<T>()
14393 (T(0),branch(1)->value())
14394 ) ? T(1) : T(0);
14395 }
14396 };
14397
14398 template <typename T>
14400 {
14401 public:
14402
14404 using binary_node<T>::branch;
14405
14413
14415 {
14416 return (
14417 std::not_equal_to<T>()
14418 (T(0),branch(0)->value()) ||
14419 std::not_equal_to<T>()
14420 (T(0),branch(1)->value())
14421 ) ? T(1) : T(0);
14422 }
14423 };
14424
14425 template <typename T, typename IFunction, std::size_t N>
14427 {
14428 public:
14429
14430 // Function of N parameters.
14432 typedef std::pair<expression_ptr,bool> branch_t;
14434
14436 : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
14437 , parameter_count_(func->param_count)
14439 {}
14440
14441 template <std::size_t NumBranches>
14443 {
14444 // Needed for incompetent and broken msvc compiler versions
14445 #ifdef _MSC_VER
14446 #pragma warning(push)
14447 #pragma warning(disable: 4127)
14448 #endif
14449
14450 if (N != NumBranches)
14451 {
14452 return false;
14453 }
14454
14455 for (std::size_t i = 0; i < NumBranches; ++i)
14456 {
14457 if (b[i] && b[i]->valid())
14458 branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
14459 else
14460 return false;
14461 }
14462
14464 assert(valid());
14465 return initialised_;
14466
14467 #ifdef _MSC_VER
14468 #pragma warning(pop)
14469 #endif
14470 }
14471
14473 {
14474 return this < (&fn);
14475 }
14476
14478 {
14479 // Needed for incompetent and broken msvc compiler versions
14480 #ifdef _MSC_VER
14481 #pragma warning(push)
14482 #pragma warning(disable: 4127)
14483 #endif
14484
14485 T v[N];
14488
14489 #ifdef _MSC_VER
14490 #pragma warning(pop)
14491 #endif
14492 }
14493
14498
14500 {
14501 return initialised_;
14502 }
14503
14508
14513
14514 template <typename T_, std::size_t BranchCount>
14516 {
14517 static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
14518 {
14519 for (std::size_t i = 0; i < BranchCount; ++i)
14520 {
14521 v[i] = b[i].first->value();
14522 }
14523 }
14524 };
14525
14526 template <typename T_>
14528 {
14529 static inline void execute(T_ (&v)[6], const branch_t (&b)[6])
14530 {
14531 v[0] = b[0].first->value();
14532 v[1] = b[1].first->value();
14533 v[2] = b[2].first->value();
14534 v[3] = b[3].first->value();
14535 v[4] = b[4].first->value();
14536 v[5] = b[5].first->value();
14537 }
14538 };
14539
14540 template <typename T_>
14542 {
14543 static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
14544 {
14545 v[0] = b[0].first->value();
14546 v[1] = b[1].first->value();
14547 v[2] = b[2].first->value();
14548 v[3] = b[3].first->value();
14549 v[4] = b[4].first->value();
14550 }
14551 };
14552
14553 template <typename T_>
14555 {
14556 static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
14557 {
14558 v[0] = b[0].first->value();
14559 v[1] = b[1].first->value();
14560 v[2] = b[2].first->value();
14561 v[3] = b[3].first->value();
14562 }
14563 };
14564
14565 template <typename T_>
14567 {
14568 static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
14569 {
14570 v[0] = b[0].first->value();
14571 v[1] = b[1].first->value();
14572 v[2] = b[2].first->value();
14573 }
14574 };
14575
14576 template <typename T_>
14578 {
14579 static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
14580 {
14581 v[0] = b[0].first->value();
14582 v[1] = b[1].first->value();
14583 }
14584 };
14585
14586 template <typename T_>
14588 {
14589 static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
14590 {
14591 v[0] = b[0].first->value();
14592 }
14593 };
14594
14595 template <typename T_, std::size_t ParamCount>
14596 struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
14597
14598 template <typename T_>
14599 struct invoke<T_,20>
14600 {
14601 static inline T_ execute(ifunction& f, T_ (&v)[20])
14602 { 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]); }
14603 };
14604
14605 template <typename T_>
14606 struct invoke<T_,19>
14607 {
14608 static inline T_ execute(ifunction& f, T_ (&v)[19])
14609 { 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]); }
14610 };
14611
14612 template <typename T_>
14613 struct invoke<T_,18>
14614 {
14615 static inline T_ execute(ifunction& f, T_ (&v)[18])
14616 { 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]); }
14617 };
14618
14619 template <typename T_>
14620 struct invoke<T_,17>
14621 {
14622 static inline T_ execute(ifunction& f, T_ (&v)[17])
14623 { 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]); }
14624 };
14625
14626 template <typename T_>
14627 struct invoke<T_,16>
14628 {
14629 static inline T_ execute(ifunction& f, T_ (&v)[16])
14630 { 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]); }
14631 };
14632
14633 template <typename T_>
14634 struct invoke<T_,15>
14635 {
14636 static inline T_ execute(ifunction& f, T_ (&v)[15])
14637 { 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]); }
14638 };
14639
14640 template <typename T_>
14641 struct invoke<T_,14>
14642 {
14643 static inline T_ execute(ifunction& f, T_ (&v)[14])
14644 { 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]); }
14645 };
14646
14647 template <typename T_>
14648 struct invoke<T_,13>
14649 {
14650 static inline T_ execute(ifunction& f, T_ (&v)[13])
14651 { 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]); }
14652 };
14653
14654 template <typename T_>
14655 struct invoke<T_,12>
14656 {
14657 static inline T_ execute(ifunction& f, T_ (&v)[12])
14658 { 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]); }
14659 };
14660
14661 template <typename T_>
14662 struct invoke<T_,11>
14663 {
14664 static inline T_ execute(ifunction& f, T_ (&v)[11])
14665 { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10]); }
14666 };
14667
14668 template <typename T_>
14669 struct invoke<T_,10>
14670 {
14671 static inline T_ execute(ifunction& f, T_ (&v)[10])
14672 { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]); }
14673 };
14674
14675 template <typename T_>
14676 struct invoke<T_,9>
14677 {
14678 static inline T_ execute(ifunction& f, T_ (&v)[9])
14679 { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); }
14680 };
14681
14682 template <typename T_>
14683 struct invoke<T_,8>
14684 {
14685 static inline T_ execute(ifunction& f, T_ (&v)[8])
14686 { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); }
14687 };
14688
14689 template <typename T_>
14690 struct invoke<T_,7>
14691 {
14692 static inline T_ execute(ifunction& f, T_ (&v)[7])
14693 { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6]); }
14694 };
14695
14696 template <typename T_>
14697 struct invoke<T_,6>
14698 {
14699 static inline T_ execute(ifunction& f, T_ (&v)[6])
14700 { return f(v[0], v[1], v[2], v[3], v[4], v[5]); }
14701 };
14702
14703 template <typename T_>
14704 struct invoke<T_,5>
14705 {
14706 static inline T_ execute(ifunction& f, T_ (&v)[5])
14707 { return f(v[0], v[1], v[2], v[3], v[4]); }
14708 };
14709
14710 template <typename T_>
14711 struct invoke<T_,4>
14712 {
14713 static inline T_ execute(ifunction& f, T_ (&v)[4])
14714 { return f(v[0], v[1], v[2], v[3]); }
14715 };
14716
14717 template <typename T_>
14718 struct invoke<T_,3>
14719 {
14720 static inline T_ execute(ifunction& f, T_ (&v)[3])
14721 { return f(v[0], v[1], v[2]); }
14722 };
14723
14724 template <typename T_>
14725 struct invoke<T_,2>
14726 {
14727 static inline T_ execute(ifunction& f, T_ (&v)[2])
14728 { return f(v[0], v[1]); }
14729 };
14730
14731 template <typename T_>
14732 struct invoke<T_,1>
14733 {
14734 static inline T_ execute(ifunction& f, T_ (&v)[1])
14735 { return f(v[0]); }
14736 };
14737
14738 private:
14739
14741 std::size_t parameter_count_;
14744 };
14745
14746 template <typename T, typename IFunction>
14748 {
14749 public:
14750
14753
14755 : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
14756 {
14757 assert(valid());
14758 }
14759
14761 {
14762 return this < (&fn);
14763 }
14764
14766 {
14767 return (*function_)();
14768 }
14769
14774
14776 {
14777 return function_;
14778 }
14779
14780 private:
14781
14783 };
14784
14785 template <typename T, typename VarArgFunction>
14787 {
14788 public:
14789
14791
14793 const std::vector<expression_ptr>& arg_list)
14794 : function_(func)
14796 {
14797 value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
14798 assert(valid());
14799 }
14800
14802 {
14803 return this < (&fn);
14804 }
14805
14807 {
14809 return (*function_)(value_list_);
14810 }
14811
14816
14818 {
14819 return function_;
14820 }
14821
14823 {
14824 for (std::size_t i = 0; i < arg_list_.size(); ++i)
14825 {
14827 {
14828 node_delete_list.push_back(&arg_list_[i]);
14829 }
14830 }
14831 }
14832
14837
14838 private:
14839
14840 inline void populate_value_list() const
14841 {
14842 for (std::size_t i = 0; i < arg_list_.size(); ++i)
14843 {
14844 value_list_[i] = arg_list_[i]->value();
14845 }
14846 }
14847
14849 std::vector<expression_ptr> arg_list_;
14850 mutable std::vector<T> value_list_;
14851 };
14852
14853 template <typename T, typename GenericFunction>
14855 {
14856 public:
14857
14867
14868 typedef std::pair<expression_ptr,bool> branch_t;
14871
14872 typedef std::vector<T> tmp_vs_t;
14873 typedef std::vector<type_store_t> typestore_list_t;
14874 typedef std::vector<range_data_type_t> range_list_t;
14875
14876 explicit generic_function_node(const std::vector<expression_ptr>& arg_list,
14877 GenericFunction* func = reinterpret_cast<GenericFunction*>(0))
14878 : function_(func)
14880 {}
14881
14883 {
14884 for (std::size_t i = 0; i < vv_list_.size(); ++i)
14885 {
14886 vecview_t& vv = vv_list_[i];
14887 if (vv && typestore_list_[i].vec_data)
14888 {
14889 vv->remove_ref(&typestore_list_[i].vec_data);
14890 typestore_list_[i].vec_data = 0;
14891 }
14892 }
14893 }
14894
14899
14904
14905 virtual bool init_branches()
14906 {
14907 expr_as_vec1_store_.resize(arg_list_.size(), T(0) );
14908 typestore_list_ .resize(arg_list_.size(), type_store_t() );
14909 range_list_ .resize(arg_list_.size(), range_data_type_t());
14910 branch_ .resize(arg_list_.size(), branch_t(reinterpret_cast<expression_ptr>(0),false));
14911 vv_list_ .resize(arg_list_.size(), vecview_t(0));
14912
14913 for (std::size_t i = 0; i < arg_list_.size(); ++i)
14914 {
14916
14917 if (0 == arg_list_[i])
14918 return false;
14919 else if (is_ivector_node(arg_list_[i]))
14920 {
14921 vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
14922
14923 if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i])))
14924 return false;
14925
14926 ts.size = vi->size();
14927 ts.data = vi->vds().data();
14929
14930 if (
14931 vi->vec()->vec_holder().rebaseable() &&
14932 vi->vec()->vec_holder().rebaseable_instance()
14933 )
14934 {
14935 vv_list_[i] = vi->vec()->vec_holder().rebaseable_instance();
14936 vv_list_[i]->set_ref(&ts.vec_data);
14937 }
14938 }
14939 #ifndef exprtk_disable_string_capabilities
14941 {
14942 string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0);
14943
14944 if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i])))
14945 return false;
14946
14947 ts.size = sbn->size();
14948 ts.data = reinterpret_cast<void*>(const_cast<char_ptr>(sbn->base()));
14950
14951 range_list_[i].data = ts.data;
14952 range_list_[i].size = ts.size;
14953 range_list_[i].type_size = sizeof(char);
14954 range_list_[i].str_node = sbn;
14955
14956 range_interface_t* ri = reinterpret_cast<range_interface_t*>(0);
14957
14958 if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i])))
14959 return false;
14960
14961 const range_t& rp = ri->range_ref();
14962
14963 if (
14964 rp.const_range() &&
14966 )
14967 {
14968 ts.size = rp.const_size();
14969 ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second;
14970 range_list_[i].range = reinterpret_cast<range_t*>(0);
14971 }
14972 else
14973 {
14974 range_list_[i].range = &(ri->range_ref());
14975 range_param_list_.push_back(i);
14976 }
14977 }
14978 #endif
14979 else if (is_variable_node(arg_list_[i]))
14980 {
14982
14983 if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i])))
14984 return false;
14985
14986 ts.size = 1;
14987 ts.data = &var->ref();
14989 }
14990 else
14991 {
14992 ts.size = 1;
14993 ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]);
14995 }
14996
14997 branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i]));
14998 }
14999
15000 return true;
15001 }
15002
15004 {
15005 return this < (&fn);
15006 }
15007
15009 {
15010 if (populate_value_list())
15011 {
15012 typedef typename GenericFunction::parameter_list_t parameter_list_t;
15013
15014 return (*function_)(parameter_list_t(typestore_list_));
15015 }
15016
15017 return std::numeric_limits<T>::quiet_NaN();
15018 }
15019
15024
15026 {
15027 return function_;
15028 }
15029
15030 protected:
15031
15032 inline virtual bool populate_value_list() const
15033 {
15034 for (std::size_t i = 0; i < branch_.size(); ++i)
15035 {
15036 expr_as_vec1_store_[i] = branch_[i].first->value();
15037 }
15038
15039 if (!range_param_list_.empty())
15040 {
15041 assert(range_param_list_.size() <= branch_.size());
15042
15043 for (std::size_t i = 0; i < range_param_list_.size(); ++i)
15044 {
15045 const std::size_t index = range_param_list_[i];
15047
15048 const range_t& rp = (*rdt.range);
15049 std::size_t r0 = 0;
15050 std::size_t r1 = 0;
15051
15052 const std::size_t data_size =
15053 #ifndef exprtk_disable_string_capabilities
15054 rdt.str_node ? rdt.str_node->size() : rdt.size;
15055 #else
15056 rdt.size;
15057 #endif
15058
15059 if (!rp(r0, r1, data_size))
15060 {
15061 return false;
15062 }
15063
15065
15066 ts.size = rp.cache_size();
15067 #ifndef exprtk_disable_string_capabilities
15068 if (ts.type == type_store_t::e_string)
15069 ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first;
15070 else
15071 #endif
15072 ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size);
15073 }
15074 }
15075
15076 return true;
15077 }
15078
15081
15082 private:
15083
15084 std::vector<expression_ptr> arg_list_;
15085 std::vector<branch_t> branch_;
15086 std::vector<vecview_t> vv_list_;
15089 std::vector<std::size_t> range_param_list_;
15090 };
15091
15092 #ifndef exprtk_disable_string_capabilities
15093 template <typename T, typename StringFunction>
15094 class string_function_node : public generic_function_node<T,StringFunction>
15095 , public string_base_node<T>
15096 , public range_interface <T>
15097 {
15098 public:
15099
15102
15104 const std::vector<typename gen_function_t::expression_ptr>& arg_list)
15106 {
15107 range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
15108 range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
15109 range_.cache.first = range_.n0_c.second;
15110 range_.cache.second = range_.n1_c.second;
15111 assert(valid());
15112 }
15113
15115 {
15116 return this < (&fn);
15117 }
15118
15120 {
15122 {
15123 typedef typename StringFunction::parameter_list_t parameter_list_t;
15124
15125 const T result =
15126 (*gen_function_t::function_)
15127 (
15129 parameter_list_t(gen_function_t::typestore_list_)
15130 );
15131
15132 range_.n1_c.second = ret_string_.size();
15133 range_.cache.second = range_.n1_c.second;
15134
15135 return result;
15136 }
15137
15138 return std::numeric_limits<T>::quiet_NaN();
15139 }
15140
15145
15147 {
15149 }
15150
15152 {
15153 return ret_string_;
15154 }
15155
15157 {
15158 return &ret_string_[0];
15159 }
15160
15162 {
15163 return ret_string_.size();
15164 }
15165
15167 {
15168 return range_;
15169 }
15170
15172 {
15173 return range_;
15174 }
15175
15176 protected:
15177
15179 mutable std::string ret_string_;
15180 };
15181 #endif
15182
15183 template <typename T, typename GenericFunction>
15184 class multimode_genfunction_node : public generic_function_node<T,GenericFunction>
15185 {
15186 public:
15187
15190
15192 const std::size_t& param_seq_index,
15193 const std::vector<typename gen_function_t::expression_ptr>& arg_list)
15196 {}
15197
15199 {
15201
15203 {
15204 typedef typename GenericFunction::parameter_list_t parameter_list_t;
15205
15206 return
15208 (
15210 parameter_list_t(gen_function_t::typestore_list_)
15211 );
15212 }
15213
15214 return std::numeric_limits<T>::quiet_NaN();
15215 }
15216
15221
15222 private:
15223
15224 std::size_t param_seq_index_;
15225 };
15226
15227 #ifndef exprtk_disable_string_capabilities
15228 template <typename T, typename StringFunction>
15230 {
15231 public:
15232
15235
15237 const std::size_t& param_seq_index,
15238 const std::vector<typename str_function_t::expression_ptr>& arg_list)
15241 {}
15242
15244 {
15246 {
15247 typedef typename StringFunction::parameter_list_t parameter_list_t;
15248
15249 const T result =
15250 (*str_function_t::function_)
15251 (
15254 parameter_list_t(str_function_t::typestore_list_)
15255 );
15256
15259
15260 return result;
15261 }
15262
15263 return std::numeric_limits<T>::quiet_NaN();
15264 }
15265
15270
15271 private:
15272
15273 const std::size_t param_seq_index_;
15274 };
15275 #endif
15276
15278
15279 template <typename T>
15281 {
15282 public:
15283
15285 {}
15286
15289
15291 {
15292 return std::numeric_limits<T>::quiet_NaN();
15293 }
15294 };
15295
15296 #ifndef exprtk_disable_return_statement
15297 template <typename T>
15298 class return_node exprtk_final : public generic_function_node<T,null_igenfunc<T> >
15299 {
15300 public:
15301
15306
15307 return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list,
15311 {
15312 assert(valid());
15313 }
15314
15316 {
15318 {
15319 typedef typename type_store<T>::parameter_list parameter_list_t;
15320
15322 assign(parameter_list_t(gen_function_t::typestore_list_));
15323
15324 throw return_exception();
15325 }
15326
15327 return std::numeric_limits<T>::quiet_NaN();
15328 }
15329
15334
15336 {
15337 return results_context_;
15338 }
15339
15340 private:
15341
15343 };
15344
15345 template <typename T>
15347 {
15348 public:
15349
15352 typedef std::pair<expression_ptr,bool> branch_t;
15353
15361
15363 {
15364 try
15365 {
15366 return_invoked_ = false;
15368
15369 return body_.first->value();
15370 }
15371 catch(const return_exception&)
15372 {
15373 return_invoked_ = true;
15374
15375 return std::numeric_limits<T>::quiet_NaN();
15376 }
15377 }
15378
15383
15385 {
15386 return results_context_ && body_.first;
15387 }
15388
15389 inline bool* retinvk_ptr()
15390 {
15391 return &return_invoked_;
15392 }
15393
15398
15403
15404 private:
15405
15407 mutable bool return_invoked_;
15409 };
15410 #endif
15411
15412 #define exprtk_define_unary_op(OpName) \
15413 template <typename T> \
15414 struct OpName##_op \
15415 { \
15416 typedef typename functor_t<T>::Type Type; \
15417 typedef typename expression_node<T>::node_type node_t; \
15418 \
15419 static inline T process(Type v) \
15420 { \
15421 return numeric:: OpName (v); \
15422 } \
15423 \
15424 static inline node_t type() \
15425 { \
15426 return expression_node<T>::e_##OpName; \
15427 } \
15428 \
15429 static inline details::operator_type operation() \
15430 { \
15431 return details::e_##OpName; \
15432 } \
15433 }; \
15434
15475 #undef exprtk_define_unary_op
15476
15477 template <typename T>
15488
15489 template <typename T>
15490 struct add_op : public opr_base<T>
15491 {
15492 typedef typename opr_base<T>::Type Type;
15494
15495 static inline T process(Type t1, Type t2) { return t1 + t2; }
15496 static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; }
15497 static inline void assign(RefType t1, Type t2) { t1 += t2; }
15500 };
15501
15502 template <typename T>
15503 struct mul_op : public opr_base<T>
15504 {
15505 typedef typename opr_base<T>::Type Type;
15507
15508 static inline T process(Type t1, Type t2) { return t1 * t2; }
15509 static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; }
15510 static inline void assign(RefType t1, Type t2) { t1 *= t2; }
15513 };
15514
15515 template <typename T>
15516 struct sub_op : public opr_base<T>
15517 {
15518 typedef typename opr_base<T>::Type Type;
15520
15521 static inline T process(Type t1, Type t2) { return t1 - t2; }
15522 static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; }
15523 static inline void assign(RefType t1, Type t2) { t1 -= t2; }
15526 };
15527
15528 template <typename T>
15529 struct div_op : public opr_base<T>
15530 {
15531 typedef typename opr_base<T>::Type Type;
15533
15534 static inline T process(Type t1, Type t2) { return t1 / t2; }
15535 static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; }
15536 static inline void assign(RefType t1, Type t2) { t1 /= t2; }
15539 };
15540
15541 template <typename T>
15542 struct mod_op : public opr_base<T>
15543 {
15544 typedef typename opr_base<T>::Type Type;
15546
15547 static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
15548 static inline void assign(RefType t1, Type t2) { t1 = numeric::modulus<T>(t1,t2); }
15551 };
15552
15553 template <typename T>
15554 struct pow_op : public opr_base<T>
15555 {
15556 typedef typename opr_base<T>::Type Type;
15558
15559 static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
15560 static inline void assign(RefType t1, Type t2) { t1 = numeric::pow<T>(t1,t2); }
15563 };
15564
15565 template <typename T>
15566 struct lt_op : public opr_base<T>
15567 {
15568 typedef typename opr_base<T>::Type Type;
15569
15570 static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); }
15571 static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
15574 };
15575
15576 template <typename T>
15577 struct lte_op : public opr_base<T>
15578 {
15579 typedef typename opr_base<T>::Type Type;
15580
15581 static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); }
15582 static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
15585 };
15586
15587 template <typename T>
15588 struct gt_op : public opr_base<T>
15589 {
15590 typedef typename opr_base<T>::Type Type;
15591
15592 static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); }
15593 static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
15596 };
15597
15598 template <typename T>
15599 struct gte_op : public opr_base<T>
15600 {
15601 typedef typename opr_base<T>::Type Type;
15602
15603 static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); }
15604 static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
15607 };
15608
15609 template <typename T>
15610 struct eq_op : public opr_base<T>
15611 {
15612 typedef typename opr_base<T>::Type Type;
15613 static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); }
15614 static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
15617 };
15618
15619 template <typename T>
15620 struct equal_op : public opr_base<T>
15621 {
15622 typedef typename opr_base<T>::Type Type;
15623
15624 static inline T process(Type t1, Type t2) { return numeric::equal(t1,t2); }
15625 static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
15628 };
15629
15630 template <typename T>
15631 struct ne_op : public opr_base<T>
15632 {
15633 typedef typename opr_base<T>::Type Type;
15634
15635 static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); }
15636 static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
15639 };
15640
15641 template <typename T>
15642 struct and_op : public opr_base<T>
15643 {
15644 typedef typename opr_base<T>::Type Type;
15645
15646 static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
15649 };
15650
15651 template <typename T>
15652 struct nand_op : public opr_base<T>
15653 {
15654 typedef typename opr_base<T>::Type Type;
15655
15656 static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
15659 };
15660
15661 template <typename T>
15662 struct or_op : public opr_base<T>
15663 {
15664 typedef typename opr_base<T>::Type Type;
15665
15666 static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
15669 };
15670
15671 template <typename T>
15672 struct nor_op : public opr_base<T>
15673 {
15674 typedef typename opr_base<T>::Type Type;
15675
15676 static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
15679 };
15680
15681 template <typename T>
15682 struct xor_op : public opr_base<T>
15683 {
15684 typedef typename opr_base<T>::Type Type;
15685
15686 static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); }
15689 };
15690
15691 template <typename T>
15692 struct xnor_op : public opr_base<T>
15693 {
15694 typedef typename opr_base<T>::Type Type;
15695
15696 static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); }
15699 };
15700
15701 template <typename T>
15702 struct in_op : public opr_base<T>
15703 {
15704 typedef typename opr_base<T>::Type Type;
15705
15706 static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
15707 static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
15710 };
15711
15712 template <typename T>
15713 struct like_op : public opr_base<T>
15714 {
15715 typedef typename opr_base<T>::Type Type;
15716
15717 static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
15718 static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
15721 };
15722
15723 template <typename T>
15724 struct ilike_op : public opr_base<T>
15725 {
15726 typedef typename opr_base<T>::Type Type;
15727
15728 static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
15729 static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
15732 };
15733
15734 template <typename T>
15735 struct inrange_op : public opr_base<T>
15736 {
15737 typedef typename opr_base<T>::Type Type;
15738
15739 static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
15740 static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
15741 {
15742 return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0);
15743 }
15746 };
15747
15748 template <typename T>
15750 {
15751 return n->value();
15752 }
15753
15754 template <typename T>
15755 inline T value(std::pair<details::expression_node<T>*,bool> n)
15756 {
15757 return n.first->value();
15758 }
15759
15760 template <typename T>
15761 inline T value(const T* t)
15762 {
15763 return (*t);
15764 }
15765
15766 template <typename T>
15767 inline T value(const T& t)
15768 {
15769 return t;
15770 }
15771
15772 template <typename T>
15774 {
15775 typedef typename opr_base<T>::Type Type;
15776
15777 template <typename Type,
15778 typename Allocator,
15779 template <typename, typename> class Sequence>
15781 {
15782 switch (arg_list.size())
15783 {
15784 case 0 : return T(0);
15785 case 1 : return process_1(arg_list);
15786 case 2 : return process_2(arg_list);
15787 case 3 : return process_3(arg_list);
15788 case 4 : return process_4(arg_list);
15789 case 5 : return process_5(arg_list);
15790 default :
15791 {
15792 T result = T(0);
15793
15794 for (std::size_t i = 0; i < arg_list.size(); ++i)
15795 {
15796 result += value(arg_list[i]);
15797 }
15798
15799 return result;
15800 }
15801 }
15802 }
15803
15804 template <typename Sequence>
15805 static inline T process_1(const Sequence& arg_list)
15806 {
15807 return value(arg_list[0]);
15808 }
15809
15810 template <typename Sequence>
15811 static inline T process_2(const Sequence& arg_list)
15812 {
15813 return value(arg_list[0]) + value(arg_list[1]);
15814 }
15815
15816 template <typename Sequence>
15817 static inline T process_3(const Sequence& arg_list)
15818 {
15819 return value(arg_list[0]) + value(arg_list[1]) +
15820 value(arg_list[2]) ;
15821 }
15822
15823 template <typename Sequence>
15824 static inline T process_4(const Sequence& arg_list)
15825 {
15826 return value(arg_list[0]) + value(arg_list[1]) +
15827 value(arg_list[2]) + value(arg_list[3]) ;
15828 }
15829
15830 template <typename Sequence>
15831 static inline T process_5(const Sequence& arg_list)
15832 {
15833 return value(arg_list[0]) + value(arg_list[1]) +
15834 value(arg_list[2]) + value(arg_list[3]) +
15835 value(arg_list[4]) ;
15836 }
15837 };
15838
15839 template <typename T>
15841 {
15842 typedef typename opr_base<T>::Type Type;
15843
15844 template <typename Type,
15845 typename Allocator,
15846 template <typename, typename> class Sequence>
15848 {
15849 switch (arg_list.size())
15850 {
15851 case 0 : return T(0);
15852 case 1 : return process_1(arg_list);
15853 case 2 : return process_2(arg_list);
15854 case 3 : return process_3(arg_list);
15855 case 4 : return process_4(arg_list);
15856 case 5 : return process_5(arg_list);
15857 default :
15858 {
15859 T result = T(value(arg_list[0]));
15860
15861 for (std::size_t i = 1; i < arg_list.size(); ++i)
15862 {
15863 result *= value(arg_list[i]);
15864 }
15865
15866 return result;
15867 }
15868 }
15869 }
15870
15871 template <typename Sequence>
15872 static inline T process_1(const Sequence& arg_list)
15873 {
15874 return value(arg_list[0]);
15875 }
15876
15877 template <typename Sequence>
15878 static inline T process_2(const Sequence& arg_list)
15879 {
15880 return value(arg_list[0]) * value(arg_list[1]);
15881 }
15882
15883 template <typename Sequence>
15884 static inline T process_3(const Sequence& arg_list)
15885 {
15886 return value(arg_list[0]) * value(arg_list[1]) *
15887 value(arg_list[2]) ;
15888 }
15889
15890 template <typename Sequence>
15891 static inline T process_4(const Sequence& arg_list)
15892 {
15893 return value(arg_list[0]) * value(arg_list[1]) *
15894 value(arg_list[2]) * value(arg_list[3]) ;
15895 }
15896
15897 template <typename Sequence>
15898 static inline T process_5(const Sequence& arg_list)
15899 {
15900 return value(arg_list[0]) * value(arg_list[1]) *
15901 value(arg_list[2]) * value(arg_list[3]) *
15902 value(arg_list[4]) ;
15903 }
15904 };
15905
15906 template <typename T>
15908 {
15909 typedef typename opr_base<T>::Type Type;
15910
15911 template <typename Type,
15912 typename Allocator,
15913 template <typename, typename> class Sequence>
15915 {
15916 switch (arg_list.size())
15917 {
15918 case 0 : return T(0);
15919 case 1 : return process_1(arg_list);
15920 case 2 : return process_2(arg_list);
15921 case 3 : return process_3(arg_list);
15922 case 4 : return process_4(arg_list);
15923 case 5 : return process_5(arg_list);
15925 }
15926 }
15927
15928 template <typename Sequence>
15929 static inline T process_1(const Sequence& arg_list)
15930 {
15931 return value(arg_list[0]);
15932 }
15933
15934 template <typename Sequence>
15935 static inline T process_2(const Sequence& arg_list)
15936 {
15937 return (value(arg_list[0]) + value(arg_list[1])) / T(2);
15938 }
15939
15940 template <typename Sequence>
15941 static inline T process_3(const Sequence& arg_list)
15942 {
15943 return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3);
15944 }
15945
15946 template <typename Sequence>
15947 static inline T process_4(const Sequence& arg_list)
15948 {
15949 return (value(arg_list[0]) + value(arg_list[1]) +
15950 value(arg_list[2]) + value(arg_list[3])) / T(4);
15951 }
15952
15953 template <typename Sequence>
15954 static inline T process_5(const Sequence& arg_list)
15955 {
15956 return (value(arg_list[0]) + value(arg_list[1]) +
15957 value(arg_list[2]) + value(arg_list[3]) +
15958 value(arg_list[4])) / T(5);
15959 }
15960 };
15961
15962 template <typename T>
15964 {
15965 typedef typename opr_base<T>::Type Type;
15966
15967 template <typename Type,
15968 typename Allocator,
15969 template <typename, typename> class Sequence>
15971 {
15972 switch (arg_list.size())
15973 {
15974 case 0 : return T(0);
15975 case 1 : return process_1(arg_list);
15976 case 2 : return process_2(arg_list);
15977 case 3 : return process_3(arg_list);
15978 case 4 : return process_4(arg_list);
15979 case 5 : return process_5(arg_list);
15980 default :
15981 {
15982 T result = T(value(arg_list[0]));
15983
15984 for (std::size_t i = 1; i < arg_list.size(); ++i)
15985 {
15986 const T v = value(arg_list[i]);
15987
15988 if (v < result)
15989 result = v;
15990 }
15991
15992 return result;
15993 }
15994 }
15995 }
15996
15997 template <typename Sequence>
15998 static inline T process_1(const Sequence& arg_list)
15999 {
16000 return value(arg_list[0]);
16001 }
16002
16003 template <typename Sequence>
16004 static inline T process_2(const Sequence& arg_list)
16005 {
16006 return std::min<T>(value(arg_list[0]),value(arg_list[1]));
16007 }
16008
16009 template <typename Sequence>
16010 static inline T process_3(const Sequence& arg_list)
16011 {
16012 return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
16013 }
16014
16015 template <typename Sequence>
16016 static inline T process_4(const Sequence& arg_list)
16017 {
16018 return std::min<T>(
16019 std::min<T>(value(arg_list[0]), value(arg_list[1])),
16020 std::min<T>(value(arg_list[2]), value(arg_list[3])));
16021 }
16022
16023 template <typename Sequence>
16024 static inline T process_5(const Sequence& arg_list)
16025 {
16026 return std::min<T>(
16027 std::min<T>(std::min<T>(value(arg_list[0]), value(arg_list[1])),
16028 std::min<T>(value(arg_list[2]), value(arg_list[3]))),
16029 value(arg_list[4]));
16030 }
16031 };
16032
16033 template <typename T>
16035 {
16036 typedef typename opr_base<T>::Type Type;
16037
16038 template <typename Type,
16039 typename Allocator,
16040 template <typename, typename> class Sequence>
16042 {
16043 switch (arg_list.size())
16044 {
16045 case 0 : return T(0);
16046 case 1 : return process_1(arg_list);
16047 case 2 : return process_2(arg_list);
16048 case 3 : return process_3(arg_list);
16049 case 4 : return process_4(arg_list);
16050 case 5 : return process_5(arg_list);
16051 default :
16052 {
16053 T result = T(value(arg_list[0]));
16054
16055 for (std::size_t i = 1; i < arg_list.size(); ++i)
16056 {
16057 const T v = value(arg_list[i]);
16058
16059 if (v > result)
16060 result = v;
16061 }
16062
16063 return result;
16064 }
16065 }
16066 }
16067
16068 template <typename Sequence>
16069 static inline T process_1(const Sequence& arg_list)
16070 {
16071 return value(arg_list[0]);
16072 }
16073
16074 template <typename Sequence>
16075 static inline T process_2(const Sequence& arg_list)
16076 {
16077 return std::max<T>(value(arg_list[0]),value(arg_list[1]));
16078 }
16079
16080 template <typename Sequence>
16081 static inline T process_3(const Sequence& arg_list)
16082 {
16083 return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
16084 }
16085
16086 template <typename Sequence>
16087 static inline T process_4(const Sequence& arg_list)
16088 {
16089 return std::max<T>(
16090 std::max<T>(value(arg_list[0]), value(arg_list[1])),
16091 std::max<T>(value(arg_list[2]), value(arg_list[3])));
16092 }
16093
16094 template <typename Sequence>
16095 static inline T process_5(const Sequence& arg_list)
16096 {
16097 return std::max<T>(
16098 std::max<T>(std::max<T>(value(arg_list[0]), value(arg_list[1])),
16099 std::max<T>(value(arg_list[2]), value(arg_list[3]))),
16100 value(arg_list[4]));
16101 }
16102 };
16103
16104 template <typename T>
16106 {
16107 typedef typename opr_base<T>::Type Type;
16108
16109 template <typename Type,
16110 typename Allocator,
16111 template <typename, typename> class Sequence>
16113 {
16114 switch (arg_list.size())
16115 {
16116 case 1 : return process_1(arg_list);
16117 case 2 : return process_2(arg_list);
16118 case 3 : return process_3(arg_list);
16119 case 4 : return process_4(arg_list);
16120 case 5 : return process_5(arg_list);
16121 default :
16122 {
16123 for (std::size_t i = 0; i < arg_list.size(); ++i)
16124 {
16125 if (std::equal_to<T>()(T(0), value(arg_list[i])))
16126 return T(0);
16127 }
16128
16129 return T(1);
16130 }
16131 }
16132 }
16133
16134 template <typename Sequence>
16135 static inline T process_1(const Sequence& arg_list)
16136 {
16137 return std::not_equal_to<T>()
16138 (T(0), value(arg_list[0])) ? T(1) : T(0);
16139 }
16140
16141 template <typename Sequence>
16142 static inline T process_2(const Sequence& arg_list)
16143 {
16144 return (
16145 std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
16146 std::not_equal_to<T>()(T(0), value(arg_list[1]))
16147 ) ? T(1) : T(0);
16148 }
16149
16150 template <typename Sequence>
16151 static inline T process_3(const Sequence& arg_list)
16152 {
16153 return (
16154 std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
16155 std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
16156 std::not_equal_to<T>()(T(0), value(arg_list[2]))
16157 ) ? T(1) : T(0);
16158 }
16159
16160 template <typename Sequence>
16161 static inline T process_4(const Sequence& arg_list)
16162 {
16163 return (
16164 std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
16165 std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
16166 std::not_equal_to<T>()(T(0), value(arg_list[2])) &&
16167 std::not_equal_to<T>()(T(0), value(arg_list[3]))
16168 ) ? T(1) : T(0);
16169 }
16170
16171 template <typename Sequence>
16172 static inline T process_5(const Sequence& arg_list)
16173 {
16174 return (
16175 std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
16176 std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
16177 std::not_equal_to<T>()(T(0), value(arg_list[2])) &&
16178 std::not_equal_to<T>()(T(0), value(arg_list[3])) &&
16179 std::not_equal_to<T>()(T(0), value(arg_list[4]))
16180 ) ? T(1) : T(0);
16181 }
16182 };
16183
16184 template <typename T>
16186 {
16187 typedef typename opr_base<T>::Type Type;
16188
16189 template <typename Type,
16190 typename Allocator,
16191 template <typename, typename> class Sequence>
16193 {
16194 switch (arg_list.size())
16195 {
16196 case 1 : return process_1(arg_list);
16197 case 2 : return process_2(arg_list);
16198 case 3 : return process_3(arg_list);
16199 case 4 : return process_4(arg_list);
16200 case 5 : return process_5(arg_list);
16201 default :
16202 {
16203 for (std::size_t i = 0; i < arg_list.size(); ++i)
16204 {
16205 if (std::not_equal_to<T>()(T(0), value(arg_list[i])))
16206 return T(1);
16207 }
16208
16209 return T(0);
16210 }
16211 }
16212 }
16213
16214 template <typename Sequence>
16215 static inline T process_1(const Sequence& arg_list)
16216 {
16217 return std::not_equal_to<T>()
16218 (T(0), value(arg_list[0])) ? T(1) : T(0);
16219 }
16220
16221 template <typename Sequence>
16222 static inline T process_2(const Sequence& arg_list)
16223 {
16224 return (
16225 std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
16226 std::not_equal_to<T>()(T(0), value(arg_list[1]))
16227 ) ? T(1) : T(0);
16228 }
16229
16230 template <typename Sequence>
16231 static inline T process_3(const Sequence& arg_list)
16232 {
16233 return (
16234 std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
16235 std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
16236 std::not_equal_to<T>()(T(0), value(arg_list[2]))
16237 ) ? T(1) : T(0);
16238 }
16239
16240 template <typename Sequence>
16241 static inline T process_4(const Sequence& arg_list)
16242 {
16243 return (
16244 std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
16245 std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
16246 std::not_equal_to<T>()(T(0), value(arg_list[2])) ||
16247 std::not_equal_to<T>()(T(0), value(arg_list[3]))
16248 ) ? T(1) : T(0);
16249 }
16250
16251 template <typename Sequence>
16252 static inline T process_5(const Sequence& arg_list)
16253 {
16254 return (
16255 std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
16256 std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
16257 std::not_equal_to<T>()(T(0), value(arg_list[2])) ||
16258 std::not_equal_to<T>()(T(0), value(arg_list[3])) ||
16259 std::not_equal_to<T>()(T(0), value(arg_list[4]))
16260 ) ? T(1) : T(0);
16261 }
16262 };
16263
16264 template <typename T>
16266 {
16267 typedef typename opr_base<T>::Type Type;
16268
16269 template <typename Type,
16270 typename Allocator,
16271 template <typename, typename> class Sequence>
16273 {
16274 switch (arg_list.size())
16275 {
16276 case 0 : return std::numeric_limits<T>::quiet_NaN();
16277 case 1 : return process_1(arg_list);
16278 case 2 : return process_2(arg_list);
16279 case 3 : return process_3(arg_list);
16280 case 4 : return process_4(arg_list);
16281 case 5 : return process_5(arg_list);
16282 case 6 : return process_6(arg_list);
16283 case 7 : return process_7(arg_list);
16284 case 8 : return process_8(arg_list);
16285 default :
16286 {
16287 for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
16288 {
16289 value(arg_list[i]);
16290 }
16291 return value(arg_list.back());
16292 }
16293 }
16294 }
16295
16296 template <typename Sequence>
16297 static inline T process_1(const Sequence& arg_list)
16298 {
16299 return value(arg_list[0]);
16300 }
16301
16302 template <typename Sequence>
16303 static inline T process_2(const Sequence& arg_list)
16304 {
16305 value(arg_list[0]);
16306 return value(arg_list[1]);
16307 }
16308
16309 template <typename Sequence>
16310 static inline T process_3(const Sequence& arg_list)
16311 {
16312 value(arg_list[0]);
16313 value(arg_list[1]);
16314 return value(arg_list[2]);
16315 }
16316
16317 template <typename Sequence>
16318 static inline T process_4(const Sequence& arg_list)
16319 {
16320 value(arg_list[0]);
16321 value(arg_list[1]);
16322 value(arg_list[2]);
16323 return value(arg_list[3]);
16324 }
16325
16326 template <typename Sequence>
16327 static inline T process_5(const Sequence& arg_list)
16328 {
16329 value(arg_list[0]);
16330 value(arg_list[1]);
16331 value(arg_list[2]);
16332 value(arg_list[3]);
16333 return value(arg_list[4]);
16334 }
16335
16336 template <typename Sequence>
16337 static inline T process_6(const Sequence& arg_list)
16338 {
16339 value(arg_list[0]);
16340 value(arg_list[1]);
16341 value(arg_list[2]);
16342 value(arg_list[3]);
16343 value(arg_list[4]);
16344 return value(arg_list[5]);
16345 }
16346
16347 template <typename Sequence>
16348 static inline T process_7(const Sequence& arg_list)
16349 {
16350 value(arg_list[0]);
16351 value(arg_list[1]);
16352 value(arg_list[2]);
16353 value(arg_list[3]);
16354 value(arg_list[4]);
16355 value(arg_list[5]);
16356 return value(arg_list[6]);
16357 }
16358
16359 template <typename Sequence>
16360 static inline T process_8(const Sequence& arg_list)
16361 {
16362 value(arg_list[0]);
16363 value(arg_list[1]);
16364 value(arg_list[2]);
16365 value(arg_list[3]);
16366 value(arg_list[4]);
16367 value(arg_list[5]);
16368 value(arg_list[6]);
16369 return value(arg_list[7]);
16370 }
16371 };
16372
16373 template <typename T>
16375 {
16377
16378 static inline T process(const ivector_ptr v)
16379 {
16380 const T* vec = v->vec()->vds().data();
16381 const std::size_t vec_size = v->size();
16382
16384
16385 if (vec_size <= static_cast<std::size_t>(lud.batch_size))
16386 {
16387 T result = T(0);
16388 int i = 0;
16389
16390 switch (vec_size)
16391 {
16392 #define case_stmt(N,fall_through) \
16393 case N : result += vec[i++]; \
16394 fall_through \
16395
16396 #ifndef exprtk_disable_superscalar_unroll
16403
16404 #endif
16406 case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;)
16407 }
16408
16409 #undef case_stmt
16410
16411 return result;
16412 }
16413
16414 T r[] = {
16415 T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0),
16416 T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0)
16417 };
16418
16419 const T* upper_bound = vec + lud.upper_bound;
16420
16421 while (vec < upper_bound)
16422 {
16423 #define exprtk_loop(N) \
16424 r[N] += vec[N]; \
16425
16426 exprtk_loop( 0) exprtk_loop( 1)
16427 exprtk_loop( 2) exprtk_loop( 3)
16428 #ifndef exprtk_disable_superscalar_unroll
16429 exprtk_loop( 4) exprtk_loop( 5)
16430 exprtk_loop( 6) exprtk_loop( 7)
16431 exprtk_loop( 8) exprtk_loop( 9)
16432 exprtk_loop(10) exprtk_loop(11)
16433 exprtk_loop(12) exprtk_loop(13)
16434 exprtk_loop(14) exprtk_loop(15)
16435 #endif
16436
16437 vec += lud.batch_size;
16438 }
16439
16440 int i = 0;
16441
16442 switch (lud.remainder)
16443 {
16444 #define case_stmt(N,fall_through) \
16445 case N : r[0] += vec[i++]; \
16446 fall_through \
16447
16448 #ifndef exprtk_disable_superscalar_unroll
16455 #endif
16457 case_stmt( 1, (void)0;)
16458 }
16459
16460 #undef exprtk_loop
16461 #undef case_stmt
16462
16463 return (r[ 0] + r[ 1] + r[ 2] + r[ 3])
16464 #ifndef exprtk_disable_superscalar_unroll
16465 + (r[ 4] + r[ 5] + r[ 6] + r[ 7])
16466 + (r[ 8] + r[ 9] + r[10] + r[11])
16467 + (r[12] + r[13] + r[14] + r[15])
16468 #endif
16469 ;
16470 }
16471 };
16472
16473 template <typename T>
16475 {
16477
16478 static inline T process(const ivector_ptr v)
16479 {
16480 const T* vec = v->vec()->vds().data();
16481 const std::size_t vec_size = v->vec()->size();
16482
16484
16485 if (vec_size <= static_cast<std::size_t>(lud.batch_size))
16486 {
16487 T result = T(1);
16488 int i = 0;
16489
16490 switch (vec_size)
16491 {
16492 #define case_stmt(N,fall_through) \
16493 case N : result *= vec[i++]; \
16494 fall_through \
16495
16496 #ifndef exprtk_disable_superscalar_unroll
16503 #endif
16505 case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;)
16506 }
16507
16508 #undef case_stmt
16509
16510 return result;
16511 }
16512
16513 T r[] = {
16514 T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1),
16515 T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1)
16516 };
16517
16518 const T* upper_bound = vec + lud.upper_bound;
16519
16520 while (vec < upper_bound)
16521 {
16522 #define exprtk_loop(N) \
16523 r[N] *= vec[N]; \
16524
16525 exprtk_loop( 0) exprtk_loop( 1)
16526 exprtk_loop( 2) exprtk_loop( 3)
16527 #ifndef exprtk_disable_superscalar_unroll
16528 exprtk_loop( 4) exprtk_loop( 5)
16529 exprtk_loop( 6) exprtk_loop( 7)
16530 exprtk_loop( 8) exprtk_loop( 9)
16531 exprtk_loop(10) exprtk_loop(11)
16532 exprtk_loop(12) exprtk_loop(13)
16533 exprtk_loop(14) exprtk_loop(15)
16534 #endif
16535
16536 vec += lud.batch_size;
16537 }
16538
16539 int i = 0;
16540
16541 switch (lud.remainder)
16542 {
16543 #define case_stmt(N,fall_through) \
16544 case N : r[0] *= vec[i++]; \
16545 fall_through \
16546
16547 #ifndef exprtk_disable_superscalar_unroll
16554 #endif
16556 case_stmt( 1, (void)0;)
16557 }
16558
16559 #undef exprtk_loop
16560 #undef case_stmt
16561
16562 return (r[ 0] * r[ 1] * r[ 2] * r[ 3])
16563 #ifndef exprtk_disable_superscalar_unroll
16564 * (r[ 4] * r[ 5] * r[ 6] * r[ 7])
16565 * (r[ 8] * r[ 9] * r[10] * r[11])
16566 * (r[12] * r[13] * r[14] * r[15])
16567 #endif
16568 ;
16569 }
16570 };
16571
16572 template <typename T>
16574 {
16576
16577 static inline T process(const ivector_ptr v)
16578 {
16579 const T vec_size = T(v->vec()->size());
16580 return vec_add_op<T>::process(v) / vec_size;
16581 }
16582 };
16583
16584 template <typename T>
16586 {
16588
16589 static inline T process(const ivector_ptr v)
16590 {
16591 const T* vec = v->vec()->vds().data();
16592 const std::size_t vec_size = v->vec()->size();
16593
16594 T result = vec[0];
16595
16596 for (std::size_t i = 1; i < vec_size; ++i)
16597 {
16598 const T v_i = vec[i];
16599
16600 if (v_i < result)
16601 result = v_i;
16602 }
16603
16604 return result;
16605 }
16606 };
16607
16608 template <typename T>
16610 {
16612
16613 static inline T process(const ivector_ptr v)
16614 {
16615 const T* vec = v->vec()->vds().data();
16616 const std::size_t vec_size = v->vec()->size();
16617
16618 T result = vec[0];
16619
16620 for (std::size_t i = 1; i < vec_size; ++i)
16621 {
16622 const T v_i = vec[i];
16623
16624 if (v_i > result)
16625 result = v_i;
16626 }
16627
16628 return result;
16629 }
16630 };
16631
16632 template <typename T>
16634 {
16635 public:
16636
16638 {}
16639
16640 inline virtual operator_type operation() const
16641 {
16642 return details::e_default;
16643 }
16644
16645 virtual const T& v0() const = 0;
16646
16647 virtual const T& v1() const = 0;
16648 };
16649
16650 template <typename T>
16652 {
16653 public:
16654
16656 {}
16657
16658 inline virtual operator_type operation() const
16659 {
16660 return details::e_default;
16661 }
16662
16663 virtual const T c() const = 0;
16664
16665 virtual const T& v() const = 0;
16666 };
16667
16668 template <typename T>
16670 {
16671 public:
16672
16674 {}
16675
16676 inline virtual operator_type operation() const
16677 {
16678 return details::e_default;
16679 }
16680
16681 virtual const T c() const = 0;
16682
16683 virtual const T& v() const = 0;
16684 };
16685
16686 template <typename T>
16688 {
16689 public:
16690
16692 {}
16693
16694 virtual const T& v() const = 0;
16695 };
16696
16697 template <typename T>
16699 {
16700 public:
16701
16703 {}
16704
16705 virtual const T& v() const = 0;
16706 };
16707
16708 template <typename T>
16710 {
16711 public:
16712
16714 {}
16715
16716 inline virtual operator_type operation() const
16717 {
16718 return details::e_default;
16719 }
16720
16721 virtual const T c() const = 0;
16722
16723 virtual void set_c(const T) = 0;
16724
16725 virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
16726 };
16727
16728 template <typename T>
16730 {
16731 public:
16732
16734 {}
16735
16736 inline virtual operator_type operation() const
16737 {
16738 return details::e_default;
16739 }
16740
16741 virtual const T c() const = 0;
16742
16743 virtual void set_c(const T) = 0;
16744
16745 virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
16746 };
16747
16748 template <typename T>
16750 {
16751 public:
16752
16754 {}
16755
16756 inline virtual operator_type operation() const
16757 {
16758 return details::e_default;
16759 }
16760
16761 virtual const T& v() const = 0;
16762 };
16763
16764 template <typename T>
16766 {
16767 public:
16768
16770 {}
16771
16772 inline virtual operator_type operation() const
16773 {
16774 return details::e_default;
16775 }
16776 };
16777
16778 template <typename T>
16780 {
16781 public:
16782
16784 {}
16785
16786 inline virtual operator_type operation() const
16787 {
16788 return details::e_default;
16789 }
16790 };
16791
16792 template <typename T>
16794 {
16795 public:
16796
16798 {}
16799
16800 virtual std::string type_id() const = 0;
16801 };
16802
16803 template <typename T>
16805 {
16806 public:
16807
16809 {}
16810
16811 virtual std::string type_id() const = 0;
16812 };
16813
16814 template <typename T, typename Operation>
16816 {
16817 public:
16818
16821
16822 explicit unary_variable_node(const T& var)
16823 : v_(var)
16824 {}
16825
16827 {
16828 return Operation::process(v_);
16829 }
16830
16832 {
16833 return Operation::type();
16834 }
16835
16837 {
16838 return Operation::operation();
16839 }
16840
16841 inline const T& v() const exprtk_override
16842 {
16843 return v_;
16844 }
16845
16846 private:
16847
16850
16851 const T& v_;
16852 };
16853
16854 template <typename T>
16856 {
16857 public:
16858
16859 // UOpr1(v0) Op UOpr2(v1)
16861 typedef typename functor_t::bfunc_t bfunc_t;
16862 typedef typename functor_t::ufunc_t ufunc_t;
16864
16865 explicit uvouv_node(const T& var0,const T& var1,
16867 : v0_(var0)
16868 , v1_(var1)
16869 , u0_(uf0 )
16870 , u1_(uf1 )
16871 , f_ (bf )
16872 {}
16873
16875 {
16876 return f_(u0_(v0_),u1_(v1_));
16877 }
16878
16883
16884 inline const T& v0()
16885 {
16886 return v0_;
16887 }
16888
16889 inline const T& v1()
16890 {
16891 return v1_;
16892 }
16893
16894 inline ufunc_t u0()
16895 {
16896 return u0_;
16897 }
16898
16899 inline ufunc_t u1()
16900 {
16901 return u1_;
16902 }
16903
16904 inline ufunc_t f()
16905 {
16906 return f_;
16907 }
16908
16909 private:
16910
16913
16914 const T& v0_;
16915 const T& v1_;
16919 };
16920
16921 template <typename T, typename Operation>
16923 {
16924 public:
16925
16928 typedef std::pair<expression_ptr,bool> branch_t;
16929
16934
16936 {
16937 return Operation::process(branch_.first->value());
16938 }
16939
16941 {
16942 return Operation::type();
16943 }
16944
16946 {
16947 return branch_.first && branch_.first->valid();
16948 }
16949
16951 {
16952 return Operation::operation();
16953 }
16954
16955 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
16956 {
16957 return branch_.first;
16958 }
16959
16960 inline void release()
16961 {
16962 branch_.second = false;
16963 }
16964
16969
16974
16975 private:
16976
16979
16981 };
16982
16983 template <typename T> struct is_const { enum {result = 0}; };
16984 template <typename T> struct is_const <const T> { enum {result = 1}; };
16985 template <typename T> struct is_const_ref { enum {result = 0}; };
16986 template <typename T> struct is_const_ref <const T&> { enum {result = 1}; };
16987 template <typename T> struct is_ref { enum {result = 0}; };
16988 template <typename T> struct is_ref<T&> { enum {result = 1}; };
16989 template <typename T> struct is_ref<const T&> { enum {result = 0}; };
16990
16991 template <std::size_t State>
16992 struct param_to_str { static std::string result() { static const std::string r("v"); return r; } };
16993
16994 template <>
16995 struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } };
16996
16997 #define exprtk_crtype(Type) \
16998 param_to_str<is_const_ref< Type >::result>::result() \
16999
17000 template <typename T>
17002 {
17004 typedef typename functor_t::bfunc_t bfunc_t;
17005
17006 struct mode0
17007 {
17008 static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
17009 {
17010 // (T0 o0 T1) o1 T2
17011 return bf1(bf0(t0,t1),t2);
17012 }
17013
17014 template <typename T0, typename T1, typename T2>
17015 static inline std::string id()
17016 {
17017 static const std::string result = "(" + exprtk_crtype(T0) + "o" +
17018 exprtk_crtype(T1) + ")o(" +
17019 exprtk_crtype(T2) + ")" ;
17020 return result;
17021 }
17022 };
17023
17024 struct mode1
17025 {
17026 static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
17027 {
17028 // T0 o0 (T1 o1 T2)
17029 return bf0(t0,bf1(t1,t2));
17030 }
17031
17032 template <typename T0, typename T1, typename T2>
17033 static inline std::string id()
17034 {
17035 static const std::string result = "(" + exprtk_crtype(T0) + ")o(" +
17036 exprtk_crtype(T1) + "o" +
17037 exprtk_crtype(T2) + ")" ;
17038 return result;
17039 }
17040 };
17041 };
17042
17043 template <typename T>
17045 {
17047 typedef typename functor_t::bfunc_t bfunc_t;
17048
17049 struct mode0
17050 {
17051 static inline T process(const T& t0, const T& t1,
17052 const T& t2, const T& t3,
17053 const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
17054 {
17055 // (T0 o0 T1) o1 (T2 o2 T3)
17056 return bf1(bf0(t0,t1),bf2(t2,t3));
17057 }
17058
17059 template <typename T0, typename T1, typename T2, typename T3>
17060 static inline std::string id()
17061 {
17062 static const std::string result = "(" + exprtk_crtype(T0) + "o" +
17063 exprtk_crtype(T1) + ")o" +
17064 "(" + exprtk_crtype(T2) + "o" +
17065 exprtk_crtype(T3) + ")" ;
17066 return result;
17067 }
17068 };
17069
17070 struct mode1
17071 {
17072 static inline T process(const T& t0, const T& t1,
17073 const T& t2, const T& t3,
17074 const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
17075 {
17076 // (T0 o0 (T1 o1 (T2 o2 T3))
17077 return bf0(t0,bf1(t1,bf2(t2,t3)));
17078 }
17079 template <typename T0, typename T1, typename T2, typename T3>
17080 static inline std::string id()
17081 {
17082 static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
17083 exprtk_crtype(T1) + ")o(" +
17084 exprtk_crtype(T2) + "o" +
17085 exprtk_crtype(T3) + "))" ;
17086 return result;
17087 }
17088 };
17089
17090 struct mode2
17091 {
17092 static inline T process(const T& t0, const T& t1,
17093 const T& t2, const T& t3,
17094 const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
17095 {
17096 // (T0 o0 ((T1 o1 T2) o2 T3)
17097 return bf0(t0,bf2(bf1(t1,t2),t3));
17098 }
17099
17100 template <typename T0, typename T1, typename T2, typename T3>
17101 static inline std::string id()
17102 {
17103 static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
17104 exprtk_crtype(T1) + "o" +
17105 exprtk_crtype(T2) + ")o(" +
17106 exprtk_crtype(T3) + "))" ;
17107 return result;
17108 }
17109 };
17110
17111 struct mode3
17112 {
17113 static inline T process(const T& t0, const T& t1,
17114 const T& t2, const T& t3,
17115 const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
17116 {
17117 // (((T0 o0 T1) o1 T2) o2 T3)
17118 return bf2(bf1(bf0(t0,t1),t2),t3);
17119 }
17120
17121 template <typename T0, typename T1, typename T2, typename T3>
17122 static inline std::string id()
17123 {
17124 static const std::string result = "((" + exprtk_crtype(T0) + "o" +
17125 exprtk_crtype(T1) + ")o(" +
17126 exprtk_crtype(T2) + "))o(" +
17127 exprtk_crtype(T3) + ")";
17128 return result;
17129 }
17130 };
17131
17132 struct mode4
17133 {
17134 static inline T process(const T& t0, const T& t1,
17135 const T& t2, const T& t3,
17136 const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
17137 {
17138 // ((T0 o0 (T1 o1 T2)) o2 T3
17139 return bf2(bf0(t0,bf1(t1,t2)),t3);
17140 }
17141
17142 template <typename T0, typename T1, typename T2, typename T3>
17143 static inline std::string id()
17144 {
17145 static const std::string result = "((" + exprtk_crtype(T0) + ")o(" +
17146 exprtk_crtype(T1) + "o" +
17147 exprtk_crtype(T2) + "))o(" +
17148 exprtk_crtype(T3) + ")" ;
17149 return result;
17150 }
17151 };
17152 };
17153
17154 #undef exprtk_crtype
17155
17156 template <typename T, typename T0, typename T1>
17157 struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; };
17158 template <typename T, typename T0, typename T1>
17160
17161 #define synthesis_node_type_define(T0_, T1_, v_) \
17162 template <typename T, typename T0, typename T1> \
17163 struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
17164 template <typename T, typename T0, typename T1> \
17165 const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
17166
17167 synthesis_node_type_define(const T0&, const T1&, e_vov)
17176 #undef synthesis_node_type_define
17177
17178 template <typename T, typename T0, typename T1, typename T2>
17179 struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; };
17180 template <typename T, typename T0, typename T1, typename T2>
17182
17183 #define synthesis_node_type_define(T0_, T1_, T2_, v_) \
17184 template <typename T, typename T0, typename T1, typename T2> \
17185 struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
17186 template <typename T, typename T0, typename T1, typename T2> \
17187 const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
17188
17189 synthesis_node_type_define(const T0&, const T1&, const T2&, e_vovov)
17197 synthesis_node_type_define( T0&, T1&, T2&, e_none )
17198 #undef synthesis_node_type_define
17199
17200 template <typename T, typename T0, typename T1, typename T2, typename T3>
17202 template <typename T, typename T0, typename T1, typename T2, typename T3>
17204
17205 #define synthesis_node_type_define(T0_, T1_, T2_, T3_, v_) \
17206 template <typename T, typename T0, typename T1, typename T2, typename T3> \
17207 struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
17208 template <typename T, typename T0, typename T1, typename T2, typename T3> \
17209 const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
17210
17211 synthesis_node_type_define(const T0&, const T1&, const T2&, const T3&, e_vovovov)
17212 synthesis_node_type_define(const T0&, const T1&, const T2&, const T3 , e_vovovoc)
17213 synthesis_node_type_define(const T0&, const T1&, const T2 , const T3&, e_vovocov)
17214 synthesis_node_type_define(const T0&, const T1 , const T2&, const T3&, e_vocovov)
17215 synthesis_node_type_define(const T0 , const T1&, const T2&, const T3&, e_covovov)
17216 synthesis_node_type_define(const T0 , const T1&, const T2 , const T3&, e_covocov)
17217 synthesis_node_type_define(const T0&, const T1 , const T2&, const T3 , e_vocovoc)
17218 synthesis_node_type_define(const T0 , const T1&, const T2&, const T3 , e_covovoc)
17219 synthesis_node_type_define(const T0&, const T1 , const T2 , const T3&, e_vococov)
17220 synthesis_node_type_define(const T0 , const T1 , const T2 , const T3 , e_none )
17221 synthesis_node_type_define(const T0 , const T1 , const T2 , const T3&, e_none )
17222 synthesis_node_type_define(const T0 , const T1 , const T2&, const T3 , e_none )
17223 synthesis_node_type_define(const T0 , const T1&, const T2 , const T3 , e_none )
17224 synthesis_node_type_define(const T0&, const T1 , const T2 , const T3 , e_none )
17225 synthesis_node_type_define(const T0 , const T1 , const T2&, const T3&, e_none )
17226 synthesis_node_type_define(const T0&, const T1&, const T2 , const T3 , e_none )
17227 #undef synthesis_node_type_define
17228
17229 template <typename T, typename T0, typename T1>
17231 {
17232 public:
17233
17235 typedef typename functor_t::bfunc_t bfunc_t;
17236 typedef T value_type;
17238
17239 T0oT1(T0 p0, T1 p1, const bfunc_t p2)
17240 : t0_(p0)
17241 , t1_(p1)
17242 , f_ (p2)
17243 {}
17244
17246 {
17248 return result;
17249 }
17250
17252 {
17253 return e_default;
17254 }
17255
17257 {
17258 return f_(t0_,t1_);
17259 }
17260
17261 inline T0 t0() const
17262 {
17263 return t0_;
17264 }
17265
17266 inline T1 t1() const
17267 {
17268 return t1_;
17269 }
17270
17271 inline bfunc_t f() const
17272 {
17273 return f_;
17274 }
17275
17276 template <typename Allocator>
17278 T0 p0, T1 p1,
17279 bfunc_t p2)
17280 {
17281 return allocator
17283 (p0, p1, p2);
17284 }
17285
17286 private:
17287
17289 T0oT1<T,T0,T1>& operator=(const T0oT1<T,T0,T1>&) { return (*this); }
17290
17294 };
17295
17296 template <typename T, typename T0, typename T1, typename T2, typename ProcessMode>
17298 {
17299 public:
17300
17302 typedef typename functor_t::bfunc_t bfunc_t;
17303 typedef T value_type;
17306
17307 T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
17308 : t0_(p0)
17309 , t1_(p1)
17310 , t2_(p2)
17311 , f0_(p3)
17312 , f1_(p4)
17313 {}
17314
17316 {
17318 return result;
17319 }
17320
17322 {
17323 return e_default;
17324 }
17325
17327 {
17328 return ProcessMode::process(t0_, t1_, t2_, f0_, f1_);
17329 }
17330
17331 inline T0 t0() const
17332 {
17333 return t0_;
17334 }
17335
17336 inline T1 t1() const
17337 {
17338 return t1_;
17339 }
17340
17341 inline T2 t2() const
17342 {
17343 return t2_;
17344 }
17345
17346 bfunc_t f0() const
17347 {
17348 return f0_;
17349 }
17350
17351 bfunc_t f1() const
17352 {
17353 return f1_;
17354 }
17355
17357 {
17358 return id();
17359 }
17360
17361 static inline std::string id()
17362 {
17363 return process_mode_t::template id<T0,T1,T2>();
17364 }
17365
17366 template <typename Allocator>
17368 {
17369 return allocator
17371 (p0, p1, p2, p3, p4);
17372 }
17373
17374 private:
17375
17378
17384 };
17385
17386 template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode>
17388 {
17389 public:
17390
17392 typedef typename functor_t::bfunc_t bfunc_t;
17393 typedef T value_type;
17394 typedef T0_ T0;
17395 typedef T1_ T1;
17396 typedef T2_ T2;
17397 typedef T3_ T3;
17400
17402 : t0_(p0)
17403 , t1_(p1)
17404 , t2_(p2)
17405 , t3_(p3)
17406 , f0_(p4)
17407 , f1_(p5)
17408 , f2_(p6)
17409 {}
17410
17412 {
17413 return ProcessMode::process(t0_, t1_, t2_, t3_, f0_, f1_, f2_);
17414 }
17415
17416 inline T0 t0() const
17417 {
17418 return t0_;
17419 }
17420
17421 inline T1 t1() const
17422 {
17423 return t1_;
17424 }
17425
17426 inline T2 t2() const
17427 {
17428 return t2_;
17429 }
17430
17431 inline T3 t3() const
17432 {
17433 return t3_;
17434 }
17435
17436 inline bfunc_t f0() const
17437 {
17438 return f0_;
17439 }
17440
17441 inline bfunc_t f1() const
17442 {
17443 return f1_;
17444 }
17445
17446 inline bfunc_t f2() const
17447 {
17448 return f2_;
17449 }
17450
17451 inline std::string type_id() const exprtk_override
17452 {
17453 return id();
17454 }
17455
17456 static inline std::string id()
17457 {
17458 return process_mode_t::template id<T0, T1, T2, T3>();
17459 }
17460
17461 template <typename Allocator>
17463 T0 p0, T1 p1, T2 p2, T3 p3,
17465 {
17466 return allocator
17468 (p0, p1, p2, p3, p4, p5, p6);
17469 }
17470
17471 private:
17472
17475
17483 };
17484
17485 template <typename T, typename T0, typename T1, typename T2>
17487 {
17488 public:
17489
17491 typedef typename functor_t::tfunc_t tfunc_t;
17492 typedef T value_type;
17494
17495 T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
17496 : t0_(p0)
17497 , t1_(p1)
17498 , t2_(p2)
17499 , f_ (p3)
17500 {}
17501
17503 {
17505 return result;
17506 }
17507
17509 {
17510 return e_default;
17511 }
17512
17514 {
17515 return f_(t0_, t1_, t2_);
17516 }
17517
17518 inline T0 t0() const
17519 {
17520 return t0_;
17521 }
17522
17523 inline T1 t1() const
17524 {
17525 return t1_;
17526 }
17527
17528 inline T2 t2() const
17529 {
17530 return t2_;
17531 }
17532
17533 tfunc_t f() const
17534 {
17535 return f_;
17536 }
17537
17538 std::string type_id() const
17539 {
17540 return id();
17541 }
17542
17543 static inline std::string id()
17544 {
17545 return "sf3";
17546 }
17547
17548 template <typename Allocator>
17550 {
17551 return allocator
17553 (p0, p1, p2, p3);
17554 }
17555
17556 private:
17557
17560
17565 };
17566
17567 template <typename T, typename T0, typename T1, typename T2>
17569 {
17570 public:
17571
17573 {}
17574
17575 virtual T0 t0() const = 0;
17576
17577 virtual T1 t1() const = 0;
17578
17579 virtual T2 t2() const = 0;
17580 };
17581
17582 template <typename T, typename T0, typename T1, typename T2, typename SF3Operation>
17584 {
17585 public:
17586
17587 typedef T value_type;
17589
17591 : t0_(p0)
17592 , t1_(p1)
17593 , t2_(p2)
17594 {}
17595
17597 {
17599 return result;
17600 }
17601
17603 {
17604 return e_default;
17605 }
17606
17608 {
17609 return SF3Operation::process(t0_, t1_, t2_);
17610 }
17611
17613 {
17614 return t0_;
17615 }
17616
17618 {
17619 return t1_;
17620 }
17621
17623 {
17624 return t2_;
17625 }
17626
17628 {
17629 return id();
17630 }
17631
17632 static inline std::string id()
17633 {
17634 return SF3Operation::id();
17635 }
17636
17637 template <typename Allocator>
17639 {
17640 return allocator
17642 (p0, p1, p2);
17643 }
17644
17645 private:
17646
17649
17653 };
17654
17655 template <typename T>
17657 {
17658 switch (n->type())
17659 {
17660 case expression_node<T>::e_vovov : return true;
17661 case expression_node<T>::e_vovoc : return true;
17662 case expression_node<T>::e_vocov : return true;
17663 case expression_node<T>::e_covov : return true;
17664 case expression_node<T>::e_covoc : return true;
17665 default : return false;
17666 }
17667 }
17668
17669 template <typename T, typename T0, typename T1, typename T2, typename T3>
17671 {
17672 public:
17673
17675 typedef typename functor_t::qfunc_t qfunc_t;
17676 typedef T value_type;
17678
17679 T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
17680 : t0_(p0)
17681 , t1_(p1)
17682 , t2_(p2)
17683 , t3_(p3)
17684 , f_ (p4)
17685 {}
17686
17688 {
17690 return result;
17691 }
17692
17694 {
17695 return e_default;
17696 }
17697
17699 {
17700 return f_(t0_, t1_, t2_, t3_);
17701 }
17702
17703 inline T0 t0() const
17704 {
17705 return t0_;
17706 }
17707
17708 inline T1 t1() const
17709 {
17710 return t1_;
17711 }
17712
17713 inline T2 t2() const
17714 {
17715 return t2_;
17716 }
17717
17718 inline T3 t3() const
17719 {
17720 return t3_;
17721 }
17722
17723 qfunc_t f() const
17724 {
17725 return f_;
17726 }
17727
17728 std::string type_id() const
17729 {
17730 return id();
17731 }
17732
17733 static inline std::string id()
17734 {
17735 return "sf4";
17736 }
17737
17738 template <typename Allocator>
17739 static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
17740 {
17741 return allocator
17743 (p0, p1, p2, p3, p4);
17744 }
17745
17746 private:
17747
17750
17756 };
17757
17758 template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation>
17760 {
17761 public:
17762
17763 typedef T value_type;
17765
17766 T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
17767 : t0_(p0)
17768 , t1_(p1)
17769 , t2_(p2)
17770 , t3_(p3)
17771 {}
17772
17774 {
17776 return result;
17777 }
17778
17780 {
17781 return SF4Operation::process(t0_, t1_, t2_, t3_);
17782 }
17783
17784 inline T0 t0() const
17785 {
17786 return t0_;
17787 }
17788
17789 inline T1 t1() const
17790 {
17791 return t1_;
17792 }
17793
17794 inline T2 t2() const
17795 {
17796 return t2_;
17797 }
17798
17799 inline T3 t3() const
17800 {
17801 return t3_;
17802 }
17803
17805 {
17806 return id();
17807 }
17808
17809 static inline std::string id()
17810 {
17811 return SF4Operation::id();
17812 }
17813
17814 template <typename Allocator>
17815 static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3)
17816 {
17817 return allocator
17819 (p0, p1, p2, p3);
17820 }
17821
17822 private:
17823
17826
17831 };
17832
17833 template <typename T>
17835 {
17836 switch (n->type())
17837 {
17838 case expression_node<T>::e_vovovov : return true;
17839 case expression_node<T>::e_vovovoc : return true;
17840 case expression_node<T>::e_vovocov : return true;
17841 case expression_node<T>::e_vocovov : return true;
17842 case expression_node<T>::e_covovov : return true;
17843 case expression_node<T>::e_covocov : return true;
17844 case expression_node<T>::e_vocovoc : return true;
17845 case expression_node<T>::e_covovoc : return true;
17846 case expression_node<T>::e_vococov : return true;
17847 default : return false;
17848 }
17849 }
17850
17851 template <typename T, typename T0, typename T1>
17853 {
17855 };
17856
17857 template <typename T, typename T0, typename T1, typename T2>
17865
17866 template <typename T, typename T0, typename T1, typename T2, typename T3>
17876
17877 template <typename T, typename Operation>
17879 {
17880 public:
17881
17884
17885 // variable op variable node
17886 explicit vov_node(const T& var0, const T& var1)
17887 : v0_(var0)
17888 , v1_(var1)
17889 {}
17890
17892 {
17893 return Operation::process(v0_,v1_);
17894 }
17895
17897 {
17898 return Operation::type();
17899 }
17900
17902 {
17903 return Operation::operation();
17904 }
17905
17906 inline const T& v0() const exprtk_override
17907 {
17908 return v0_;
17909 }
17910
17911 inline const T& v1() const exprtk_override
17912 {
17913 return v1_;
17914 }
17915
17916 protected:
17917
17918 const T& v0_;
17919 const T& v1_;
17920
17921 private:
17922
17925 };
17926
17927 template <typename T, typename Operation>
17929 {
17930 public:
17931
17934
17935 // constant op variable node
17936 explicit cov_node(const T& const_var, const T& var)
17937 : c_(const_var)
17938 , v_(var)
17939 {}
17940
17942 {
17943 return Operation::process(c_,v_);
17944 }
17945
17947 {
17948 return Operation::type();
17949 }
17950
17952 {
17953 return Operation::operation();
17954 }
17955
17956 inline const T c() const exprtk_override
17957 {
17958 return c_;
17959 }
17960
17961 inline const T& v() const exprtk_override
17962 {
17963 return v_;
17964 }
17965
17966 protected:
17967
17968 const T c_;
17969 const T& v_;
17970
17971 private:
17972
17975 };
17976
17977 template <typename T, typename Operation>
17979 {
17980 public:
17981
17984
17985 // variable op constant node
17986 explicit voc_node(const T& var, const T& const_var)
17987 : v_(var)
17988 , c_(const_var)
17989 {}
17990
17992 {
17993 return Operation::process(v_,c_);
17994 }
17995
17997 {
17998 return Operation::operation();
17999 }
18000
18001 inline const T c() const exprtk_override
18002 {
18003 return c_;
18004 }
18005
18006 inline const T& v() const exprtk_override
18007 {
18008 return v_;
18009 }
18010
18011 protected:
18012
18013 const T& v_;
18014 const T c_;
18015
18016 private:
18017
18020 };
18021
18022 template <typename T, typename Operation>
18024 {
18025 public:
18026
18028 typedef std::pair<expression_ptr,bool> branch_t;
18030
18031 // variable op binary node
18032 explicit vob_node(const T& var, const expression_ptr branch)
18033 : v_(var)
18034 {
18036 assert(valid());
18037 }
18038
18040 {
18041 return Operation::process(v_,branch_.first->value());
18042 }
18043
18044 inline const T& v() const exprtk_override
18045 {
18046 return v_;
18047 }
18048
18050 {
18051 return branch_.first && branch_.first->valid();
18052 }
18053
18054 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
18055 {
18056 return branch_.first;
18057 }
18058
18063
18068
18069 private:
18070
18073
18074 const T& v_;
18076 };
18077
18078 template <typename T, typename Operation>
18080 {
18081 public:
18082
18084 typedef std::pair<expression_ptr,bool> branch_t;
18086
18087 // binary node op variable node
18088 explicit bov_node(const expression_ptr branch, const T& var)
18089 : v_(var)
18090 {
18092 assert(valid());
18093 }
18094
18096 {
18097 return Operation::process(branch_.first->value(),v_);
18098 }
18099
18100 inline const T& v() const exprtk_override
18101 {
18102 return v_;
18103 }
18104
18106 {
18107 return branch_.first && branch_.first->valid();
18108 }
18109
18110 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
18111 {
18112 return branch_.first;
18113 }
18114
18119
18124
18125 private:
18126
18129
18130 const T& v_;
18132 };
18133
18134 template <typename T, typename Operation>
18136 {
18137 public:
18138
18140 typedef std::pair<expression_ptr,bool> branch_t;
18142
18143 // constant op variable node
18145 : c_(const_var)
18146 {
18148 assert(valid());
18149 }
18150
18152 {
18153 return Operation::process(c_,branch_.first->value());
18154 }
18155
18157 {
18158 return Operation::operation();
18159 }
18160
18161 inline const T c() const exprtk_override
18162 {
18163 return c_;
18164 }
18165
18166 inline void set_c(const T new_c) exprtk_override
18167 {
18168 (*const_cast<T*>(&c_)) = new_c;
18169 }
18170
18172 {
18173 return branch_.first && branch_.first->valid();
18174 }
18175
18176 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
18177 {
18178 return branch_.first;
18179 }
18180
18182 {
18183 branch_.second = false;
18184 return branch_.first;
18185 }
18186
18191
18196
18197 private:
18198
18201
18202 const T c_;
18204 };
18205
18206 template <typename T, typename Operation>
18208 {
18209 public:
18210
18212 typedef std::pair<expression_ptr,bool> branch_t;
18214
18215 // binary node op constant node
18217 : c_(const_var)
18218 {
18220 assert(valid());
18221 }
18222
18224 {
18225 return Operation::process(branch_.first->value(),c_);
18226 }
18227
18229 {
18230 return Operation::operation();
18231 }
18232
18233 inline const T c() const exprtk_override
18234 {
18235 return c_;
18236 }
18237
18238 inline void set_c(const T new_c) exprtk_override
18239 {
18240 (*const_cast<T*>(&c_)) = new_c;
18241 }
18242
18244 {
18245 return branch_.first && branch_.first->valid();
18246 }
18247
18248 inline expression_node<T>* branch(const std::size_t&) const exprtk_override
18249 {
18250 return branch_.first;
18251 }
18252
18254 {
18255 branch_.second = false;
18256 return branch_.first;
18257 }
18258
18263
18268
18269 private:
18270
18273
18274 const T c_;
18276 };
18277
18278 #ifndef exprtk_disable_string_capabilities
18279 template <typename T, typename SType0, typename SType1, typename Operation>
18281 {
18282 public:
18283
18286
18287 // string op string node
18289 : s0_(p0)
18290 , s1_(p1)
18291 {}
18292
18294 {
18295 return Operation::process(s0_,s1_);
18296 }
18297
18299 {
18300 return Operation::type();
18301 }
18302
18304 {
18305 return Operation::operation();
18306 }
18307
18308 inline std::string& s0()
18309 {
18310 return s0_;
18311 }
18312
18313 inline std::string& s1()
18314 {
18315 return s1_;
18316 }
18317
18318 protected:
18319
18322
18323 private:
18324
18327 };
18328
18329 template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
18331 {
18332 public:
18333
18337
18338 // string-range op string node
18340 : s0_ (p0 )
18341 , s1_ (p1 )
18342 , rp0_(rp0)
18343 {}
18344
18346 {
18347 rp0_.free();
18348 }
18349
18351 {
18352 std::size_t r0 = 0;
18353 std::size_t r1 = 0;
18354
18355 if (rp0_(r0, r1, s0_.size()))
18356 return Operation::process(s0_.substr(r0, (r1 - r0) + 1), s1_);
18357 else
18358 return T(0);
18359 }
18360
18362 {
18363 return Operation::type();
18364 }
18365
18367 {
18368 return Operation::operation();
18369 }
18370
18371 inline std::string& s0()
18372 {
18373 return s0_;
18374 }
18375
18376 inline std::string& s1()
18377 {
18378 return s1_;
18379 }
18380
18381 protected:
18382
18386
18387 private:
18388
18391 };
18392
18393 template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
18395 {
18396 public:
18397
18401
18402 // string op string range node
18404 : s0_ (p0 )
18405 , s1_ (p1 )
18406 , rp1_(rp1)
18407 {}
18408
18410 {
18411 rp1_.free();
18412 }
18413
18415 {
18416 std::size_t r0 = 0;
18417 std::size_t r1 = 0;
18418
18419 if (rp1_(r0, r1, s1_.size()))
18420 {
18421 return Operation::process
18422 (
18423 s0_,
18424 s1_.substr(r0, (r1 - r0) + 1)
18425 );
18426 }
18427 else
18428 return T(0);
18429 }
18430
18432 {
18433 return Operation::type();
18434 }
18435
18437 {
18438 return Operation::operation();
18439 }
18440
18441 inline std::string& s0()
18442 {
18443 return s0_;
18444 }
18445
18446 inline std::string& s1()
18447 {
18448 return s1_;
18449 }
18450
18451 protected:
18452
18456
18457 private:
18458
18461 };
18462
18463 template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
18465 {
18466 public:
18467
18471
18472 // string-range op string-range node
18474 : s0_ (p0 )
18475 , s1_ (p1 )
18476 , rp0_(rp0)
18477 , rp1_(rp1)
18478 {}
18479
18481 {
18482 rp0_.free();
18483 rp1_.free();
18484 }
18485
18487 {
18488 std::size_t r0_0 = 0;
18489 std::size_t r0_1 = 0;
18490 std::size_t r1_0 = 0;
18491 std::size_t r1_1 = 0;
18492
18493 if (
18494 rp0_(r0_0, r1_0, s0_.size()) &&
18495 rp1_(r0_1, r1_1, s1_.size())
18496 )
18497 {
18498 return Operation::process
18499 (
18500 s0_.substr(r0_0, (r1_0 - r0_0) + 1),
18501 s1_.substr(r0_1, (r1_1 - r0_1) + 1)
18502 );
18503 }
18504 else
18505 return T(0);
18506 }
18507
18509 {
18510 return Operation::type();
18511 }
18512
18514 {
18515 return Operation::operation();
18516 }
18517
18518 inline std::string& s0()
18519 {
18520 return s0_;
18521 }
18522
18523 inline std::string& s1()
18524 {
18525 return s1_;
18526 }
18527
18528 protected:
18529
18534
18535 private:
18536
18539 };
18540
18541 template <typename T, typename Operation>
18543 {
18544 public:
18545
18552
18553 using binary_node<T>::branch;
18554
18559 , str0_base_ptr_ (0)
18560 , str1_base_ptr_ (0)
18561 , str0_range_ptr_(0)
18562 , str1_range_ptr_(0)
18564 {
18566 {
18567 str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
18568
18569 if (0 == str0_base_ptr_)
18570 return;
18571
18572 irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
18573
18574 if (0 == range)
18575 return;
18576
18577 str0_range_ptr_ = &(range->range_ref());
18578 }
18579
18581 {
18582 str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
18583
18584 if (0 == str1_base_ptr_)
18585 return;
18586
18587 irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
18588
18589 if (0 == range)
18590 return;
18591
18592 str1_range_ptr_ = &(range->range_ref());
18593 }
18594
18595 initialised_ =
18600
18601 assert(valid());
18602 }
18603
18605 {
18606 branch(0)->value();
18607 branch(1)->value();
18608
18609 std::size_t str0_r0 = 0;
18610 std::size_t str0_r1 = 0;
18611
18612 std::size_t str1_r0 = 0;
18613 std::size_t str1_r1 = 0;
18614
18615 const range_t& range0 = (*str0_range_ptr_);
18616 const range_t& range1 = (*str1_range_ptr_);
18617
18618 if (
18621 )
18622 {
18623 return Operation::process
18624 (
18625 str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0)),
18627 );
18628 }
18629
18630 return std::numeric_limits<T>::quiet_NaN();
18631 }
18632
18634 {
18635 return Operation::type();
18636 }
18637
18639 {
18640 return initialised_;
18641 }
18642
18643 private:
18644
18647
18653 };
18654
18655 template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
18657 {
18658 public:
18659
18663
18664 // string op string op string node
18666 : s0_(p0)
18667 , s1_(p1)
18668 , s2_(p2)
18669 {}
18670
18672 {
18673 return Operation::process(s0_, s1_, s2_);
18674 }
18675
18677 {
18678 return Operation::type();
18679 }
18680
18682 {
18683 return Operation::operation();
18684 }
18685
18686 inline std::string& s0()
18687 {
18688 return s0_;
18689 }
18690
18691 inline std::string& s1()
18692 {
18693 return s1_;
18694 }
18695
18696 inline std::string& s2()
18697 {
18698 return s2_;
18699 }
18700
18701 protected:
18702
18706
18707 private:
18708
18711 };
18712 #endif
18713
18714 template <typename T, typename PowOp>
18716 {
18717 public:
18718
18721
18722 explicit ipow_node(const T& v)
18723 : v_(v)
18724 {}
18725
18727 {
18728 return PowOp::result(v_);
18729 }
18730
18735
18736 private:
18737
18740
18741 const T& v_;
18742 };
18743
18744 template <typename T, typename PowOp>
18746 {
18747 public:
18748
18750 typedef std::pair<expression_ptr, bool> branch_t;
18752
18754 {
18756 assert(valid());
18757 }
18758
18760 {
18761 return PowOp::result(branch_.first->value());
18762 }
18763
18768
18770 {
18771 return branch_.first && branch_.first->valid();
18772 }
18773
18778
18783
18784 private:
18785
18788
18790 };
18791
18792 template <typename T, typename PowOp>
18794 {
18795 public:
18796
18799
18800 explicit ipowinv_node(const T& v)
18801 : v_(v)
18802 {}
18803
18805 {
18806 return (T(1) / PowOp::result(v_));
18807 }
18808
18813
18814 private:
18815
18818
18819 const T& v_;
18820 };
18821
18822 template <typename T, typename PowOp>
18824 {
18825 public:
18826
18828 typedef std::pair<expression_ptr, bool> branch_t;
18830
18836
18838 {
18839 return (T(1) / PowOp::result(branch_.first->value()));
18840 }
18841
18846
18848 {
18849 return branch_.first && branch_.first->valid();
18850 }
18851
18856
18861
18862 private:
18863
18866
18868 };
18869
18870 template <typename T>
18872 {
18873 return (0 != dynamic_cast<const vov_base_node<T>*>(node));
18874 }
18875
18876 template <typename T>
18878 {
18879 return (0 != dynamic_cast<const cov_base_node<T>*>(node));
18880 }
18881
18882 template <typename T>
18884 {
18885 return (0 != dynamic_cast<const voc_base_node<T>*>(node));
18886 }
18887
18888 template <typename T>
18890 {
18891 return (0 != dynamic_cast<const cob_base_node<T>*>(node));
18892 }
18893
18894 template <typename T>
18896 {
18897 return (0 != dynamic_cast<const boc_base_node<T>*>(node));
18898 }
18899
18900 template <typename T>
18902 {
18903 return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node));
18904 }
18905
18906 template <typename T>
18908 {
18909 return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node));
18910 }
18911
18912 template <typename T>
18914 {
18915 return (0 != dynamic_cast<const uv_base_node<T>*>(node));
18916 }
18917
18918 template <typename T>
18920 {
18922 }
18923
18924 template <typename T>
18926 {
18928 }
18929
18930 template <typename T>
18932 {
18934 }
18935
18936 template <typename T>
18938 {
18940 }
18941
18942 template <typename T>
18944 {
18945 return node && (expression_node<T>::e_strass == node->type());
18946 }
18947
18948 template <typename T>
18950 {
18952 }
18953
18954 template <typename T>
18956 {
18958 }
18959
18960 template <typename T>
18962 {
18964 }
18965
18966 template <typename T>
18968 {
18970 }
18971
18972 template <typename T>
18974 {
18976 }
18977
18978 template <typename T>
18980 {
18982 }
18983
18984 template <typename T>
18986 {
18987 if (node)
18988 {
18989 switch (node->type())
18990 {
19001 case expression_node<T>::e_stringvararg : return true;
19002 default : return false;
19003 }
19004 }
19005
19006 return false;
19007 }
19008
19010 {
19011 public:
19012
19013 template <typename ResultNode, typename OpType, typename ExprNode>
19015 {
19017 allocate<ResultNode>(operation, branch[0]);
19018 result->node_depth();
19019 return result;
19020 }
19021
19022 template <typename ResultNode, typename OpType, typename ExprNode>
19024 {
19026 allocate<ResultNode>(operation, branch[0], branch[1]);
19027 result->node_depth();
19028 return result;
19029 }
19030
19031 template <typename ResultNode, typename OpType, typename ExprNode>
19033 {
19035 allocate<ResultNode>(operation, branch[0], branch[1], branch[2]);
19036 result->node_depth();
19037 return result;
19038 }
19039
19040 template <typename ResultNode, typename OpType, typename ExprNode>
19042 {
19044 allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3]);
19045 result->node_depth();
19046 return result;
19047 }
19048
19049 template <typename ResultNode, typename OpType, typename ExprNode>
19051 {
19053 allocate<ResultNode>(operation, branch[0],branch[1], branch[2], branch[3], branch[4]);
19054 result->node_depth();
19055 return result;
19056 }
19057
19058 template <typename ResultNode, typename OpType, typename ExprNode>
19060 {
19062 allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3], branch[4], branch[5]);
19063 result->node_depth();
19064 return result;
19065 }
19066
19067 template <typename node_type>
19069 {
19070 return (new node_type());
19071 }
19072
19073 template <typename node_type,
19074 typename Type,
19075 typename Allocator,
19076 template <typename, typename> class Sequence>
19078 {
19080 result = (new node_type(seq));
19081 result->node_depth();
19082 return result;
19083 }
19084
19085 template <typename node_type, typename T1>
19087 {
19089 result = (new node_type(t1));
19090 result->node_depth();
19091 return result;
19092 }
19093
19094 template <typename node_type, typename T1>
19096 {
19098 result = (new node_type(t1));
19099 result->node_depth();
19100 return result;
19101 }
19102
19103 template <typename node_type,
19104 typename T1, typename T2>
19105 inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const
19106 {
19108 result = (new node_type(t1, t2));
19109 result->node_depth();
19110 return result;
19111 }
19112
19113 template <typename node_type,
19114 typename T1, typename T2>
19116 {
19118 result = (new node_type(t1, t2));
19119 result->node_depth();
19120 return result;
19121 }
19122
19123 template <typename node_type,
19124 typename T1, typename T2>
19126 {
19128 result = (new node_type(t1, t2));
19129 result->node_depth();
19130 return result;
19131 }
19132
19133 template <typename node_type,
19134 typename T1, typename T2>
19136 {
19138 result = (new node_type(t1, t2));
19139 result->node_depth();
19140 return result;
19141 }
19142
19143 template <typename node_type,
19144 typename T1, typename T2>
19146 {
19148 result = (new node_type(t1, t2));
19149 result->node_depth();
19150 return result;
19151 }
19152
19153 template <typename node_type,
19154 typename T1, typename T2, typename T3>
19156 {
19158 result = (new node_type(t1, t2, t3));
19159 result->node_depth();
19160 return result;
19161 }
19162
19163 template <typename node_type,
19164 typename T1, typename T2, typename T3, typename T4>
19166 {
19168 result = (new node_type(t1, t2, t3, t4));
19169 result->node_depth();
19170 return result;
19171 }
19172
19173 template <typename node_type,
19174 typename T1, typename T2, typename T3>
19176 {
19178 result = (new node_type(t1, t2, t3));
19179 result->node_depth();
19180 return result;
19181 }
19182
19183 template <typename node_type,
19184 typename T1, typename T2, typename T3, typename T4>
19186 {
19188 result = (new node_type(t1, t2, t3, t4));
19189 result->node_depth();
19190 return result;
19191 }
19192
19193 template <typename node_type,
19194 typename T1, typename T2, typename T3, typename T4, typename T5>
19196 {
19198 result = (new node_type(t1, t2, t3, t4, t5));
19199 result->node_depth();
19200 return result;
19201 }
19202
19203 template <typename node_type,
19204 typename T1, typename T2, typename T3>
19206 const T3& t3) const
19207 {
19209 result = (new node_type(t1, t2, t3));
19210 result->node_depth();
19211 return result;
19212 }
19213
19214 template <typename node_type,
19215 typename T1, typename T2,
19216 typename T3, typename T4>
19218 const T3& t3, const T4& t4) const
19219 {
19221 result = (new node_type(t1, t2, t3, t4));
19222 result->node_depth();
19223 return result;
19224 }
19225
19226 template <typename node_type,
19227 typename T1, typename T2,
19228 typename T3, typename T4, typename T5>
19230 const T3& t3, const T4& t4,
19231 const T5& t5) const
19232 {
19234 result = (new node_type(t1, t2, t3, t4, t5));
19235 result->node_depth();
19236 return result;
19237 }
19238
19239 template <typename node_type,
19240 typename T1, typename T2,
19241 typename T3, typename T4, typename T5, typename T6>
19243 const T3& t3, const T4& t4,
19244 const T5& t5, const T6& t6) const
19245 {
19247 result = (new node_type(t1, t2, t3, t4, t5, t6));
19248 result->node_depth();
19249 return result;
19250 }
19251
19252 template <typename node_type,
19253 typename T1, typename T2,
19254 typename T3, typename T4,
19255 typename T5, typename T6, typename T7>
19257 const T3& t3, const T4& t4,
19258 const T5& t5, const T6& t6,
19259 const T7& t7) const
19260 {
19262 result = (new node_type(t1, t2, t3, t4, t5, t6, t7));
19263 result->node_depth();
19264 return result;
19265 }
19266
19267 template <typename node_type,
19268 typename T1, typename T2,
19269 typename T3, typename T4,
19270 typename T5, typename T6,
19271 typename T7, typename T8>
19273 const T3& t3, const T4& t4,
19274 const T5& t5, const T6& t6,
19275 const T7& t7, const T8& t8) const
19276 {
19278 result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8));
19279 result->node_depth();
19280 return result;
19281 }
19282
19283 template <typename node_type,
19284 typename T1, typename T2,
19285 typename T3, typename T4,
19286 typename T5, typename T6,
19287 typename T7, typename T8, typename T9>
19289 const T3& t3, const T4& t4,
19290 const T5& t5, const T6& t6,
19291 const T7& t7, const T8& t8,
19292 const T9& t9) const
19293 {
19295 result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9));
19296 result->node_depth();
19297 return result;
19298 }
19299
19300 template <typename node_type,
19301 typename T1, typename T2,
19302 typename T3, typename T4,
19303 typename T5, typename T6,
19304 typename T7, typename T8,
19305 typename T9, typename T10>
19307 const T3& t3, const T4& t4,
19308 const T5& t5, const T6& t6,
19309 const T7& t7, const T8& t8,
19310 const T9& t9, const T10& t10) const
19311 {
19313 result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10));
19314 result->node_depth();
19315 return result;
19316 }
19317
19318 template <typename node_type,
19319 typename T1, typename T2, typename T3>
19321 {
19323 result = (new node_type(t1, t2, t3));
19324 result->node_depth();
19325 return result;
19326 }
19327
19328 template <typename node_type,
19329 typename T1, typename T2,
19330 typename T3, typename T4>
19332 T3 t3, T4 t4) const
19333 {
19335 result = (new node_type(t1, t2, t3, t4));
19336 result->node_depth();
19337 return result;
19338 }
19339
19340 template <typename node_type,
19341 typename T1, typename T2,
19342 typename T3, typename T4,
19343 typename T5>
19345 T3 t3, T4 t4,
19346 T5 t5) const
19347 {
19349 result = (new node_type(t1, t2, t3, t4, t5));
19350 result->node_depth();
19351 return result;
19352 }
19353
19354 template <typename node_type,
19355 typename T1, typename T2,
19356 typename T3, typename T4,
19357 typename T5, typename T6>
19359 T3 t3, T4 t4,
19360 T5 t5, T6 t6) const
19361 {
19363 result = (new node_type(t1, t2, t3, t4, t5, t6));
19364 result->node_depth();
19365 return result;
19366 }
19367
19368 template <typename node_type,
19369 typename T1, typename T2,
19370 typename T3, typename T4,
19371 typename T5, typename T6, typename T7>
19373 T3 t3, T4 t4,
19374 T5 t5, T6 t6,
19375 T7 t7) const
19376 {
19378 result = (new node_type(t1, t2, t3, t4, t5, t6, t7));
19379 result->node_depth();
19380 return result;
19381 }
19382
19383 template <typename T>
19384 void inline free(expression_node<T>*& e) const
19385 {
19386 exprtk_debug(("node_allocator::free() - deleting expression_node "
19387 "type: %03d addr: %p\n",
19388 static_cast<int>(e->type()),
19389 reinterpret_cast<void*>(e)));
19390 delete e;
19391 e = 0;
19392 }
19393 };
19394
19395 inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
19396 {
19397 #define register_op(Symbol, Type, Args) \
19398 m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
19399
19400 register_op("abs" , e_abs , 1)
19401 register_op("acos" , e_acos , 1)
19402 register_op("acosh" , e_acosh , 1)
19403 register_op("asin" , e_asin , 1)
19404 register_op("asinh" , e_asinh , 1)
19405 register_op("atan" , e_atan , 1)
19406 register_op("atanh" , e_atanh , 1)
19407 register_op("ceil" , e_ceil , 1)
19408 register_op("cos" , e_cos , 1)
19409 register_op("cosh" , e_cosh , 1)
19410 register_op("exp" , e_exp , 1)
19411 register_op("expm1" , e_expm1 , 1)
19412 register_op("floor" , e_floor , 1)
19413 register_op("log" , e_log , 1)
19414 register_op("log10" , e_log10 , 1)
19415 register_op("log2" , e_log2 , 1)
19416 register_op("log1p" , e_log1p , 1)
19417 register_op("round" , e_round , 1)
19418 register_op("sin" , e_sin , 1)
19419 register_op("sinc" , e_sinc , 1)
19420 register_op("sinh" , e_sinh , 1)
19421 register_op("sec" , e_sec , 1)
19422 register_op("csc" , e_csc , 1)
19423 register_op("sqrt" , e_sqrt , 1)
19424 register_op("tan" , e_tan , 1)
19425 register_op("tanh" , e_tanh , 1)
19426 register_op("cot" , e_cot , 1)
19427 register_op("rad2deg" , e_r2d , 1)
19428 register_op("deg2rad" , e_d2r , 1)
19429 register_op("deg2grad" , e_d2g , 1)
19430 register_op("grad2deg" , e_g2d , 1)
19431 register_op("sgn" , e_sgn , 1)
19432 register_op("not" , e_notl , 1)
19433 register_op("erf" , e_erf , 1)
19434 register_op("erfc" , e_erfc , 1)
19435 register_op("ncdf" , e_ncdf , 1)
19436 register_op("frac" , e_frac , 1)
19437 register_op("trunc" , e_trunc , 1)
19438 register_op("atan2" , e_atan2 , 2)
19439 register_op("mod" , e_mod , 2)
19440 register_op("logn" , e_logn , 2)
19441 register_op("pow" , e_pow , 2)
19442 register_op("root" , e_root , 2)
19443 register_op("roundn" , e_roundn , 2)
19444 register_op("equal" , e_equal , 2)
19445 register_op("not_equal" , e_nequal , 2)
19446 register_op("hypot" , e_hypot , 2)
19447 register_op("shr" , e_shr , 2)
19448 register_op("shl" , e_shl , 2)
19449 register_op("clamp" , e_clamp , 3)
19450 register_op("iclamp" , e_iclamp , 3)
19451 register_op("inrange" , e_inrange , 3)
19452 #undef register_op
19453 }
19454
19455 } // namespace details
19456
19458 {
19459 public:
19460
19462 : allow_zero_parameters_(false)
19463 , has_side_effects_(true)
19464 , min_num_args_(0)
19465 , max_num_args_(std::numeric_limits<std::size_t>::max())
19466 {}
19467
19469 {
19471 }
19472
19473 inline bool& has_side_effects()
19474 {
19475 return has_side_effects_;
19476 }
19477
19478 std::size_t& min_num_args()
19479 {
19480 return min_num_args_;
19481 }
19482
19483 std::size_t& max_num_args()
19484 {
19485 return max_num_args_;
19486 }
19487
19488 private:
19489
19492 std::size_t min_num_args_;
19493 std::size_t max_num_args_;
19494 };
19495
19496 template <typename FunctionType>
19497 void enable_zero_parameters(FunctionType& func)
19498 {
19499 func.allow_zero_parameters() = true;
19500
19501 if (0 != func.min_num_args())
19502 {
19503 func.min_num_args() = 0;
19504 }
19505 }
19506
19507 template <typename FunctionType>
19508 void disable_zero_parameters(FunctionType& func)
19509 {
19510 func.allow_zero_parameters() = false;
19511 }
19512
19513 template <typename FunctionType>
19514 void enable_has_side_effects(FunctionType& func)
19515 {
19516 func.has_side_effects() = true;
19517 }
19518
19519 template <typename FunctionType>
19520 void disable_has_side_effects(FunctionType& func)
19521 {
19522 func.has_side_effects() = false;
19523 }
19524
19525 template <typename FunctionType>
19526 void set_min_num_args(FunctionType& func, const std::size_t& num_args)
19527 {
19528 func.min_num_args() = num_args;
19529
19530 if ((0 != func.min_num_args()) && func.allow_zero_parameters())
19531 func.allow_zero_parameters() = false;
19532 }
19533
19534 template <typename FunctionType>
19535 void set_max_num_args(FunctionType& func, const std::size_t& num_args)
19536 {
19537 func.max_num_args() = num_args;
19538 }
19539
19540 template <typename T>
19542 {
19543 public:
19544
19545 explicit ifunction(const std::size_t& pc)
19546 : param_count(pc)
19547 {}
19548
19549 virtual ~ifunction()
19550 {}
19551
19552 #define empty_method_body(N) \
19553 { \
19554 exprtk_debug(("ifunction::operator() - Operator(" #N ") has not been overridden\n")); \
19555 return std::numeric_limits<T>::quiet_NaN(); \
19556 } \
19557
19558 inline virtual T operator() ()
19560
19561 inline virtual T operator() (const T&)
19563
19564 inline virtual T operator() (const T&,const T&)
19566
19567 inline virtual T operator() (const T&, const T&, const T&)
19569
19570 inline virtual T operator() (const T&, const T&, const T&, const T&)
19572
19573 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&)
19575
19576 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&)
19578
19579 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19581
19582 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19584
19585 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19587
19588 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19590
19591 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19592 const T&)
19594
19595 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19596 const T&, const T&)
19598
19599 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19600 const T&, const T&, const T&)
19602
19603 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19604 const T&, const T&, const T&, const T&)
19606
19607 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19608 const T&, const T&, const T&, const T&, const T&)
19610
19611 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19612 const T&, const T&, const T&, const T&, const T&, const T&)
19614
19615 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19616 const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19618
19619 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19620 const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19622
19623 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19624 const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19626
19627 inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
19628 const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
19630
19631 #undef empty_method_body
19632
19633 std::size_t param_count;
19634 };
19635
19636 template <typename T>
19638 {
19639 public:
19640
19642 {}
19643
19644 inline virtual T operator() (const std::vector<T>&)
19645 {
19646 exprtk_debug(("ivararg_function::operator() - Operator has not been overridden\n"));
19647 return std::numeric_limits<T>::quiet_NaN();
19648 }
19649 };
19650
19651 template <typename T>
19653 {
19654 public:
19655
19662
19663 typedef T type;
19666
19667 explicit igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar)
19668 : parameter_sequence(param_seq)
19669 , rtrn_type(rtr_type)
19670 {}
19671
19673 {}
19674
19675 #define igeneric_function_empty_body(N) \
19676 { \
19677 exprtk_debug(("igeneric_function::operator() - Operator(" #N ") has not been overridden\n")); \
19678 return std::numeric_limits<T>::quiet_NaN(); \
19679 } \
19680
19681 // f(i_0,i_1,....,i_N) --> Scalar
19684
19685 // f(i_0,i_1,....,i_N) --> String
19686 inline virtual T operator() (std::string&, parameter_list_t)
19688
19689 // f(psi,i_0,i_1,....,i_N) --> Scalar
19690 inline virtual T operator() (const std::size_t&, parameter_list_t)
19692
19693 // f(psi,i_0,i_1,....,i_N) --> String
19694 inline virtual T operator() (const std::size_t&, std::string&, parameter_list_t)
19696
19697 #undef igeneric_function_empty_body
19698
19701 };
19702
19703 #ifndef exprtk_disable_string_capabilities
19704 template <typename T>
19706 {
19707 public:
19708
19710
19711 stringvar_base(const std::string& name, stringvar_node_t* svn)
19712 : name_(name)
19713 , string_varnode_(svn)
19714 {}
19715
19716 bool valid() const
19717 {
19718 return !name_.empty() && (0 != string_varnode_);
19719 }
19720
19721 std::string name() const
19722 {
19723 assert(string_varnode_);
19724 return name_;
19725 }
19726
19727 void rebase(std::string& s)
19728 {
19729 assert(string_varnode_);
19731 }
19732
19733 private:
19734
19735 std::string name_;
19737 };
19738 #endif
19739
19740 template <typename T> class parser;
19741 template <typename T> class expression_helper;
19742
19743 template <typename T>
19745 {
19746 public:
19747
19754
19755 typedef T (*ff00_functor)();
19756 typedef T (*ff01_functor)(T);
19757 typedef T (*ff02_functor)(T, T);
19758 typedef T (*ff03_functor)(T, T, T);
19759 typedef T (*ff04_functor)(T, T, T, T);
19760 typedef T (*ff05_functor)(T, T, T, T, T);
19761 typedef T (*ff06_functor)(T, T, T, T, T, T);
19762 typedef T (*ff07_functor)(T, T, T, T, T, T, T);
19763 typedef T (*ff08_functor)(T, T, T, T, T, T, T, T);
19764 typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T);
19765 typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T);
19766 typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T);
19767 typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T);
19768 typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T);
19769 typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T);
19770 typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T);
19771
19772 protected:
19773
19775 {
19776 using exprtk::ifunction<T>::operator();
19777
19778 explicit freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {}
19780 { return f(); }
19782 };
19783
19785 {
19786 using exprtk::ifunction<T>::operator();
19787
19788 explicit freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {}
19789 inline T operator() (const T& v0) exprtk_override
19790 { return f(v0); }
19792 };
19793
19795 {
19796 using exprtk::ifunction<T>::operator();
19797
19798 explicit freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {}
19799 inline T operator() (const T& v0, const T& v1) exprtk_override
19800 { return f(v0, v1); }
19802 };
19803
19805 {
19806 using exprtk::ifunction<T>::operator();
19807
19808 explicit freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {}
19809 inline T operator() (const T& v0, const T& v1, const T& v2) exprtk_override
19810 { return f(v0, v1, v2); }
19812 };
19813
19815 {
19816 using exprtk::ifunction<T>::operator();
19817
19818 explicit freefunc04(ff04_functor ff) : exprtk::ifunction<T>(4), f(ff) {}
19819 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3) exprtk_override
19820 { return f(v0, v1, v2, v3); }
19822 };
19823
19825 {
19826 using exprtk::ifunction<T>::operator();
19827
19828 explicit freefunc05(ff05_functor ff) : exprtk::ifunction<T>(5), f(ff) {}
19829 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) exprtk_override
19830 { return f(v0, v1, v2, v3, v4); }
19832 };
19833
19835 {
19836 using exprtk::ifunction<T>::operator();
19837
19838 explicit freefunc06(ff06_functor ff) : exprtk::ifunction<T>(6), f(ff) {}
19839 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) exprtk_override
19840 { return f(v0, v1, v2, v3, v4, v5); }
19842 };
19843
19845 {
19846 using exprtk::ifunction<T>::operator();
19847
19848 explicit freefunc07(ff07_functor ff) : exprtk::ifunction<T>(7), f(ff) {}
19849 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19850 const T& v5, const T& v6) exprtk_override
19851 { return f(v0, v1, v2, v3, v4, v5, v6); }
19853 };
19854
19856 {
19857 using exprtk::ifunction<T>::operator();
19858
19859 explicit freefunc08(ff08_functor ff) : exprtk::ifunction<T>(8), f(ff) {}
19860 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19861 const T& v5, const T& v6, const T& v7) exprtk_override
19862 { return f(v0, v1, v2, v3, v4, v5, v6, v7); }
19864 };
19865
19867 {
19868 using exprtk::ifunction<T>::operator();
19869
19870 explicit freefunc09(ff09_functor ff) : exprtk::ifunction<T>(9), f(ff) {}
19871 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19872 const T& v5, const T& v6, const T& v7, const T& v8) exprtk_override
19873 { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); }
19875 };
19876
19878 {
19879 using exprtk::ifunction<T>::operator();
19880
19881 explicit freefunc10(ff10_functor ff) : exprtk::ifunction<T>(10), f(ff) {}
19882 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19883 const T& v5, const T& v6, const T& v7, const T& v8, const T& v9) exprtk_override
19884 { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); }
19886 };
19887
19889 {
19890 using exprtk::ifunction<T>::operator();
19891
19892 explicit freefunc11(ff11_functor ff) : exprtk::ifunction<T>(11), f(ff) {}
19893 inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19894 const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10) exprtk_override
19895 { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); }
19897 };
19898
19900 {
19901 using exprtk::ifunction<T>::operator();
19902
19903 explicit freefunc12(ff12_functor ff) : exprtk::ifunction<T>(12), f(ff) {}
19904 inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19905 const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19906 const T& v10, const T& v11) exprtk_override
19907 { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11); }
19909 };
19910
19912 {
19913 using exprtk::ifunction<T>::operator();
19914
19915 explicit freefunc13(ff13_functor ff) : exprtk::ifunction<T>(13), f(ff) {}
19916 inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19917 const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19918 const T& v10, const T& v11, const T& v12) exprtk_override
19919 { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12); }
19921 };
19922
19924 {
19925 using exprtk::ifunction<T>::operator();
19926
19927 explicit freefunc14(ff14_functor ff) : exprtk::ifunction<T>(14), f(ff) {}
19928 inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19929 const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19930 const T& v10, const T& v11, const T& v12, const T& v13) exprtk_override
19931 { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13); }
19933 };
19934
19936 {
19937 using exprtk::ifunction<T>::operator();
19938
19939 explicit freefunc15(ff15_functor ff) : exprtk::ifunction<T>(15), f(ff) {}
19940 inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19941 const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19942 const T& v10, const T& v11, const T& v12, const T& v13, const T& v14) exprtk_override
19943 { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14); }
19945 };
19946
19947 template <typename Type, typename RawType>
19949 {
19956 #ifndef exprtk_disable_string_capabilities
19958 #endif
19959
19960 typedef Type type_t;
19962 typedef std::pair<bool,type_ptr> type_pair_t;
19963 typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t;
19964 typedef typename type_map_t::iterator tm_itr_t;
19965 typedef typename type_map_t::const_iterator tm_const_itr_t;
19966
19967 enum { lut_size = 256 };
19968
19970 std::size_t size;
19971
19973 : size(0)
19974 {}
19975
19976 struct deleter
19977 {
19978 #define exprtk_define_process(Type) \
19979 static inline void process(std::pair<bool,Type*>& n) \
19980 { \
19981 delete n.second; \
19982 } \
19983
19986 #ifndef exprtk_disable_string_capabilities
19988 #endif
19989
19990 #undef exprtk_define_process
19991
19992 template <typename DeleteType>
19993 static inline void process(std::pair<bool,DeleteType*>&)
19994 {}
19995 };
19996
19997 inline bool symbol_exists(const std::string& symbol_name) const
19998 {
19999 if (symbol_name.empty())
20000 return false;
20001 else if (map.end() != map.find(symbol_name))
20002 return true;
20003 else
20004 return false;
20005 }
20006
20007 template <typename PtrType>
20008 inline std::string entity_name(const PtrType& ptr) const
20009 {
20010 if (map.empty())
20011 return std::string();
20012
20013 tm_const_itr_t itr = map.begin();
20014
20015 while (map.end() != itr)
20016 {
20017 if (itr->second.second == ptr)
20018 {
20019 return itr->first;
20020 }
20021 else
20022 ++itr;
20023 }
20024
20025 return std::string();
20026 }
20027
20028 inline bool is_constant(const std::string& symbol_name) const
20029 {
20030 if (symbol_name.empty())
20031 return false;
20032 else
20033 {
20034 const tm_const_itr_t itr = map.find(symbol_name);
20035
20036 if (map.end() == itr)
20037 return false;
20038 else
20039 return (*itr).second.first;
20040 }
20041 }
20042
20043 template <typename Tie, typename RType>
20044 inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const)
20045 {
20046 if (symbol_name.size() > 1)
20047 {
20048 for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
20049 {
20050 if (details::imatch(symbol_name, details::reserved_symbols[i]))
20051 {
20052 return false;
20053 }
20054 }
20055 }
20056
20057 const tm_itr_t itr = map.find(symbol_name);
20058
20059 if (map.end() == itr)
20060 {
20061 map[symbol_name] = Tie::make(t,is_const);
20062 ++size;
20063 }
20064
20065 return true;
20066 }
20067
20069 {
20070 static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false)
20071 {
20072 return std::make_pair(is_const, new vector_t(v.first, v.second));
20073 }
20074 };
20075
20077 {
20078 template <typename Allocator>
20079 static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false)
20080 {
20081 return std::make_pair(is_const, new vector_t(v));
20082 }
20083 };
20084
20086 {
20087 static inline std::pair<bool,vector_t*> make(exprtk::vector_view<T>& v, const bool is_const = false)
20088 {
20089 return std::make_pair(is_const, new vector_t(v));
20090 }
20091 };
20092
20094 {
20095 template <typename Allocator>
20096 static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false)
20097 {
20098 return std::make_pair(is_const, new vector_t(v));
20099 }
20100 };
20101
20102 template <std::size_t v_size>
20103 inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false)
20104 {
20105 return add_impl<tie_array,std::pair<T*,std::size_t> >
20106 (symbol_name, std::make_pair(v,v_size), is_const);
20107 }
20108
20109 inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false)
20110 {
20111 return add_impl<tie_array,std::pair<T*,std::size_t> >
20112 (symbol_name, std::make_pair(v,v_size), is_const);
20113 }
20114
20115 template <typename Allocator>
20116 inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false)
20117 {
20118 return add_impl<tie_stdvec,std::vector<T,Allocator>&>
20119 (symbol_name, v, is_const);
20120 }
20121
20122 inline bool add(const std::string& symbol_name, exprtk::vector_view<T>& v, const bool is_const = false)
20123 {
20124 return add_impl<tie_vecview,exprtk::vector_view<T>&>
20125 (symbol_name, v, is_const);
20126 }
20127
20128 template <typename Allocator>
20129 inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
20130 {
20131 return add_impl<tie_stddeq,std::deque<T,Allocator>&>
20132 (symbol_name, v, is_const);
20133 }
20134
20135 inline bool add(const std::string& symbol_name, RawType& t_, const bool is_const = false)
20136 {
20137 struct tie
20138 {
20139 static inline std::pair<bool,variable_node_t*> make(T& t, const bool is_constant = false)
20140 {
20141 return std::make_pair(is_constant, new variable_node_t(t));
20142 }
20143
20144 #ifndef exprtk_disable_string_capabilities
20145 static inline std::pair<bool,stringvar_node_t*> make(std::string& t, const bool is_constant = false)
20146 {
20147 return std::make_pair(is_constant, new stringvar_node_t(t));
20148 }
20149 #endif
20150
20151 static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false)
20152 {
20153 return std::make_pair(is_constant,&t);
20154 }
20155
20156 static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_constant = false)
20157 {
20158 return std::make_pair(is_constant,&t);
20159 }
20160
20161 static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false)
20162 {
20163 return std::make_pair(is_constant,&t);
20164 }
20165 };
20166
20167 const tm_itr_t itr = map.find(symbol_name);
20168
20169 if (map.end() == itr)
20170 {
20171 map[symbol_name] = tie::make(t_,is_const);
20172 ++size;
20173 }
20174
20175 return true;
20176 }
20177
20178 inline type_ptr get(const std::string& symbol_name) const
20179 {
20180 const tm_const_itr_t itr = map.find(symbol_name);
20181
20182 if (map.end() == itr)
20183 return reinterpret_cast<type_ptr>(0);
20184 else
20185 return itr->second.second;
20186 }
20187
20188 template <typename TType, typename TRawType, typename PtrType>
20190 {
20191 static inline bool test(const PtrType, const void*)
20192 {
20193 return false;
20194 }
20195 };
20196
20197 template <typename TType, typename TRawType>
20198 struct ptr_match<TType,TRawType,variable_node_t*>
20199 {
20200 static inline bool test(const variable_node_t* p, const void* ptr)
20201 {
20202 exprtk_debug(("ptr_match::test() - %p <--> %p\n", reinterpret_cast<const void*>(&(p->ref())), ptr));
20203 return (&(p->ref()) == ptr);
20204 }
20205 };
20206
20207 inline type_ptr get_from_varptr(const void* ptr) const
20208 {
20209 tm_const_itr_t itr = map.begin();
20210
20211 while (map.end() != itr)
20212 {
20213 type_ptr ret_ptr = itr->second.second;
20214
20216 {
20217 return ret_ptr;
20218 }
20219
20220 ++itr;
20221 }
20222
20223 return type_ptr(0);
20224 }
20225
20226 inline bool remove(const std::string& symbol_name, const bool delete_node = true)
20227 {
20228 const tm_itr_t itr = map.find(symbol_name);
20229
20230 if (map.end() != itr)
20231 {
20232 if (delete_node)
20233 {
20234 deleter::process((*itr).second);
20235 }
20236
20237 map.erase(itr);
20238 --size;
20239
20240 return true;
20241 }
20242 else
20243 return false;
20244 }
20245
20246 inline RawType& type_ref(const std::string& symbol_name)
20247 {
20248 struct init_type
20249 {
20250 static inline double set(double) { return (0.0); }
20251 static inline double set(long double) { return (0.0); }
20252 static inline float set(float) { return (0.0f); }
20253 static inline std::string set(std::string) { return std::string(""); }
20254 };
20255
20256 static RawType null_type = init_type::set(RawType());
20257
20258 const tm_const_itr_t itr = map.find(symbol_name);
20259
20260 if (map.end() == itr)
20261 return null_type;
20262 else
20263 return itr->second.second->ref();
20264 }
20265
20266 inline void clear(const bool delete_node = true)
20267 {
20268 if (!map.empty())
20269 {
20270 if (delete_node)
20271 {
20272 tm_itr_t itr = map.begin();
20273 tm_itr_t end = map.end ();
20274
20275 while (end != itr)
20276 {
20277 deleter::process((*itr).second);
20278 ++itr;
20279 }
20280 }
20281
20282 map.clear();
20283 }
20284
20285 size = 0;
20286 }
20287
20288 template <typename Allocator,
20289 template <typename, typename> class Sequence>
20290 inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const
20291 {
20292 std::size_t count = 0;
20293
20294 if (!map.empty())
20295 {
20296 tm_const_itr_t itr = map.begin();
20297 tm_const_itr_t end = map.end ();
20298
20299 while (end != itr)
20300 {
20301 list.push_back(std::make_pair((*itr).first,itr->second.second->ref()));
20302 ++itr;
20303 ++count;
20304 }
20305 }
20306
20307 return count;
20308 }
20309
20310 template <typename Allocator,
20311 template <typename, typename> class Sequence>
20312 inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const
20313 {
20314 std::size_t count = 0;
20315
20316 if (!map.empty())
20317 {
20318 tm_const_itr_t itr = map.begin();
20319 tm_const_itr_t end = map.end ();
20320
20321 while (end != itr)
20322 {
20323 vlist.push_back((*itr).first);
20324 ++itr;
20325 ++count;
20326 }
20327 }
20328
20329 return count;
20330 }
20331 };
20332
20337 #ifndef exprtk_disable_string_capabilities
20340 #endif
20341 typedef ifunction <T> function_t;
20342 typedef ivararg_function <T> vararg_function_t;
20347
20348 static const std::size_t lut_size = 256;
20349
20350 // Symbol Table Holder
20352 {
20353 struct st_data
20354 {
20362 #ifndef exprtk_disable_string_capabilities
20364 #endif
20365
20367 {
20368 for (std::size_t i = 0; i < details::reserved_words_size; ++i)
20369 {
20371 }
20372
20373 for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
20374 {
20376 }
20377 }
20378
20380 {
20381 for (std::size_t i = 0; i < free_function_list_.size(); ++i)
20382 {
20383 delete free_function_list_[i];
20384 }
20385 }
20386
20387 inline bool is_reserved_symbol(const std::string& symbol) const
20388 {
20389 return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
20390 }
20391
20392 static inline st_data* create()
20393 {
20394 return (new st_data);
20395 }
20396
20397 static inline void destroy(st_data*& sd)
20398 {
20399 delete sd;
20400 sd = reinterpret_cast<st_data*>(0);
20401 }
20402
20404 std::list<std::string> local_stringvar_list_;
20405 std::set<std::string> reserved_symbol_table_;
20406 std::vector<ifunction<T>*> free_function_list_;
20407 };
20408
20410 : ref_count(1)
20411 , data_(st_data::create())
20413 {}
20414
20415 explicit control_block(st_data* data)
20416 : ref_count(1)
20417 , data_(data)
20419 {}
20420
20422 {
20423 if (data_ && (0 == ref_count))
20424 {
20426 }
20427 }
20428
20429 static inline control_block* create()
20430 {
20431 return (new control_block);
20432 }
20433
20434 template <typename SymTab>
20435 static inline void destroy(control_block*& cntrl_blck, SymTab* sym_tab)
20436 {
20437 if (cntrl_blck)
20438 {
20439 if (
20440 (0 != cntrl_blck->ref_count) &&
20441 (0 == --cntrl_blck->ref_count)
20442 )
20443 {
20444 if (sym_tab)
20445 sym_tab->clear();
20446
20447 delete cntrl_blck;
20448 }
20449
20450 cntrl_blck = 0;
20451 }
20452 }
20453
20458
20459 std::size_t ref_count;
20462 };
20463
20464 public:
20465
20472
20474 {
20475 exprtk::details::dump_ptr("~symbol_table", this);
20477 }
20478
20480 {
20483 }
20484
20486 {
20487 if (this != &st)
20488 {
20490
20493 }
20494
20495 return (*this);
20496 }
20497
20498 inline bool operator==(const symbol_table<T>& st) const
20499 {
20500 return (this == &st) || (control_block_ == st.control_block_);
20501 }
20502
20504 {
20506 }
20507
20508 inline void clear_variables(const bool delete_node = true)
20509 {
20510 local_data().variable_store.clear(delete_node);
20511 }
20512
20513 inline void clear_functions()
20514 {
20515 local_data().function_store.clear();
20516 }
20517
20518 inline void clear_strings()
20519 {
20520 #ifndef exprtk_disable_string_capabilities
20521 local_data().stringvar_store.clear();
20522 #endif
20523 }
20524
20525 inline void clear_vectors()
20526 {
20527 local_data().vector_store.clear();
20528 }
20529
20531 {
20533 }
20534
20535 inline void clear()
20536 {
20537 if (!valid()) return;
20538 clear_variables ();
20539 clear_functions ();
20540 clear_strings ();
20541 clear_vectors ();
20543 }
20544
20545 inline std::size_t variable_count() const
20546 {
20547 if (valid())
20548 return local_data().variable_store.size;
20549 else
20550 return 0;
20551 }
20552
20553 #ifndef exprtk_disable_string_capabilities
20554 inline std::size_t stringvar_count() const
20555 {
20556 if (valid())
20557 return local_data().stringvar_store.size;
20558 else
20559 return 0;
20560 }
20561 #endif
20562
20563 inline std::size_t function_count() const
20564 {
20565 if (valid())
20566 return local_data().function_store.size;
20567 else
20568 return 0;
20569 }
20570
20571 inline std::size_t vector_count() const
20572 {
20573 if (valid())
20574 return local_data().vector_store.size;
20575 else
20576 return 0;
20577 }
20578
20579 inline variable_ptr get_variable(const std::string& variable_name) const
20580 {
20581 if (!valid())
20582 return reinterpret_cast<variable_ptr>(0);
20583 else if (!valid_symbol(variable_name))
20584 return reinterpret_cast<variable_ptr>(0);
20585 else
20586 return local_data().variable_store.get(variable_name);
20587 }
20588
20589 inline variable_ptr get_variable(const T& var_ref) const
20590 {
20591 if (!valid())
20592 return reinterpret_cast<variable_ptr>(0);
20593 else
20594 return local_data().variable_store.get_from_varptr(
20595 reinterpret_cast<const void*>(&var_ref));
20596 }
20597
20598 #ifndef exprtk_disable_string_capabilities
20599 inline stringvar_ptr get_stringvar(const std::string& string_name) const
20600 {
20601 if (!valid())
20602 return reinterpret_cast<stringvar_ptr>(0);
20603 else if (!valid_symbol(string_name))
20604 return reinterpret_cast<stringvar_ptr>(0);
20605 else
20606 return local_data().stringvar_store.get(string_name);
20607 }
20608
20609 inline stringvar_base<T> get_stringvar_base(const std::string& string_name) const
20610 {
20611 static stringvar_base<T> null_stringvar_base("",reinterpret_cast<stringvar_ptr>(0));
20612 if (!valid())
20613 return null_stringvar_base;
20614 else if (!valid_symbol(string_name))
20615 return null_stringvar_base;
20616
20617 stringvar_ptr stringvar = local_data().stringvar_store.get(string_name);
20618
20619 if (0 == stringvar)
20620 {
20621 return null_stringvar_base;
20622 }
20623
20624 return stringvar_base<T>(string_name,stringvar);
20625 }
20626 #endif
20627
20628 inline function_ptr get_function(const std::string& function_name) const
20629 {
20630 if (!valid())
20631 return reinterpret_cast<function_ptr>(0);
20632 else if (!valid_symbol(function_name))
20633 return reinterpret_cast<function_ptr>(0);
20634 else
20635 return local_data().function_store.get(function_name);
20636 }
20637
20638 inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
20639 {
20640 if (!valid())
20641 return reinterpret_cast<vararg_function_ptr>(0);
20642 else if (!valid_symbol(vararg_function_name))
20643 return reinterpret_cast<vararg_function_ptr>(0);
20644 else
20645 return local_data().vararg_function_store.get(vararg_function_name);
20646 }
20647
20648 inline generic_function_ptr get_generic_function(const std::string& function_name) const
20649 {
20650 if (!valid())
20651 return reinterpret_cast<generic_function_ptr>(0);
20652 else if (!valid_symbol(function_name))
20653 return reinterpret_cast<generic_function_ptr>(0);
20654 else
20655 return local_data().generic_function_store.get(function_name);
20656 }
20657
20658 inline generic_function_ptr get_string_function(const std::string& function_name) const
20659 {
20660 if (!valid())
20661 return reinterpret_cast<generic_function_ptr>(0);
20662 else if (!valid_symbol(function_name))
20663 return reinterpret_cast<generic_function_ptr>(0);
20664 else
20665 return local_data().string_function_store.get(function_name);
20666 }
20667
20668 inline generic_function_ptr get_overload_function(const std::string& function_name) const
20669 {
20670 if (!valid())
20671 return reinterpret_cast<generic_function_ptr>(0);
20672 else if (!valid_symbol(function_name))
20673 return reinterpret_cast<generic_function_ptr>(0);
20674 else
20675 return local_data().overload_function_store.get(function_name);
20676 }
20677
20679
20680 inline vector_holder_ptr get_vector(const std::string& vector_name) const
20681 {
20682 if (!valid())
20683 return reinterpret_cast<vector_holder_ptr>(0);
20684 else if (!valid_symbol(vector_name))
20685 return reinterpret_cast<vector_holder_ptr>(0);
20686 else
20687 return local_data().vector_store.get(vector_name);
20688 }
20689
20690 inline T& variable_ref(const std::string& symbol_name)
20691 {
20692 static T null_var = T(0);
20693 if (!valid())
20694 return null_var;
20695 else if (!valid_symbol(symbol_name))
20696 return null_var;
20697 else
20698 return local_data().variable_store.type_ref(symbol_name);
20699 }
20700
20701 #ifndef exprtk_disable_string_capabilities
20702 inline std::string& stringvar_ref(const std::string& symbol_name)
20703 {
20704 static std::string null_stringvar;
20705 if (!valid())
20706 return null_stringvar;
20707 else if (!valid_symbol(symbol_name))
20708 return null_stringvar;
20709 else
20710 return local_data().stringvar_store.type_ref(symbol_name);
20711 }
20712 #endif
20713
20714 inline bool is_constant_node(const std::string& symbol_name) const
20715 {
20716 if (!valid())
20717 return false;
20718 else if (!valid_symbol(symbol_name))
20719 return false;
20720 else
20721 return local_data().variable_store.is_constant(symbol_name);
20722 }
20723
20724 #ifndef exprtk_disable_string_capabilities
20725 inline bool is_constant_string(const std::string& symbol_name) const
20726 {
20727 if (!valid())
20728 return false;
20729 else if (!valid_symbol(symbol_name))
20730 return false;
20731 else if (!local_data().stringvar_store.symbol_exists(symbol_name))
20732 return false;
20733 else
20734 return local_data().stringvar_store.is_constant(symbol_name);
20735 }
20736 #endif
20737
20738 inline bool create_variable(const std::string& variable_name, const T& value = T(0))
20739 {
20740 if (!valid())
20741 return false;
20742 else if (!valid_symbol(variable_name))
20743 return false;
20744 else if (symbol_exists(variable_name))
20745 return false;
20746
20747 local_data().local_symbol_list_.push_back(value);
20748 T& t = local_data().local_symbol_list_.back();
20749
20750 return add_variable(variable_name,t);
20751 }
20752
20753 #ifndef exprtk_disable_string_capabilities
20754 inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string(""))
20755 {
20756 if (!valid())
20757 return false;
20758 else if (!valid_symbol(stringvar_name))
20759 return false;
20760 else if (symbol_exists(stringvar_name))
20761 return false;
20762
20763 local_data().local_stringvar_list_.push_back(value);
20764 std::string& s = local_data().local_stringvar_list_.back();
20765
20766 return add_stringvar(stringvar_name,s);
20767 }
20768 #endif
20769
20770 inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false)
20771 {
20772 if (!valid())
20773 return false;
20774 else if (!valid_symbol(variable_name))
20775 return false;
20776 else if (symbol_exists(variable_name))
20777 return false;
20778 else
20779 return local_data().variable_store.add(variable_name, t, is_constant);
20780 }
20781
20782 inline bool add_constant(const std::string& constant_name, const T& value)
20783 {
20784 if (!valid())
20785 return false;
20786 else if (!valid_symbol(constant_name))
20787 return false;
20788 else if (symbol_exists(constant_name))
20789 return false;
20790
20791 local_data().local_symbol_list_.push_back(value);
20792 T& t = local_data().local_symbol_list_.back();
20793
20794 return add_variable(constant_name, t, true);
20795 }
20796
20797 #ifndef exprtk_disable_string_capabilities
20798 inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false)
20799 {
20800 if (!valid())
20801 return false;
20802 else if (!valid_symbol(stringvar_name))
20803 return false;
20804 else if (symbol_exists(stringvar_name))
20805 return false;
20806 else
20807 return local_data().stringvar_store.add(stringvar_name, s, is_constant);
20808 }
20809 #endif
20810
20811 inline bool add_function(const std::string& function_name, function_t& function)
20812 {
20813 if (!valid())
20814 return false;
20815 else if (!valid_symbol(function_name))
20816 return false;
20817 else if (symbol_exists(function_name))
20818 return false;
20819 else
20820 return local_data().function_store.add(function_name,function);
20821 }
20822
20823 inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
20824 {
20825 if (!valid())
20826 return false;
20827 else if (!valid_symbol(vararg_function_name))
20828 return false;
20829 else if (symbol_exists(vararg_function_name))
20830 return false;
20831 else
20832 return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
20833 }
20834
20835 inline bool add_function(const std::string& function_name, generic_function_t& function)
20836 {
20837 if (!valid())
20838 return false;
20839 else if (!valid_symbol(function_name))
20840 return false;
20841 else if (symbol_exists(function_name))
20842 return false;
20843 else
20844 {
20845 switch (function.rtrn_type)
20846 {
20848 return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20849 local_data().generic_function_store.add(function_name,function) : false;
20850
20852 return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20853 local_data().string_function_store.add(function_name,function) : false;
20854
20856 return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ?
20857 local_data().overload_function_store.add(function_name,function) : false;
20858 }
20859 }
20860
20861 return false;
20862 }
20863
20864 #define exprtk_define_freefunction(NN) \
20865 inline bool add_function(const std::string& function_name, ff##NN##_functor function) \
20866 { \
20867 if (!valid()) \
20868 { return false; } \
20869 if (!valid_symbol(function_name)) \
20870 { return false; } \
20871 if (symbol_exists(function_name)) \
20872 { return false; } \
20873 \
20874 exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
20875 \
20876 local_data().free_function_list_.push_back(ifunc); \
20877 \
20878 return add_function(function_name,(*local_data().free_function_list_.back())); \
20879 } \
20880
20889
20890 #undef exprtk_define_freefunction
20891
20892 inline bool add_reserved_function(const std::string& function_name, function_t& function)
20893 {
20894 if (!valid())
20895 return false;
20896 else if (!valid_symbol(function_name,false))
20897 return false;
20898 else if (symbol_exists(function_name,false))
20899 return false;
20900 else
20901 return local_data().function_store.add(function_name,function);
20902 }
20903
20904 inline bool add_reserved_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
20905 {
20906 if (!valid())
20907 return false;
20908 else if (!valid_symbol(vararg_function_name,false))
20909 return false;
20910 else if (symbol_exists(vararg_function_name,false))
20911 return false;
20912 else
20913 return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
20914 }
20915
20916 inline bool add_reserved_function(const std::string& function_name, generic_function_t& function)
20917 {
20918 if (!valid())
20919 return false;
20920 else if (!valid_symbol(function_name,false))
20921 return false;
20922 else if (symbol_exists(function_name,false))
20923 return false;
20924 else
20925 {
20926 switch (function.rtrn_type)
20927 {
20929 return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20930 local_data().generic_function_store.add(function_name,function) : false;
20931
20933 return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20934 local_data().string_function_store.add(function_name,function) : false;
20935
20937 return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ?
20938 local_data().overload_function_store.add(function_name,function) : false;
20939 }
20940 }
20941
20942 return false;
20943 }
20944
20945 #define exprtk_define_reserved_function(NN) \
20946 inline bool add_reserved_function(const std::string& function_name, ff##NN##_functor function) \
20947 { \
20948 if (!valid()) \
20949 { return false; } \
20950 if (!valid_symbol(function_name,false)) \
20951 { return false; } \
20952 if (symbol_exists(function_name,false)) \
20953 { return false; } \
20954 \
20955 exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
20956 \
20957 local_data().free_function_list_.push_back(ifunc); \
20958 \
20959 return add_reserved_function(function_name,(*local_data().free_function_list_.back())); \
20960 } \
20961
20970
20971 #undef exprtk_define_reserved_function
20972
20973 template <std::size_t N>
20974 inline bool add_vector(const std::string& vector_name, T (&v)[N])
20975 {
20976 if (!valid())
20977 return false;
20978 else if (!valid_symbol(vector_name))
20979 return false;
20980 else if (symbol_exists(vector_name))
20981 return false;
20982 else
20983 return local_data().vector_store.add(vector_name,v);
20984 }
20985
20986 inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size)
20987 {
20988 if (!valid())
20989 return false;
20990 else if (!valid_symbol(vector_name))
20991 return false;
20992 else if (symbol_exists(vector_name))
20993 return false;
20994 else if (0 == v_size)
20995 return false;
20996 else
20997 return local_data().vector_store.add(vector_name, v, v_size);
20998 }
20999
21000 template <typename Allocator>
21001 inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v)
21002 {
21003 if (!valid())
21004 return false;
21005 else if (!valid_symbol(vector_name))
21006 return false;
21007 else if (symbol_exists(vector_name))
21008 return false;
21009 else if (0 == v.size())
21010 return false;
21011 else
21012 return local_data().vector_store.add(vector_name,v);
21013 }
21014
21015 inline bool add_vector(const std::string& vector_name, exprtk::vector_view<T>& v)
21016 {
21017 if (!valid())
21018 return false;
21019 else if (!valid_symbol(vector_name))
21020 return false;
21021 else if (symbol_exists(vector_name))
21022 return false;
21023 else if (0 == v.size())
21024 return false;
21025 else
21026 return local_data().vector_store.add(vector_name,v);
21027 }
21028
21029 inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
21030 {
21031 if (!valid())
21032 return false;
21033 else
21034 return local_data().variable_store.remove(variable_name, delete_node);
21035 }
21036
21037 #ifndef exprtk_disable_string_capabilities
21038 inline bool remove_stringvar(const std::string& string_name)
21039 {
21040 if (!valid())
21041 return false;
21042 else
21043 return local_data().stringvar_store.remove(string_name);
21044 }
21045 #endif
21046
21047 inline bool remove_function(const std::string& function_name)
21048 {
21049 if (!valid())
21050 return false;
21051 else
21052 return local_data().function_store.remove(function_name);
21053 }
21054
21055 inline bool remove_vararg_function(const std::string& vararg_function_name)
21056 {
21057 if (!valid())
21058 return false;
21059 else
21060 return local_data().vararg_function_store.remove(vararg_function_name);
21061 }
21062
21063 inline bool remove_vector(const std::string& vector_name)
21064 {
21065 if (!valid())
21066 return false;
21067 else
21068 return local_data().vector_store.remove(vector_name);
21069 }
21070
21071 inline bool add_constants()
21072 {
21073 return add_pi () &&
21074 add_epsilon () &&
21075 add_infinity() ;
21076 }
21077
21078 inline bool add_pi()
21079 {
21081 static const T local_pi = details::numeric::details::const_pi_impl<T>(num_type);
21082 return add_constant("pi",local_pi);
21083 }
21084
21085 inline bool add_epsilon()
21086 {
21087 static const T local_epsilon = details::numeric::details::epsilon_type<T>::value();
21088 return add_constant("epsilon",local_epsilon);
21089 }
21090
21091 inline bool add_infinity()
21092 {
21093 static const T local_infinity = std::numeric_limits<T>::infinity();
21094 return add_constant("inf",local_infinity);
21095 }
21096
21097 template <typename Package>
21098 inline bool add_package(Package& package)
21099 {
21100 return package.register_package(*this);
21101 }
21102
21103 template <typename Allocator,
21104 template <typename, typename> class Sequence>
21105 inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const
21106 {
21107 if (!valid())
21108 return 0;
21109 else
21110 return local_data().variable_store.get_list(vlist);
21111 }
21112
21113 template <typename Allocator,
21114 template <typename, typename> class Sequence>
21115 inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const
21116 {
21117 if (!valid())
21118 return 0;
21119 else
21120 return local_data().variable_store.get_list(vlist);
21121 }
21122
21123 #ifndef exprtk_disable_string_capabilities
21124 template <typename Allocator,
21125 template <typename, typename> class Sequence>
21126 inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const
21127 {
21128 if (!valid())
21129 return 0;
21130 else
21131 return local_data().stringvar_store.get_list(svlist);
21132 }
21133
21134 template <typename Allocator,
21135 template <typename, typename> class Sequence>
21136 inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const
21137 {
21138 if (!valid())
21139 return 0;
21140 else
21141 return local_data().stringvar_store.get_list(svlist);
21142 }
21143 #endif
21144
21145 template <typename Allocator,
21146 template <typename, typename> class Sequence>
21147 inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vec_list) const
21148 {
21149 if (!valid())
21150 return 0;
21151 else
21152 return local_data().vector_store.get_list(vec_list);
21153 }
21154
21155 template <typename Allocator,
21156 template <typename, typename> class Sequence>
21157 inline std::size_t get_function_list(Sequence<std::string,Allocator>& function_list) const
21158 {
21159 if (!valid())
21160 return 0;
21161
21162 std::vector<std::string> function_names;
21163 std::size_t count = 0;
21164
21165 count += local_data().function_store .get_list(function_names);
21166 count += local_data().vararg_function_store .get_list(function_names);
21167 count += local_data().generic_function_store .get_list(function_names);
21168 count += local_data().string_function_store .get_list(function_names);
21169 count += local_data().overload_function_store.get_list(function_names);
21170
21171 std::set<std::string> function_set;
21172
21173 for (std::size_t i = 0; i < function_names.size(); ++i)
21174 {
21175 function_set.insert(function_names[i]);
21176 }
21177
21178 std::copy(function_set.begin(), function_set.end(),
21179 std::back_inserter(function_list));
21180
21181 return count;
21182 }
21183
21184 inline std::vector<std::string> get_function_list() const
21185 {
21186 std::vector<std::string> result;
21187 get_function_list(result);
21188 return result;
21189 }
21190
21191 inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const
21192 {
21193 /*
21194 Function will return true if symbol_name exists as either a
21195 reserved symbol, variable, stringvar, vector or function name
21196 in any of the type stores.
21197 */
21198 if (!valid())
21199 return false;
21200 else if (local_data().variable_store.symbol_exists(symbol_name))
21201 return true;
21202 #ifndef exprtk_disable_string_capabilities
21203 else if (local_data().stringvar_store.symbol_exists(symbol_name))
21204 return true;
21205 #endif
21206 else if (local_data().vector_store.symbol_exists(symbol_name))
21207 return true;
21208 else if (local_data().function_store.symbol_exists(symbol_name))
21209 return true;
21210 else if (check_reserved_symb && local_data().is_reserved_symbol(symbol_name))
21211 return true;
21212 else
21213 return false;
21214 }
21215
21216 inline bool is_variable(const std::string& variable_name) const
21217 {
21218 if (!valid())
21219 return false;
21220 else
21221 return local_data().variable_store.symbol_exists(variable_name);
21222 }
21223
21224 #ifndef exprtk_disable_string_capabilities
21225 inline bool is_stringvar(const std::string& stringvar_name) const
21226 {
21227 if (!valid())
21228 return false;
21229 else
21230 return local_data().stringvar_store.symbol_exists(stringvar_name);
21231 }
21232
21233 inline bool is_conststr_stringvar(const std::string& symbol_name) const
21234 {
21235 if (!valid())
21236 return false;
21237 else if (!valid_symbol(symbol_name))
21238 return false;
21239 else if (!local_data().stringvar_store.symbol_exists(symbol_name))
21240 return false;
21241
21242 return (
21243 local_data().stringvar_store.symbol_exists(symbol_name) ||
21244 local_data().stringvar_store.is_constant (symbol_name)
21245 );
21246 }
21247 #endif
21248
21249 inline bool is_function(const std::string& function_name) const
21250 {
21251 if (!valid())
21252 return false;
21253 else
21254 return local_data().function_store.symbol_exists(function_name);
21255 }
21256
21257 inline bool is_vararg_function(const std::string& vararg_function_name) const
21258 {
21259 if (!valid())
21260 return false;
21261 else
21262 return local_data().vararg_function_store.symbol_exists(vararg_function_name);
21263 }
21264
21265 inline bool is_vector(const std::string& vector_name) const
21266 {
21267 if (!valid())
21268 return false;
21269 else
21270 return local_data().vector_store.symbol_exists(vector_name);
21271 }
21272
21273 inline std::string get_variable_name(const expression_ptr& ptr) const
21274 {
21275 return local_data().variable_store.entity_name(ptr);
21276 }
21277
21278 inline std::string get_vector_name(const vector_holder_ptr& ptr) const
21279 {
21280 return local_data().vector_store.entity_name(ptr);
21281 }
21282
21283 #ifndef exprtk_disable_string_capabilities
21284 inline std::string get_stringvar_name(const expression_ptr& ptr) const
21285 {
21286 return local_data().stringvar_store.entity_name(ptr);
21287 }
21288
21289 inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const
21290 {
21291 return local_data().stringvar_store.entity_name(ptr);
21292 }
21293 #endif
21294
21295 inline bool valid() const
21296 {
21297 // Symbol table sanity check.
21299 }
21300
21301 inline void load_from(const symbol_table<T>& st)
21302 {
21303 {
21304 std::vector<std::string> name_list;
21305
21306 st.local_data().function_store.get_list(name_list);
21307
21308 if (!name_list.empty())
21309 {
21310 for (std::size_t i = 0; i < name_list.size(); ++i)
21311 {
21312 exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]);
21313 add_function(name_list[i],ifunc);
21314 }
21315 }
21316 }
21317
21318 {
21319 std::vector<std::string> name_list;
21320
21321 st.local_data().vararg_function_store.get_list(name_list);
21322
21323 if (!name_list.empty())
21324 {
21325 for (std::size_t i = 0; i < name_list.size(); ++i)
21326 {
21327 exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]);
21328 add_function(name_list[i],ivafunc);
21329 }
21330 }
21331 }
21332
21333 {
21334 std::vector<std::string> name_list;
21335
21336 st.local_data().generic_function_store.get_list(name_list);
21337
21338 if (!name_list.empty())
21339 {
21340 for (std::size_t i = 0; i < name_list.size(); ++i)
21341 {
21342 exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]);
21343 add_function(name_list[i],ifunc);
21344 }
21345 }
21346 }
21347
21348 {
21349 std::vector<std::string> name_list;
21350
21351 st.local_data().string_function_store.get_list(name_list);
21352
21353 if (!name_list.empty())
21354 {
21355 for (std::size_t i = 0; i < name_list.size(); ++i)
21356 {
21357 exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]);
21358 add_function(name_list[i],ifunc);
21359 }
21360 }
21361 }
21362
21363 {
21364 std::vector<std::string> name_list;
21365
21366 st.local_data().overload_function_store.get_list(name_list);
21367
21368 if (!name_list.empty())
21369 {
21370 for (std::size_t i = 0; i < name_list.size(); ++i)
21371 {
21372 exprtk::igeneric_function<T>& ifunc = *st.get_overload_function(name_list[i]);
21373 add_function(name_list[i],ifunc);
21374 }
21375 }
21376 }
21377 }
21378
21380 {
21381 std::vector<std::string> name_list;
21382
21383 st.local_data().variable_store.get_list(name_list);
21384
21385 if (!name_list.empty())
21386 {
21387 for (std::size_t i = 0; i < name_list.size(); ++i)
21388 {
21389 T& variable = st.get_variable(name_list[i])->ref();
21390 add_variable(name_list[i], variable);
21391 }
21392 }
21393 }
21394
21395 inline void load_vectors_from(const symbol_table<T>& st)
21396 {
21397 std::vector<std::string> name_list;
21398
21399 st.local_data().vector_store.get_list(name_list);
21400
21401 if (!name_list.empty())
21402 {
21403 for (std::size_t i = 0; i < name_list.size(); ++i)
21404 {
21405 vector_holder_t& vecholder = *st.get_vector(name_list[i]);
21406 add_vector(name_list[i], vecholder.data(), vecholder.size());
21407 }
21408 }
21409 }
21410
21411 private:
21412
21413 inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const
21414 {
21415 if (symbol.empty())
21416 return false;
21417 else if (!details::is_letter(symbol[0]))
21418 return false;
21419 else if (symbol.size() > 1)
21420 {
21421 for (std::size_t i = 1; i < symbol.size(); ++i)
21422 {
21423 if (
21424 !details::is_letter_or_digit(symbol[i]) &&
21425 ('_' != symbol[i])
21426 )
21427 {
21428 if ((i < (symbol.size() - 1)) && ('.' == symbol[i]))
21429 continue;
21430 else
21431 return false;
21432 }
21433 }
21434 }
21435
21436 return (check_reserved_symb) ? (!local_data().is_reserved_symbol(symbol)) : true;
21437 }
21438
21439 inline bool valid_function(const std::string& symbol) const
21440 {
21441 if (symbol.empty())
21442 return false;
21443 else if (!details::is_letter(symbol[0]))
21444 return false;
21445 else if (symbol.size() > 1)
21446 {
21447 for (std::size_t i = 1; i < symbol.size(); ++i)
21448 {
21449 if (
21450 !details::is_letter_or_digit(symbol[i]) &&
21451 ('_' != symbol[i])
21452 )
21453 {
21454 if ((i < (symbol.size() - 1)) && ('.' == symbol[i]))
21455 continue;
21456 else
21457 return false;
21458 }
21459 }
21460 }
21461
21462 return true;
21463 }
21464
21466
21468 {
21469 return *(control_block_->data_);
21470 }
21471
21472 inline const local_data_t& local_data() const
21473 {
21474 return *(control_block_->data_);
21475 }
21476
21478
21479 friend class parser<T>;
21480 }; // class symbol_table
21481
21482 template <typename T>
21483 class function_compositor;
21484
21485 template <typename T>
21487 {
21488 private:
21489
21492 typedef std::vector<symbol_table<T> > symtab_list_t;
21493
21495 {
21505
21506 static std::string to_str(data_type dt)
21507 {
21508 switch(dt)
21509 {
21510 case e_unknown : return "e_unknown ";
21511 case e_expr : return "e_expr" ;
21512 case e_vecholder : return "e_vecholder";
21513 case e_data : return "e_data" ;
21514 case e_vecdata : return "e_vecdata" ;
21515 case e_string : return "e_string" ;
21516 }
21517
21518 return "";
21519 }
21520
21522 {
21524 : pointer(0)
21525 , type(e_unknown)
21526 , size(0)
21527 {}
21528
21529 data_pack(void* ptr, const data_type dt, const std::size_t sz = 0)
21530 : pointer(ptr)
21531 , type(dt)
21532 , size(sz)
21533 {}
21534
21535 void* pointer;
21537 std::size_t size;
21538 };
21539
21540 typedef std::vector<data_pack> local_data_list_t;
21543
21545 : ref_count(0)
21546 , expr (0)
21547 , results (0)
21548 , retinv_null(false)
21550 {}
21551
21553 : ref_count(1)
21554 , expr (e)
21555 , results (0)
21556 , retinv_null(false)
21558 {}
21559
21561 {
21563 {
21564 destroy_node(expr);
21565 }
21566
21567 if (!local_data_list.empty())
21568 {
21569 for (std::size_t i = 0; i < local_data_list.size(); ++i)
21570 {
21571 switch (local_data_list[i].type)
21572 {
21573 case e_expr : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer);
21574 break;
21575
21576 case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer);
21577 break;
21578
21579 case e_data : delete reinterpret_cast<T*>(local_data_list[i].pointer);
21580 break;
21581
21582 case e_vecdata : delete [] reinterpret_cast<T*>(local_data_list[i].pointer);
21583 break;
21584
21585 case e_string : delete reinterpret_cast<std::string*>(local_data_list[i].pointer);
21586 break;
21587
21588 default : break;
21589 }
21590 }
21591 }
21592
21593 if (results)
21594 {
21595 delete results;
21596 }
21597 }
21598
21600 {
21601 return new control_block(e);
21602 }
21603
21604 static inline void destroy(cntrl_blck_ptr_t& cntrl_blck)
21605 {
21606 if (cntrl_blck)
21607 {
21608 if (
21609 (0 != cntrl_blck->ref_count) &&
21610 (0 == --cntrl_blck->ref_count)
21611 )
21612 {
21613 delete cntrl_blck;
21614 }
21615
21616 cntrl_blck = 0;
21617 }
21618 }
21619
21620 std::size_t ref_count;
21626
21627 friend class function_compositor<T>;
21628 };
21629
21630 public:
21631
21633 : control_block_(0)
21634 {
21636 }
21637
21644
21646 : control_block_(0)
21647 {
21650 }
21651
21653 {
21654 if (this != &e)
21655 {
21656 if (control_block_)
21657 {
21658 if (
21659 (0 != control_block_->ref_count) &&
21660 (0 == --control_block_->ref_count)
21661 )
21662 {
21663 delete control_block_;
21664 }
21665
21666 control_block_ = 0;
21667 }
21668
21669 control_block_ = e.control_block_;
21671 symbol_table_list_ = e.symbol_table_list_;
21672 }
21673
21674 return *this;
21675 }
21676
21677 inline bool operator==(const expression<T>& e) const
21678 {
21679 return (this == &e);
21680 }
21681
21682 inline bool operator!() const
21683 {
21684 return (
21685 (0 == control_block_ ) ||
21686 (0 == control_block_->expr)
21687 );
21688 }
21689
21691 {
21692 exprtk::details::dump_ptr("expression::release", this);
21694
21695 return (*this);
21696 }
21697
21702
21703 inline T value() const
21704 {
21705 assert(control_block_ );
21706 assert(control_block_->expr);
21707
21708 return control_block_->expr->value();
21709 }
21710
21711 inline T operator() () const
21712 {
21713 return value();
21714 }
21715
21716 inline operator T() const
21717 {
21718 return value();
21719 }
21720
21721 inline operator bool() const
21722 {
21723 return details::is_true(value());
21724 }
21725
21727 {
21728 for (std::size_t i = 0; i < symbol_table_list_.size(); ++i)
21729 {
21730 if (st == symbol_table_list_[i])
21731 {
21732 return false;
21733 }
21734 }
21735
21736 symbol_table_list_.push_back(st);
21737 return true;
21738 }
21739
21740 inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const
21741 {
21742 return symbol_table_list_[index];
21743 }
21744
21745 inline symbol_table<T>& get_symbol_table(const std::size_t& index = 0)
21746 {
21747 return symbol_table_list_[index];
21748 }
21749
21750 std::size_t num_symbol_tables() const
21751 {
21752 return symbol_table_list_.size();
21753 }
21754
21756
21757 inline const results_context_t& results() const
21758 {
21760 return (*control_block_->results);
21761 else
21762 {
21763 static const results_context_t null_results;
21764 return null_results;
21765 }
21766 }
21767
21768 inline bool return_invoked() const
21769 {
21770 return (*control_block_->return_invoked);
21771 }
21772
21773 private:
21774
21776 {
21777 return symbol_table_list_;
21778 }
21779
21780 inline void set_expression(const expression_ptr expr)
21781 {
21782 if (expr)
21783 {
21784 if (control_block_)
21785 {
21786 if (0 == --control_block_->ref_count)
21787 {
21788 delete control_block_;
21789 }
21790 }
21791
21793 }
21794 }
21795
21797 {
21798 if (expr)
21799 {
21800 if (control_block_)
21801 {
21803 local_data_list.push_back(
21805 data_pack(reinterpret_cast<void*>(expr),
21807 }
21808 }
21809 }
21810
21812 {
21813 if (vec_holder)
21814 {
21815 if (control_block_)
21816 {
21818 local_data_list.push_back(
21820 data_pack(reinterpret_cast<void*>(vec_holder),
21822 }
21823 }
21824 }
21825
21826 inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0)
21827 {
21828 if (data)
21829 {
21830 if (control_block_)
21831 {
21833
21834 switch (data_mode)
21835 {
21836 case 0 : dt = control_block::e_data; break;
21837 case 1 : dt = control_block::e_vecdata; break;
21838 case 2 : dt = control_block::e_string; break;
21839 }
21840
21842 local_data_list.push_back(
21844 data_pack(reinterpret_cast<void*>(data), dt, size));
21845 }
21846 }
21847 }
21848
21850 {
21851 if (control_block_)
21852 {
21854 }
21855 else
21856 {
21857 static typename control_block::local_data_list_t null_local_data_list;
21858 return null_local_data_list;
21859 }
21860 }
21861
21863 {
21864 if (control_block_ && rc)
21865 {
21866 control_block_->results = rc;
21867 }
21868 }
21869
21870 inline void set_retinvk(bool* retinvk_ptr)
21871 {
21872 if (control_block_)
21873 {
21874 control_block_->return_invoked = retinvk_ptr;
21875 }
21876 }
21877
21880
21881 friend class parser<T>;
21882 friend class expression_helper<T>;
21883 friend class function_compositor<T>;
21884 template <typename TT>
21885 friend bool is_valid(const expression<TT>& expr);
21886 }; // class expression
21887
21888 template <typename T>
21890 {
21891 public:
21892
21907
21908 static inline bool is_literal(const expression<T>& expr)
21909 {
21911 }
21912
21913 static inline bool is_variable(const expression<T>& expr)
21914 {
21916 }
21917
21918 static inline bool is_string(const expression<T>& expr)
21919 {
21921 }
21922
21923 static inline bool is_unary(const expression<T>& expr)
21924 {
21926 }
21927
21928 static inline bool is_binary(const expression<T>& expr)
21929 {
21931 }
21932
21933 static inline bool is_function(const expression<T>& expr)
21934 {
21936 }
21937
21938 static inline bool is_vararg(const expression<T>& expr)
21939 {
21941 }
21942
21943 static inline bool is_null(const expression<T>& expr)
21944 {
21946 }
21947
21948 static inline bool is_assert(const expression<T>& expr)
21949 {
21951 }
21952
21953 static inline bool is_sf3ext(const expression<T>& expr)
21954 {
21956 }
21957
21958 static inline bool is_sf4ext(const expression<T>& expr)
21959 {
21961 }
21962
21963 static inline bool is_type(const expression<T>& expr, const node_types node_type)
21964 {
21965 if (0 == expr.control_block_)
21966 {
21967 return false;
21968 }
21969
21970 switch (node_type)
21971 {
21972 case e_literal : return is_literal_node(expr);
21973 case e_variable : return is_variable (expr);
21974 case e_string : return is_string (expr);
21975 case e_unary : return is_unary (expr);
21976 case e_binary : return is_binary (expr);
21977 case e_function : return is_function (expr);
21978 case e_null : return is_null (expr);
21979 case e_assert : return is_assert (expr);
21980 case e_sf3ext : return is_sf3ext (expr);
21981 case e_sf4ext : return is_sf4ext (expr);
21982 };
21983
21984 return false;
21985 }
21986
21987 static inline bool match_type_sequence(const expression<T>& expr, const std::vector<node_types>& type_seq)
21988 {
21989 if ((0 == expr.control_block_) || !is_vararg(expr))
21990 {
21991 return false;
21992 }
21993
21995
21996 mo_vararg_t* vnode = dynamic_cast<mo_vararg_t*>(expr.control_block_->expr);
21997
21998 if (
21999 (0 == vnode) ||
22000 type_seq.empty() ||
22001 (vnode->size() < type_seq.size())
22002 )
22003 {
22004 return false;
22005 }
22006
22007 for (std::size_t i = 0; i < type_seq.size(); ++i)
22008 {
22009 assert((*vnode)[i]);
22010
22011 switch(type_seq[i])
22012 {
22013 case e_literal : { if (details::is_literal_node ((*vnode)[i])) continue; } break;
22014 case e_variable : { if (details::is_variable_node ((*vnode)[i])) continue; } break;
22015 case e_string : { if (details::is_generally_string_node((*vnode)[i])) continue; } break;
22016 case e_unary : { if (details::is_unary_node ((*vnode)[i])) continue; } break;
22017 case e_binary : { if (details::is_binary_node ((*vnode)[i])) continue; } break;
22018 case e_function : { if (details::is_function ((*vnode)[i])) continue; } break;
22019 case e_null : { if (details::is_null_node ((*vnode)[i])) continue; } break;
22020 case e_assert : { if (details::is_assert_node ((*vnode)[i])) continue; } break;
22021 case e_sf3ext : { if (details::is_sf3ext_node ((*vnode)[i])) continue; } break;
22022 case e_sf4ext : { if (details::is_sf4ext_node ((*vnode)[i])) continue; } break;
22023 case e_vararg : break;
22024 }
22025
22026 return false;
22027 }
22028
22029 return true;
22030 }
22031 };
22032
22033 template <typename T>
22034 inline bool is_valid(const expression<T>& expr)
22035 {
22036 return expr.control_block_ && !expression_helper<T>::is_null(expr);
22037 }
22038
22039 namespace parser_error
22040 {
22053
22054 struct type
22055 {
22057 : mode(parser_error::e_unknown)
22058 , line_no (0)
22059 , column_no(0)
22060 {}
22061
22064 std::string diagnostic;
22065 std::string src_location;
22066 std::string error_line;
22067 std::size_t line_no;
22068 std::size_t column_no;
22069 };
22070
22071 inline type make_error(const error_mode mode,
22072 const std::string& diagnostic = "",
22073 const std::string& src_location = "")
22074 {
22075 type t;
22076 t.mode = mode;
22078 t.diagnostic = diagnostic;
22079 t.src_location = src_location;
22080 exprtk_debug(("%s\n", diagnostic .c_str()));
22081 return t;
22082 }
22083
22084 inline type make_error(const error_mode mode,
22085 const lexer::token& tk,
22086 const std::string& diagnostic = "",
22087 const std::string& src_location = "")
22088 {
22089 type t;
22090 t.mode = mode;
22091 t.token = tk;
22092 t.diagnostic = diagnostic;
22093 t.src_location = src_location;
22094 exprtk_debug(("%s\n", diagnostic .c_str()));
22095 return t;
22096 }
22097
22098 inline std::string to_str(error_mode mode)
22099 {
22100 switch (mode)
22101 {
22102 case e_unknown : return std::string("Unknown Error");
22103 case e_syntax : return std::string("Syntax Error" );
22104 case e_token : return std::string("Token Error" );
22105 case e_numeric : return std::string("Numeric Error");
22106 case e_symtab : return std::string("Symbol Error" );
22107 case e_lexer : return std::string("Lexer Error" );
22108 case e_helper : return std::string("Helper Error" );
22109 case e_parser : return std::string("Parser Error" );
22110 default : return std::string("Unknown Error");
22111 }
22112 }
22113
22114 inline bool update_error(type& error, const std::string& expression)
22115 {
22116 if (
22117 expression.empty() ||
22118 (error.token.position > expression.size()) ||
22119 (std::numeric_limits<std::size_t>::max() == error.token.position)
22120 )
22121 {
22122 return false;
22123 }
22124
22125 std::size_t error_line_start = 0;
22126
22127 for (std::size_t i = error.token.position; i > 0; --i)
22128 {
22129 const details::char_t c = expression[i];
22130
22131 if (('\n' == c) || ('\r' == c))
22132 {
22133 error_line_start = i + 1;
22134 break;
22135 }
22136 }
22137
22138 std::size_t next_nl_position = std::min(expression.size(),
22139 expression.find_first_of('\n',error.token.position + 1));
22140
22141 error.column_no = error.token.position - error_line_start;
22142 error.error_line = expression.substr(error_line_start,
22143 next_nl_position - error_line_start);
22144
22145 error.line_no = 0;
22146
22147 for (std::size_t i = 0; i < next_nl_position; ++i)
22148 {
22149 if ('\n' == expression[i])
22150 ++error.line_no;
22151 }
22152
22153 return true;
22154 }
22155
22156 inline void dump_error(const type& error)
22157 {
22158 printf("Position: %02d Type: [%s] Msg: %s\n",
22159 static_cast<int>(error.token.position),
22160 exprtk::parser_error::to_str(error.mode).c_str(),
22161 error.diagnostic.c_str());
22162 }
22163 }
22164
22165 namespace details
22166 {
22167 template <typename Parser>
22169 {
22170 p.state_.type_check_enabled = false;
22171 }
22172 }
22173
22174 template <typename T>
22176 {
22177 private:
22178
22185
22186 typedef const T& cref_t;
22187 typedef const T const_t;
22208 #ifndef exprtk_disable_break_continue
22215 #endif
22229 #ifndef exprtk_disable_string_capabilities
22240 #endif
22259
22265
22267
22268 typedef std::map<operator_t, unary_functor_t > unary_op_map_t;
22269 typedef std::map<operator_t, binary_functor_t > binary_op_map_t;
22270 typedef std::map<operator_t, trinary_functor_t> trinary_op_map_t;
22271
22272 typedef std::map<std::string,std::pair<trinary_functor_t ,operator_t> > sf3_map_t;
22273 typedef std::map<std::string,std::pair<quaternary_functor_t,operator_t> > sf4_map_t;
22274
22275 typedef std::map<binary_functor_t,operator_t> inv_binary_op_map_t;
22276 typedef std::multimap<std::string,details::base_operation_t,details::ilesscompare> base_ops_map_t;
22277 typedef std::set<std::string,details::ilesscompare> disabled_func_set_t;
22278
22282
22290
22296
22301
22303
22304 typedef parser_helper prsrhlpr_t;
22305
22307 {
22317
22323 #ifndef exprtk_disable_string_capabilities
22325 #endif
22326
22328 : name("???")
22329 , size (std::numeric_limits<std::size_t>::max())
22330 , index(std::numeric_limits<std::size_t>::max())
22331 , depth(std::numeric_limits<std::size_t>::max())
22332 , ref_count(0)
22333 , ip_index (0)
22334 , type (e_none)
22335 , active (false)
22336 , data (0)
22337 , var_node (0)
22338 , vec_node (0)
22339 #ifndef exprtk_disable_string_capabilities
22340 , str_node(0)
22341 #endif
22342 {}
22343
22344 bool operator < (const scope_element& se) const
22345 {
22346 if (ip_index < se.ip_index)
22347 return true;
22348 else if (ip_index > se.ip_index)
22349 return false;
22350 else if (depth < se.depth)
22351 return true;
22352 else if (depth > se.depth)
22353 return false;
22354 else if (index < se.index)
22355 return true;
22356 else if (index > se.index)
22357 return false;
22358 else
22359 return (name < se.name);
22360 }
22361
22362 void clear()
22363 {
22364 name = "???";
22365 size = std::numeric_limits<std::size_t>::max();
22366 index = std::numeric_limits<std::size_t>::max();
22367 depth = std::numeric_limits<std::size_t>::max();
22368 type = e_none;
22369 active = false;
22370 ref_count = 0;
22371 ip_index = 0;
22372 data = 0;
22373 var_node = 0;
22374 vec_node = 0;
22375 #ifndef exprtk_disable_string_capabilities
22376 str_node = 0;
22377 #endif
22378 }
22379
22380 std::string name;
22381 std::size_t size;
22382 std::size_t index;
22383 std::size_t depth;
22384 std::size_t ref_count;
22385 std::size_t ip_index;
22388 void* data;
22391 #ifndef exprtk_disable_string_capabilities
22393 #endif
22394 };
22395
22397 {
22398 public:
22399
22403
22405 : parser_(p)
22406 , input_param_cnt_(0)
22407 {}
22408
22409 inline std::size_t size() const
22410 {
22411 return element_.size();
22412 }
22413
22414 inline bool empty() const
22415 {
22416 return element_.empty();
22417 }
22418
22419 inline scope_element& get_element(const std::size_t& index)
22420 {
22421 if (index < element_.size())
22422 return element_[index];
22423 else
22424 return null_element_;
22425 }
22426
22427 inline scope_element& get_element(const std::string& var_name,
22428 const std::size_t index = std::numeric_limits<std::size_t>::max())
22429 {
22430 const std::size_t current_depth = parser_.state_.scope_depth;
22431
22432 for (std::size_t i = 0; i < element_.size(); ++i)
22433 {
22434 scope_element& se = element_[i];
22435
22436 if (se.depth > current_depth)
22437 continue;
22438 else if (
22439 details::imatch(se.name, var_name) &&
22440 (se.index == index)
22441 )
22442 return se;
22443 }
22444
22445 return null_element_;
22446 }
22447
22448 inline scope_element& get_active_element(const std::string& var_name,
22449 const std::size_t index = std::numeric_limits<std::size_t>::max())
22450 {
22451 const std::size_t current_depth = parser_.state_.scope_depth;
22452
22453 for (std::size_t i = 0; i < element_.size(); ++i)
22454 {
22455 scope_element& se = element_[i];
22456
22457 if (se.depth > current_depth)
22458 continue;
22459 else if (
22460 details::imatch(se.name, var_name) &&
22461 (se.index == index) &&
22462 (se.active)
22463 )
22464 return se;
22465 }
22466
22467 return null_element_;
22468 }
22469
22470 inline bool add_element(const scope_element& se)
22471 {
22472 for (std::size_t i = 0; i < element_.size(); ++i)
22473 {
22474 scope_element& cse = element_[i];
22475
22476 if (
22477 details::imatch(cse.name, se.name) &&
22478 (cse.depth <= se.depth) &&
22479 (cse.index == se.index) &&
22480 (cse.size == se.size ) &&
22481 (cse.type == se.type ) &&
22482 (cse.active)
22483 )
22484 return false;
22485 }
22486
22487 element_.push_back(se);
22488 std::sort(element_.begin(),element_.end());
22489
22490 return true;
22491 }
22492
22493 inline void deactivate(const std::size_t& scope_depth)
22494 {
22495 exprtk_debug(("deactivate() - Scope depth: %d\n",
22496 static_cast<int>(parser_.state_.scope_depth)));
22497
22498 for (std::size_t i = 0; i < element_.size(); ++i)
22499 {
22500 scope_element& se = element_[i];
22501
22502 if (se.active && (se.depth >= scope_depth))
22503 {
22504 exprtk_debug(("deactivate() - element[%02d] '%s'\n",
22505 static_cast<int>(i),
22506 se.name.c_str()));
22507
22508 se.active = false;
22509 }
22510 }
22511 }
22512
22514 {
22515 exprtk_debug(("free_element() - se[%s]\n", se.name.c_str()));
22516
22517 switch (se.type)
22518 {
22519 case scope_element::e_literal : delete reinterpret_cast<T*>(se.data);
22520 delete se.var_node;
22521 break;
22522
22523 case scope_element::e_variable : delete reinterpret_cast<T*>(se.data);
22524 delete se.var_node;
22525 break;
22526
22527 case scope_element::e_vector : delete[] reinterpret_cast<T*>(se.data);
22528 delete se.vec_node;
22529 break;
22530
22531 case scope_element::e_vecelem : delete se.var_node;
22532 break;
22533
22534 #ifndef exprtk_disable_string_capabilities
22535 case scope_element::e_string : delete reinterpret_cast<std::string*>(se.data);
22536 delete se.str_node;
22537 break;
22538 #endif
22539
22540 default : return;
22541 }
22542
22543 se.clear();
22544 }
22545
22546 inline void cleanup()
22547 {
22548 for (std::size_t i = 0; i < element_.size(); ++i)
22549 {
22551 }
22552
22553 element_.clear();
22554
22555 input_param_cnt_ = 0;
22556 }
22557
22558 inline std::size_t next_ip_index()
22559 {
22560 return ++input_param_cnt_;
22561 }
22562
22564 {
22565 for (std::size_t i = 0; i < element_.size(); ++i)
22566 {
22567 scope_element& se = element_[i];
22568
22569 if (
22570 se.active &&
22571 se.var_node &&
22573 )
22574 {
22575 variable_node_ptr vn = reinterpret_cast<variable_node_ptr>(se.var_node);
22576
22577 if (&(vn->ref()) == (&v))
22578 {
22579 return se.var_node;
22580 }
22581 }
22582 }
22583
22584 return expression_node_ptr(0);
22585 }
22586
22587 inline std::string get_vector_name(const T* data)
22588 {
22589 for (std::size_t i = 0; i < element_.size(); ++i)
22590 {
22591 scope_element& se = element_[i];
22592
22593 if (
22594 se.active &&
22595 se.vec_node &&
22596 (se.vec_node->data() == data)
22597 )
22598 {
22599 return se.name;
22600 }
22601 }
22602
22603 return "neo-vector";
22604 }
22605
22606 private:
22607
22610
22612 std::vector<scope_element> element_;
22614 std::size_t input_param_cnt_;
22615 };
22616
22618 {
22619 public:
22620
22622
22624 : parser_(p)
22625 {
22627 #ifdef exprtk_enable_debugging
22628 const std::string depth(2 * parser_.state_.scope_depth,'-');
22629 exprtk_debug(("%s> Scope Depth: %02d\n",
22630 depth.c_str(),
22631 static_cast<int>(parser_.state_.scope_depth)));
22632 #endif
22633 }
22634
22636 {
22639 #ifdef exprtk_enable_debugging
22640 const std::string depth(2 * parser_.state_.scope_depth,'-');
22641 exprtk_debug(("<%s Scope Depth: %02d\n",
22642 depth.c_str(),
22643 static_cast<int>(parser_.state_.scope_depth)));
22644 #endif
22645 }
22646
22647 private:
22648
22651
22653 };
22654
22655 template <typename T_>
22657 {
22658 static inline bool is_within(const T_& v, const T_& begin, const T_& end)
22659 {
22660 assert(begin <= end);
22661 return (begin <= v) && (v < end);
22662 }
22663
22664 static inline bool is_less(const T_& v, const T_& begin)
22665 {
22666 return (v < begin);
22667 }
22668
22669 static inline bool is_greater(const T_& v, const T_& end)
22670 {
22671 return (end <= v);
22672 }
22673
22674 static inline bool end_inclusive()
22675 {
22676 return false;
22677 }
22678 };
22679
22680 template <typename T_>
22682 {
22683 static inline bool is_within(const T_& v, const T_& begin, const T_& end)
22684 {
22685 assert(begin <= end);
22686 return (begin <= v) && (v <= end);
22687 }
22688
22689 static inline bool is_less(const T_& v, const T_& begin)
22690 {
22691 return (v < begin);
22692 }
22693
22694 static inline bool is_greater(const T_& v, const T_& end)
22695 {
22696 return (end < v);
22697 }
22698
22699 static inline bool end_inclusive()
22700 {
22701 return true;
22702 }
22703 };
22704
22705 template <typename IntervalPointType,
22706 typename RangePolicy = halfopen_range_policy<IntervalPointType> >
22708 {
22709 public:
22710
22711 typedef IntervalPointType interval_point_t;
22712 typedef std::pair<interval_point_t, interval_point_t> interval_t;
22713 typedef std::map<interval_point_t, interval_t> interval_map_t;
22714 typedef typename interval_map_t::const_iterator interval_map_citr_t;
22715
22716 std::size_t size() const
22717 {
22718 return interval_map_.size();
22719 }
22720
22721 void reset()
22722 {
22723 interval_map_.clear();
22724 }
22725
22726 bool in_interval(const interval_point_t point, interval_t& interval) const
22727 {
22728 interval_map_citr_t itr = RangePolicy::end_inclusive() ?
22729 interval_map_.lower_bound(point):
22730 interval_map_.upper_bound(point);
22731
22732 for (; itr != interval_map_.end(); ++itr)
22733 {
22734 const interval_point_t& begin = itr->second.first;
22735 const interval_point_t& end = itr->second.second;
22736
22737 if (RangePolicy::is_within(point, begin, end))
22738 {
22739 interval = interval_t(begin,end);
22740 return true;
22741 }
22742 else if (RangePolicy::is_greater(point, end))
22743 {
22744 break;
22745 }
22746 }
22747
22748 return false;
22749 }
22750
22751 bool in_interval(const interval_point_t point) const
22752 {
22753 interval_t interval;
22754 return in_interval(point,interval);
22755 }
22756
22758 {
22759 if ((end <= begin) || in_interval(begin) || in_interval(end))
22760 {
22761 return false;
22762 }
22763
22764 interval_map_[end] = std::make_pair(begin, end);
22765
22766 return true;
22767 }
22768
22769 bool add_interval(const interval_t interval)
22770 {
22771 return add_interval(interval.first, interval.second);
22772 }
22773
22774 private:
22775
22777 };
22778
22780 {
22781 public:
22782
22784
22786 : parser_(p)
22787 , limit_exceeded_(false)
22788 {
22790 {
22791 limit_exceeded_ = true;
22792 parser_.set_error(make_error(
22794 "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) +
22795 " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_),
22797 }
22798 }
22799
22801 {
22802 assert(parser_.state_.stack_depth > 0);
22804 }
22805
22807 {
22808 return limit_exceeded_;
22809 }
22810
22811 private:
22812
22815
22818 };
22819
22821 {
22823
22827 #ifndef exprtk_disable_string_capabilities
22829 #endif
22833
22835 {
22837 : symbol_table(0)
22838 , variable(0)
22839 {}
22840
22843 };
22844
22855
22856 #ifndef exprtk_disable_string_capabilities
22858 {
22860 : symbol_table(0)
22861 , str_var(0)
22862 {}
22863
22866 };
22867 #endif
22868
22869 inline bool empty() const
22870 {
22871 return symtab_list_.empty();
22872 }
22873
22874 inline void clear()
22875 {
22876 symtab_list_.clear();
22877 }
22878
22879 inline bool valid() const
22880 {
22881 if (!empty())
22882 {
22883 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22884 {
22885 if (symtab_list_[i].valid())
22886 return true;
22887 }
22888 }
22889
22890 return false;
22891 }
22892
22893 inline bool valid_symbol(const std::string& symbol) const
22894 {
22895 if (!symtab_list_.empty())
22896 return symtab_list_[0].valid_symbol(symbol);
22897 else
22898 return false;
22899 }
22900
22901 inline bool valid_function_name(const std::string& symbol) const
22902 {
22903 if (!symtab_list_.empty())
22904 return symtab_list_[0].valid_function(symbol);
22905 else
22906 return false;
22907 }
22908
22909 inline variable_context get_variable_context(const std::string& variable_name) const
22910 {
22911 variable_context result;
22912
22913 if (valid_symbol(variable_name))
22914 {
22915 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22916 {
22917 if (!symtab_list_[i].valid())
22918 {
22919 continue;
22920 }
22921
22922 result.variable = local_data(i)
22923 .variable_store.get(variable_name);
22924 if (result.variable)
22925 {
22926 result.symbol_table = &symtab_list_[i];
22927 break;
22928 }
22929 }
22930 }
22931
22932 return result;
22933 }
22934
22935 inline variable_ptr get_variable(const std::string& variable_name) const
22936 {
22937 if (!valid_symbol(variable_name))
22938 return reinterpret_cast<variable_ptr>(0);
22939
22940 variable_ptr result = reinterpret_cast<variable_ptr>(0);
22941
22942 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22943 {
22944 if (!symtab_list_[i].valid())
22945 continue;
22946 else
22947 result = local_data(i)
22948 .variable_store.get(variable_name);
22949
22950 if (result) break;
22951 }
22952
22953 return result;
22954 }
22955
22956 inline variable_ptr get_variable(const T& var_ref) const
22957 {
22958 variable_ptr result = reinterpret_cast<variable_ptr>(0);
22959
22960 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22961 {
22962 if (!symtab_list_[i].valid())
22963 continue;
22964 else
22965 result = local_data(i).variable_store
22966 .get_from_varptr(reinterpret_cast<const void*>(&var_ref));
22967
22968 if (result) break;
22969 }
22970
22971 return result;
22972 }
22973
22974 #ifndef exprtk_disable_string_capabilities
22975 inline string_context get_string_context(const std::string& string_name) const
22976 {
22977 string_context result;
22978
22979 if (!valid_symbol(string_name))
22980 return result;
22981
22982 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22983 {
22984 if (!symtab_list_[i].valid())
22985 {
22986 continue;
22987 }
22988
22989 result.str_var = local_data(i).stringvar_store.get(string_name);
22990
22991 if (result.str_var)
22992 {
22993 result.symbol_table = &symtab_list_[i];
22994 break;
22995 }
22996 }
22997
22998 return result;
22999 }
23000
23001 inline stringvar_ptr get_stringvar(const std::string& string_name) const
23002 {
23003 if (!valid_symbol(string_name))
23004 return reinterpret_cast<stringvar_ptr>(0);
23005
23006 stringvar_ptr result = reinterpret_cast<stringvar_ptr>(0);
23007
23008 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23009 {
23010 if (!symtab_list_[i].valid())
23011 continue;
23012 else
23013 result = local_data(i)
23014 .stringvar_store.get(string_name);
23015
23016 if (result) break;
23017 }
23018
23019 return result;
23020 }
23021 #endif
23022
23023 inline function_ptr get_function(const std::string& function_name) const
23024 {
23025 if (!valid_function_name(function_name))
23026 return reinterpret_cast<function_ptr>(0);
23027
23028 function_ptr result = reinterpret_cast<function_ptr>(0);
23029
23030 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23031 {
23032 if (!symtab_list_[i].valid())
23033 continue;
23034 else
23035 result = local_data(i)
23036 .function_store.get(function_name);
23037
23038 if (result) break;
23039 }
23040
23041 return result;
23042 }
23043
23044 inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
23045 {
23046 if (!valid_function_name(vararg_function_name))
23047 return reinterpret_cast<vararg_function_ptr>(0);
23048
23049 vararg_function_ptr result = reinterpret_cast<vararg_function_ptr>(0);
23050
23051 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23052 {
23053 if (!symtab_list_[i].valid())
23054 continue;
23055 else
23056 result = local_data(i)
23057 .vararg_function_store.get(vararg_function_name);
23058
23059 if (result) break;
23060 }
23061
23062 return result;
23063 }
23064
23065 inline generic_function_ptr get_generic_function(const std::string& function_name) const
23066 {
23067 if (!valid_function_name(function_name))
23068 return reinterpret_cast<generic_function_ptr>(0);
23069
23070 generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
23071
23072 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23073 {
23074 if (!symtab_list_[i].valid())
23075 continue;
23076 else
23077 result = local_data(i)
23078 .generic_function_store.get(function_name);
23079
23080 if (result) break;
23081 }
23082
23083 return result;
23084 }
23085
23086 inline generic_function_ptr get_string_function(const std::string& function_name) const
23087 {
23088 if (!valid_function_name(function_name))
23089 return reinterpret_cast<generic_function_ptr>(0);
23090
23091 generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
23092
23093 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23094 {
23095 if (!symtab_list_[i].valid())
23096 continue;
23097 else
23098 result =
23099 local_data(i).string_function_store.get(function_name);
23100
23101 if (result) break;
23102 }
23103
23104 return result;
23105 }
23106
23107 inline generic_function_ptr get_overload_function(const std::string& function_name) const
23108 {
23109 if (!valid_function_name(function_name))
23110 return reinterpret_cast<generic_function_ptr>(0);
23111
23112 generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
23113
23114 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23115 {
23116 if (!symtab_list_[i].valid())
23117 continue;
23118 else
23119 result =
23120 local_data(i).overload_function_store.get(function_name);
23121
23122 if (result) break;
23123 }
23124
23125 return result;
23126 }
23127
23128 inline vector_context get_vector_context(const std::string& vector_name) const
23129 {
23130 vector_context result;
23131 if (!valid_symbol(vector_name))
23132 return result;
23133
23134 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23135 {
23136 if (!symtab_list_[i].valid())
23137 {
23138 continue;
23139 }
23140
23141 result.vector_holder = local_data(i).vector_store.get(vector_name);
23142
23143 if (result.vector_holder)
23144 {
23145 result.symbol_table = &symtab_list_[i];
23146 break;
23147 }
23148 }
23149
23150 return result;
23151 }
23152
23153 inline vector_holder_ptr get_vector(const std::string& vector_name) const
23154 {
23155 if (!valid_symbol(vector_name))
23156 return reinterpret_cast<vector_holder_ptr>(0);
23157
23158 vector_holder_ptr result = reinterpret_cast<vector_holder_ptr>(0);
23159
23160 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23161 {
23162 if (!symtab_list_[i].valid())
23163 {
23164 continue;
23165 }
23166
23167 result = local_data(i).vector_store.get(vector_name);
23168
23169 if (result)
23170 {
23171 break;
23172 }
23173 }
23174
23175 return result;
23176 }
23177
23178 inline bool is_constant_node(const std::string& symbol_name) const
23179 {
23180 if (!valid_symbol(symbol_name))
23181 return false;
23182
23183 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23184 {
23185 if (!symtab_list_[i].valid())
23186 {
23187 continue;
23188 }
23189
23190 if (local_data(i).variable_store.is_constant(symbol_name))
23191 {
23192 return true;
23193 }
23194 }
23195
23196 return false;
23197 }
23198
23199 #ifndef exprtk_disable_string_capabilities
23200 inline bool is_constant_string(const std::string& symbol_name) const
23201 {
23202 if (!valid_symbol(symbol_name))
23203 return false;
23204
23205 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23206 {
23207 if (!symtab_list_[i].valid())
23208 continue;
23209 else if (!local_data(i).stringvar_store.symbol_exists(symbol_name))
23210 continue;
23211 else if (local_data(i).stringvar_store.is_constant(symbol_name))
23212 return true;
23213 }
23214
23215 return false;
23216 }
23217 #endif
23218
23219 inline bool symbol_exists(const std::string& symbol) const
23220 {
23221 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23222 {
23223 if (!symtab_list_[i].valid())
23224 {
23225 continue;
23226 }
23227
23228 if (symtab_list_[i].symbol_exists(symbol))
23229 {
23230 return true;
23231 }
23232 }
23233
23234 return false;
23235 }
23236
23237 inline bool is_variable(const std::string& variable_name) const
23238 {
23239 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23240 {
23241 if (!symtab_list_[i].valid())
23242 continue;
23243 else if (
23244 symtab_list_[i].local_data().variable_store
23245 .symbol_exists(variable_name)
23246 )
23247 return true;
23248 }
23249
23250 return false;
23251 }
23252
23253 #ifndef exprtk_disable_string_capabilities
23254 inline bool is_stringvar(const std::string& stringvar_name) const
23255 {
23256 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23257 {
23258 if (!symtab_list_[i].valid())
23259 continue;
23260 else if (
23261 symtab_list_[i].local_data().stringvar_store
23262 .symbol_exists(stringvar_name)
23263 )
23264 return true;
23265 }
23266
23267 return false;
23268 }
23269
23270 inline bool is_conststr_stringvar(const std::string& symbol_name) const
23271 {
23272 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23273 {
23274 if (!symtab_list_[i].valid())
23275 continue;
23276 else if (
23277 symtab_list_[i].local_data().stringvar_store
23278 .symbol_exists(symbol_name)
23279 )
23280 {
23281 return (
23282 local_data(i).stringvar_store.symbol_exists(symbol_name) ||
23283 local_data(i).stringvar_store.is_constant (symbol_name)
23284 );
23285
23286 }
23287 }
23288
23289 return false;
23290 }
23291 #endif
23292
23293 inline bool is_function(const std::string& function_name) const
23294 {
23295 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23296 {
23297 if (!symtab_list_[i].valid())
23298 continue;
23299 else if (
23300 local_data(i).vararg_function_store
23301 .symbol_exists(function_name)
23302 )
23303 return true;
23304 }
23305
23306 return false;
23307 }
23308
23309 inline bool is_vararg_function(const std::string& vararg_function_name) const
23310 {
23311 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23312 {
23313 if (!symtab_list_[i].valid())
23314 continue;
23315 else if (
23316 local_data(i).vararg_function_store
23317 .symbol_exists(vararg_function_name)
23318 )
23319 return true;
23320 }
23321
23322 return false;
23323 }
23324
23325 inline bool is_vector(const std::string& vector_name) const
23326 {
23327 for (std::size_t i = 0; i < symtab_list_.size(); ++i)
23328 {
23329 if (!symtab_list_[i].valid())
23330 continue;
23331 else if (
23332 local_data(i).vector_store
23333 .symbol_exists(vector_name)
23334 )
23335 return true;
23336 }
23337
23338 return false;
23339 }
23340
23341 inline std::string get_variable_name(const expression_node_ptr& ptr) const
23342 {
23343 return local_data().variable_store.entity_name(ptr);
23344 }
23345
23346 inline std::string get_vector_name(const vector_holder_ptr& ptr) const
23347 {
23348 return local_data().vector_store.entity_name(ptr);
23349 }
23350
23351 #ifndef exprtk_disable_string_capabilities
23352 inline std::string get_stringvar_name(const expression_node_ptr& ptr) const
23353 {
23354 return local_data().stringvar_store.entity_name(ptr);
23355 }
23356
23357 inline std::string get_conststr_stringvar_name(const expression_node_ptr& ptr) const
23358 {
23359 return local_data().stringvar_store.entity_name(ptr);
23360 }
23361 #endif
23362
23363 inline local_data_t& local_data(const std::size_t& index = 0)
23364 {
23365 return symtab_list_[index].local_data();
23366 }
23367
23368 inline const local_data_t& local_data(const std::size_t& index = 0) const
23369 {
23370 return symtab_list_[index].local_data();
23371 }
23372
23373 inline symbol_table_t& get_symbol_table(const std::size_t& index = 0)
23374 {
23375 return symtab_list_[index];
23376 }
23377 };
23378
23380 {
23382 : type_check_enabled(true)
23383 {
23384 reset();
23385 }
23386
23387 void reset()
23388 {
23389 parsing_return_stmt = false;
23390 parsing_break_stmt = false;
23391 parsing_assert_stmt = false;
23392 return_stmt_present = false;
23393 side_effect_present = false;
23394 scope_depth = 0;
23395 stack_depth = 0;
23397 }
23398
23399 #ifndef exprtk_enable_debugging
23400 void activate_side_effect(const std::string&)
23401 #else
23402 void activate_side_effect(const std::string& source)
23403 #endif
23404 {
23406 {
23407 side_effect_present = true;
23408
23409 exprtk_debug(("activate_side_effect() - caller: %s\n", source.c_str()));
23410 }
23411 }
23412
23419 std::size_t scope_depth;
23420 std::size_t stack_depth;
23422 };
23423
23424 public:
23425
23427 {
23428
23435
23441
23443
23447
23449 {}
23450
23451 virtual bool process(const std::string& /*unknown_symbol*/,
23452 usr_symbol_type& st,
23453 T& default_value,
23454 std::string& error_message)
23455 {
23456 if (e_usrmode_default != mode)
23457 return false;
23458
23460 default_value = T(0);
23461 error_message.clear();
23462
23463 return true;
23464 }
23465
23466 virtual bool process(const std::string& /* unknown_symbol */,
23467 symbol_table_t& /* symbol_table */,
23468 std::string& /* error_message */)
23469 {
23470 return false;
23471 }
23472 };
23473
23481
23494
23496 {
23497 public:
23498
23499 typedef std::pair<std::string,symbol_type> symbol_t;
23500 typedef std::vector<symbol_t> symbol_list_t;
23501
23510
23511 template <typename Allocator,
23512 template <typename, typename> class Sequence>
23513 inline std::size_t symbols(Sequence<symbol_t,Allocator>& symbols_list)
23514 {
23516 return 0;
23517 else if (symbol_name_list_.empty())
23518 return 0;
23519
23520 for (std::size_t i = 0; i < symbol_name_list_.size(); ++i)
23521 {
23523 }
23524
23525 std::sort(symbol_name_list_.begin(), symbol_name_list_.end());
23526
23527 std::unique_copy
23528 (
23529 symbol_name_list_.begin(),
23530 symbol_name_list_.end (),
23531 std::back_inserter(symbols_list)
23532 );
23533
23534 return symbols_list.size();
23535 }
23536
23537 template <typename Allocator,
23538 template <typename, typename> class Sequence>
23539 inline std::size_t assignment_symbols(Sequence<symbol_t,Allocator>& assignment_list)
23540 {
23542 return 0;
23543 else if (assignment_name_list_.empty())
23544 return 0;
23545
23546 for (std::size_t i = 0; i < assignment_name_list_.size(); ++i)
23547 {
23549 }
23550
23551 std::sort(assignment_name_list_.begin(),assignment_name_list_.end());
23552
23553 std::unique_copy
23554 (
23555 assignment_name_list_.begin(),
23556 assignment_name_list_.end (),
23557 std::back_inserter(assignment_list)
23558 );
23559
23560 return assignment_list.size();
23561 }
23562
23563 void clear()
23564 {
23565 symbol_name_list_ .clear();
23566 assignment_name_list_.clear();
23567 retparam_list_ .clear();
23568 return_present_ = false;
23569 final_stmt_return_ = false;
23570 }
23571
23573 {
23574 return collect_variables_;
23575 }
23576
23578 {
23579 return collect_functions_;
23580 }
23581
23583 {
23584 return collect_assignments_;
23585 }
23586
23587 bool return_present() const
23588 {
23589 return return_present_;
23590 }
23591
23593 {
23594 return final_stmt_return_;
23595 }
23596
23597 typedef std::vector<std::string> retparam_list_t;
23598
23600 {
23601 return retparam_list_;
23602 }
23603
23604 private:
23605
23606 inline void add_symbol(const std::string& symbol, const symbol_type st)
23607 {
23608 switch (st)
23609 {
23610 case e_st_variable :
23611 case e_st_vector :
23612 case e_st_string :
23613 case e_st_local_variable :
23614 case e_st_local_vector :
23617 .push_back(std::make_pair(symbol, st));
23618 break;
23619
23622 .push_back(std::make_pair(symbol, st));
23623 break;
23624
23625 default : return;
23626 }
23627 }
23628
23629 inline void add_assignment(const std::string& symbol, const symbol_type st)
23630 {
23631 switch (st)
23632 {
23633 case e_st_variable :
23634 case e_st_vector :
23637 .push_back(std::make_pair(symbol, st));
23638 break;
23639
23640 default : return;
23641 }
23642 }
23643
23644 std::size_t options_;
23653
23654 friend class parser<T>;
23655 };
23656
23658 {
23659 private:
23660
23661 typedef std::set<std::string,details::ilesscompare> disabled_entity_set_t;
23662 typedef disabled_entity_set_t::iterator des_itr_t;
23663
23664 public:
23665
23683
23703
23714
23722
23729
23736
23744
23745 static const std::size_t default_compile_all_opts =
23746 e_replacer +
23747 e_joiner +
23753
23754 settings_store(const std::size_t compile_options = default_compile_all_opts)
23755 : max_stack_depth_(400)
23756 , max_node_depth_(10000)
23757 , max_local_vector_size_(2000000000)
23758 {
23759 load_compile_options(compile_options);
23760 }
23761
23763 {
23764 disabled_func_set_.clear();
23765 return (*this);
23766 }
23767
23769 {
23770 disabled_ctrl_set_.clear();
23771 return (*this);
23772 }
23773
23775 {
23776 disabled_logic_set_.clear();
23777 return (*this);
23778 }
23779
23781 {
23783 return (*this);
23784 }
23785
23787 {
23789 return (*this);
23790 }
23791
23793 {
23795 return (*this);
23796 }
23797
23799 {
23800 disable_vardef_ = false;
23801 return (*this);
23802 }
23803
23805 {
23807 return (*this);
23808 }
23809
23811 {
23813 return (*this);
23814 }
23815
23817 {
23820 std::insert_iterator<disabled_entity_set_t>
23822 return (*this);
23823 }
23824
23826 {
23829 std::insert_iterator<disabled_entity_set_t>
23831 return (*this);
23832 }
23833
23835 {
23836 std::copy(details::logic_ops_list,
23838 std::insert_iterator<disabled_entity_set_t>
23840 return (*this);
23841 }
23842
23844 {
23847 std::insert_iterator<disabled_entity_set_t>
23849 return (*this);
23850 }
23851
23853 {
23856 std::insert_iterator<disabled_entity_set_t>
23858 return (*this);
23859 }
23860
23862 {
23865 std::insert_iterator<disabled_entity_set_t>
23867 return (*this);
23868 }
23869
23871 {
23872 disable_vardef_ = true;
23873 return (*this);
23874 }
23875
23877 {
23879 return (*this);
23880 }
23881
23883 {
23885 return (*this);
23886 }
23887
23888 bool replacer_enabled () const { return enable_replacer_; }
23890 bool joiner_enabled () const { return enable_joiner_; }
23898 bool vardef_disabled () const { return disable_vardef_; }
23901
23902 bool function_enabled(const std::string& function_name) const
23903 {
23904 if (disabled_func_set_.empty())
23905 return true;
23906 else
23907 return (disabled_func_set_.end() == disabled_func_set_.find(function_name));
23908 }
23909
23910 bool control_struct_enabled(const std::string& control_struct) const
23911 {
23912 if (disabled_ctrl_set_.empty())
23913 return true;
23914 else
23915 return (disabled_ctrl_set_.end() == disabled_ctrl_set_.find(control_struct));
23916 }
23917
23918 bool logic_enabled(const std::string& logic_operation) const
23919 {
23920 if (disabled_logic_set_.empty())
23921 return true;
23922 else
23923 return (disabled_logic_set_.end() == disabled_logic_set_.find(logic_operation));
23924 }
23925
23926 bool arithmetic_enabled(const details::operator_type& arithmetic_operation) const
23927 {
23928 if (disabled_logic_set_.empty())
23929 return true;
23930 else
23932 .find(arith_opr_to_string(arithmetic_operation));
23933 }
23934
23935 bool assignment_enabled(const details::operator_type& assignment) const
23936 {
23937 if (disabled_assignment_set_.empty())
23938 return true;
23939 else
23941 .find(assign_opr_to_string(assignment));
23942 }
23943
23944 bool inequality_enabled(const details::operator_type& inequality) const
23945 {
23946 if (disabled_inequality_set_.empty())
23947 return true;
23948 else
23950 .find(inequality_opr_to_string(inequality));
23951 }
23952
23953 bool function_disabled(const std::string& function_name) const
23954 {
23955 if (disabled_func_set_.empty())
23956 return false;
23957 else
23958 return (disabled_func_set_.end() != disabled_func_set_.find(function_name));
23959 }
23960
23961 bool control_struct_disabled(const std::string& control_struct) const
23962 {
23963 if (disabled_ctrl_set_.empty())
23964 return false;
23965 else
23966 return (disabled_ctrl_set_.end() != disabled_ctrl_set_.find(control_struct));
23967 }
23968
23969 bool logic_disabled(const std::string& logic_operation) const
23970 {
23971 if (disabled_logic_set_.empty())
23972 return false;
23973 else
23974 return (disabled_logic_set_.end() != disabled_logic_set_.find(logic_operation));
23975 }
23976
23977 bool assignment_disabled(const details::operator_type assignment_operation) const
23978 {
23979 if (disabled_assignment_set_.empty())
23980 return false;
23981 else
23983 .find(assign_opr_to_string(assignment_operation));
23984 }
23985
23986 bool logic_disabled(const details::operator_type logic_operation) const
23987 {
23988 if (disabled_logic_set_.empty())
23989 return false;
23990 else
23992 .find(logic_opr_to_string(logic_operation));
23993 }
23994
23995 bool arithmetic_disabled(const details::operator_type arithmetic_operation) const
23996 {
23997 if (disabled_arithmetic_set_.empty())
23998 return false;
23999 else
24001 .find(arith_opr_to_string(arithmetic_operation));
24002 }
24003
24004 bool inequality_disabled(const details::operator_type& inequality) const
24005 {
24006 if (disabled_inequality_set_.empty())
24007 return false;
24008 else
24010 .find(inequality_opr_to_string(inequality));
24011 }
24012
24014 {
24015 if (
24016 (e_bf_unknown != bf) &&
24017 (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1))
24018 )
24019 {
24021 }
24022
24023 return (*this);
24024 }
24025
24027 {
24028 if (
24029 (e_ctrl_unknown != ctrl_struct) &&
24030 (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1))
24031 )
24032 {
24033 disabled_ctrl_set_.insert(details::cntrl_struct_list[ctrl_struct - 1]);
24034 }
24035
24036 return (*this);
24037 }
24038
24040 {
24041 if (
24042 (e_logic_unknown != logic) &&
24043 (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1))
24044 )
24045 {
24047 }
24048
24049 return (*this);
24050 }
24051
24053 {
24054 if (
24055 (e_arith_unknown != arithmetic) &&
24056 (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1))
24057 )
24058 {
24060 }
24061
24062 return (*this);
24063 }
24064
24066 {
24067 if (
24068 (e_assign_unknown != assignment) &&
24069 (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1))
24070 )
24071 {
24073 }
24074
24075 return (*this);
24076 }
24077
24079 {
24080 if (
24081 (e_ineq_unknown != inequality) &&
24082 (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1))
24083 )
24084 {
24086 }
24087
24088 return (*this);
24089 }
24090
24092 {
24093 if (
24094 (e_bf_unknown != bf) &&
24095 (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1))
24096 )
24097 {
24099
24100 if (disabled_func_set_.end() != itr)
24101 {
24102 disabled_func_set_.erase(itr);
24103 }
24104 }
24105
24106 return (*this);
24107 }
24108
24110 {
24111 if (
24112 (e_ctrl_unknown != ctrl_struct) &&
24113 (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1))
24114 )
24115 {
24116 const des_itr_t itr = disabled_ctrl_set_.find(details::cntrl_struct_list[ctrl_struct - 1]);
24117
24118 if (disabled_ctrl_set_.end() != itr)
24119 {
24120 disabled_ctrl_set_.erase(itr);
24121 }
24122 }
24123
24124 return (*this);
24125 }
24126
24128 {
24129 if (
24130 (e_logic_unknown != logic) &&
24131 (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1))
24132 )
24133 {
24135
24136 if (disabled_logic_set_.end() != itr)
24137 {
24138 disabled_logic_set_.erase(itr);
24139 }
24140 }
24141
24142 return (*this);
24143 }
24144
24146 {
24147 if (
24148 (e_arith_unknown != arithmetic) &&
24149 (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1))
24150 )
24151 {
24152 const des_itr_t itr = disabled_arithmetic_set_.find(details::arithmetic_ops_list[arithmetic - 1]);
24153
24154 if (disabled_arithmetic_set_.end() != itr)
24155 {
24156 disabled_arithmetic_set_.erase(itr);
24157 }
24158 }
24159
24160 return (*this);
24161 }
24162
24164 {
24165 if (
24166 (e_assign_unknown != assignment) &&
24167 (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1))
24168 )
24169 {
24170 const des_itr_t itr = disabled_assignment_set_.find(details::assignment_ops_list[assignment - 1]);
24171
24172 if (disabled_assignment_set_.end() != itr)
24173 {
24174 disabled_assignment_set_.erase(itr);
24175 }
24176 }
24177
24178 return (*this);
24179 }
24180
24182 {
24183 if (
24184 (e_ineq_unknown != inequality) &&
24185 (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1))
24186 )
24187 {
24188 const des_itr_t itr = disabled_inequality_set_.find(details::inequality_ops_list[inequality - 1]);
24189
24190 if (disabled_inequality_set_.end() != itr)
24191 {
24192 disabled_inequality_set_.erase(itr);
24193 }
24194 }
24195
24196 return (*this);
24197 }
24198
24199 void set_max_stack_depth(const std::size_t max_stack_depth)
24200 {
24202 }
24203
24204 void set_max_node_depth(const std::size_t max_node_depth)
24205 {
24207 }
24208
24213
24214 std::size_t max_stack_depth() const
24215 {
24216 return max_stack_depth_;
24217 }
24218
24219 std::size_t max_node_depth() const
24220 {
24221 return max_node_depth_;
24222 }
24223
24224 std::size_t max_local_vector_size() const
24225 {
24227 }
24228
24229 private:
24230
24231 void load_compile_options(const std::size_t compile_options)
24232 {
24233 enable_replacer_ = (compile_options & e_replacer ) == e_replacer;
24234 enable_joiner_ = (compile_options & e_joiner ) == e_joiner;
24235 enable_numeric_check_ = (compile_options & e_numeric_check ) == e_numeric_check;
24236 enable_bracket_check_ = (compile_options & e_bracket_check ) == e_bracket_check;
24240 enable_collect_vars_ = (compile_options & e_collect_vars ) == e_collect_vars;
24241 enable_collect_funcs_ = (compile_options & e_collect_funcs ) == e_collect_funcs;
24243 disable_vardef_ = (compile_options & e_disable_vardef ) == e_disable_vardef;
24246 }
24247
24249 {
24250 switch (opr)
24251 {
24252 case details::e_assign : return ":=";
24253 case details::e_addass : return "+=";
24254 case details::e_subass : return "-=";
24255 case details::e_mulass : return "*=";
24256 case details::e_divass : return "/=";
24257 case details::e_modass : return "%=";
24258 default : return "" ;
24259 }
24260 }
24261
24263 {
24264 switch (opr)
24265 {
24266 case details::e_add : return "+";
24267 case details::e_sub : return "-";
24268 case details::e_mul : return "*";
24269 case details::e_div : return "/";
24270 case details::e_mod : return "%";
24271 case details::e_pow : return "^";
24272 default : return "" ;
24273 }
24274 }
24275
24277 {
24278 switch (opr)
24279 {
24280 case details::e_lt : return "<" ;
24281 case details::e_lte : return "<=";
24282 case details::e_eq : return "==";
24283 case details::e_equal : return "=" ;
24284 case details::e_ne : return "!=";
24285 case details::e_nequal: return "<>";
24286 case details::e_gte : return ">=";
24287 case details::e_gt : return ">" ;
24288 default : return "" ;
24289 }
24290 }
24291
24293 {
24294 switch (opr)
24295 {
24296 case details::e_and : return "and" ;
24297 case details::e_or : return "or" ;
24298 case details::e_xor : return "xor" ;
24299 case details::e_nand : return "nand";
24300 case details::e_nor : return "nor" ;
24301 case details::e_xnor : return "xnor";
24302 case details::e_notl : return "not" ;
24303 default : return "" ;
24304 }
24305 }
24306
24320
24327
24328 std::size_t max_stack_depth_;
24329 std::size_t max_node_depth_;
24331
24332 friend class parser<T>;
24333 };
24334
24336
24340 , results_context_(0)
24341 , unknown_symbol_resolver_(reinterpret_cast<unknown_symbol_resolver*>(0))
24342 #ifdef _MSC_VER
24343 #pragma warning(push)
24344 #pragma warning (disable:4355)
24345 #endif
24346 , sem_(*this)
24347 #ifdef _MSC_VER
24348 #pragma warning(pop)
24349 #endif
24355 , assert_check_(0)
24356 {
24358
24359 load_operations_map (base_ops_map_ );
24365
24374 }
24375
24377 {}
24378
24380 {
24383
24386
24389
24391 {
24397 }
24398
24400 {
24401 for (std::size_t i = 0; i < details::reserved_words_size; ++i)
24402 {
24404 }
24405
24408 }
24409
24411 {
24415 }
24416
24417 if (
24421 )
24422 {
24424
24426 {
24428 }
24429
24431 {
24433 }
24434
24436 {
24439 }
24440 }
24441 }
24442
24443 inline bool compile(const std::string& expression_string, expression<T>& expr)
24444 {
24445 state_ .reset();
24446 error_list_ .clear();
24447 brkcnt_list_ .clear();
24448 synthesis_error_ .clear();
24450 immutable_symtok_map_.clear();
24451 current_state_stack_ .clear();
24452 assert_ids_ .clear();
24453 sem_ .cleanup();
24454
24456
24458
24459 if (expression_string.empty())
24460 {
24461 set_error(make_error(
24463 "ERR001 - Empty expression!",
24465
24466 return false;
24467 }
24468
24469 if (!init(expression_string))
24470 {
24472 return false;
24473 }
24474
24475 if (lexer().empty())
24476 {
24477 set_error(make_error(
24479 "ERR002 - Empty expression!",
24481
24482 return false;
24483 }
24484
24486 {
24487 exprtk_debug(("halt_compilation_check() - compile checkpoint 0\n"));
24488 return false;
24489 }
24490
24491 if (!run_assemblies())
24492 {
24493 return false;
24494 }
24495
24497 {
24498 exprtk_debug(("halt_compilation_check() - compile checkpoint 1\n"));
24499 return false;
24500 }
24501
24503 dec_.clear();
24504
24505 lexer().begin();
24506
24507 next_token();
24508
24510
24511 if ((0 != e) && (token_t::e_eof == current_token().type))
24512 {
24513 bool* retinvk_ptr = 0;
24514
24516 {
24517 dec_.return_present_ = true;
24518
24520 .return_envelope(e, results_context_, retinvk_ptr);
24521 }
24522
24523 expr.set_expression(e);
24524 expr.set_retinvk(retinvk_ptr);
24525
24526 register_local_vars(expr);
24528
24529 return !(!expr);
24530 }
24531 else
24532 {
24533 if (error_list_.empty())
24534 {
24535 set_error(make_error(
24537 current_token(),
24538 "ERR003 - Invalid expression encountered",
24540 }
24541
24542 if ((0 != e) && branch_deletable(e))
24543 {
24544 destroy_node(e);
24545 }
24546
24547 dec_.clear ();
24548 sem_.cleanup ();
24550
24551 return false;
24552 }
24553 }
24554
24555 inline expression_t compile(const std::string& expression_string, symbol_table_t& symtab)
24556 {
24559 compile(expression_string,expression);
24560 return expression;
24561 }
24562
24564 {
24565 for (std::size_t i = 0; i < lexer().size(); ++i)
24566 {
24567 if (lexer()[i].is_error())
24568 {
24569 std::string diagnostic = "ERR004 - ";
24570
24571 switch (lexer()[i].type)
24572 {
24573 case lexer::token::e_error : diagnostic += "General token error";
24574 break;
24575
24576 case lexer::token::e_err_symbol : diagnostic += "Symbol error";
24577 break;
24578
24579 case lexer::token::e_err_number : diagnostic += "Invalid numeric token";
24580 break;
24581
24582 case lexer::token::e_err_string : diagnostic += "Invalid string token";
24583 break;
24584
24585 case lexer::token::e_err_sfunc : diagnostic += "Invalid special function token";
24586 break;
24587
24588 default : diagnostic += "Unknown compiler error";
24589 }
24590
24591 set_error(make_error(
24593 lexer()[i],
24594 diagnostic + ": " + lexer()[i].value,
24596 }
24597 }
24598 }
24599
24600 inline bool run_assemblies()
24601 {
24603 {
24605 }
24606
24608 {
24610 }
24611
24613 {
24615 }
24616
24617 if (
24621 )
24622 {
24624 {
24626 {
24627 lexer::helper::bracket_checker* bracket_checker_ptr = 0;
24628 lexer::helper::numeric_checker<T>* numeric_checker_ptr = 0;
24629 lexer::helper::sequence_validator* sequence_validator_ptr = 0;
24630 lexer::helper::sequence_validator_3tokens* sequence_validator3_ptr = 0;
24631
24632 if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner)))
24633 {
24634 set_error(make_error(
24636 bracket_checker_ptr->error_token(),
24637 "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'",
24639 }
24640 else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker<T>*>(helper_assembly_.error_token_scanner)))
24641 {
24642 for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i)
24643 {
24644 lexer::token error_token = lexer()[numeric_checker_ptr->error_index(i)];
24645
24646 set_error(make_error(
24648 error_token,
24649 "ERR006 - Invalid numeric token: '" + error_token.value + "'",
24651 }
24652
24653 if (numeric_checker_ptr->error_count())
24654 {
24655 numeric_checker_ptr->clear_errors();
24656 }
24657 }
24658 else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner)))
24659 {
24660 for (std::size_t i = 0; i < sequence_validator_ptr->error_count(); ++i)
24661 {
24662 std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i);
24663
24664 set_error(make_error(
24666 error_token.first,
24667 "ERR007 - Invalid token sequence: '" +
24668 error_token.first.value + "' and '" +
24669 error_token.second.value + "'",
24671 }
24672
24673 if (sequence_validator_ptr->error_count())
24674 {
24675 sequence_validator_ptr->clear_errors();
24676 }
24677 }
24678 else if (0 != (sequence_validator3_ptr = dynamic_cast<lexer::helper::sequence_validator_3tokens*>(helper_assembly_.error_token_scanner)))
24679 {
24680 for (std::size_t i = 0; i < sequence_validator3_ptr->error_count(); ++i)
24681 {
24682 std::pair<lexer::token,lexer::token> error_token = sequence_validator3_ptr->error(i);
24683
24684 set_error(make_error(
24686 error_token.first,
24687 "ERR008 - Invalid token sequence: '" +
24688 error_token.first.value + "' and '" +
24689 error_token.second.value + "'",
24691 }
24692
24693 if (sequence_validator3_ptr->error_count())
24694 {
24695 sequence_validator3_ptr->clear_errors();
24696 }
24697 }
24698 }
24699
24700 return false;
24701 }
24702 }
24703
24704 return true;
24705 }
24706
24708 {
24709 return settings_;
24710 }
24711
24712 inline parser_error::type get_error(const std::size_t& index) const
24713 {
24714 if (index < error_list_.size())
24715 {
24716 return error_list_[index];
24717 }
24718
24719 throw std::invalid_argument("parser::get_error() - Invalid error index specified");
24720 }
24721
24722 inline std::string error() const
24723 {
24724 if (!error_list_.empty())
24725 {
24726 return error_list_[0].diagnostic;
24727 }
24728 else
24729 return std::string("No Error");
24730 }
24731
24732 inline std::size_t error_count() const
24733 {
24734 return error_list_.size();
24735 }
24736
24738 {
24739 return dec_;
24740 }
24741
24742 inline bool replace_symbol(const std::string& old_symbol, const std::string& new_symbol)
24743 {
24745 return false;
24746 else if (details::is_reserved_word(old_symbol))
24747 return false;
24748 else
24749 return symbol_replacer_.add_replace(old_symbol,new_symbol,lexer::token::e_symbol);
24750 }
24751
24752 inline bool remove_replace_symbol(const std::string& symbol)
24753 {
24755 return false;
24756 else if (details::is_reserved_word(symbol))
24757 return false;
24758 else
24759 return symbol_replacer_.remove(symbol);
24760 }
24761
24763 {
24765
24766 if (usr)
24768 else
24770 }
24771
24776
24782
24784 {
24785 loop_runtime_check_ = &lrtchk;
24786 }
24787
24792
24794 {
24795 compilation_check_ptr_ = &compchk;
24796 }
24797
24798 inline void register_assert_check(assert_check& assrt_chck)
24799 {
24800 assert_check_ = &assrt_chck;
24801 }
24802
24804 {
24806 }
24807
24812
24817
24819 {
24821 }
24822
24823 private:
24824
24825 inline bool valid_base_operation(const std::string& symbol) const
24826 {
24827 const std::size_t length = symbol.size();
24828
24829 if (
24830 (length < 3) || // Shortest base op symbol length
24831 (length > 9) // Longest base op symbol length
24832 )
24833 return false;
24834 else
24835 return settings_.function_enabled(symbol) &&
24836 (base_ops_map_.end() != base_ops_map_.find(symbol));
24837 }
24838
24839 inline bool valid_vararg_operation(const std::string& symbol) const
24840 {
24841 static const std::string s_sum = "sum" ;
24842 static const std::string s_mul = "mul" ;
24843 static const std::string s_avg = "avg" ;
24844 static const std::string s_min = "min" ;
24845 static const std::string s_max = "max" ;
24846 static const std::string s_mand = "mand";
24847 static const std::string s_mor = "mor" ;
24848 static const std::string s_multi = "~" ;
24849 static const std::string s_mswitch = "[*]" ;
24850
24851 return
24852 (
24853 details::imatch(symbol,s_sum ) ||
24854 details::imatch(symbol,s_mul ) ||
24855 details::imatch(symbol,s_avg ) ||
24856 details::imatch(symbol,s_min ) ||
24857 details::imatch(symbol,s_max ) ||
24858 details::imatch(symbol,s_mand ) ||
24859 details::imatch(symbol,s_mor ) ||
24860 details::imatch(symbol,s_multi ) ||
24861 details::imatch(symbol,s_mswitch)
24862 ) &&
24864 }
24865
24867 {
24868 return settings_.logic_disabled(operation);
24869 }
24870
24872 {
24873 return settings_.arithmetic_disabled(operation);
24874 }
24875
24877 {
24878 return settings_.assignment_disabled(operation);
24879 }
24880
24882 {
24883 return settings_.inequality_disabled(operation);
24884 }
24885
24886 #ifdef exprtk_enable_debugging
24887 inline void next_token()
24888 {
24889 const std::string ct_str = current_token().value;
24890 const std::size_t ct_pos = current_token().position;
24891 parser_helper::next_token();
24892 const std::string depth(2 * state_.scope_depth,' ');
24893 exprtk_debug(("%s"
24894 "prev[%s | %04d] --> curr[%s | %04d] stack_level: %3d\n",
24895 depth.c_str(),
24896 ct_str.c_str(),
24897 static_cast<unsigned int>(ct_pos),
24898 current_token().value.c_str(),
24899 static_cast<unsigned int>(current_token().position),
24900 static_cast<unsigned int>(state_.stack_depth)));
24901 }
24902 #endif
24903
24905 {
24906 std::vector<expression_node_ptr> arg_list;
24907 std::vector<bool> side_effect_list;
24908
24909 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
24910
24911 lexer::token begin_token;
24912 lexer::token end_token;
24913
24914 for ( ; ; )
24915 {
24917
24918 begin_token = current_token();
24919
24921
24922 if (0 == arg)
24923 {
24924 if (error_list_.empty())
24925 {
24926 set_error(make_error(
24928 current_token(),
24929 "ERR009 - Invalid expression encountered",
24931 }
24932
24933 return error_node();
24934 }
24935 else
24936 {
24937 arg_list.push_back(arg);
24938
24939 side_effect_list.push_back(state_.side_effect_present);
24940
24941 end_token = current_token();
24942
24943 const std::string sub_expr = construct_subexpr(begin_token, end_token);
24944
24945 exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n",
24946 static_cast<int>(arg_list.size() - 1),
24947 sub_expr.c_str()));
24948
24949 exprtk_debug(("parse_corpus(%02d) - Side effect present: %s\n",
24950 static_cast<int>(arg_list.size() - 1),
24951 state_.side_effect_present ? "true" : "false"));
24952
24953 exprtk_debug(("-------------------------------------------------\n"));
24954 }
24955
24956 if (token_is(token_t::e_eof,prsrhlpr_t::e_hold))
24957 {
24958 if (lexer().finished())
24959 break;
24960 else
24961 next_token();
24962 }
24963 }
24964
24965 if (
24966 !arg_list.empty() &&
24967 is_return_node(arg_list.back())
24968 )
24969 {
24970 dec_.final_stmt_return_ = true;
24971 }
24972
24973 const expression_node_ptr result = simplify(arg_list,side_effect_list);
24974
24975 sdd.delete_ptr = (0 == result);
24976
24977 return result;
24978 }
24979
24980 std::string construct_subexpr(lexer::token& begin_token,
24981 lexer::token& end_token,
24982 const bool cleanup_whitespace = true)
24983 {
24984 std::string result = lexer().substr(begin_token.position,end_token.position);
24985 if (cleanup_whitespace)
24986 {
24987 for (std::size_t i = 0; i < result.size(); ++i)
24988 {
24989 if (details::is_whitespace(result[i])) result[i] = ' ';
24990 }
24991 }
24992
24993 return result;
24994 }
24995
24997
24998 struct state_t
24999 {
25000 inline void set(const precedence_level& l,
25001 const precedence_level& r,
25002 const details::operator_type& o,
25003 const token_t tkn = token_t())
25004 {
25005 left = l;
25006 right = r;
25007 operation = o;
25008 token = tkn;
25009 }
25010
25011 inline void reset()
25012 {
25013 left = e_level00;
25014 right = e_level00;
25016 }
25017
25022 };
25023
25025 {
25027 }
25028
25029 inline void pop_current_state()
25030 {
25031 if (!current_state_stack_.empty())
25032 {
25033 current_state_stack_.pop_back();
25034 }
25035 }
25036
25037 inline state_t current_state() const
25038 {
25039 return (!current_state_stack_.empty()) ?
25040 current_state_stack_.back() :
25041 state_t();
25042 }
25043
25045 {
25047
25049 {
25050 const std::string error_message =
25051 !context.error_message.empty() ? " Details: " + context.error_message : "";
25052
25053 set_error(make_error(
25055 token_t(),
25056 "ERR010 - Internal compilation check failed." + error_message,
25058
25059 return true;
25060 }
25061
25062 return false;
25063 }
25064
25066 {
25068 {
25069 exprtk_debug(("halt_compilation_check() - parse_expression checkpoint 2\n"));
25070 return error_node();
25071 }
25072
25073 stack_limit_handler slh(*this);
25074
25075 if (!slh)
25076 {
25077 return error_node();
25078 }
25079
25081
25082 if (0 == expression)
25083 {
25084 return error_node();
25085 }
25086
25087 bool break_loop = false;
25088
25090
25091 for ( ; ; )
25092 {
25094
25095 switch (current_token().type)
25096 {
25116 default :
25117 if (token_t::e_symbol == current_token().type)
25118 {
25119 static const std::string s_and = "and" ;
25120 static const std::string s_nand = "nand" ;
25121 static const std::string s_or = "or" ;
25122 static const std::string s_nor = "nor" ;
25123 static const std::string s_xor = "xor" ;
25124 static const std::string s_xnor = "xnor" ;
25125 static const std::string s_in = "in" ;
25126 static const std::string s_like = "like" ;
25127 static const std::string s_ilike = "ilike";
25128 static const std::string s_and1 = "&" ;
25129 static const std::string s_or1 = "|" ;
25130 static const std::string s_not = "not" ;
25131
25132 if (details::imatch(current_token().value,s_and))
25133 {
25135 break;
25136 }
25137 else if (details::imatch(current_token().value,s_and1))
25138 {
25139 #ifndef exprtk_disable_sc_andor
25141 #else
25143 #endif
25144 break;
25145 }
25146 else if (details::imatch(current_token().value,s_nand))
25147 {
25149 break;
25150 }
25151 else if (details::imatch(current_token().value,s_or))
25152 {
25154 break;
25155 }
25156 else if (details::imatch(current_token().value,s_or1))
25157 {
25158 #ifndef exprtk_disable_sc_andor
25160 #else
25162 #endif
25163 break;
25164 }
25165 else if (details::imatch(current_token().value,s_nor))
25166 {
25168 break;
25169 }
25170 else if (details::imatch(current_token().value,s_xor))
25171 {
25173 break;
25174 }
25175 else if (details::imatch(current_token().value,s_xnor))
25176 {
25178 break;
25179 }
25180 else if (details::imatch(current_token().value,s_in))
25181 {
25183 break;
25184 }
25185 else if (details::imatch(current_token().value,s_like))
25186 {
25188 break;
25189 }
25190 else if (details::imatch(current_token().value,s_ilike))
25191 {
25193 break;
25194 }
25195 else if (details::imatch(current_token().value,s_not))
25196 {
25197 break;
25198 }
25199 }
25200
25201 break_loop = true;
25202 }
25203
25204 if (break_loop)
25205 {
25207 break;
25208 }
25209 else if (current_state.left < precedence)
25210 break;
25211
25212 const lexer::token prev_token = current_token();
25213
25214 next_token();
25215
25216 expression_node_ptr right_branch = error_node();
25217 expression_node_ptr new_expression = error_node();
25218
25220 {
25221 free_node(node_allocator_, expression);
25222
25223 set_error(make_error(
25225 prev_token,
25226 "ERR011 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'",
25228
25229 return error_node();
25230 }
25232 {
25233 free_node(node_allocator_, expression);
25234
25235 set_error(make_error(
25237 prev_token,
25238 "ERR012 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'",
25240
25241 return error_node();
25242 }
25244 {
25245 free_node(node_allocator_, expression);
25246
25247 set_error(make_error(
25249 prev_token,
25250 "ERR013 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
25252
25253 return error_node();
25254 }
25256 {
25257 free_node(node_allocator_, expression);
25258
25259 set_error(make_error(
25261 prev_token,
25262 "ERR014 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'",
25264
25265 return error_node();
25266 }
25267
25268 if (0 != (right_branch = parse_expression(current_state.right)))
25269 {
25270 if (
25272 details::is_return_node(right_branch)
25273 )
25274 {
25275 free_node(node_allocator_, expression );
25276 free_node(node_allocator_, right_branch);
25277
25278 set_error(make_error(
25280 prev_token,
25281 "ERR015 - Return statements cannot be part of sub-expressions",
25283
25284 return error_node();
25285 }
25286
25288
25289 new_expression = expression_generator_
25290 (
25292 expression,
25293 right_branch
25294 );
25295
25297 }
25298
25299 if (0 == new_expression)
25300 {
25301 if (error_list_.empty())
25302 {
25303 set_error(make_error(
25305 prev_token,
25306 !synthesis_error_.empty() ?
25308 "ERR016 - General parsing error at token: '" + prev_token.value + "'",
25310 }
25311
25312 free_node(node_allocator_, expression );
25313 free_node(node_allocator_, right_branch);
25314
25315 return error_node();
25316 }
25317 else
25318 {
25319 if (
25320 token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
25321 (e_level00 == precedence)
25322 )
25323 {
25325 }
25326 else
25327 expression = new_expression;
25328
25330 }
25331 }
25332
25333 if ((0 != expression) && (expression->node_depth() > settings_.max_node_depth_))
25334 {
25335 set_error(make_error(
25337 current_token(),
25338 "ERR017 - Expression depth of " + details::to_str(static_cast<int>(expression->node_depth())) +
25339 " exceeds maximum allowed expression depth of " + details::to_str(static_cast<int>(settings_.max_node_depth_)),
25341
25342 free_node(node_allocator_, expression);
25343
25344 return error_node();
25345 }
25346
25347 return expression;
25348 }
25349
25351 {
25352 {
25354 ubn_t* n = dynamic_cast<ubn_t*>(node);
25355
25356 if (n)
25357 {
25358 expression_node_ptr un_r = n->branch(0);
25359 n->release();
25360 free_node(node_allocator_, node);
25361 node = un_r;
25362
25363 return true;
25364 }
25365 }
25366
25367 {
25369
25370 uvn_t* n = dynamic_cast<uvn_t*>(node);
25371
25372 if (n)
25373 {
25374 const T& v = n->v();
25375 expression_node_ptr return_node = error_node();
25376
25377 if (
25378 (0 != (return_node = symtab_store_.get_variable(v))) ||
25379 (0 != (return_node = sem_ .get_variable(v)))
25380 )
25381 {
25382 free_node(node_allocator_, node);
25383 node = return_node;
25384
25385 return true;
25386 }
25387 else
25388 {
25389 set_error(make_error(
25391 current_token(),
25392 "ERR018 - Failed to find variable node in symbol table",
25394
25395 free_node(node_allocator_, node);
25396
25397 return false;
25398 }
25399 }
25400 }
25401
25402 return false;
25403 }
25404
25406 {
25407 return reinterpret_cast<expression_node_ptr>(0);
25408 }
25409
25435
25436 template <typename Type, std::size_t N>
25438 {
25439 typedef Type* ptr_t;
25440
25442 : delete_ptr(true)
25443 , parser_(pr)
25444 , p_(&p)
25445 {}
25446
25448 : delete_ptr(true)
25449 , parser_(pr)
25450 , p_(&p[0])
25451 {}
25452
25454 {
25455 if (delete_ptr)
25456 {
25457 for (std::size_t i = 0; i < N; ++i)
25458 {
25459 free_node(parser_.node_allocator_, p_[i]);
25460 }
25461 }
25462 }
25463
25467
25468 private:
25469
25472 };
25473
25474 template <typename Type>
25476 {
25477 typedef Type* ptr_t;
25478
25479 scoped_deq_delete(parser<T>& pr, std::deque<ptr_t>& deq)
25480 : delete_ptr(true)
25481 , parser_(pr)
25482 , deq_(deq)
25483 {}
25484
25486 {
25487 if (delete_ptr && !deq_.empty())
25488 {
25489 for (std::size_t i = 0; i < deq_.size(); ++i)
25490 {
25491 exprtk_debug(("~scoped_deq_delete() - deleting node: %p\n", reinterpret_cast<void*>(deq_[i])));
25492 free_node(parser_.node_allocator_,deq_[i]);
25493 }
25494
25495 deq_.clear();
25496 }
25497 }
25498
25501 std::deque<ptr_t>& deq_;
25502
25503 private:
25504
25507 };
25508
25509 template <typename Type>
25511 {
25512 typedef Type* ptr_t;
25513
25514 scoped_vec_delete(parser<T>& pr, std::vector<ptr_t>& vec)
25515 : delete_ptr(true)
25516 , parser_(pr)
25517 , vec_(vec)
25518 {}
25519
25521 {
25522 if (delete_ptr && !vec_.empty())
25523 {
25524 for (std::size_t i = 0; i < vec_.size(); ++i)
25525 {
25526 exprtk_debug(("~scoped_vec_delete() - deleting node: %p\n", reinterpret_cast<void*>(vec_[i])));
25527 free_node(parser_.node_allocator_,vec_[i]);
25528 }
25529
25530 vec_.clear();
25531 }
25532 }
25533
25534 ptr_t operator[](const std::size_t index)
25535 {
25536 return vec_[index];
25537 }
25538
25541 std::vector<ptr_t>& vec_;
25542
25543 private:
25544
25547 };
25548
25550 {
25551 explicit scoped_bool_negator(bool& bb)
25552 : b(bb)
25553 { b = !b; }
25554
25556 { b = !b; }
25557
25558 bool& b;
25559 };
25560
25562 {
25563 explicit scoped_bool_or_restorer(bool& bb)
25564 : b(bb)
25565 , original_value_(bb)
25566 {}
25567
25569 {
25570 b = b || original_value_;
25571 }
25572
25573 bool& b;
25575 };
25576
25578 {
25579 explicit scoped_inc_dec(std::size_t& v)
25580 : v_(v)
25581 { ++v_; }
25582
25584 {
25585 assert(v_ > 0);
25586 --v_;
25587 }
25588
25589 std::size_t& v_;
25590 };
25591
25592 inline expression_node_ptr parse_function_invocation(ifunction<T>* function, const std::string& function_name)
25593 {
25594 expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0);
25595
25596 switch (function->param_count)
25597 {
25598 case 0 : func_node = parse_function_call_0 (function,function_name); break;
25599 case 1 : func_node = parse_function_call< 1>(function,function_name); break;
25600 case 2 : func_node = parse_function_call< 2>(function,function_name); break;
25601 case 3 : func_node = parse_function_call< 3>(function,function_name); break;
25602 case 4 : func_node = parse_function_call< 4>(function,function_name); break;
25603 case 5 : func_node = parse_function_call< 5>(function,function_name); break;
25604 case 6 : func_node = parse_function_call< 6>(function,function_name); break;
25605 case 7 : func_node = parse_function_call< 7>(function,function_name); break;
25606 case 8 : func_node = parse_function_call< 8>(function,function_name); break;
25607 case 9 : func_node = parse_function_call< 9>(function,function_name); break;
25608 case 10 : func_node = parse_function_call<10>(function,function_name); break;
25609 case 11 : func_node = parse_function_call<11>(function,function_name); break;
25610 case 12 : func_node = parse_function_call<12>(function,function_name); break;
25611 case 13 : func_node = parse_function_call<13>(function,function_name); break;
25612 case 14 : func_node = parse_function_call<14>(function,function_name); break;
25613 case 15 : func_node = parse_function_call<15>(function,function_name); break;
25614 case 16 : func_node = parse_function_call<16>(function,function_name); break;
25615 case 17 : func_node = parse_function_call<17>(function,function_name); break;
25616 case 18 : func_node = parse_function_call<18>(function,function_name); break;
25617 case 19 : func_node = parse_function_call<19>(function,function_name); break;
25618 case 20 : func_node = parse_function_call<20>(function,function_name); break;
25619 default : {
25620 set_error(make_error(
25622 current_token(),
25623 "ERR019 - Invalid number of parameters for function: '" + function_name + "'",
25625
25626 return error_node();
25627 }
25628 }
25629
25630 if (func_node)
25631 return func_node;
25632 else
25633 {
25634 set_error(make_error(
25636 current_token(),
25637 "ERR020 - Failed to generate call to function: '" + function_name + "'",
25639
25640 return error_node();
25641 }
25642 }
25643
25644 template <std::size_t NumberofParameters>
25645 inline expression_node_ptr parse_function_call(ifunction<T>* function, const std::string& function_name)
25646 {
25647 #ifdef _MSC_VER
25648 #pragma warning(push)
25649 #pragma warning(disable: 4127)
25650 #endif
25651 if (0 == NumberofParameters)
25652 {
25653 set_error(make_error(
25655 current_token(),
25656 "ERR021 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
25658
25659 return error_node();
25660 }
25661 #ifdef _MSC_VER
25662 #pragma warning(pop)
25663 #endif
25664
25665 expression_node_ptr branch[NumberofParameters];
25667
25668 std::fill_n(branch, NumberofParameters, reinterpret_cast<expression_node_ptr>(0));
25669
25671
25672 next_token();
25673
25675 {
25676 set_error(make_error(
25678 current_token(),
25679 "ERR022 - Expecting argument list for function: '" + function_name + "'",
25681
25682 return error_node();
25683 }
25684
25685 for (int i = 0; i < static_cast<int>(NumberofParameters); ++i)
25686 {
25687 branch[i] = parse_expression();
25688
25689 if (0 == branch[i])
25690 {
25691 set_error(make_error(
25693 current_token(),
25694 "ERR023 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
25696
25697 return error_node();
25698 }
25699 else if (i < static_cast<int>(NumberofParameters - 1))
25700 {
25702 {
25703 set_error(make_error(
25705 current_token(),
25706 "ERR024 - Invalid number of arguments for function: '" + function_name + "'",
25708
25709 return error_node();
25710 }
25711 }
25712 }
25713
25715 {
25716 set_error(make_error(
25718 current_token(),
25719 "ERR025 - Invalid number of arguments for function: '" + function_name + "'",
25721
25722 return error_node();
25723 }
25724 else
25725 result = expression_generator_.function(function,branch);
25726
25727 sd.delete_ptr = (0 == result);
25728
25729 return result;
25730 }
25731
25732 inline expression_node_ptr parse_function_call_0(ifunction<T>* function, const std::string& function_name)
25733 {
25735
25737
25738 next_token();
25739
25740 if (
25743 )
25744 {
25745 set_error(make_error(
25747 current_token(),
25748 "ERR026 - Expecting '()' to proceed call to function: '" + function_name + "'",
25750
25751 free_node(node_allocator_, result);
25752
25753 return error_node();
25754 }
25755 else
25756 return result;
25757 }
25758
25759 template <std::size_t MaxNumberofParameters>
25760 inline std::size_t parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters], const std::string& function_name = "")
25761 {
25762 std::fill_n(param_list, MaxNumberofParameters, reinterpret_cast<expression_node_ptr>(0));
25763
25765
25766 next_token();
25767
25769 {
25770 set_error(make_error(
25772 current_token(),
25773 "ERR027 - Expected a '(' at start of function call to '" + function_name +
25774 "', instead got: '" + current_token().value + "'",
25776
25777 return 0;
25778 }
25779
25781 {
25782 set_error(make_error(
25784 current_token(),
25785 "ERR028 - Expected at least one input parameter for function call '" + function_name + "'",
25787
25788 return 0;
25789 }
25790
25791 std::size_t param_index = 0;
25792
25793 for (; param_index < MaxNumberofParameters; ++param_index)
25794 {
25795 param_list[param_index] = parse_expression();
25796
25797 if (0 == param_list[param_index])
25798 return 0;
25799 else if (token_is(token_t::e_rbracket))
25800 {
25801 sd.delete_ptr = false;
25802 break;
25803 }
25804 else if (token_is(token_t::e_comma))
25805 continue;
25806 else
25807 {
25808 set_error(make_error(
25810 current_token(),
25811 "ERR029 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
25813
25814 return 0;
25815 }
25816 }
25817
25818 if (sd.delete_ptr)
25819 {
25820 set_error(make_error(
25822 current_token(),
25823 "ERR030 - Invalid number of input parameters passed to function '" + function_name + "'",
25825
25826 return 0;
25827 }
25828
25829 return (param_index + 1);
25830 }
25831
25833 {
25834 typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t;
25835
25836 const std::string operation_name = current_token().value;
25837 const token_t diagnostic_token = current_token();
25838
25839 map_range_t itr_range = base_ops_map_.equal_range(operation_name);
25840
25841 if (0 == std::distance(itr_range.first,itr_range.second))
25842 {
25843 set_error(make_error(
25845 diagnostic_token,
25846 "ERR031 - No entry found for base operation: " + operation_name,
25848
25849 return error_node();
25850 }
25851
25852 static const std::size_t MaxNumberofParameters = 4;
25853 expression_node_ptr param_list[MaxNumberofParameters] = {0};
25854
25855 const std::size_t parameter_count = parse_base_function_call(param_list, operation_name);
25856
25857 if ((parameter_count > 0) && (parameter_count <= MaxNumberofParameters))
25858 {
25859 for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr)
25860 {
25861 const details::base_operation_t& operation = itr->second;
25862
25863 if (operation.num_params == parameter_count)
25864 {
25865 switch (parameter_count)
25866 {
25867 #define base_opr_case(N) \
25868 case N : { \
25869 expression_node_ptr pl##N[N] = {0}; \
25870 std::copy(param_list, param_list + N, pl##N); \
25871 lodge_symbol(operation_name, e_st_function); \
25872 return expression_generator_(operation.type, pl##N); \
25873 } \
25874
25875 base_opr_case(1)
25876 base_opr_case(2)
25877 base_opr_case(3)
25878 base_opr_case(4)
25879 #undef base_opr_case
25880 }
25881 }
25882 }
25883 }
25884
25885 for (std::size_t i = 0; i < MaxNumberofParameters; ++i)
25886 {
25887 free_node(node_allocator_, param_list[i]);
25888 }
25889
25890 set_error(make_error(
25892 diagnostic_token,
25893 "ERR032 - Invalid number of input parameters for call to function: '" + operation_name + "'",
25895
25896 return error_node();
25897 }
25898
25900 {
25901 // Parse: [if][(][condition][,][consequent][,][alternative][)]
25902
25903 expression_node_ptr consequent = error_node();
25904 expression_node_ptr alternative = error_node();
25905
25906 bool result = true;
25907
25909 {
25910 set_error(make_error(
25912 current_token(),
25913 "ERR033 - Expected ',' between if-statement condition and consequent",
25915
25916 result = false;
25917 }
25918 else if (0 == (consequent = parse_expression()))
25919 {
25920 set_error(make_error(
25922 current_token(),
25923 "ERR034 - Failed to parse consequent for if-statement",
25925
25926 result = false;
25927 }
25928 else if (!token_is(token_t::e_comma))
25929 {
25930 set_error(make_error(
25932 current_token(),
25933 "ERR035 - Expected ',' between if-statement consequent and alternative",
25935
25936 result = false;
25937 }
25938 else if (0 == (alternative = parse_expression()))
25939 {
25940 set_error(make_error(
25942 current_token(),
25943 "ERR036 - Failed to parse alternative for if-statement",
25945
25946 result = false;
25947 }
25948 else if (!token_is(token_t::e_rbracket))
25949 {
25950 set_error(make_error(
25952 current_token(),
25953 "ERR037 - Expected ')' at the end of if-statement",
25955
25956 result = false;
25957 }
25958
25959 #ifndef exprtk_disable_string_capabilities
25960 if (result)
25961 {
25962 const bool consq_is_str = is_generally_string_node(consequent );
25963 const bool alter_is_str = is_generally_string_node(alternative);
25964
25965 if (consq_is_str || alter_is_str)
25966 {
25967 if (consq_is_str && alter_is_str)
25968 {
25969 expression_node_ptr result_node =
25971 .conditional_string(condition, consequent, alternative);
25972
25973 if (result_node && result_node->valid())
25974 {
25975 return result_node;
25976 }
25977
25978 set_error(make_error(
25980 current_token(),
25981 "ERR038 - Failed to synthesize node: conditional_string",
25983
25984 free_node(node_allocator_, result_node);
25985 return error_node();
25986 }
25987
25988 set_error(make_error(
25990 current_token(),
25991 "ERR039 - Return types of if-statement differ: string/non-string",
25993
25994 result = false;
25995 }
25996 }
25997 #endif
25998
25999 if (result)
26000 {
26001 const bool consq_is_vec = is_ivector_node(consequent );
26002 const bool alter_is_vec = is_ivector_node(alternative);
26003
26004 if (consq_is_vec || alter_is_vec)
26005 {
26006 if (consq_is_vec && alter_is_vec)
26007 {
26009 .conditional_vector(condition, consequent, alternative);
26010 }
26011
26012 set_error(make_error(
26014 current_token(),
26015 "ERR040 - Return types of if-statement differ: vector/non-vector",
26017
26018 result = false;
26019 }
26020 }
26021
26022 if (!result)
26023 {
26024 free_node(node_allocator_, condition );
26025 free_node(node_allocator_, consequent );
26026 free_node(node_allocator_, alternative);
26027
26028 return error_node();
26029 }
26030 else
26032 .conditional(condition, consequent, alternative);
26033 }
26034
26036 {
26037 expression_node_ptr consequent = error_node();
26038 expression_node_ptr alternative = error_node();
26039
26040 bool result = true;
26041
26042 if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
26043 {
26044 if (0 == (consequent = parse_multi_sequence("if-statement-01")))
26045 {
26046 set_error(make_error(
26048 current_token(),
26049 "ERR041 - Failed to parse body of consequent for if-statement",
26051
26052 result = false;
26053 }
26054 else if
26055 (
26057 !token_is("else",prsrhlpr_t::e_hold) &&
26058 !token_is_loop(prsrhlpr_t::e_hold) &&
26059 !token_is_arithmetic_opr(prsrhlpr_t::e_hold) &&
26060 !token_is_right_bracket (prsrhlpr_t::e_hold) &&
26061 !token_is_ineq_opr (prsrhlpr_t::e_hold) &&
26062 !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
26064 )
26065 {
26066 set_error(make_error(
26068 current_token(),
26069 "ERR042 - Expected ';' at the end of the consequent for if-statement (1)",
26071
26072 result = false;
26073 }
26074 }
26075 else
26076 {
26077 if (
26079 token_is(token_t::e_mul,prsrhlpr_t::e_hold)
26080 )
26081 {
26082 next_token();
26083 }
26084
26085 if (0 != (consequent = parse_expression()))
26086 {
26088 {
26089 set_error(make_error(
26091 current_token(),
26092 "ERR043 - Expected ';' at the end of the consequent for if-statement (2)",
26094
26095 result = false;
26096 }
26097 }
26098 else
26099 {
26100 set_error(make_error(
26102 current_token(),
26103 "ERR044 - Failed to parse body of consequent for if-statement",
26105
26106 result = false;
26107 }
26108 }
26109
26110 if (result)
26111 {
26112 if (details::imatch(current_token().value,"else"))
26113 {
26114 next_token();
26115
26116 if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
26117 {
26118 if (0 == (alternative = parse_multi_sequence("else-statement-01")))
26119 {
26120 set_error(make_error(
26122 current_token(),
26123 "ERR045 - Failed to parse body of the 'else' for if-statement",
26125
26126 result = false;
26127 }
26128 }
26129 else if (details::imatch(current_token().value,"if"))
26130 {
26131 if (0 == (alternative = parse_conditional_statement()))
26132 {
26133 set_error(make_error(
26135 current_token(),
26136 "ERR046 - Failed to parse body of if-else statement",
26138
26139 result = false;
26140 }
26141 }
26142 else if (0 != (alternative = parse_expression()))
26143 {
26144 if (
26145 !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
26147 )
26148 {
26149 set_error(make_error(
26151 current_token(),
26152 "ERR047 - Expected ';' at the end of the 'else-if' for the if-statement",
26154
26155 result = false;
26156 }
26157 }
26158 else
26159 {
26160 set_error(make_error(
26162 current_token(),
26163 "ERR048 - Failed to parse body of the 'else' for if-statement",
26165
26166 result = false;
26167 }
26168 }
26169 }
26170
26171 #ifndef exprtk_disable_string_capabilities
26172 if (result)
26173 {
26174 const bool consq_is_str = is_generally_string_node(consequent );
26175 const bool alter_is_str = is_generally_string_node(alternative);
26176
26177 if (consq_is_str || alter_is_str)
26178 {
26179 if (consq_is_str && alter_is_str)
26180 {
26182 .conditional_string(condition, consequent, alternative);
26183 }
26184
26185 set_error(make_error(
26187 current_token(),
26188 "ERR049 - Return types of if-statement differ: string/non-string",
26190
26191 result = false;
26192 }
26193 }
26194 #endif
26195
26196 if (result)
26197 {
26198 const bool consq_is_vec = is_ivector_node(consequent );
26199 const bool alter_is_vec = is_ivector_node(alternative);
26200
26201 if (consq_is_vec || alter_is_vec)
26202 {
26203 if (consq_is_vec && alter_is_vec)
26204 {
26206 .conditional_vector(condition, consequent, alternative);
26207 }
26208
26209 set_error(make_error(
26211 current_token(),
26212 "ERR050 - Return types of if-statement differ: vector/non-vector",
26214
26215 result = false;
26216 }
26217 }
26218
26219 if (!result)
26220 {
26221 free_node(node_allocator_, condition );
26222 free_node(node_allocator_, consequent );
26223 free_node(node_allocator_, alternative);
26224
26225 return error_node();
26226 }
26227 else
26229 .conditional(condition, consequent, alternative);
26230 }
26231
26233 {
26234 expression_node_ptr condition = error_node();
26235
26236 next_token();
26237
26239 {
26240 set_error(make_error(
26242 current_token(),
26243 "ERR051 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
26245
26246 return error_node();
26247 }
26248 else if (0 == (condition = parse_expression()))
26249 {
26250 set_error(make_error(
26252 current_token(),
26253 "ERR052 - Failed to parse condition for if-statement",
26255
26256 return error_node();
26257 }
26258 else if (token_is(token_t::e_comma,prsrhlpr_t::e_hold))
26259 {
26260 // if (x,y,z)
26261 return parse_conditional_statement_01(condition);
26262 }
26263 else if (token_is(token_t::e_rbracket))
26264 {
26265 /*
26266 00. if (x) y;
26267 01. if (x) y; else z;
26268 02. if (x) y; else {z0; ... zn;}
26269 03. if (x) y; else if (z) w;
26270 04. if (x) y; else if (z) w; else u;
26271 05. if (x) y; else if (z) w; else {u0; ... un;}
26272 06. if (x) y; else if (z) {w0; ... wn;}
26273 07. if (x) {y0; ... yn;}
26274 08. if (x) {y0; ... yn;} else z;
26275 09. if (x) {y0; ... yn;} else {z0; ... zn;};
26276 10. if (x) {y0; ... yn;} else if (z) w;
26277 11. if (x) {y0; ... yn;} else if (z) w; else u;
26278 12. if (x) {y0; ... nex;} else if (z) w; else {u0 ... un;}
26279 13. if (x) {y0; ... yn;} else if (z) {w0; ... wn;}
26280 */
26281 return parse_conditional_statement_02(condition);
26282 }
26283
26284 set_error(make_error(
26286 current_token(),
26287 "ERR053 - Invalid if-statement",
26289
26290 free_node(node_allocator_, condition);
26291
26292 return error_node();
26293 }
26294
26296 {
26297 // Parse: [condition][?][consequent][:][alternative]
26298 expression_node_ptr consequent = error_node();
26299 expression_node_ptr alternative = error_node();
26300
26301 bool result = true;
26302
26303 if (0 == condition)
26304 {
26305 set_error(make_error(
26307 current_token(),
26308 "ERR054 - Encountered invalid condition branch for ternary if-statement",
26310
26311 return error_node();
26312 }
26313 else if (!token_is(token_t::e_ternary))
26314 {
26315 set_error(make_error(
26317 current_token(),
26318 "ERR055 - Expected '?' after condition of ternary if-statement",
26320
26321 result = false;
26322 }
26323 else if (0 == (consequent = parse_expression()))
26324 {
26325 set_error(make_error(
26327 current_token(),
26328 "ERR056 - Failed to parse consequent for ternary if-statement",
26330
26331 result = false;
26332 }
26333 else if (!token_is(token_t::e_colon))
26334 {
26335 set_error(make_error(
26337 current_token(),
26338 "ERR057 - Expected ':' between ternary if-statement consequent and alternative",
26340
26341 result = false;
26342 }
26343 else if (0 == (alternative = parse_expression()))
26344 {
26345 set_error(make_error(
26347 current_token(),
26348 "ERR058 - Failed to parse alternative for ternary if-statement",
26350
26351 result = false;
26352 }
26353
26354 #ifndef exprtk_disable_string_capabilities
26355 if (result)
26356 {
26357 const bool consq_is_str = is_generally_string_node(consequent );
26358 const bool alter_is_str = is_generally_string_node(alternative);
26359
26360 if (consq_is_str || alter_is_str)
26361 {
26362 if (consq_is_str && alter_is_str)
26363 {
26365 .conditional_string(condition, consequent, alternative);
26366 }
26367
26368 set_error(make_error(
26370 current_token(),
26371 "ERR059 - Return types of ternary differ: string/non-string",
26373
26374 result = false;
26375 }
26376 }
26377 #endif
26378
26379 if (result)
26380 {
26381 const bool consq_is_vec = is_ivector_node(consequent );
26382 const bool alter_is_vec = is_ivector_node(alternative);
26383
26384 if (consq_is_vec || alter_is_vec)
26385 {
26386 if (consq_is_vec && alter_is_vec)
26387 {
26389 .conditional_vector(condition, consequent, alternative);
26390 }
26391
26392 set_error(make_error(
26394 current_token(),
26395 "ERR060 - Return types of ternary differ: vector/non-vector",
26397
26398 result = false;
26399 }
26400 }
26401
26402 if (!result)
26403 {
26404 free_node(node_allocator_, condition );
26405 free_node(node_allocator_, consequent );
26406 free_node(node_allocator_, alternative);
26407
26408 return error_node();
26409 }
26410 else
26412 .conditional(condition, consequent, alternative);
26413 }
26414
26416 {
26417 if (settings_.logic_disabled("not"))
26418 {
26419 set_error(make_error(
26421 current_token(),
26422 "ERR061 - Invalid or disabled logic operation 'not'",
26424
26425 return error_node();
26426 }
26427
26428 return parse_base_operation();
26429 }
26430
26432 {
26433 assert(!brkcnt_list_.empty());
26434 brkcnt_list_.pop_front();
26435 }
26436
26438 {
26439 // Parse: [while][(][test expr][)][{][expression][}]
26440 expression_node_ptr condition = error_node();
26442 expression_node_ptr result_node = error_node();
26443
26444 bool result = true;
26445
26446 next_token();
26447
26449 {
26450 set_error(make_error(
26452 current_token(),
26453 "ERR062 - Expected '(' at start of while-loop condition statement",
26455
26456 return error_node();
26457 }
26458 else if (0 == (condition = parse_expression()))
26459 {
26460 set_error(make_error(
26462 current_token(),
26463 "ERR063 - Failed to parse condition for while-loop",
26465
26466 return error_node();
26467 }
26468 else if (!token_is(token_t::e_rbracket))
26469 {
26470 set_error(make_error(
26472 current_token(),
26473 "ERR064 - Expected ')' at end of while-loop condition statement",
26475
26476 result = false;
26477 }
26478
26479 brkcnt_list_.push_front(false);
26480
26481 if (result)
26482 {
26484
26485 if (0 == (branch = parse_multi_sequence("while-loop", true)))
26486 {
26487 set_error(make_error(
26489 current_token(),
26490 "ERR065 - Failed to parse body of while-loop"));
26491 result = false;
26492 }
26493 else if (0 == (result_node = expression_generator_.while_loop(condition,
26494 branch,
26495 brkcnt_list_.front())))
26496 {
26497 set_error(make_error(
26499 current_token(),
26500 "ERR066 - Failed to synthesize while-loop",
26502
26503 result = false;
26504 }
26505 }
26506
26508
26509 if (!result)
26510 {
26511 free_node(node_allocator_, branch );
26512 free_node(node_allocator_, condition );
26513 free_node(node_allocator_, result_node);
26514
26515 return error_node();
26516 }
26517
26518 if (result_node && result_node->valid())
26519 {
26520 return result_node;
26521 }
26522
26523 set_error(make_error(
26525 current_token(),
26526 "ERR067 - Failed to synthesize 'valid' while-loop",
26528
26529 free_node(node_allocator_, result_node);
26530
26531 return error_node();
26532 }
26533
26535 {
26536 // Parse: [repeat][{][expression][}][until][(][test expr][)]
26537 expression_node_ptr condition = error_node();
26539 next_token();
26540
26541 std::vector<expression_node_ptr> arg_list;
26542 std::vector<bool> side_effect_list;
26543
26544 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
26545
26546 brkcnt_list_.push_front(false);
26547
26548 if (details::imatch(current_token().value,"until"))
26549 {
26550 next_token();
26552 }
26553 else
26554 {
26555 const token_t::token_type separator = token_t::e_eof;
26556
26557 scope_handler sh(*this);
26558
26560
26562
26563 for ( ; ; )
26564 {
26566
26568
26569 if (0 == arg)
26570 return error_node();
26571 else
26572 {
26573 arg_list.push_back(arg);
26574 side_effect_list.push_back(state_.side_effect_present);
26575 }
26576
26577 if (details::imatch(current_token().value,"until"))
26578 {
26579 next_token();
26580 break;
26581 }
26582
26583 const bool is_next_until = peek_token_is(token_t::e_symbol) &&
26584 peek_token_is("until");
26585
26586 if (!token_is(separator) && is_next_until)
26587 {
26588 set_error(make_error(
26590 current_token(),
26591 "ERR068 - Expected '" + token_t::to_str(separator) + "' in body of repeat until loop",
26593
26594 return error_node();
26595 }
26596
26597 if (details::imatch(current_token().value,"until"))
26598 {
26599 next_token();
26600 break;
26601 }
26602 }
26603
26604 branch = simplify(arg_list,side_effect_list);
26605
26606 sdd.delete_ptr = (0 == branch);
26607
26608 if (sdd.delete_ptr)
26609 {
26610 set_error(make_error(
26612 current_token(),
26613 "ERR069 - Failed to parse body of repeat until loop",
26615
26616 return error_node();
26617 }
26618 }
26619
26621 {
26622 set_error(make_error(
26624 current_token(),
26625 "ERR070 - Expected '(' before condition statement of repeat until loop",
26627
26628 free_node(node_allocator_, branch);
26629 return error_node();
26630 }
26631 else if (0 == (condition = parse_expression()))
26632 {
26633 set_error(make_error(
26635 current_token(),
26636 "ERR071 - Failed to parse condition for repeat until loop",
26638
26639 free_node(node_allocator_, branch);
26640 return error_node();
26641 }
26642 else if (!token_is(token_t::e_rbracket))
26643 {
26644 set_error(make_error(
26646 current_token(),
26647 "ERR072 - Expected ')' after condition of repeat until loop",
26649
26650 free_node(node_allocator_, branch );
26651 free_node(node_allocator_, condition);
26652
26653 return error_node();
26654 }
26655
26656 expression_node_ptr result_node =
26659 condition,
26660 branch,
26661 brkcnt_list_.front());
26662
26663 if (0 == result_node)
26664 {
26665 set_error(make_error(
26667 current_token(),
26668 "ERR073 - Failed to synthesize repeat until loop",
26670
26671 free_node(node_allocator_, condition);
26672
26673 return error_node();
26674 }
26675
26677
26678 if (result_node && result_node->valid())
26679 {
26680 return result_node;
26681 }
26682
26683 set_error(make_error(
26685 current_token(),
26686 "ERR074 - Failed to synthesize 'valid' repeat until loop",
26688
26689 free_node(node_allocator_, result_node);
26690
26691 return error_node();
26692 }
26693
26695 {
26696 expression_node_ptr initialiser = error_node();
26697 expression_node_ptr condition = error_node();
26698 expression_node_ptr incrementor = error_node();
26699 expression_node_ptr loop_body = error_node();
26700
26701 scope_element* se = 0;
26702 bool result = true;
26703
26704 next_token();
26705
26706 scope_handler sh(*this);
26707
26709 {
26710 set_error(make_error(
26712 current_token(),
26713 "ERR075 - Expected '(' at start of for-loop",
26715
26716 return error_node();
26717 }
26718
26720 {
26721 if (
26722 !token_is(token_t::e_symbol,prsrhlpr_t::e_hold) &&
26723 details::imatch(current_token().value,"var")
26724 )
26725 {
26726 next_token();
26727
26728 if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
26729 {
26730 set_error(make_error(
26732 current_token(),
26733 "ERR076 - Expected a variable at the start of initialiser section of for-loop",
26735
26736 return error_node();
26737 }
26739 {
26740 set_error(make_error(
26742 current_token(),
26743 "ERR077 - Expected variable assignment of initialiser section of for-loop",
26745
26746 return error_node();
26747 }
26748
26749 const std::string loop_counter_symbol = current_token().value;
26750
26751 se = &sem_.get_element(loop_counter_symbol);
26752
26753 if ((se->name == loop_counter_symbol) && se->active)
26754 {
26755 set_error(make_error(
26757 current_token(),
26758 "ERR078 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
26760
26761 return error_node();
26762 }
26763 else if (!symtab_store_.is_variable(loop_counter_symbol))
26764 {
26765 if (
26766 !se->active &&
26767 (se->name == loop_counter_symbol) &&
26769 )
26770 {
26771 se->active = true;
26772 se->ref_count++;
26773 }
26774 else
26775 {
26776 scope_element nse;
26777 nse.name = loop_counter_symbol;
26778 nse.active = true;
26779 nse.ref_count = 1;
26781 nse.depth = state_.scope_depth;
26782 nse.data = new T(T(0));
26783 nse.var_node = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data));
26784
26785 if (!sem_.add_element(nse))
26786 {
26787 set_error(make_error(
26789 current_token(),
26790 "ERR079 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
26792
26793 sem_.free_element(nse);
26794
26795 result = false;
26796 }
26797 else
26798 {
26799 exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n", nse.name.c_str()));
26800
26801 state_.activate_side_effect("parse_for_loop()");
26802 }
26803 }
26804 }
26805 }
26806
26807 if (0 == (initialiser = parse_expression()))
26808 {
26809 set_error(make_error(
26811 current_token(),
26812 "ERR080 - Failed to parse initialiser of for-loop",
26814
26815 result = false;
26816 }
26817 else if (!token_is(token_t::e_eof))
26818 {
26819 set_error(make_error(
26821 current_token(),
26822 "ERR081 - Expected ';' after initialiser of for-loop",
26824
26825 result = false;
26826 }
26827 }
26828
26830 {
26831 if (0 == (condition = parse_expression()))
26832 {
26833 set_error(make_error(
26835 current_token(),
26836 "ERR082 - Failed to parse condition of for-loop",
26838
26839 result = false;
26840 }
26841 else if (!token_is(token_t::e_eof))
26842 {
26843 set_error(make_error(
26845 current_token(),
26846 "ERR083 - Expected ';' after condition section of for-loop",
26848
26849 result = false;
26850 }
26851 }
26852
26854 {
26855 if (0 == (incrementor = parse_expression()))
26856 {
26857 set_error(make_error(
26859 current_token(),
26860 "ERR084 - Failed to parse incrementor of for-loop",
26862
26863 result = false;
26864 }
26865 else if (!token_is(token_t::e_rbracket))
26866 {
26867 set_error(make_error(
26869 current_token(),
26870 "ERR085 - Expected ')' after incrementor section of for-loop",
26872
26873 result = false;
26874 }
26875 }
26876
26877 if (result)
26878 {
26879 brkcnt_list_.push_front(false);
26880
26882
26883 if (0 == (loop_body = parse_multi_sequence("for-loop", true)))
26884 {
26885 set_error(make_error(
26887 current_token(),
26888 "ERR086 - Failed to parse body of for-loop",
26890
26891 result = false;
26892 }
26893 }
26894
26895 if (!result)
26896 {
26897 if (se)
26898 {
26899 se->ref_count--;
26900 }
26901
26902 free_node(node_allocator_, initialiser);
26903 free_node(node_allocator_, condition );
26904 free_node(node_allocator_, incrementor);
26905 free_node(node_allocator_, loop_body );
26906 return error_node();
26907 }
26908
26909 expression_node_ptr result_node =
26910 expression_generator_.for_loop(initialiser,
26911 condition,
26912 incrementor,
26913 loop_body,
26914 brkcnt_list_.front());
26916
26917 if (result_node && result_node->valid())
26918 {
26919 return result_node;
26920 }
26921
26922 set_error(make_error(
26924 current_token(),
26925 "ERR087 - Failed to synthesize 'valid' for-loop",
26927
26928 free_node(node_allocator_, result_node);
26929
26930 return error_node();
26931 }
26932
26934 {
26935 std::vector<expression_node_ptr> arg_list;
26937
26938 if (!details::imatch(current_token().value,"switch"))
26939 {
26940 set_error(make_error(
26942 current_token(),
26943 "ERR088 - Expected keyword 'switch'",
26945
26946 return error_node();
26947 }
26948
26949 scoped_vec_delete<expression_node_t> svd((*this),arg_list);
26950
26951 next_token();
26952
26954 {
26955 set_error(make_error(
26957 current_token(),
26958 "ERR089 - Expected '{' for call to switch statement",
26960
26961 return error_node();
26962 }
26963
26964 expression_node_ptr default_statement = error_node();
26965
26966 scoped_expression_delete defstmt_delete((*this), default_statement);
26967
26968 for ( ; ; )
26969 {
26970 if (details::imatch("case",current_token().value))
26971 {
26972 next_token();
26973
26975
26976 if (0 == condition)
26977 return error_node();
26978 else if (!token_is(token_t::e_colon))
26979 {
26980 set_error(make_error(
26982 current_token(),
26983 "ERR090 - Expected ':' for case of switch statement",
26985
26986 free_node(node_allocator_, condition);
26987
26988 return error_node();
26989 }
26990
26991 expression_node_ptr consequent =
26992 (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
26993 parse_multi_sequence("switch-consequent") :
26995
26996 if (0 == consequent)
26997 {
26998 free_node(node_allocator_, condition);
26999
27000 return error_node();
27001 }
27002 else if (!token_is(token_t::e_eof))
27003 {
27004 set_error(make_error(
27006 current_token(),
27007 "ERR091 - Expected ';' at end of case for switch statement",
27009
27010 free_node(node_allocator_, condition );
27011 free_node(node_allocator_, consequent);
27012
27013 return error_node();
27014 }
27015
27016 // Can we optimise away the case statement?
27017 if (is_constant_node(condition) && is_false(condition))
27018 {
27019 free_node(node_allocator_, condition );
27020 free_node(node_allocator_, consequent);
27021 }
27022 else
27023 {
27024 arg_list.push_back(condition );
27025 arg_list.push_back(consequent);
27026 }
27027
27028 }
27029 else if (details::imatch("default",current_token().value))
27030 {
27031 if (0 != default_statement)
27032 {
27033 set_error(make_error(
27035 current_token(),
27036 "ERR092 - Multiple default cases for switch statement",
27038
27039 return error_node();
27040 }
27041
27042 next_token();
27043
27045 {
27046 set_error(make_error(
27048 current_token(),
27049 "ERR093 - Expected ':' for default of switch statement",
27051
27052 return error_node();
27053 }
27054
27055 default_statement =
27056 (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
27057 parse_multi_sequence("switch-default"):
27059
27060 if (0 == default_statement)
27061 return error_node();
27062 else if (!token_is(token_t::e_eof))
27063 {
27064 set_error(make_error(
27066 current_token(),
27067 "ERR094 - Expected ';' at end of default for switch statement",
27069
27070 return error_node();
27071 }
27072 }
27074 break;
27075 else
27076 {
27077 set_error(make_error(
27079 current_token(),
27080 "ERR095 - Expected '}' at end of switch statement",
27082
27083 return error_node();
27084 }
27085 }
27086
27087 const bool default_statement_present = (0 != default_statement);
27088
27089 if (default_statement_present)
27090 {
27091 arg_list.push_back(default_statement);
27092 }
27093 else
27094 {
27095 arg_list.push_back(node_allocator_.allocate_c<literal_node_t>(std::numeric_limits<T>::quiet_NaN()));
27096 }
27097
27098 result = expression_generator_.switch_statement(arg_list, (0 != default_statement));
27099
27100 svd.delete_ptr = (0 == result);
27101 defstmt_delete.delete_ptr = (0 == result);
27102
27103 return result;
27104 }
27105
27107 {
27108 std::vector<expression_node_ptr> arg_list;
27109
27110 if (!details::imatch(current_token().value,"[*]"))
27111 {
27112 set_error(make_error(
27114 current_token(),
27115 "ERR096 - Expected token '[*]'",
27117
27118 return error_node();
27119 }
27120
27121 scoped_vec_delete<expression_node_t> svd((*this),arg_list);
27122
27123 next_token();
27124
27126 {
27127 set_error(make_error(
27129 current_token(),
27130 "ERR097 - Expected '{' for call to [*] statement",
27132
27133 return error_node();
27134 }
27135
27136 for ( ; ; )
27137 {
27138 if (!details::imatch("case",current_token().value))
27139 {
27140 set_error(make_error(
27142 current_token(),
27143 "ERR098 - Expected a 'case' statement for multi-switch",
27145
27146 return error_node();
27147 }
27148
27149 next_token();
27150
27152
27153 if (0 == condition)
27154 return error_node();
27155
27157 {
27158 set_error(make_error(
27160 current_token(),
27161 "ERR099 - Expected ':' for case of [*] statement",
27163
27164 return error_node();
27165 }
27166
27167 expression_node_ptr consequent =
27168 (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
27169 parse_multi_sequence("multi-switch-consequent") :
27171
27172 if (0 == consequent)
27173 return error_node();
27174
27176 {
27177 set_error(make_error(
27179 current_token(),
27180 "ERR100 - Expected ';' at end of case for [*] statement",
27182
27183 return error_node();
27184 }
27185
27186 // Can we optimise away the case statement?
27187 if (is_constant_node(condition) && is_false(condition))
27188 {
27189 free_node(node_allocator_, condition );
27190 free_node(node_allocator_, consequent);
27191 }
27192 else
27193 {
27194 arg_list.push_back(condition );
27195 arg_list.push_back(consequent);
27196 }
27197
27198 if (token_is(token_t::e_rcrlbracket,prsrhlpr_t::e_hold))
27199 {
27200 break;
27201 }
27202 }
27203
27205 {
27206 set_error(make_error(
27208 current_token(),
27209 "ERR101 - Expected '}' at end of [*] statement",
27211
27212 return error_node();
27213 }
27214
27216
27217 svd.delete_ptr = (0 == result);
27218
27219 return result;
27220 }
27221
27223 {
27224 std::vector<expression_node_ptr> arg_list;
27225
27227 const std::string symbol = current_token().value;
27228
27229 if (details::imatch(symbol,"~"))
27230 {
27231 next_token();
27232 return parse_multi_sequence();
27233 }
27234 else if (details::imatch(symbol,"[*]"))
27235 {
27237 }
27238 else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ;
27239 else if (details::imatch(symbol, "mand")) opt_type = details::e_mand;
27240 else if (details::imatch(symbol, "max" )) opt_type = details::e_max ;
27241 else if (details::imatch(symbol, "min" )) opt_type = details::e_min ;
27242 else if (details::imatch(symbol, "mor" )) opt_type = details::e_mor ;
27243 else if (details::imatch(symbol, "mul" )) opt_type = details::e_prod;
27244 else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ;
27245 else
27246 {
27247 set_error(make_error(
27249 current_token(),
27250 "ERR102 - Unsupported built-in vararg function: " + symbol,
27252
27253 return error_node();
27254 }
27255
27256 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
27257
27258 lodge_symbol(symbol, e_st_function);
27259
27260 next_token();
27261
27263 {
27264 set_error(make_error(
27266 current_token(),
27267 "ERR103 - Expected '(' for call to vararg function: " + symbol,
27269
27270 return error_node();
27271 }
27272
27274 {
27275 set_error(make_error(
27277 current_token(),
27278 "ERR104 - vararg function: " + symbol +
27279 " requires at least one input parameter",
27281
27282 return error_node();
27283 }
27284
27285 for ( ; ; )
27286 {
27288
27289 if (0 == arg)
27290 return error_node();
27291 else
27292 arg_list.push_back(arg);
27293
27295 break;
27296 else if (!token_is(token_t::e_comma))
27297 {
27298 set_error(make_error(
27300 current_token(),
27301 "ERR105 - Expected ',' for call to vararg function: " + symbol,
27303
27304 return error_node();
27305 }
27306 }
27307
27308 const expression_node_ptr result = expression_generator_.vararg_function(opt_type,arg_list);
27309
27310 sdd.delete_ptr = (0 == result);
27311 return result;
27312 }
27313
27314 #ifndef exprtk_disable_string_capabilities
27316 {
27318 {
27319 set_error(make_error(
27321 current_token(),
27322 "ERR106 - Expected '[' as start of string range definition",
27324
27325 free_node(node_allocator_, expression);
27326
27327 return error_node();
27328 }
27330 {
27332 }
27333
27334 range_t rp;
27335
27336 if (!parse_range(rp,true))
27337 {
27338 free_node(node_allocator_, expression);
27339
27340 return error_node();
27341 }
27342
27344
27345 if (0 == result)
27346 {
27347 set_error(make_error(
27349 current_token(),
27350 "ERR107 - Failed to generate string range node",
27352
27353 free_node(node_allocator_, expression);
27354 rp.free();
27355 }
27356
27357 rp.clear();
27358
27359 if (result && result->valid())
27360 {
27361 return result;
27362 }
27363
27364 set_error(make_error(
27366 current_token(),
27367 "ERR108 - Failed to synthesize node: string_range_node",
27369
27370 free_node(node_allocator_, result);
27371 rp.free();
27372 return error_node();
27373 }
27374 #else
27376 {
27377 return error_node();
27378 }
27379 #endif
27380
27382 {
27383 // Allow no more than 100 range calls, eg: s[][][]...[][]
27384 const std::size_t max_rangesize_parses = 100;
27385
27386 std::size_t i = 0;
27387
27388 while
27389 (
27390 (0 != expression) &&
27391 (i++ < max_rangesize_parses) &&
27392 error_list_.empty() &&
27393 is_generally_string_node(expression) &&
27394 token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)
27395 )
27396 {
27398 }
27399
27400 return (i > 1);
27401 }
27402
27404 {
27405 if
27406 (
27407 (0 != expression) &&
27408 error_list_.empty() &&
27409 is_ivector_node(expression)
27410 )
27411 {
27412 if (
27414 token_is(token_t::e_mul,prsrhlpr_t::e_hold) &&
27416 )
27417 {
27420 }
27421 else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold))
27422 {
27424 }
27425 else if (
27426 token_is(token_t::e_rbracket,prsrhlpr_t::e_hold) &&
27428 )
27429 {
27432 }
27433 else
27434 return;
27435
27437
27438 if (vi)
27439 {
27441 const std::string vector_name = sem_.get_vector_name(vec.data());
27442 expression_node_ptr index = parse_vector_index(vector_name);
27443
27444 if (index)
27445 {
27446 expression = synthesize_vector_element(vector_name, &vec, expression, index);
27447 return;
27448 }
27449 }
27450
27451 free_node(node_allocator_, expression);
27453 }
27454 }
27455
27456 template <typename Allocator1,
27457 typename Allocator2,
27458 template <typename, typename> class Sequence>
27459 inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator1>& expression_list,
27460 Sequence<bool,Allocator2>& side_effect_list,
27461 const bool specialise_on_final_type = false)
27462 {
27463 if (expression_list.empty())
27464 return error_node();
27465 else if (1 == expression_list.size())
27466 return expression_list[0];
27467
27468 Sequence<expression_node_ptr,Allocator1> tmp_expression_list;
27469
27470 bool return_node_present = false;
27471
27472 for (std::size_t i = 0; i < (expression_list.size() - 1); ++i)
27473 {
27474 if (is_variable_node(expression_list[i]))
27475 continue;
27476 else if (
27477 is_return_node (expression_list[i]) ||
27478 is_break_node (expression_list[i]) ||
27479 is_continue_node(expression_list[i])
27480 )
27481 {
27482 tmp_expression_list.push_back(expression_list[i]);
27483
27484 // Remove all subexpressions after first short-circuit
27485 // node has been encountered.
27486
27487 for (std::size_t j = i + 1; j < expression_list.size(); ++j)
27488 {
27489 free_node(node_allocator_, expression_list[j]);
27490 }
27491
27492 return_node_present = true;
27493
27494 break;
27495 }
27496 else if (
27497 is_constant_node(expression_list[i]) ||
27498 is_null_node (expression_list[i]) ||
27499 !side_effect_list[i]
27500 )
27501 {
27502 free_node(node_allocator_, expression_list[i]);
27503 continue;
27504 }
27505 else
27506 tmp_expression_list.push_back(expression_list[i]);
27507 }
27508
27509 if (!return_node_present)
27510 {
27511 tmp_expression_list.push_back(expression_list.back());
27512 }
27513
27514 expression_list.swap(tmp_expression_list);
27515
27516 if (tmp_expression_list.size() > expression_list.size())
27517 {
27518 exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n",
27519 static_cast<int>(tmp_expression_list.size()),
27520 static_cast<int>(expression_list .size())));
27521 }
27522
27523 if (
27524 return_node_present ||
27525 side_effect_list.back() ||
27526 (expression_list.size() > 1)
27527 )
27528 state_.activate_side_effect("simplify()");
27529
27530 if (1 == expression_list.size())
27531 return expression_list[0];
27532 else if (specialise_on_final_type && is_generally_string_node(expression_list.back()))
27534 else
27536 }
27537
27538 inline expression_node_ptr parse_multi_sequence(const std::string& source = "",
27539 const bool enforce_crlbrackets = false)
27540 {
27544
27545 if (!token_is(open_bracket))
27546 {
27547 if (!enforce_crlbrackets && token_is(token_t::e_lbracket))
27548 {
27549 open_bracket = token_t::e_lbracket;
27550 close_bracket = token_t::e_rbracket;
27551 separator = token_t::e_comma;
27552 }
27553 else
27554 {
27555 set_error(make_error(
27557 current_token(),
27558 "ERR109 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" +
27559 ((!source.empty()) ? std::string(" section of " + source): ""),
27561
27562 return error_node();
27563 }
27564 }
27565 else if (token_is(close_bracket))
27566 {
27568 }
27569
27570 std::vector<expression_node_ptr> arg_list;
27571 std::vector<bool> side_effect_list;
27572
27574
27575 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
27576
27577 scope_handler sh(*this);
27578
27580
27581 for ( ; ; )
27582 {
27584
27586
27587 if (0 == arg)
27588 return error_node();
27589 else
27590 {
27591 arg_list.push_back(arg);
27592 side_effect_list.push_back(state_.side_effect_present);
27593 }
27594
27595 if (token_is(close_bracket))
27596 break;
27597
27598 const bool is_next_close = peek_token_is(close_bracket);
27599
27600 if (!token_is(separator) && is_next_close)
27601 {
27602 set_error(make_error(
27604 current_token(),
27605 "ERR110 - Expected '" + details::to_str(separator) + "' for call to multi-sequence section of " + source,
27607
27608 return error_node();
27609 }
27610
27611 if (token_is(close_bracket))
27612 break;
27613 }
27614
27615 result = simplify(arg_list, side_effect_list, source.empty());
27616
27617 sdd.delete_ptr = (0 == result);
27618 return result;
27619 }
27620
27621 inline bool parse_range(range_t& rp, const bool skip_lsqr = false)
27622 {
27623 // Examples of valid ranges:
27624 // 1. [1:5] -> [1,5)
27625 // 2. [ :5] -> [0,5)
27626 // 3. [1: ] -> [1,end)
27627 // 4. [x:y] -> [x,y) where x <= y
27628 // 5. [x+1:y/2] -> [x+1,y/2) where x+1 <= y/2
27629 // 6. [ :y] -> [0,y) where 0 <= y
27630 // 7. [x: ] -> [x,end) where x <= end
27631
27632 rp.clear();
27633
27634 if (!skip_lsqr && !token_is(token_t::e_lsqrbracket))
27635 {
27636 set_error(make_error(
27638 current_token(),
27639 "ERR111 - Expected '[' for start of range",
27641
27642 return false;
27643 }
27644
27646 {
27647 rp.n0_c.first = true;
27648 rp.n0_c.second = 0;
27649 rp.cache.first = 0;
27650 }
27651 else
27652 {
27654
27655 if (0 == r0)
27656 {
27657 set_error(make_error(
27659 current_token(),
27660 "ERR112 - Failed parse begin section of range",
27662
27663 return false;
27664 }
27665 else if (is_constant_node(r0))
27666 {
27667 const T r0_value = r0->value();
27668
27669 if (r0_value >= T(0))
27670 {
27671 rp.n0_c.first = true;
27672 rp.n0_c.second = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
27673 rp.cache.first = rp.n0_c.second;
27674 }
27675
27676 free_node(node_allocator_, r0);
27677
27678 if (r0_value < T(0))
27679 {
27680 set_error(make_error(
27682 current_token(),
27683 "ERR113 - Range lower bound less than zero! Constraint: r0 >= 0",
27685
27686 return false;
27687 }
27688 }
27689 else
27690 {
27691 rp.n0_e.first = true;
27692 rp.n0_e.second = r0;
27693 }
27694
27696 {
27697 set_error(make_error(
27699 current_token(),
27700 "ERR114 - Expected ':' for break in range",
27702
27703 rp.free();
27704
27705 return false;
27706 }
27707 }
27708
27710 {
27711 rp.n1_c.first = true;
27712 rp.n1_c.second = std::numeric_limits<std::size_t>::max();
27713 }
27714 else
27715 {
27717
27718 if (0 == r1)
27719 {
27720 set_error(make_error(
27722 current_token(),
27723 "ERR115 - Failed parse end section of range",
27725
27726 rp.free();
27727
27728 return false;
27729 }
27730 else if (is_constant_node(r1))
27731 {
27732 const T r1_value = r1->value();
27733
27734 if (r1_value >= T(0))
27735 {
27736 rp.n1_c.first = true;
27737 rp.n1_c.second = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
27738 rp.cache.second = rp.n1_c.second;
27739 }
27740
27741 free_node(node_allocator_, r1);
27742
27743 if (r1_value < T(0))
27744 {
27745 set_error(make_error(
27747 current_token(),
27748 "ERR116 - Range upper bound less than zero! Constraint: r1 >= 0",
27750
27751 rp.free();
27752
27753 return false;
27754 }
27755 }
27756 else
27757 {
27758 rp.n1_e.first = true;
27759 rp.n1_e.second = r1;
27760 }
27761
27763 {
27764 set_error(make_error(
27766 current_token(),
27767 "ERR117 - Expected ']' for start of range",
27769
27770 rp.free();
27771
27772 return false;
27773 }
27774 }
27775
27776 if (rp.const_range())
27777 {
27778 std::size_t r0 = 0;
27779 std::size_t r1 = 0;
27780
27781 bool rp_result = false;
27782
27783 try
27784 {
27785 rp_result = rp(r0, r1);
27786 }
27787 catch (std::runtime_error&)
27788 {}
27789
27790 if (!rp_result || (r0 > r1))
27791 {
27792 set_error(make_error(
27794 current_token(),
27795 "ERR118 - Invalid range, Constraint: r0 <= r1",
27797
27798 return false;
27799 }
27800 }
27801
27802 return true;
27803 }
27804
27805 inline void lodge_symbol(const std::string& symbol,
27806 const symbol_type st)
27807 {
27808 dec_.add_symbol(symbol,st);
27809 }
27810
27811 #ifndef exprtk_disable_string_capabilities
27813 {
27814 const std::string symbol = current_token().value;
27815
27816 typedef details::stringvar_node<T>* strvar_node_t;
27817
27819 strvar_node_t const_str_node = static_cast<strvar_node_t>(0);
27820
27822
27823 if (scope_element::e_string == se.type)
27824 {
27825 se.active = true;
27826 result = se.str_node;
27828 }
27829 else
27830 {
27831 typedef typename symtab_store::string_context str_ctxt_t;
27832 str_ctxt_t str_ctx = symtab_store_.get_string_context(symbol);
27833
27834 if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol))
27835 {
27836 set_error(make_error(
27838 current_token(),
27839 "ERR119 - Unknown string symbol",
27841
27842 return error_node();
27843 }
27844
27845 assert(str_ctx.str_var != 0);
27846 assert(str_ctx.symbol_table != 0);
27847
27848 result = str_ctx.str_var;
27849
27851 {
27852 const_str_node = static_cast<strvar_node_t>(result);
27853 result = expression_generator_(const_str_node->str());
27854 }
27855 else if (symbol_table_t::e_immutable == str_ctx.symbol_table->mutability())
27856 {
27858 current_token(),
27859 make_memory_range(str_ctx.str_var->base(), str_ctx.str_var->size()));
27860 }
27861
27862 lodge_symbol(symbol, e_st_string);
27863 }
27864
27866 {
27867 next_token();
27868
27870 {
27871 next_token();
27872 next_token();
27873
27874 if (const_str_node)
27875 {
27876 free_node(node_allocator_, result);
27877
27878 return expression_generator_(T(const_str_node->size()));
27879 }
27880 else
27882 (static_cast<details::stringvar_node<T>*>(result)->ref());
27883 }
27884
27885 range_t rp;
27886
27887 if (!parse_range(rp))
27888 {
27889 free_node(node_allocator_, result);
27890
27891 return error_node();
27892 }
27893 else if (const_str_node)
27894 {
27895 free_node(node_allocator_, result);
27896 result = expression_generator_(const_str_node->ref(),rp);
27897 }
27898 else
27900 (result)->ref(), rp);
27901
27902 if (result)
27903 rp.clear();
27904 }
27905 else
27906 next_token();
27907
27908 return result;
27909 }
27910 #else
27912 {
27913 return error_node();
27914 }
27915 #endif
27916
27917 #ifndef exprtk_disable_string_capabilities
27919 {
27920 const std::string const_str = current_token().value;
27921 expression_node_ptr result = expression_generator_(const_str);
27922
27924 {
27925 next_token();
27926
27928 {
27929 next_token();
27930 next_token();
27931
27932 free_node(node_allocator_, result);
27933
27934 return expression_generator_(T(const_str.size()));
27935 }
27936
27937 range_t rp;
27938
27939 if (!parse_range(rp))
27940 {
27941 free_node(node_allocator_, result);
27942 rp.free();
27943
27944 return error_node();
27945 }
27946
27947 free_node(node_allocator_, result);
27948
27949 if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits<std::size_t>::max()))
27950 {
27951 rp.n1_c.second = const_str.size() - 1;
27952 rp.cache.second = rp.n1_c.second;
27953 }
27954
27955 if (
27956 (rp.n0_c.first && (rp.n0_c.second >= const_str.size())) ||
27957 (rp.n1_c.first && (rp.n1_c.second >= const_str.size()))
27958 )
27959 {
27960 set_error(make_error(
27962 current_token(),
27963 "ERR120 - Overflow in range for string: '" + const_str + "'[" +
27964 (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" +
27965 (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]",
27967
27968 rp.free();
27969
27970 return error_node();
27971 }
27972
27973 result = expression_generator_(const_str,rp);
27974
27975 if (result)
27976 rp.clear();
27977 }
27978 else
27979 next_token();
27980
27981 return result;
27982 }
27983 #else
27985 {
27986 return error_node();
27987 }
27988 #endif
27989
27990 inline expression_node_ptr parse_vector_index(const std::string& vector_name = "")
27991 {
27992 expression_node_ptr index_expr = error_node();
27993
27994 if (0 == (index_expr = parse_expression()))
27995 {
27996 set_error(make_error(
27998 current_token(),
27999 "ERR121 - Failed to parse index for vector: '" + vector_name + "'",
28001
28002 return error_node();
28003 }
28005 {
28006 set_error(make_error(
28008 current_token(),
28009 "ERR122 - Expected ']' for index of vector: '" + vector_name + "'",
28011
28012 free_node(node_allocator_, index_expr);
28013
28014 return error_node();
28015 }
28016
28017 return index_expr;
28018 }
28019
28021 {
28022 const std::string vector_name = current_token().value;
28023
28025
28026 const scope_element& se = sem_.get_active_element(vector_name);
28027
28028 if (
28029 !details::imatch(se.name, vector_name) ||
28030 (se.depth > state_.scope_depth) ||
28032 )
28033 {
28034 typedef typename symtab_store::vector_context vec_ctxt_t;
28035 vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(vector_name);
28036
28037 if (0 == vec_ctx.vector_holder)
28038 {
28039 set_error(make_error(
28041 current_token(),
28042 "ERR123 - Symbol '" + vector_name + " not a vector",
28044
28045 return error_node();
28046 }
28047
28048 assert(0 != vec_ctx.vector_holder);
28049 assert(0 != vec_ctx.symbol_table );
28050
28051 vec = vec_ctx.vector_holder;
28052
28053 if (symbol_table_t::e_immutable == vec_ctx.symbol_table->mutability())
28054 {
28056 current_token(),
28057 make_memory_range(vec->data(), vec->size()));
28058 }
28059 }
28060 else
28061 {
28062 vec = se.vec_node;
28063 }
28064
28065 assert(0 != vec);
28066
28067 next_token();
28068
28070 {
28072 }
28074 {
28075 return (vec->rebaseable()) ?
28077 expression_generator_(T(vec->size()));
28078 }
28079
28080 expression_node_ptr index_expr = parse_vector_index(vector_name);
28081
28082 if (index_expr)
28083 {
28085
28086 return synthesize_vector_element(vector_name, vec, vec_node, index_expr);
28087 }
28088
28089 return error_node();
28090 }
28091
28092 inline expression_node_ptr synthesize_vector_element(const std::string& vector_name,
28094 expression_node_ptr vec_node,
28095 expression_node_ptr index_expr)
28096 {
28097 // Perform compile-time range check
28098 if (details::is_constant_node(index_expr))
28099 {
28100 const std::size_t index = static_cast<std::size_t>(details::numeric::to_int32(index_expr->value()));
28101 const std::size_t vec_size = vec->size();
28102
28103 if (index >= vec_size)
28104 {
28105 set_error(make_error(
28107 current_token(),
28108 "ERR124 - Index of " + details::to_str(index) + " out of range for "
28109 "vector '" + vector_name + "' of size " + details::to_str(vec_size),
28111
28112 free_node(node_allocator_, vec_node );
28113 free_node(node_allocator_, index_expr);
28114
28115 return error_node();
28116 }
28117 }
28118
28119 return expression_generator_.vector_element(vector_name, vec, vec_node, index_expr);
28120 }
28121
28122 inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name)
28123 {
28124 std::vector<expression_node_ptr> arg_list;
28125
28127
28128 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
28129
28130 next_token();
28131
28133 {
28135 {
28136 if (!vararg_function->allow_zero_parameters())
28137 {
28138 set_error(make_error(
28140 current_token(),
28141 "ERR125 - Zero parameter call to vararg function: "
28142 + vararg_function_name + " not allowed",
28144
28145 return error_node();
28146 }
28147 }
28148 else
28149 {
28150 for ( ; ; )
28151 {
28153
28154 if (0 == arg)
28155 return error_node();
28156 else
28157 arg_list.push_back(arg);
28158
28160 break;
28161 else if (!token_is(token_t::e_comma))
28162 {
28163 set_error(make_error(
28165 current_token(),
28166 "ERR126 - Expected ',' for call to vararg function: "
28167 + vararg_function_name,
28169
28170 return error_node();
28171 }
28172 }
28173 }
28174 }
28175 else if (!vararg_function->allow_zero_parameters())
28176 {
28177 set_error(make_error(
28179 current_token(),
28180 "ERR127 - Zero parameter call to vararg function: "
28181 + vararg_function_name + " not allowed",
28183
28184 return error_node();
28185 }
28186
28187 if (arg_list.size() < vararg_function->min_num_args())
28188 {
28189 set_error(make_error(
28191 current_token(),
28192 "ERR128 - Invalid number of parameters to call to vararg function: "
28193 + vararg_function_name + ", require at least "
28194 + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters",
28196
28197 return error_node();
28198 }
28199 else if (arg_list.size() > vararg_function->max_num_args())
28200 {
28201 set_error(make_error(
28203 current_token(),
28204 "ERR129 - Invalid number of parameters to call to vararg function: "
28205 + vararg_function_name + ", require no more than "
28206 + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters",
28208
28209 return error_node();
28210 }
28211
28212 result = expression_generator_.vararg_function_call(vararg_function,arg_list);
28213
28214 sdd.delete_ptr = (0 == result);
28215
28216 return result;
28217 }
28218
28220 {
28221 public:
28222
28224 {
28227 e_string = 'S'
28229
28231 {
28233 std::string param_seq;
28234 };
28235
28237 typedef std::vector<function_prototype_t> function_definition_list_t;
28238
28240 const std::string& func_name,
28241 const std::string& func_prototypes,
28242 const return_type_t default_return_type)
28243 : invalid_state_(true)
28244 , parser_(p)
28245 , function_name_(func_name)
28246 , default_return_type_(default_return_type)
28247 {
28248 parse_function_prototypes(func_prototypes);
28249 }
28250
28251 bool verify(const std::string& param_seq, std::size_t& pseq_index)
28252 {
28253 if (function_definition_list_.empty())
28254 return true;
28255
28256 std::vector<std::pair<std::size_t,char> > error_list;
28257
28258 for (std::size_t i = 0; i < function_definition_list_.size(); ++i)
28259 {
28260 details::char_t diff_value = 0;
28261 std::size_t diff_index = 0;
28262
28263 const bool result = details::sequence_match(function_definition_list_[i].param_seq,
28264 param_seq,
28265 diff_index, diff_value);
28266
28267 if (result)
28268 {
28269 pseq_index = i;
28270 return true;
28271 }
28272 else
28273 error_list.push_back(std::make_pair(diff_index, diff_value));
28274 }
28275
28276 if (1 == error_list.size())
28277 {
28278 parser_.set_error(make_error(
28281 "ERR130 - Failed parameter type check for function '" + function_name_ + "', "
28282 "Expected '" + function_definition_list_[0].param_seq +
28283 "' call set: '" + param_seq + "'",
28285 }
28286 else
28287 {
28288 // find first with largest diff_index;
28289 std::size_t max_diff_index = 0;
28290
28291 for (std::size_t i = 1; i < error_list.size(); ++i)
28292 {
28293 if (error_list[i].first > error_list[max_diff_index].first)
28294 {
28295 max_diff_index = i;
28296 }
28297 }
28298
28299 parser_.set_error(make_error(
28302 "ERR131 - Failed parameter type check for function '" + function_name_ + "', "
28303 "Best match: '" + function_definition_list_[max_diff_index].param_seq +
28304 "' call set: '" + param_seq + "'",
28306 }
28307
28308 return false;
28309 }
28310
28311 std::size_t paramseq_count() const
28312 {
28313 return function_definition_list_.size();
28314 }
28315
28316 std::string paramseq(const std::size_t& index) const
28317 {
28318 return function_definition_list_[index].param_seq;
28319 }
28320
28321 return_type_t return_type(const std::size_t& index) const
28322 {
28323 return function_definition_list_[index].return_type;
28324 }
28325
28326 bool invalid() const
28327 {
28328 return !invalid_state_;
28329 }
28330
28332 {
28333
28334 for (std::size_t i = 0; i < function_definition_list_.size(); ++i)
28335 {
28336 if (std::string::npos != function_definition_list_[i].param_seq.find("Z"))
28337 {
28338 return true;
28339 }
28340 }
28341
28342 return false;
28343 }
28344
28345 private:
28346
28347 std::vector<std::string> split_param_seq(const std::string& param_seq, const details::char_t delimiter = '|') const
28348 {
28349 std::string::const_iterator current_begin = param_seq.begin();
28350 std::string::const_iterator iter = param_seq.begin();
28351
28352 std::vector<std::string> result;
28353
28354 while (iter != param_seq.end())
28355 {
28356 if (*iter == delimiter)
28357 {
28358 result.push_back(std::string(current_begin, iter));
28359 current_begin = ++iter;
28360 }
28361 else
28362 ++iter;
28363 }
28364
28365 if (current_begin != iter)
28366 {
28367 result.push_back(std::string(current_begin, iter));
28368 }
28369
28370 return result;
28371 }
28372
28373 inline bool is_valid_token(std::string param_seq,
28374 function_prototype_t& funcproto) const
28375 {
28376 // Determine return type
28378
28379 if (param_seq.size() > 2)
28380 {
28381 if (':' == param_seq[1])
28382 {
28383 // Note: Only overloaded igeneric functions can have return
28384 // type definitions.
28386 return false;
28387
28388 switch (param_seq[0])
28389 {
28390 case 'T' : funcproto.return_type = type_checker::e_numeric;
28391 break;
28392
28393 case 'S' : funcproto.return_type = type_checker::e_string;
28394 break;
28395
28396 default : return false;
28397 }
28398
28399 param_seq.erase(0,2);
28400 }
28401 }
28402
28403 if (
28404 (std::string::npos != param_seq.find("?*")) ||
28405 (std::string::npos != param_seq.find("**"))
28406 )
28407 {
28408 return false;
28409 }
28410 else if (
28411 (std::string::npos == param_seq.find_first_not_of("STV*?|")) ||
28412 ("Z" == param_seq)
28413 )
28414 {
28415 funcproto.param_seq = param_seq;
28416 return true;
28417 }
28418
28419 return false;
28420 }
28421
28422 void parse_function_prototypes(const std::string& func_prototypes)
28423 {
28424 if (func_prototypes.empty())
28425 return;
28426
28427 std::vector<std::string> param_seq_list = split_param_seq(func_prototypes);
28428
28429 typedef std::map<std::string,std::size_t> param_seq_map_t;
28430 param_seq_map_t param_seq_map;
28431
28432 for (std::size_t i = 0; i < param_seq_list.size(); ++i)
28433 {
28434 function_prototype_t func_proto;
28435
28436 if (!is_valid_token(param_seq_list[i], func_proto))
28437 {
28438 invalid_state_ = false;
28439
28440 parser_.set_error(make_error(
28443 "ERR132 - Invalid parameter sequence of '" + param_seq_list[i] +
28444 "' for function: " + function_name_,
28446 return;
28447 }
28448
28449 param_seq_map_t::const_iterator seq_itr = param_seq_map.find(param_seq_list[i]);
28450
28451 if (param_seq_map.end() != seq_itr)
28452 {
28453 invalid_state_ = false;
28454
28455 parser_.set_error(make_error(
28458 "ERR133 - Function '" + function_name_ + "' has a parameter sequence conflict between " +
28459 "pseq_idx[" + details::to_str(seq_itr->second) + "] and" +
28460 "pseq_idx[" + details::to_str(i) + "] " +
28461 "param seq: " + param_seq_list[i],
28463 return;
28464 }
28465
28466 function_definition_list_.push_back(func_proto);
28467 }
28468 }
28469
28472
28475 std::string function_name_;
28478 };
28479
28480 inline expression_node_ptr parse_generic_function_call(igeneric_function<T>* function, const std::string& function_name)
28481 {
28482 std::vector<expression_node_ptr> arg_list;
28483
28484 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
28485
28486 next_token();
28487
28488 std::string param_type_list;
28489
28490 type_checker tc(
28491 (*this),
28492 function_name,
28493 function->parameter_sequence,
28495
28496 if (tc.invalid())
28497 {
28498 set_error(make_error(
28500 current_token(),
28501 "ERR134 - Type checker instantiation failure for generic function: " + function_name,
28503
28504 return error_node();
28505 }
28506
28508 {
28510 {
28511 if (
28512 !function->allow_zero_parameters() &&
28514 )
28515 {
28516 set_error(make_error(
28518 current_token(),
28519 "ERR135 - Zero parameter call to generic function: "
28520 + function_name + " not allowed",
28522
28523 return error_node();
28524 }
28525 }
28526 else
28527 {
28528 for ( ; ; )
28529 {
28531
28532 if (0 == arg)
28533 return error_node();
28534
28535 if (is_ivector_node(arg))
28536 param_type_list += 'V';
28537 else if (is_generally_string_node(arg))
28538 param_type_list += 'S';
28539 else // Everything else is assumed to be a scalar returning expression
28540 param_type_list += 'T';
28541
28542 arg_list.push_back(arg);
28543
28545 break;
28546 else if (!token_is(token_t::e_comma))
28547 {
28548 set_error(make_error(
28550 current_token(),
28551 "ERR136 - Expected ',' for call to generic function: " + function_name,
28553
28554 return error_node();
28555 }
28556 }
28557 }
28558 }
28559 else if (
28560 !function->parameter_sequence.empty() &&
28561 function->allow_zero_parameters () &&
28562 !tc .allow_zero_parameters ()
28563 )
28564 {
28565 set_error(make_error(
28567 current_token(),
28568 "ERR137 - Zero parameter call to generic function: "
28569 + function_name + " not allowed",
28571
28572 return error_node();
28573 }
28574
28575 std::size_t param_seq_index = 0;
28576
28577 if (
28579 !tc.verify(param_type_list, param_seq_index)
28580 )
28581 {
28582 set_error(make_error(
28584 current_token(),
28585 "ERR138 - Invalid input parameter sequence for call to generic function: " + function_name,
28587
28588 return error_node();
28589 }
28590
28592
28593 result = (tc.paramseq_count() <= 1) ?
28595 .generic_function_call(function, arg_list) :
28597 .generic_function_call(function, arg_list, param_seq_index);
28598
28599 sdd.delete_ptr = (0 == result);
28600
28601 return result;
28602 }
28603
28604 inline bool parse_igeneric_function_params(std::string& param_type_list,
28605 std::vector<expression_node_ptr>& arg_list,
28606 const std::string& function_name,
28607 igeneric_function<T>* function,
28608 const type_checker& tc)
28609 {
28611 {
28613 {
28614 if (
28615 !function->allow_zero_parameters() &&
28617 )
28618 {
28619 set_error(make_error(
28621 current_token(),
28622 "ERR139 - Zero parameter call to generic function: "
28623 + function_name + " not allowed",
28625
28626 return false;
28627 }
28628 }
28629 else
28630 {
28631 for ( ; ; )
28632 {
28634
28635 if (0 == arg)
28636 return false;
28637
28638 if (is_ivector_node(arg))
28639 param_type_list += 'V';
28640 else if (is_generally_string_node(arg))
28641 param_type_list += 'S';
28642 else // Everything else is a scalar returning expression
28643 param_type_list += 'T';
28644
28645 arg_list.push_back(arg);
28646
28648 break;
28649 else if (!token_is(token_t::e_comma))
28650 {
28651 set_error(make_error(
28653 current_token(),
28654 "ERR140 - Expected ',' for call to string function: " + function_name,
28656
28657 return false;
28658 }
28659 }
28660 }
28661
28662 return true;
28663 }
28664 else
28665 return false;
28666 }
28667
28668 #ifndef exprtk_disable_string_capabilities
28669 inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name)
28670 {
28671 // Move pass the function name
28672 next_token();
28673
28674 std::string param_type_list;
28675
28676 type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string);
28677
28678 if (
28679 (!function->parameter_sequence.empty()) &&
28680 (0 == tc.paramseq_count())
28681 )
28682 {
28683 return error_node();
28684 }
28685
28686 std::vector<expression_node_ptr> arg_list;
28687 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
28688
28689 if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc))
28690 {
28691 return error_node();
28692 }
28693
28694 std::size_t param_seq_index = 0;
28695
28696 if (!tc.verify(param_type_list, param_seq_index))
28697 {
28698 set_error(make_error(
28700 current_token(),
28701 "ERR141 - Invalid input parameter sequence for call to string function: " + function_name,
28703
28704 return error_node();
28705 }
28706
28708
28709 result = (tc.paramseq_count() <= 1) ?
28711 .string_function_call(function, arg_list) :
28713 .string_function_call(function, arg_list, param_seq_index);
28714
28715 sdd.delete_ptr = (0 == result);
28716
28717 return result;
28718 }
28719
28720 inline expression_node_ptr parse_overload_function_call(igeneric_function<T>* function, const std::string& function_name)
28721 {
28722 // Move pass the function name
28723 next_token();
28724
28725 std::string param_type_list;
28726
28727 type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_overload);
28728
28729 if (
28730 (!function->parameter_sequence.empty()) &&
28731 (0 == tc.paramseq_count())
28732 )
28733 {
28734 return error_node();
28735 }
28736
28737 std::vector<expression_node_ptr> arg_list;
28738 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
28739
28740 if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc))
28741 {
28742 return error_node();
28743 }
28744
28745 std::size_t param_seq_index = 0;
28746
28747 if (!tc.verify(param_type_list, param_seq_index))
28748 {
28749 set_error(make_error(
28751 current_token(),
28752 "ERR142 - Invalid input parameter sequence for call to overloaded function: " + function_name,
28754
28755 return error_node();
28756 }
28757
28759
28760 if (type_checker::e_numeric == tc.return_type(param_seq_index))
28761 {
28762 if (tc.paramseq_count() <= 1)
28763 result = expression_generator_
28764 .generic_function_call(function, arg_list);
28765 else
28766 result = expression_generator_
28767 .generic_function_call(function, arg_list, param_seq_index);
28768 }
28769 else if (type_checker::e_string == tc.return_type(param_seq_index))
28770 {
28771 if (tc.paramseq_count() <= 1)
28772 result = expression_generator_
28773 .string_function_call(function, arg_list);
28774 else
28775 result = expression_generator_
28776 .string_function_call(function, arg_list, param_seq_index);
28777 }
28778 else
28779 {
28780 set_error(make_error(
28782 current_token(),
28783 "ERR143 - Invalid return type for call to overloaded function: " + function_name,
28785 }
28786
28787 sdd.delete_ptr = (0 == result);
28788 return result;
28789 }
28790 #endif
28791
28792 template <typename Type, std::size_t NumberOfParameters>
28794 {
28795 static inline expression_node_ptr process(parser<Type>& p, const details::operator_type opt_type, const std::string& sf_name)
28796 {
28797 expression_node_ptr branch[NumberOfParameters];
28799
28800 std::fill_n(branch, NumberOfParameters, reinterpret_cast<expression_node_ptr>(0));
28801
28803
28804 p.next_token();
28805
28807 {
28808 p.set_error(make_error(
28810 p.current_token(),
28811 "ERR144 - Expected '(' for special function '" + sf_name + "'",
28813
28814 return error_node();
28815 }
28816
28817 for (std::size_t i = 0; i < NumberOfParameters; ++i)
28818 {
28819 branch[i] = p.parse_expression();
28820
28821 if (0 == branch[i])
28822 {
28823 return p.error_node();
28824 }
28825 else if (i < (NumberOfParameters - 1))
28826 {
28827 if (!p.token_is(token_t::e_comma))
28828 {
28829 p.set_error(make_error(
28831 p.current_token(),
28832 "ERR145 - Expected ',' before next parameter of special function '" + sf_name + "'",
28834
28835 return p.error_node();
28836 }
28837 }
28838 }
28839
28841 {
28842 p.set_error(make_error(
28844 p.current_token(),
28845 "ERR146 - Invalid number of parameters for special function '" + sf_name + "'",
28847
28848 return p.error_node();
28849 }
28850 else
28851 result = p.expression_generator_.special_function(opt_type,branch);
28852
28853 sd.delete_ptr = (0 == result);
28854
28855 return result;
28856 }
28857 };
28858
28860 {
28861 const std::string sf_name = current_token().value;
28862
28863 // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
28864 if (
28865 !details::is_digit(sf_name[2]) ||
28866 !details::is_digit(sf_name[3])
28867 )
28868 {
28869 set_error(make_error(
28871 current_token(),
28872 "ERR147 - Invalid special function[1]: " + sf_name,
28874
28875 return error_node();
28876 }
28877
28878 const int id = (sf_name[2] - '0') * 10 +
28879 (sf_name[3] - '0');
28880
28881 if (id >= details::e_sffinal)
28882 {
28883 set_error(make_error(
28885 current_token(),
28886 "ERR148 - Invalid special function[2]: " + sf_name,
28888
28889 return error_node();
28890 }
28891
28892 const int sf_3_to_4 = details::e_sf48;
28893 const details::operator_type opt_type = details::operator_type(id + 1000);
28894 const std::size_t NumberOfParameters = (id < (sf_3_to_4 - 1000)) ? 3U : 4U;
28895
28896 switch (NumberOfParameters)
28897 {
28898 case 3 : return parse_special_function_impl<T,3>::process((*this), opt_type, sf_name);
28899 case 4 : return parse_special_function_impl<T,4>::process((*this), opt_type, sf_name);
28900 default : return error_node();
28901 }
28902 }
28903
28909
28910 #ifndef exprtk_disable_break_continue
28912 {
28914 {
28915 set_error(make_error(
28917 current_token(),
28918 "ERR149 - Invoking 'break' within a break call is not allowed",
28920
28921 return error_node();
28922 }
28923 else if (0 == state_.parsing_loop_stmt_count)
28924 {
28925 set_error(make_error(
28927 current_token(),
28928 "ERR150 - Invalid use of 'break', allowed only in the scope of a loop",
28930
28931 return error_node();
28932 }
28933
28935
28936 if (!brkcnt_list_.empty())
28937 {
28938 next_token();
28939
28940 brkcnt_list_.front() = true;
28941
28942 expression_node_ptr return_expr = error_node();
28943
28945 {
28946 if (0 == (return_expr = parse_expression()))
28947 {
28948 set_error(make_error(
28950 current_token(),
28951 "ERR151 - Failed to parse return expression for 'break' statement",
28953
28954 return error_node();
28955 }
28957 {
28958 set_error(make_error(
28960 current_token(),
28961 "ERR152 - Expected ']' at the completion of break's return expression",
28963
28964 free_node(node_allocator_, return_expr);
28965
28966 return error_node();
28967 }
28968 }
28969
28970 state_.activate_side_effect("parse_break_statement()");
28971
28972 return node_allocator_.allocate<details::break_node<T> >(return_expr);
28973 }
28974 else
28975 {
28976 set_error(make_error(
28978 current_token(),
28979 "ERR153 - Invalid use of 'break', allowed only in the scope of a loop",
28981 }
28982
28983 return error_node();
28984 }
28985
28987 {
28989 {
28990 set_error(make_error(
28992 current_token(),
28993 "ERR154 - Invalid use of 'continue', allowed only in the scope of a loop",
28995
28996 return error_node();
28997 }
28998 else
28999 {
29000 next_token();
29001
29002 brkcnt_list_.front() = true;
29003 state_.activate_side_effect("parse_continue_statement()");
29004
29006 }
29007 }
29008 #endif
29009
29010 inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name)
29011 {
29012 expression_node_ptr size_expression_node = error_node();
29013
29015 {
29016 set_error(make_error(
29018 current_token(),
29019 "ERR155 - Expected '[' as part of vector size definition",
29021
29022 return error_node();
29023 }
29024 else if (0 == (size_expression_node = parse_expression()))
29025 {
29026 set_error(make_error(
29028 current_token(),
29029 "ERR156 - Failed to determine size of vector '" + vec_name + "'",
29031
29032 return error_node();
29033 }
29034 else if (!is_constant_node(size_expression_node))
29035 {
29036 const bool is_rebaseble_vector =
29037 (size_expression_node->type() == details::expression_node<T>::e_vecsize) &&
29038 static_cast<details::vector_size_node<T>*>(size_expression_node)->vec_holder()->rebaseable();
29039
29040 free_node(node_allocator_, size_expression_node);
29041
29042 const std::string error_msg = (is_rebaseble_vector) ?
29043 std::string("Rebasable/Resizable vector cannot be used to define the size of vector") :
29044 std::string("Expected a constant literal number as size of vector");
29045 set_error(make_error(
29047 current_token(),
29048 "ERR157 - " + error_msg + " '" + vec_name + "'",
29050
29051 return error_node();
29052 }
29053
29054 const T vector_size = size_expression_node->value();
29055
29056 free_node(node_allocator_, size_expression_node);
29057
29058 const std::size_t max_vector_size = settings_.max_local_vector_size();
29059
29060 if (
29061 (vector_size <= T(0)) ||
29062 std::not_equal_to<T>()
29063 (T(0),vector_size - details::numeric::trunc(vector_size)) ||
29064 (static_cast<std::size_t>(vector_size) > max_vector_size)
29065 )
29066 {
29067 set_error(make_error(
29069 current_token(),
29070 "ERR158 - Invalid vector size. Must be an integer in the "
29071 "range [0," + details::to_str(static_cast<std::size_t>(max_vector_size)) + "], size: " +
29074
29075 return error_node();
29076 }
29077
29079
29080 const std::size_t vec_size = static_cast<std::size_t>(details::numeric::to_int32(vector_size));
29081
29082 scope_element& se = sem_.get_element(vec_name);
29083
29084 if (se.name == vec_name)
29085 {
29086 if (se.active)
29087 {
29088 set_error(make_error(
29090 current_token(),
29091 "ERR159 - Illegal redefinition of local vector: '" + vec_name + "'",
29093
29094 return error_node();
29095 }
29096 else if (
29097 (se.size == vec_size) &&
29099 )
29100 {
29101 vec_holder = se.vec_node;
29102 se.active = true;
29104 se.ref_count++;
29105 }
29106 }
29107
29108 if (0 == vec_holder)
29109 {
29110 scope_element nse;
29111 nse.name = vec_name;
29112 nse.active = true;
29113 nse.ref_count = 1;
29115 nse.depth = state_.scope_depth;
29116 nse.size = vec_size;
29117 nse.data = new T[vec_size];
29118 nse.vec_node = new typename scope_element::vector_holder_t(reinterpret_cast<T*>(nse.data),nse.size);
29119
29120 details::set_zero_value(reinterpret_cast<T*>(nse.data),vec_size);
29121
29122 if (!sem_.add_element(nse))
29123 {
29124 set_error(make_error(
29126 current_token(),
29127 "ERR160 - Failed to add new local vector '" + vec_name + "' to SEM",
29129
29130 sem_.free_element(nse);
29131
29132 return error_node();
29133 }
29134
29135 vec_holder = nse.vec_node;
29136
29137 exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n",
29138 nse.name.c_str(),
29139 static_cast<int>(nse.size)));
29140 }
29141
29142 state_.activate_side_effect("parse_define_vector_statement()");
29143
29145
29146 std::vector<expression_node_ptr> vec_initilizer_list;
29147
29148 scoped_vec_delete<expression_node_t> svd((*this),vec_initilizer_list);
29149
29150 bool single_value_initialiser = false;
29151 bool range_value_initialiser = false;
29152 bool vec_to_vec_initialiser = false;
29153 bool null_initialisation = false;
29154
29156 {
29157 set_error(make_error(
29159 current_token(),
29160 "ERR161 - Expected ']' as part of vector size definition",
29162
29163 return error_node();
29164 }
29165 else if (!token_is(token_t::e_eof))
29166 {
29168 {
29169 set_error(make_error(
29171 current_token(),
29172 "ERR162 - Expected ':=' as part of vector definition",
29174
29175 return error_node();
29176 }
29178 {
29179 expression_node_ptr initialiser_component = parse_expression();
29180
29181 if (0 == initialiser_component)
29182 {
29183 set_error(make_error(
29185 current_token(),
29186 "ERR163 - Failed to parse first component of vector initialiser for vector: " + vec_name,
29188
29189 return error_node();
29190 }
29191
29192 vec_initilizer_list.push_back(initialiser_component);
29193
29195 {
29196 initialiser_component = parse_expression();
29197
29198 if (0 == initialiser_component)
29199 {
29200 set_error(make_error(
29202 current_token(),
29203 "ERR164 - Failed to parse second component of vector initialiser for vector: " + vec_name,
29205
29206 return error_node();
29207 }
29208
29209 vec_initilizer_list.push_back(initialiser_component);
29210 }
29211
29213 {
29214 set_error(make_error(
29216 current_token(),
29217 "ERR165 - Expected ']' to close single value vector initialiser",
29219
29220 return error_node();
29221 }
29222
29223 switch (vec_initilizer_list.size())
29224 {
29225 case 1 : single_value_initialiser = true; break;
29226 case 2 : range_value_initialiser = true; break;
29227 }
29228 }
29230 {
29231 expression_node_ptr initialiser = error_node();
29232
29233 // Is this a vector to vector assignment and initialisation?
29234 if (token_t::e_symbol == current_token().type)
29235 {
29236 // Is it a locally defined vector?
29237 const scope_element& lcl_se = sem_.get_active_element(current_token().value);
29238
29239 if (scope_element::e_vector == lcl_se.type)
29240 {
29241 if (0 != (initialiser = parse_expression()))
29242 vec_initilizer_list.push_back(initialiser);
29243 else
29244 return error_node();
29245 }
29246 // Are we dealing with a user defined vector?
29247 else if (symtab_store_.is_vector(current_token().value))
29248 {
29250
29251 if (0 != (initialiser = parse_expression()))
29252 vec_initilizer_list.push_back(initialiser);
29253 else
29254 return error_node();
29255 }
29256 // Are we dealing with a null initialisation vector definition?
29257 else if (token_is(token_t::e_symbol,"null"))
29258 null_initialisation = true;
29259 }
29260
29261 if (!null_initialisation)
29262 {
29263 if (0 == initialiser)
29264 {
29265 set_error(make_error(
29267 current_token(),
29268 "ERR166 - Expected '{' as part of vector initialiser list",
29270
29271 return error_node();
29272 }
29273 else
29274 vec_to_vec_initialiser = true;
29275 }
29276 }
29278 {
29279 for ( ; ; )
29280 {
29281 expression_node_ptr initialiser = parse_expression();
29282
29283 if (0 == initialiser)
29284 {
29285 set_error(make_error(
29287 current_token(),
29288 "ERR167 - Expected '{' as part of vector initialiser list",
29290
29291 return error_node();
29292 }
29293 else
29294 vec_initilizer_list.push_back(initialiser);
29295
29297 break;
29298
29299 const bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
29300
29301 if (!token_is(token_t::e_comma) && is_next_close)
29302 {
29303 set_error(make_error(
29305 current_token(),
29306 "ERR168 - Expected ',' between vector initialisers",
29308
29309 return error_node();
29310 }
29311
29313 break;
29314 }
29315 }
29316
29317 if (
29318 !token_is(token_t::e_rbracket , prsrhlpr_t::e_hold) &&
29319 !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) &&
29320 !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold)
29321 )
29322 {
29324 {
29325 set_error(make_error(
29327 current_token(),
29328 "ERR169 - Expected ';' at end of vector definition",
29330
29331 return error_node();
29332 }
29333 }
29334
29335 if (
29336 !single_value_initialiser &&
29337 !range_value_initialiser &&
29338 (T(vec_initilizer_list.size()) > vector_size)
29339 )
29340 {
29341 set_error(make_error(
29343 current_token(),
29344 "ERR170 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
29346
29347 return error_node();
29348 }
29349 }
29350
29352
29353 if (
29354 (vec_initilizer_list.size() == 1) &&
29355 single_value_initialiser
29356 )
29357 {
29358 if (details::is_constant_node(vec_initilizer_list[0]))
29359 {
29360 // vector_init_zero_value_node var v[10] := [0]
29361 if (T(0) == vec_initilizer_list[0]->value())
29362 {
29363 result = node_allocator_
29365 (*vec_holder)[0],
29366 vec_size,
29367 vec_initilizer_list);
29368 }
29369 else
29370 {
29371 // vector_init_single_constvalue_node var v[10] := [123]
29372 result = node_allocator_
29374 (*vec_holder)[0],
29375 vec_size,
29376 vec_initilizer_list);
29377 }
29378 }
29379 else
29380 {
29381 // vector_init_single_value_node var v[10] := [123 + (x / y)]
29382 result = node_allocator_
29384 (*vec_holder)[0],
29385 vec_size,
29386 vec_initilizer_list);
29387 }
29388 }
29389 else if (
29390 (vec_initilizer_list.size() == 2) &&
29391 range_value_initialiser
29392 )
29393 {
29394 bool base_const = details::is_constant_node(vec_initilizer_list[0]);
29395 bool inc_const = details::is_constant_node(vec_initilizer_list[1]);
29396
29397 if (base_const && inc_const)
29398 {
29399 // vector_init_single_value_node var v[10] := [1 : 3.5]
29400 result = node_allocator_
29402 (*vec_holder)[0],
29403 vec_size,
29404 vec_initilizer_list);
29405 }
29406 else if (base_const && !inc_const)
29407 {
29408 // vector_init_single_value_node var v[10] := [1 : x + y]
29409 result = node_allocator_
29411 (*vec_holder)[0],
29412 vec_size,
29413 vec_initilizer_list);
29414 }
29415 else if (!base_const && inc_const)
29416 {
29417 // vector_init_single_value_node var v[10] := [x + y : 3]
29418 result = node_allocator_
29420 (*vec_holder)[0],
29421 vec_size,
29422 vec_initilizer_list);
29423 }
29424 else if (!base_const && !inc_const)
29425 {
29426 // vector_init_single_value_node var v[10] := [x + y : z / w]
29427 result = node_allocator_
29429 (*vec_holder)[0],
29430 vec_size,
29431 vec_initilizer_list);
29432 }
29433 }
29434 else if (null_initialisation)
29435 result = expression_generator_(T(0.0));
29436 else if (vec_to_vec_initialiser)
29437 {
29439
29440 result = expression_generator_(
29442 vec_node,
29443 vec_initilizer_list[0]);
29444 }
29445 else
29446 {
29447 result = node_allocator_
29449 (*vec_holder)[0],
29450 vec_size,
29451 vec_initilizer_list,
29452 single_value_initialiser);
29453 }
29454
29455 svd.delete_ptr = false;
29456
29457 if (result && result->valid())
29458 {
29459 return result;
29460 }
29461
29463
29464 set_error(make_error(
29466 current_token(),
29467 "ERR171 - Failed to generate initialisation node for vector: " + vec_name,
29469
29470 return error_node();
29471 }
29472
29473 #ifndef exprtk_disable_string_capabilities
29474 inline expression_node_ptr parse_define_string_statement(const std::string& str_name, expression_node_ptr initialisation_expression)
29475 {
29476 stringvar_node_t* str_node = reinterpret_cast<stringvar_node_t*>(0);
29477
29478 scope_element& se = sem_.get_element(str_name);
29479
29480 if (se.name == str_name)
29481 {
29482 if (se.active)
29483 {
29484 set_error(make_error(
29486 current_token(),
29487 "ERR172 - Illegal redefinition of local variable: '" + str_name + "'",
29489
29490 free_node(node_allocator_, initialisation_expression);
29491
29492 return error_node();
29493 }
29494 else if (scope_element::e_string == se.type)
29495 {
29496 str_node = se.str_node;
29497 se.active = true;
29499 se.ref_count++;
29500 }
29501 }
29502
29503 if (0 == str_node)
29504 {
29505 scope_element nse;
29506 nse.name = str_name;
29507 nse.active = true;
29508 nse.ref_count = 1;
29510 nse.depth = state_.scope_depth;
29511 nse.data = new std::string;
29512 nse.str_node = new stringvar_node_t(*reinterpret_cast<std::string*>(nse.data));
29513
29514 if (!sem_.add_element(nse))
29515 {
29516 set_error(make_error(
29518 current_token(),
29519 "ERR173 - Failed to add new local string variable '" + str_name + "' to SEM",
29521
29522 free_node(node_allocator_, initialisation_expression);
29523
29524 sem_.free_element(nse);
29525
29526 return error_node();
29527 }
29528
29529 str_node = nse.str_node;
29530
29531 exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n", nse.name.c_str()));
29532 }
29533
29535
29536 state_.activate_side_effect("parse_define_string_statement()");
29537
29538 expression_node_ptr branch[2] = {0};
29539
29540 branch[0] = str_node;
29541 branch[1] = initialisation_expression;
29542
29544 }
29545 #else
29547 {
29548 return error_node();
29549 }
29550 #endif
29551
29552 inline bool local_variable_is_shadowed(const std::string& symbol)
29553 {
29554 const scope_element& se = sem_.get_element(symbol);
29555 return (se.name == symbol) && se.active;
29556 }
29557
29559 {
29561 {
29562 set_error(make_error(
29564 current_token(),
29565 "ERR174 - Illegal variable definition",
29567
29568 return error_node();
29569 }
29570 else if (!details::imatch(current_token().value,"var"))
29571 {
29572 return error_node();
29573 }
29574 else
29575 next_token();
29576
29577 const std::string var_name = current_token().value;
29578
29579 expression_node_ptr initialisation_expression = error_node();
29580
29582 {
29583 set_error(make_error(
29585 current_token(),
29586 "ERR175 - Expected a symbol for variable definition",
29588
29589 return error_node();
29590 }
29591 else if (details::is_reserved_symbol(var_name))
29592 {
29593 set_error(make_error(
29595 current_token(),
29596 "ERR176 - Illegal redefinition of reserved keyword: '" + var_name + "'",
29598
29599 return error_node();
29600 }
29601 else if (symtab_store_.symbol_exists(var_name))
29602 {
29603 set_error(make_error(
29605 current_token(),
29606 "ERR177 - Illegal redefinition of variable '" + var_name + "'",
29608
29609 return error_node();
29610 }
29611 else if (local_variable_is_shadowed(var_name))
29612 {
29613 set_error(make_error(
29615 current_token(),
29616 "ERR178 - Illegal redefinition of local variable: '" + var_name + "'",
29618
29619 return error_node();
29620 }
29621 else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold))
29622 {
29623 return parse_define_vector_statement(var_name);
29624 }
29625 else if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
29626 {
29627 return parse_uninitialised_var_statement(var_name);
29628 }
29629 else if (token_is(token_t::e_assign))
29630 {
29631 if (0 == (initialisation_expression = parse_expression()))
29632 {
29633 set_error(make_error(
29635 current_token(),
29636 "ERR179 - Failed to parse initialisation expression",
29638
29639 return error_node();
29640 }
29641 }
29642
29643 if (
29644 !token_is(token_t::e_rbracket , prsrhlpr_t::e_hold) &&
29645 !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) &&
29646 !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold)
29647 )
29648 {
29649 if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
29650 {
29651 set_error(make_error(
29653 current_token(),
29654 "ERR180 - Expected ';' after variable definition",
29656
29657 free_node(node_allocator_, initialisation_expression);
29658
29659 return error_node();
29660 }
29661 }
29662
29663 if (
29664 (0 != initialisation_expression) &&
29665 details::is_generally_string_node(initialisation_expression)
29666 )
29667 {
29668 return parse_define_string_statement(var_name,initialisation_expression);
29669 }
29670
29671 expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
29672
29673 scope_element& se = sem_.get_element(var_name);
29674
29675 if (se.name == var_name)
29676 {
29677 if (se.active)
29678 {
29679 set_error(make_error(
29681 current_token(),
29682 "ERR181 - Illegal redefinition of local variable: '" + var_name + "'",
29684
29685 free_node(node_allocator_, initialisation_expression);
29686
29687 return error_node();
29688 }
29689 else if (scope_element::e_variable == se.type)
29690 {
29691 var_node = se.var_node;
29692 se.active = true;
29694 se.ref_count++;
29695 }
29696 }
29697
29698 if (0 == var_node)
29699 {
29700 scope_element nse;
29701 nse.name = var_name;
29702 nse.active = true;
29703 nse.ref_count = 1;
29705 nse.depth = state_.scope_depth;
29706 nse.data = new T(T(0));
29707 nse.var_node = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data));
29708
29709 if (!sem_.add_element(nse))
29710 {
29711 set_error(make_error(
29713 current_token(),
29714 "ERR182 - Failed to add new local variable '" + var_name + "' to SEM",
29716
29717 free_node(node_allocator_, initialisation_expression);
29718
29719 sem_.free_element(nse);
29720
29721 return error_node();
29722 }
29723
29724 var_node = nse.var_node;
29725
29726 exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n", nse.name.c_str()));
29727 }
29728
29729 state_.activate_side_effect("parse_define_var_statement()");
29730
29732
29733 expression_node_ptr branch[2] = {0};
29734
29735 branch[0] = var_node;
29736 branch[1] = initialisation_expression ? initialisation_expression : expression_generator_(T(0));
29737
29739 }
29740
29742 {
29744 {
29745 set_error(make_error(
29747 current_token(),
29748 "ERR183 - Illegal const variable definition",
29750
29751 return error_node();
29752 }
29753 else if (!token_is("const"))
29754 {
29755 set_error(make_error(
29757 current_token(),
29758 "ERR184 - Expected 'const' keyword for const-variable definition",
29760
29761 return error_node();
29762 }
29763 else if (!token_is("var"))
29764 {
29765 set_error(make_error(
29767 current_token(),
29768 "ERR185 - Expected 'var' keyword for const-variable definition",
29770
29771 return error_node();
29772 }
29773
29774 const std::string var_name = current_token().value;
29775
29776 expression_node_ptr initialisation_expression = error_node();
29777
29779 {
29780 set_error(make_error(
29782 current_token(),
29783 "ERR186 - Expected a symbol for const-variable definition",
29785
29786 return error_node();
29787 }
29788 else if (details::is_reserved_symbol(var_name))
29789 {
29790 set_error(make_error(
29792 current_token(),
29793 "ERR187 - Illegal redefinition of reserved keyword: '" + var_name + "'",
29795
29796 return error_node();
29797 }
29798 else if (symtab_store_.symbol_exists(var_name))
29799 {
29800 set_error(make_error(
29802 current_token(),
29803 "ERR188 - Illegal redefinition of variable '" + var_name + "'",
29805
29806 return error_node();
29807 }
29808 else if (local_variable_is_shadowed(var_name))
29809 {
29810 set_error(make_error(
29812 current_token(),
29813 "ERR189 - Illegal redefinition of local variable: '" + var_name + "'",
29815
29816 return error_node();
29817 }
29818 else if (token_is(token_t::e_assign))
29819 {
29820 if (0 == (initialisation_expression = parse_expression()))
29821 {
29822 set_error(make_error(
29824 current_token(),
29825 "ERR190 - Failed to parse initialisation expression for const-variable: '" + var_name + "'",
29827
29828 return error_node();
29829 }
29830 else if (!details::is_literal_node(initialisation_expression))
29831 {
29832 set_error(make_error(
29834 current_token(),
29835 "ERR191 - initialisation expression for const-variable: '" + var_name + "' must be a constant/literal",
29837
29838 free_node(node_allocator_, initialisation_expression);
29839
29840 return error_node();
29841 }
29842 }
29843
29844 const T init_value = initialisation_expression->value();
29845
29846 free_node(node_allocator_, initialisation_expression);
29847
29848 expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
29849
29850 scope_element& se = sem_.get_element(var_name);
29851
29852 if (se.name == var_name)
29853 {
29854 if (se.active)
29855 {
29856 set_error(make_error(
29858 current_token(),
29859 "ERR192 - Illegal redefinition of local variable: '" + var_name + "'",
29861
29862 return error_node();
29863 }
29864 else if (scope_element::e_literal == se.type)
29865 {
29866 var_node = se.var_node;
29867 se.active = true;
29869 se.ref_count++;
29870 }
29871 }
29872
29873 if (0 == var_node)
29874 {
29875 scope_element nse;
29876 nse.name = var_name;
29877 nse.active = true;
29878 nse.ref_count = 1;
29880 nse.depth = state_.scope_depth;
29881 nse.data = 0;
29883
29884 if (!sem_.add_element(nse))
29885 {
29886 set_error(make_error(
29888 current_token(),
29889 "ERR193 - Failed to add new local const-variable '" + var_name + "' to SEM",
29891
29892 sem_.free_element(nse);
29893
29894 return error_node();
29895 }
29896
29897 var_node = nse.var_node;
29898
29899 exprtk_debug(("parse_define_constvar_statement() - INFO - Added new local const-variable: %s\n", nse.name.c_str()));
29900 }
29901
29902 state_.activate_side_effect("parse_define_constvar_statement()");
29903
29905
29906 return expression_generator_(var_node->value());
29907 }
29908
29909 inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name)
29910 {
29911 if (
29914 )
29915 {
29916 set_error(make_error(
29918 current_token(),
29919 "ERR194 - Expected a '{}' for uninitialised var definition",
29921
29922 return error_node();
29923 }
29924 else if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
29925 {
29926 set_error(make_error(
29928 current_token(),
29929 "ERR195 - Expected ';' after uninitialised variable definition",
29931
29932 return error_node();
29933 }
29934
29935 expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
29936
29937 scope_element& se = sem_.get_element(var_name);
29938
29939 if (se.name == var_name)
29940 {
29941 if (se.active)
29942 {
29943 set_error(make_error(
29945 current_token(),
29946 "ERR196 - Illegal redefinition of local variable: '" + var_name + "'",
29948
29949 return error_node();
29950 }
29951 else if (scope_element::e_variable == se.type)
29952 {
29953 var_node = se.var_node;
29954 se.active = true;
29955 se.ref_count++;
29956 }
29957 }
29958
29959 if (0 == var_node)
29960 {
29961 scope_element nse;
29962 nse.name = var_name;
29963 nse.active = true;
29964 nse.ref_count = 1;
29966 nse.depth = state_.scope_depth;
29967 nse.ip_index = sem_.next_ip_index();
29968 nse.data = new T(T(0));
29969 nse.var_node = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data));
29970
29971 if (!sem_.add_element(nse))
29972 {
29973 set_error(make_error(
29975 current_token(),
29976 "ERR197 - Failed to add new local variable '" + var_name + "' to SEM",
29978
29979 sem_.free_element(nse);
29980
29981 return error_node();
29982 }
29983
29984 exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n",
29985 nse.name.c_str()));
29986 }
29987
29989
29990 state_.activate_side_effect("parse_uninitialised_var_statement()");
29991
29992 return expression_generator_(T(0));
29993 }
29994
29996 {
29997 if (!details::imatch(current_token().value,"swap"))
29998 {
29999 return error_node();
30000 }
30001 else
30002 next_token();
30003
30005 {
30006 set_error(make_error(
30008 current_token(),
30009 "ERR198 - Expected '(' at start of swap statement",
30011
30012 return error_node();
30013 }
30014
30015 expression_node_ptr variable0 = error_node();
30016 expression_node_ptr variable1 = error_node();
30017
30018 bool variable0_generated = false;
30019 bool variable1_generated = false;
30020
30021 const std::string var0_name = current_token().value;
30022
30023 if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
30024 {
30025 set_error(make_error(
30027 current_token(),
30028 "ERR199 - Expected a symbol for variable or vector element definition",
30030
30031 return error_node();
30032 }
30034 {
30035 if (0 == (variable0 = parse_vector()))
30036 {
30037 set_error(make_error(
30039 current_token(),
30040 "ERR200 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
30042
30043 return error_node();
30044 }
30045
30046 variable0_generated = true;
30047 }
30048 else
30049 {
30050 if (symtab_store_.is_variable(var0_name))
30051 {
30052 variable0 = symtab_store_.get_variable(var0_name);
30053 }
30054
30055 const scope_element& se = sem_.get_element(var0_name);
30056
30057 if (
30058 (se.active) &&
30059 (se.name == var0_name) &&
30061 )
30062 {
30063 variable0 = se.var_node;
30064 }
30065
30066 lodge_symbol(var0_name, e_st_variable);
30067
30068 if (0 == variable0)
30069 {
30070 set_error(make_error(
30072 current_token(),
30073 "ERR201 - First parameter to swap is an invalid variable: '" + var0_name + "'",
30075
30076 return error_node();
30077 }
30078 else
30079 next_token();
30080 }
30081
30083 {
30084 set_error(make_error(
30086 current_token(),
30087 "ERR202 - Expected ',' between parameters to swap",
30089
30090 if (variable0_generated)
30091 {
30092 free_node(node_allocator_, variable0);
30093 }
30094
30095 return error_node();
30096 }
30097
30098 const std::string var1_name = current_token().value;
30099
30100 if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
30101 {
30102 set_error(make_error(
30104 current_token(),
30105 "ERR203 - Expected a symbol for variable or vector element definition",
30107
30108 if (variable0_generated)
30109 {
30110 free_node(node_allocator_, variable0);
30111 }
30112
30113 return error_node();
30114 }
30116 {
30117 if (0 == (variable1 = parse_vector()))
30118 {
30119 set_error(make_error(
30121 current_token(),
30122 "ERR204 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
30124
30125 if (variable0_generated)
30126 {
30127 free_node(node_allocator_, variable0);
30128 }
30129
30130 return error_node();
30131 }
30132
30133 variable1_generated = true;
30134 }
30135 else
30136 {
30137 if (symtab_store_.is_variable(var1_name))
30138 {
30139 variable1 = symtab_store_.get_variable(var1_name);
30140 }
30141
30142 const scope_element& se = sem_.get_element(var1_name);
30143
30144 if (
30145 (se.active) &&
30146 (se.name == var1_name) &&
30148 )
30149 {
30150 variable1 = se.var_node;
30151 }
30152
30153 lodge_symbol(var1_name, e_st_variable);
30154
30155 if (0 == variable1)
30156 {
30157 set_error(make_error(
30159 current_token(),
30160 "ERR205 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
30162
30163 if (variable0_generated)
30164 {
30165 free_node(node_allocator_, variable0);
30166 }
30167
30168 return error_node();
30169 }
30170 else
30171 next_token();
30172 }
30173
30175 {
30176 set_error(make_error(
30178 current_token(),
30179 "ERR206 - Expected ')' at end of swap statement",
30181
30182 if (variable0_generated)
30183 {
30184 free_node(node_allocator_, variable0);
30185 }
30186
30187 if (variable1_generated)
30188 {
30189 free_node(node_allocator_, variable1);
30190 }
30191
30192 return error_node();
30193 }
30194
30195 typedef details::variable_node<T>* variable_node_ptr;
30196
30197 variable_node_ptr v0 = variable_node_ptr(0);
30198 variable_node_ptr v1 = variable_node_ptr(0);
30199
30201
30202 if (
30203 (0 != (v0 = dynamic_cast<variable_node_ptr>(variable0))) &&
30204 (0 != (v1 = dynamic_cast<variable_node_ptr>(variable1)))
30205 )
30206 {
30208
30209 if (variable0_generated)
30210 {
30211 free_node(node_allocator_, variable0);
30212 }
30213
30214 if (variable1_generated)
30215 {
30216 free_node(node_allocator_, variable1);
30217 }
30218 }
30219 else
30221 (variable0, variable1);
30222
30223 state_.activate_side_effect("parse_swap_statement()");
30224
30225 return result;
30226 }
30227
30228 #ifndef exprtk_disable_return_statement
30230 {
30232 {
30233 set_error(make_error(
30235 current_token(),
30236 "ERR207 - Return call within a return call is not allowed",
30238
30239 return error_node();
30240 }
30241
30243
30244 std::vector<expression_node_ptr> arg_list;
30245
30246 scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
30247
30248 if (!details::imatch(current_token().value,"return"))
30249 {
30250 return error_node();
30251 }
30252 else
30253 next_token();
30254
30256 {
30257 set_error(make_error(
30259 current_token(),
30260 "ERR208 - Expected '[' at start of return statement",
30262
30263 return error_node();
30264 }
30266 {
30267 for ( ; ; )
30268 {
30270
30271 if (0 == arg)
30272 return error_node();
30273
30274 arg_list.push_back(arg);
30275
30277 break;
30278 else if (!token_is(token_t::e_comma))
30279 {
30280 set_error(make_error(
30282 current_token(),
30283 "ERR209 - Expected ',' between values during call to return",
30285
30286 return error_node();
30287 }
30288 }
30289 }
30291 {
30292 set_error(make_error(
30294 current_token(),
30295 "ERR210 - Zero parameter return statement not allowed",
30297
30298 return error_node();
30299 }
30300
30301 const lexer::token prev_token = current_token();
30302
30304 {
30305 if (!arg_list.empty())
30306 {
30307 set_error(make_error(
30309 prev_token,
30310 "ERR211 - Invalid ']' found during return call",
30312
30313 return error_node();
30314 }
30315 }
30316
30317 std::string ret_param_type_list;
30318
30319 for (std::size_t i = 0; i < arg_list.size(); ++i)
30320 {
30321 if (0 == arg_list[i])
30322 return error_node();
30323 else if (is_ivector_node(arg_list[i]))
30324 ret_param_type_list += 'V';
30325 else if (is_generally_string_node(arg_list[i]))
30326 ret_param_type_list += 'S';
30327 else
30328 ret_param_type_list += 'T';
30329 }
30330
30331 dec_.retparam_list_.push_back(ret_param_type_list);
30332
30334
30335 sdd.delete_ptr = (0 == result);
30336
30338
30339 state_.activate_side_effect("parse_return_statement()");
30340
30341 return result;
30342 }
30343 #else
30345 {
30346 return error_node();
30347 }
30348 #endif
30349
30351 {
30352 assert(details::imatch(current_token().value, "assert"));
30353
30355 {
30356 set_error(make_error(
30358 current_token(),
30359 "ERR212 - Assert statement within an assert statement is not allowed",
30361
30362 return error_node();
30363 }
30364
30366
30367 next_token();
30368
30369 std::vector<expression_node_ptr> assert_arg_list(3, error_node());
30370 scoped_vec_delete<expression_node_t> sdd((*this), assert_arg_list);
30371
30372 expression_node_ptr& assert_condition = assert_arg_list[0];
30373 expression_node_ptr& assert_message = assert_arg_list[1];
30374 expression_node_ptr& assert_id = assert_arg_list[2];
30375
30377 {
30378 set_error(make_error(
30380 current_token(),
30381 "ERR213 - Expected '(' at start of assert statement",
30383
30384 return error_node();
30385 }
30386
30387 const token_t start_token = current_token();
30388
30389 // Parse the assert condition
30390 if (0 == (assert_condition = parse_expression()))
30391 {
30392 set_error(make_error(
30394 current_token(),
30395 "ERR214 - Failed to parse condition for assert statement",
30397
30398 return error_node();
30399 }
30400
30401 const token_t end_token = current_token();
30402
30404 {
30406 {
30407 set_error(make_error(
30409 current_token(),
30410 "ERR215 - Expected ',' between condition and message for assert statement",
30412
30413 return error_node();
30414 }
30415 // Parse the assert message
30416 else if (
30417 (0 == (assert_message = parse_expression())) ||
30418 !details::is_generally_string_node(assert_message)
30419 )
30420 {
30421 set_error(make_error(
30423 current_token(),
30424 "ERR216 - " +
30425 (assert_message ?
30426 std::string("Expected string for assert message") :
30427 std::string("Failed to parse message for assert statement")),
30429
30430 return error_node();
30431 }
30432 else if (!token_is(token_t::e_rbracket))
30433 {
30435 {
30436 set_error(make_error(
30438 current_token(),
30439 "ERR217 - Expected ',' between message and ID for assert statement",
30441
30442 return error_node();
30443 }
30444 // Parse assert ID
30445 else if (
30446 (0 == (assert_id = parse_expression())) ||
30448 )
30449 {
30450 set_error(make_error(
30452 current_token(),
30453 "ERR218 - " +
30454 (assert_id ?
30455 std::string("Expected literal string for assert ID") :
30456 std::string("Failed to parse string for assert ID")),
30458
30459 return error_node();
30460 }
30461 else if (!token_is(token_t::e_rbracket))
30462 {
30463 set_error(make_error(
30465 current_token(),
30466 "ERR219 - Expected ')' at start of assert statement",
30468
30469 return error_node();
30470 }
30471 }
30472 }
30473
30475 context.condition = lexer().substr(start_token.position, end_token.position);
30476 context.offet = start_token.position;
30477
30478 if (0 == assert_check_)
30479 {
30480 exprtk_debug(("parse_assert_statement() - assert functionality is disabled. assert condition: %s\n",
30481 context.condition.c_str()));
30482
30483 return new details::null_node<T>();
30484 }
30485
30486 #ifndef exprtk_disable_string_capabilities
30487 if (assert_message && details::is_const_string_node(assert_message))
30488 {
30489 context.message = dynamic_cast<details::string_base_node<T>*>(assert_message)->str();
30490 }
30491
30492 if (assert_id && details::is_const_string_node(assert_id))
30493 {
30494 context.id = dynamic_cast<details::string_base_node<T>*>(assert_id)->str();
30495
30496 if (assert_ids_.end() != assert_ids_.find(context.id))
30497 {
30498 set_error(make_error(
30500 current_token(),
30501 "ERR220 - Duplicate assert ID: " + context.id,
30503
30504 return error_node();
30505 }
30506
30507 assert_ids_.insert(context.id);
30508 free_node(node_allocator_, assert_id);
30509 }
30510 #endif
30511
30512 expression_node_ptr result_node =
30514 assert_condition,
30515 assert_message,
30516 context);
30517
30518 exprtk_debug(("parse_assert_statement() - assert condition: [%s]\n", context.condition.c_str() ));
30519 exprtk_debug(("parse_assert_statement() - assert message: [%s]\n", context.message .c_str() ));
30520 exprtk_debug(("parse_assert_statement() - assert id: [%s]\n", context.id .c_str() ));
30521 exprtk_debug(("parse_assert_statement() - assert offset: [%d]\n", static_cast<int>(context.offet)));
30522
30523 if (0 == result_node)
30524 {
30525 set_error(make_error(
30527 current_token(),
30528 "ERR221 - Failed to synthesize assert",
30530
30531 return error_node();
30532 }
30533
30534 sdd.delete_ptr = false;
30535 return result_node;
30536 }
30537
30538 inline bool post_variable_process(const std::string& symbol)
30539 {
30540 if (
30544 )
30545 {
30547 {
30548 set_error(make_error(
30550 current_token(),
30551 "ERR222 - Invalid sequence of variable '" + symbol + "' and bracket",
30553
30554 return false;
30555 }
30556
30558 }
30559
30560 return true;
30561 }
30562
30563 inline bool post_bracket_process(const typename token_t::token_type& token, expression_node_ptr& branch)
30564 {
30565 bool implied_mul = false;
30566
30568 return true;
30569
30570 const lexer::parser_helper::token_advance_mode hold = prsrhlpr_t::e_hold;
30571
30572 switch (token)
30573 {
30574 case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket , hold) ||
30577 break;
30578
30579 case token_t::e_lbracket : implied_mul = token_is(token_t::e_lbracket , hold) ||
30582 break;
30583
30584 case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket , hold) ||
30587 break;
30588
30589 default : return true;
30590 }
30591
30592 if (implied_mul)
30593 {
30595 {
30596 set_error(make_error(
30598 current_token(),
30599 "ERR223 - Invalid sequence of brackets",
30601
30602 return false;
30603 }
30604 else if (token_t::e_eof != current_token().type)
30605 {
30608 next_token();
30609 }
30610 }
30611
30612 return true;
30613 }
30614
30617 typedef std::map<interval_t,token_t> immutable_symtok_map_t;
30618
30620 {
30621 const T* begin = reinterpret_cast<const T*>(&t);
30622 const T* end = begin + 1;
30623 return interval_t(begin, end);
30624 }
30625
30626 inline interval_t make_memory_range(const T* begin, const std::size_t size)
30627 {
30628 return interval_t(begin, begin + size);
30629 }
30630
30631 inline interval_t make_memory_range(details::char_cptr begin, const std::size_t size)
30632 {
30633 return interval_t(begin, begin + size);
30634 }
30635
30636 void lodge_immutable_symbol(const lexer::token& token, const interval_t interval)
30637 {
30639 immutable_symtok_map_[interval] = token;
30640 }
30641
30643 {
30644 const std::string symbol = current_token().value;
30645
30646 // Are we dealing with a variable or a special constant?
30647 typedef typename symtab_store::variable_context var_ctxt_t;
30648 var_ctxt_t var_ctx = symtab_store_.get_variable_context(symbol);
30649
30650 if (var_ctx.variable)
30651 {
30652 assert(var_ctx.symbol_table);
30653
30654 expression_node_ptr result_variable = var_ctx.variable;
30655
30656 if (symtab_store_.is_constant_node(symbol))
30657 {
30658 result_variable = expression_generator_(var_ctx.variable->value());
30659 }
30660 else if (symbol_table_t::e_immutable == var_ctx.symbol_table->mutability())
30661 {
30662 lodge_immutable_symbol(current_token(), make_memory_range(var_ctx.variable->ref()));
30663 result_variable = var_ctx.variable;
30664 }
30665
30666 if (!post_variable_process(symbol))
30667 return error_node();
30668
30669 lodge_symbol(symbol, e_st_variable);
30670
30671 next_token();
30672
30673 return result_variable;
30674 }
30675
30676 // Are we dealing with a locally defined variable, vector or string?
30677 if (!sem_.empty())
30678 {
30680
30681 if (se.active && details::imatch(se.name, symbol))
30682 {
30683 if (
30686 )
30687 {
30688 se.active = true;
30690
30691 if (!post_variable_process(symbol))
30692 return error_node();
30693
30694 next_token();
30695
30696 return (scope_element::e_variable == se.type) ?
30697 se.var_node :
30699 }
30700 else if (scope_element::e_vector == se.type)
30701 {
30702 return parse_vector();
30703 }
30704 #ifndef exprtk_disable_string_capabilities
30705 else if (scope_element::e_string == se.type)
30706 {
30707 return parse_string();
30708 }
30709 #endif
30710 }
30711 }
30712
30713 #ifndef exprtk_disable_string_capabilities
30714 // Are we dealing with a string variable?
30715 if (symtab_store_.is_stringvar(symbol))
30716 {
30717 return parse_string();
30718 }
30719 #endif
30720
30721 {
30722 // Are we dealing with a function?
30723 ifunction<T>* function = symtab_store_.get_function(symbol);
30724
30725 if (function)
30726 {
30727 lodge_symbol(symbol, e_st_function);
30728
30729 expression_node_ptr func_node =
30730 parse_function_invocation(function,symbol);
30731
30732 if (func_node)
30733 return func_node;
30734 else
30735 {
30736 set_error(make_error(
30738 current_token(),
30739 "ERR224 - Failed to generate node for function: '" + symbol + "'",
30741
30742 return error_node();
30743 }
30744 }
30745 }
30746
30747 {
30748 // Are we dealing with a vararg function?
30749 ivararg_function<T>* vararg_function = symtab_store_.get_vararg_function(symbol);
30750
30751 if (vararg_function)
30752 {
30753 lodge_symbol(symbol, e_st_function);
30754
30755 expression_node_ptr vararg_func_node =
30756 parse_vararg_function_call(vararg_function, symbol);
30757
30758 if (vararg_func_node)
30759 return vararg_func_node;
30760 else
30761 {
30762 set_error(make_error(
30764 current_token(),
30765 "ERR225 - Failed to generate node for vararg function: '" + symbol + "'",
30767
30768 return error_node();
30769 }
30770 }
30771 }
30772
30773 {
30774 // Are we dealing with a vararg generic function?
30775 igeneric_function<T>* generic_function = symtab_store_.get_generic_function(symbol);
30776
30777 if (generic_function)
30778 {
30779 lodge_symbol(symbol, e_st_function);
30780
30781 expression_node_ptr genericfunc_node =
30782 parse_generic_function_call(generic_function, symbol);
30783
30784 if (genericfunc_node)
30785 return genericfunc_node;
30786 else
30787 {
30788 set_error(make_error(
30790 current_token(),
30791 "ERR226 - Failed to generate node for generic function: '" + symbol + "'",
30793
30794 return error_node();
30795 }
30796 }
30797 }
30798
30799 #ifndef exprtk_disable_string_capabilities
30800 {
30801 // Are we dealing with a vararg string returning function?
30802 igeneric_function<T>* string_function = symtab_store_.get_string_function(symbol);
30803
30804 if (string_function)
30805 {
30806 lodge_symbol(symbol, e_st_function);
30807
30808 expression_node_ptr stringfunc_node =
30809 parse_string_function_call(string_function, symbol);
30810
30811 if (stringfunc_node)
30812 return stringfunc_node;
30813 else
30814 {
30815 set_error(make_error(
30817 current_token(),
30818 "ERR227 - Failed to generate node for string function: '" + symbol + "'",
30820
30821 return error_node();
30822 }
30823 }
30824 }
30825
30826 {
30827 // Are we dealing with a vararg overloaded scalar/string returning function?
30828 igeneric_function<T>* overload_function = symtab_store_.get_overload_function(symbol);
30829
30830 if (overload_function)
30831 {
30832 lodge_symbol(symbol, e_st_function);
30833
30834 expression_node_ptr overloadfunc_node =
30835 parse_overload_function_call(overload_function, symbol);
30836
30837 if (overloadfunc_node)
30838 return overloadfunc_node;
30839 else
30840 {
30841 set_error(make_error(
30843 current_token(),
30844 "ERR228 - Failed to generate node for overload function: '" + symbol + "'",
30846
30847 return error_node();
30848 }
30849 }
30850 }
30851 #endif
30852
30853 // Are we dealing with a vector?
30854 if (symtab_store_.is_vector(symbol))
30855 {
30856 lodge_symbol(symbol, e_st_vector);
30857 return parse_vector();
30858 }
30859
30860 if (details::is_reserved_symbol(symbol))
30861 {
30862 if (
30863 settings_.function_enabled(symbol) ||
30865 )
30866 {
30867 set_error(make_error(
30869 current_token(),
30870 "ERR229 - Invalid use of reserved symbol '" + symbol + "'",
30872
30873 return error_node();
30874 }
30875 }
30876
30877 // Should we handle unknown symbols?
30879 {
30881 {
30883
30884 std::string error_message;
30885
30887 {
30888 T default_value = T(0);
30889
30891
30892 if (unknown_symbol_resolver_->process(symbol, usr_symbol_type, default_value, error_message))
30893 {
30894 bool create_result = false;
30895
30896 switch (usr_symbol_type)
30897 {
30899 create_result = symtab.create_variable(symbol, default_value);
30900 break;
30901
30903 create_result = symtab.add_constant(symbol, default_value);
30904 break;
30905
30906 default : create_result = false;
30907 }
30908
30909 if (create_result)
30910 {
30912
30913 if (var)
30914 {
30915 if (symtab_store_.is_constant_node(symbol))
30916 {
30917 var = expression_generator_(var->value());
30918 }
30919
30920 lodge_symbol(symbol, e_st_variable);
30921
30922 if (!post_variable_process(symbol))
30923 return error_node();
30924
30925 next_token();
30926
30927 return var;
30928 }
30929 }
30930 }
30931
30932 set_error(make_error(
30934 current_token(),
30935 "ERR230 - Failed to create variable: '" + symbol + "'" +
30936 (error_message.empty() ? "" : " - " + error_message),
30938
30939 }
30941 {
30942 if (unknown_symbol_resolver_->process(symbol, symtab, error_message))
30943 {
30945
30946 if (result)
30947 {
30948 return result;
30949 }
30950 }
30951
30952 set_error(make_error(
30954 current_token(),
30955 "ERR231 - Failed to resolve symbol: '" + symbol + "'" +
30956 (error_message.empty() ? "" : " - " + error_message),
30958 }
30959
30960 return error_node();
30961 }
30962 }
30963
30964 set_error(make_error(
30966 current_token(),
30967 "ERR232 - Undefined symbol: '" + symbol + "'",
30969
30970 return error_node();
30971 }
30972
30974 {
30975 static const std::string symbol_if = "if" ;
30976 static const std::string symbol_while = "while" ;
30977 static const std::string symbol_repeat = "repeat" ;
30978 static const std::string symbol_for = "for" ;
30979 static const std::string symbol_switch = "switch" ;
30980 static const std::string symbol_null = "null" ;
30981 static const std::string symbol_break = "break" ;
30982 static const std::string symbol_continue = "continue";
30983 static const std::string symbol_var = "var" ;
30984 static const std::string symbol_const = "const" ;
30985 static const std::string symbol_swap = "swap" ;
30986 static const std::string symbol_return = "return" ;
30987 static const std::string symbol_not = "not" ;
30988 static const std::string symbol_assert = "assert" ;
30989
30990 const std::string symbol = current_token().value;
30991
30992 if (valid_vararg_operation(symbol))
30993 {
30994 return parse_vararg_function();
30995 }
30996 else if (details::imatch(symbol, symbol_not))
30997 {
30998 return parse_not_statement();
30999 }
31000 else if (valid_base_operation(symbol))
31001 {
31002 return parse_base_operation();
31003 }
31004 else if (
31005 details::imatch(symbol, symbol_if) &&
31007 )
31008 {
31010 }
31011 else if (
31012 details::imatch(symbol, symbol_while) &&
31014 )
31015 {
31016 return parse_while_loop();
31017 }
31018 else if (
31019 details::imatch(symbol, symbol_repeat) &&
31021 )
31022 {
31023 return parse_repeat_until_loop();
31024 }
31025 else if (
31026 details::imatch(symbol, symbol_for) &&
31028 )
31029 {
31030 return parse_for_loop();
31031 }
31032 else if (
31033 details::imatch(symbol, symbol_switch) &&
31035 )
31036 {
31037 return parse_switch_statement();
31038 }
31039 else if (details::is_valid_sf_symbol(symbol))
31040 {
31041 return parse_special_function();
31042 }
31043 else if (details::imatch(symbol, symbol_null))
31044 {
31045 return parse_null_statement();
31046 }
31047 #ifndef exprtk_disable_break_continue
31048 else if (details::imatch(symbol, symbol_break))
31049 {
31050 return parse_break_statement();
31051 }
31052 else if (details::imatch(symbol, symbol_continue))
31053 {
31054 return parse_continue_statement();
31055 }
31056 #endif
31057 else if (details::imatch(symbol, symbol_var))
31058 {
31060 }
31061 else if (details::imatch(symbol, symbol_const))
31062 {
31064 }
31065 else if (details::imatch(symbol, symbol_swap))
31066 {
31067 return parse_swap_statement();
31068 }
31069 #ifndef exprtk_disable_return_statement
31070 else if (
31071 details::imatch(symbol, symbol_return) &&
31073 )
31074 {
31075 return parse_return_statement();
31076 }
31077 #endif
31078 else if (details::imatch(symbol, symbol_assert))
31079 {
31080 return parse_assert_statement();
31081 }
31082 else if (symtab_store_.valid() || !sem_.empty())
31083 {
31084 return parse_symtab_symbol();
31085 }
31086 else
31087 {
31088 set_error(make_error(
31090 current_token(),
31091 "ERR233 - Unknown variable or function encountered. Symbol table(s) "
31092 "is either invalid or does not contain symbol: '" + symbol + "'",
31094
31095 return error_node();
31096 }
31097 }
31098
31100 {
31101 stack_limit_handler slh(*this);
31102
31103 if (!slh)
31104 {
31105 return error_node();
31106 }
31107
31109
31110 if (token_t::e_number == current_token().type)
31111 {
31112 T numeric_value = T(0);
31113
31114 if (details::string_to_real(current_token().value, numeric_value))
31115 {
31116 expression_node_ptr literal_exp = expression_generator_(numeric_value);
31117
31118 if (0 == literal_exp)
31119 {
31120 set_error(make_error(
31122 current_token(),
31123 "ERR234 - Failed generate node for scalar: '" + current_token().value + "'",
31125
31126 return error_node();
31127 }
31128
31129 next_token();
31130 branch = literal_exp;
31131 }
31132 else
31133 {
31134 set_error(make_error(
31136 current_token(),
31137 "ERR235 - Failed to convert '" + current_token().value + "' to a number",
31139
31140 return error_node();
31141 }
31142 }
31143 else if (token_t::e_symbol == current_token().type)
31144 {
31145 branch = parse_symbol();
31146 }
31147 #ifndef exprtk_disable_string_capabilities
31148 else if (token_t::e_string == current_token().type)
31149 {
31150 branch = parse_const_string();
31151 }
31152 #endif
31153 else if (token_t::e_lbracket == current_token().type)
31154 {
31155 next_token();
31156
31157 if (0 == (branch = parse_expression()))
31158 return error_node();
31159 else if (token_is(token_t::e_eof))
31160 {}
31161 else if (!token_is(token_t::e_rbracket))
31162 {
31163 set_error(make_error(
31165 current_token(),
31166 "ERR236 - Expected ')' instead of: '" + current_token().value + "'",
31168
31170
31171 return error_node();
31172 }
31173 else if (!post_bracket_process(token_t::e_lbracket,branch))
31174 {
31176
31177 return error_node();
31178 }
31179
31181 }
31182 else if (token_t::e_lsqrbracket == current_token().type)
31183 {
31184 next_token();
31185
31186 if (0 == (branch = parse_expression()))
31187 return error_node();
31189 {
31190 set_error(make_error(
31192 current_token(),
31193 "ERR237 - Expected ']' instead of: '" + current_token().value + "'",
31195
31197
31198 return error_node();
31199 }
31201 {
31203
31204 return error_node();
31205 }
31206 }
31207 else if (token_t::e_lcrlbracket == current_token().type)
31208 {
31209 next_token();
31210
31211 if (0 == (branch = parse_expression()))
31212 return error_node();
31214 {
31215 set_error(make_error(
31217 current_token(),
31218 "ERR238 - Expected '}' instead of: '" + current_token().value + "'",
31220
31222
31223 return error_node();
31224 }
31226 {
31228
31229 return error_node();
31230 }
31231 }
31232 else if (token_t::e_sub == current_token().type)
31233 {
31234 next_token();
31235 branch = parse_expression(e_level11);
31236
31237 if (
31238 branch &&
31239 !(
31240 details::is_neg_unary_node (branch) &&
31242 )
31243 )
31244 {
31246
31247 if (0 == result)
31248 {
31250
31251 return error_node();
31252 }
31253 else
31254 branch = result;
31255 }
31256 }
31257 else if (token_t::e_add == current_token().type)
31258 {
31259 next_token();
31260 branch = parse_expression(e_level13);
31261 }
31262 else if (token_t::e_eof == current_token().type)
31263 {
31264 set_error(make_error(
31266 current_token(),
31267 "ERR239 - Premature end of expression[1]",
31269
31270 return error_node();
31271 }
31272 else
31273 {
31274 set_error(make_error(
31276 current_token(),
31277 "ERR240 - Premature end of expression[2]",
31279
31280 return error_node();
31281 }
31282
31283 if (
31284 branch &&
31285 (e_level00 == precedence) &&
31286 token_is(token_t::e_ternary,prsrhlpr_t::e_hold)
31287 )
31288 {
31289 branch = parse_ternary_conditional_statement(branch);
31290 }
31291
31293
31294 return branch;
31295 }
31296
31297 template <typename Type>
31299 {
31300 public:
31301
31304 typedef std::map<std::string,synthesize_functor_t> synthesize_map_t;
31306 typedef const Type& vtype;
31307 typedef const Type ctype;
31308
31310 {
31311 #ifndef exprtk_disable_enhanced_features
31315
31316 #define register_synthezier(S) \
31317 synthesize_map_[S ::node_type::id()] = S ::process; \
31318
31331
31341
31351
31360
31370
31379
31380 #undef register_synthezier
31381 #endif
31382 }
31383
31384 inline void set_parser(parser_t& p)
31385 {
31386 parser_ = &p;
31387 }
31388
31389 inline void set_uom(unary_op_map_t& unary_op_map)
31390 {
31391 unary_op_map_ = &unary_op_map;
31392 }
31393
31394 inline void set_bom(binary_op_map_t& binary_op_map)
31395 {
31396 binary_op_map_ = &binary_op_map;
31397 }
31398
31399 inline void set_ibom(inv_binary_op_map_t& inv_binary_op_map)
31400 {
31401 inv_binary_op_map_ = &inv_binary_op_map;
31402 }
31403
31404 inline void set_sf3m(sf3_map_t& sf3_map)
31405 {
31406 sf3_map_ = &sf3_map;
31407 }
31408
31409 inline void set_sf4m(sf4_map_t& sf4_map)
31410 {
31411 sf4_map_ = &sf4_map;
31412 }
31413
31415 {
31416 node_allocator_ = &na;
31417 }
31418
31419 inline void set_strength_reduction_state(const bool enabled)
31420 {
31422 }
31423
31424 inline bool strength_reduction_enabled() const
31425 {
31427 }
31428
31429 inline bool valid_operator(const details::operator_type& operation, binary_functor_t& bop)
31430 {
31431 typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation);
31432
31433 if (binary_op_map_->end() == bop_itr)
31434 return false;
31435
31436 bop = bop_itr->second;
31437
31438 return true;
31439 }
31440
31441 inline bool valid_operator(const details::operator_type& operation, unary_functor_t& uop)
31442 {
31443 typename unary_op_map_t::iterator uop_itr = unary_op_map_->find(operation);
31444
31445 if ((*unary_op_map_).end() == uop_itr)
31446 return false;
31447
31448 uop = uop_itr->second;
31449
31450 return true;
31451 }
31452
31454 {
31455 return (*inv_binary_op_map_).find(bop)->second;
31456 }
31457
31458 inline expression_node_ptr operator() (const Type& v) const
31459 {
31461 }
31462
31463 #ifndef exprtk_disable_string_capabilities
31464 inline expression_node_ptr operator() (const std::string& s) const
31465 {
31467 }
31468
31469 inline expression_node_ptr operator() (std::string& s, range_t& rp) const
31470 {
31472 }
31473
31474 inline expression_node_ptr operator() (const std::string& s, range_t& rp) const
31475 {
31477 }
31478
31480 {
31481 if (is_generally_string_node(branch))
31483 else
31484 return error_node();
31485 }
31486 #endif
31487
31488 inline bool unary_optimisable(const details::operator_type& operation) const
31489 {
31490 return (details::e_abs == operation) || (details::e_acos == operation) ||
31491 (details::e_acosh == operation) || (details::e_asin == operation) ||
31492 (details::e_asinh == operation) || (details::e_atan == operation) ||
31493 (details::e_atanh == operation) || (details::e_ceil == operation) ||
31494 (details::e_cos == operation) || (details::e_cosh == operation) ||
31495 (details::e_exp == operation) || (details::e_expm1 == operation) ||
31496 (details::e_floor == operation) || (details::e_log == operation) ||
31497 (details::e_log10 == operation) || (details::e_log2 == operation) ||
31498 (details::e_log1p == operation) || (details::e_neg == operation) ||
31499 (details::e_pos == operation) || (details::e_round == operation) ||
31500 (details::e_sin == operation) || (details::e_sinc == operation) ||
31501 (details::e_sinh == operation) || (details::e_sqrt == operation) ||
31502 (details::e_tan == operation) || (details::e_tanh == operation) ||
31503 (details::e_cot == operation) || (details::e_sec == operation) ||
31504 (details::e_csc == operation) || (details::e_r2d == operation) ||
31505 (details::e_d2r == operation) || (details::e_d2g == operation) ||
31506 (details::e_g2d == operation) || (details::e_notl == operation) ||
31507 (details::e_sgn == operation) || (details::e_erf == operation) ||
31508 (details::e_erfc == operation) || (details::e_ncdf == operation) ||
31509 (details::e_frac == operation) || (details::e_trunc == operation) ;
31510 }
31511
31512 inline bool sf3_optimisable(const std::string& sf3id, trinary_functor_t& tfunc) const
31513 {
31514 typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id);
31515
31516 if (sf3_map_->end() == itr)
31517 return false;
31518 else
31519 tfunc = itr->second.first;
31520
31521 return true;
31522 }
31523
31524 inline bool sf4_optimisable(const std::string& sf4id, quaternary_functor_t& qfunc) const
31525 {
31526 typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id);
31527
31528 if (sf4_map_->end() == itr)
31529 return false;
31530 else
31531 qfunc = itr->second.first;
31532
31533 return true;
31534 }
31535
31536 inline bool sf3_optimisable(const std::string& sf3id, details::operator_type& operation) const
31537 {
31538 typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id);
31539
31540 if (sf3_map_->end() == itr)
31541 return false;
31542 else
31543 operation = itr->second.second;
31544
31545 return true;
31546 }
31547
31548 inline bool sf4_optimisable(const std::string& sf4id, details::operator_type& operation) const
31549 {
31550 typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id);
31551
31552 if (sf4_map_->end() == itr)
31553 return false;
31554 else
31555 operation = itr->second.second;
31556
31557 return true;
31558 }
31559
31561 {
31562 if (0 == branch[0])
31563 {
31564 return error_node();
31565 }
31566 else if (details::is_null_node(branch[0]))
31567 {
31568 return branch[0];
31569 }
31570 else if (details::is_break_node(branch[0]))
31571 {
31572 return error_node();
31573 }
31574 else if (details::is_continue_node(branch[0]))
31575 {
31576 return error_node();
31577 }
31578 else if (details::is_constant_node(branch[0]))
31579 {
31580 return synthesize_expression<unary_node_t,1>(operation,branch);
31581 }
31582 else if (unary_optimisable(operation) && details::is_variable_node(branch[0]))
31583 {
31584 return synthesize_uv_expression(operation,branch);
31585 }
31586 else if (unary_optimisable(operation) && details::is_ivector_node(branch[0]))
31587 {
31588 return synthesize_uvec_expression(operation,branch);
31589 }
31590 else
31591 return synthesize_unary_expression(operation,branch);
31592 }
31593
31594 inline bool is_assignment_operation(const details::operator_type& operation) const
31595 {
31596 return (
31597 (details::e_addass == operation) ||
31598 (details::e_subass == operation) ||
31599 (details::e_mulass == operation) ||
31600 (details::e_divass == operation) ||
31601 (details::e_modass == operation)
31602 ) &&
31604 }
31605
31606 #ifndef exprtk_disable_string_capabilities
31607 inline bool valid_string_operation(const details::operator_type& operation) const
31608 {
31609 return (details::e_add == operation) ||
31610 (details::e_lt == operation) ||
31611 (details::e_lte == operation) ||
31612 (details::e_gt == operation) ||
31613 (details::e_gte == operation) ||
31614 (details::e_eq == operation) ||
31615 (details::e_ne == operation) ||
31616 (details::e_in == operation) ||
31617 (details::e_like == operation) ||
31618 (details::e_ilike == operation) ||
31619 (details::e_assign == operation) ||
31620 (details::e_addass == operation) ||
31621 (details::e_swap == operation) ;
31622 }
31623 #else
31624 inline bool valid_string_operation(const details::operator_type&) const
31625 {
31626 return false;
31627 }
31628 #endif
31629
31630 inline std::string to_str(const details::operator_type& operation) const
31631 {
31632 switch (operation)
31633 {
31634 case details::e_add : return "+" ;
31635 case details::e_sub : return "-" ;
31636 case details::e_mul : return "*" ;
31637 case details::e_div : return "/" ;
31638 case details::e_mod : return "%" ;
31639 case details::e_pow : return "^" ;
31640 case details::e_lt : return "<" ;
31641 case details::e_lte : return "<=" ;
31642 case details::e_gt : return ">" ;
31643 case details::e_gte : return ">=" ;
31644 case details::e_eq : return "==" ;
31645 case details::e_ne : return "!=" ;
31646 case details::e_and : return "and" ;
31647 case details::e_nand : return "nand" ;
31648 case details::e_or : return "or" ;
31649 case details::e_nor : return "nor" ;
31650 case details::e_xor : return "xor" ;
31651 case details::e_xnor : return "xnor" ;
31652 default : return "UNKNOWN";
31653 }
31654 }
31655
31656 inline bool operation_optimisable(const details::operator_type& operation) const
31657 {
31658 return (details::e_add == operation) ||
31659 (details::e_sub == operation) ||
31660 (details::e_mul == operation) ||
31661 (details::e_div == operation) ||
31662 (details::e_mod == operation) ||
31663 (details::e_pow == operation) ||
31664 (details::e_lt == operation) ||
31665 (details::e_lte == operation) ||
31666 (details::e_gt == operation) ||
31667 (details::e_gte == operation) ||
31668 (details::e_eq == operation) ||
31669 (details::e_ne == operation) ||
31670 (details::e_and == operation) ||
31671 (details::e_nand == operation) ||
31672 (details::e_or == operation) ||
31673 (details::e_nor == operation) ||
31674 (details::e_xor == operation) ||
31675 (details::e_xnor == operation) ;
31676 }
31677
31678 inline std::string branch_to_id(expression_node_ptr branch) const
31679 {
31680 static const std::string null_str ("(null)" );
31681 static const std::string const_str ("(c)" );
31682 static const std::string var_str ("(v)" );
31683 static const std::string vov_str ("(vov)" );
31684 static const std::string cov_str ("(cov)" );
31685 static const std::string voc_str ("(voc)" );
31686 static const std::string str_str ("(s)" );
31687 static const std::string strrng_str ("(rngs)" );
31688 static const std::string cs_str ("(cs)" );
31689 static const std::string cstrrng_str("(crngs)");
31690
31691 if (details::is_null_node(branch))
31692 return null_str;
31693 else if (details::is_constant_node(branch))
31694 return const_str;
31695 else if (details::is_variable_node(branch))
31696 return var_str;
31697 else if (details::is_vov_node(branch))
31698 return vov_str;
31699 else if (details::is_cov_node(branch))
31700 return cov_str;
31701 else if (details::is_voc_node(branch))
31702 return voc_str;
31703 else if (details::is_string_node(branch))
31704 return str_str;
31705 else if (details::is_const_string_node(branch))
31706 return cs_str;
31707 else if (details::is_string_range_node(branch))
31708 return strrng_str;
31709 else if (details::is_const_string_range_node(branch))
31710 return cstrrng_str;
31711 else if (details::is_t0ot1ot2_node(branch))
31712 return "(" + dynamic_cast<details::T0oT1oT2_base_node<T>*>(branch)->type_id() + ")";
31713 else if (details::is_t0ot1ot2ot3_node(branch))
31714 return "(" + dynamic_cast<details::T0oT1oT2oT3_base_node<T>*>(branch)->type_id() + ")";
31715 else
31716 return "ERROR";
31717 }
31718
31719 inline std::string branch_to_id(expression_node_ptr (&branch)[2]) const
31720 {
31721 return branch_to_id(branch[0]) + std::string("o") + branch_to_id(branch[1]);
31722 }
31723
31724 inline bool cov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31725 {
31726 if (!operation_optimisable(operation))
31727 return false;
31728 else
31729 return details::is_constant_node(branch[0]) &&
31730 details::is_variable_node(branch[1]) ;
31731 }
31732
31733 inline bool voc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31734 {
31735 if (!operation_optimisable(operation))
31736 return false;
31737 else
31738 return details::is_variable_node(branch[0]) &&
31739 details::is_constant_node(branch[1]) ;
31740 }
31741
31742 inline bool vov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31743 {
31744 if (!operation_optimisable(operation))
31745 return false;
31746 else
31747 return details::is_variable_node(branch[0]) &&
31748 details::is_variable_node(branch[1]) ;
31749 }
31750
31751 inline bool cob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31752 {
31753 if (!operation_optimisable(operation))
31754 return false;
31755 else
31756 return details::is_constant_node(branch[0]) &&
31757 !details::is_constant_node(branch[1]) ;
31758 }
31759
31760 inline bool boc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31761 {
31762 if (!operation_optimisable(operation))
31763 return false;
31764 else
31765 return !details::is_constant_node(branch[0]) &&
31766 details::is_constant_node(branch[1]) ;
31767 }
31768
31769 inline bool cocob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31770 {
31771 if (
31772 (details::e_add == operation) ||
31773 (details::e_sub == operation) ||
31774 (details::e_mul == operation) ||
31775 (details::e_div == operation)
31776 )
31777 {
31778 return (details::is_constant_node(branch[0]) && details::is_cob_node(branch[1])) ||
31779 (details::is_constant_node(branch[1]) && details::is_cob_node(branch[0])) ;
31780 }
31781 else
31782 return false;
31783 }
31784
31785 inline bool coboc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31786 {
31787 if (
31788 (details::e_add == operation) ||
31789 (details::e_sub == operation) ||
31790 (details::e_mul == operation) ||
31791 (details::e_div == operation)
31792 )
31793 {
31794 return (details::is_constant_node(branch[0]) && details::is_boc_node(branch[1])) ||
31795 (details::is_constant_node(branch[1]) && details::is_boc_node(branch[0])) ;
31796 }
31797 else
31798 return false;
31799 }
31800
31801 inline bool uvouv_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31802 {
31803 if (!operation_optimisable(operation))
31804 return false;
31805 else
31806 return details::is_uv_node(branch[0]) &&
31807 details::is_uv_node(branch[1]) ;
31808 }
31809
31810 inline bool vob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31811 {
31812 if (!operation_optimisable(operation))
31813 return false;
31814 else
31815 return details::is_variable_node(branch[0]) &&
31816 !details::is_variable_node(branch[1]) ;
31817 }
31818
31819 inline bool bov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31820 {
31821 if (!operation_optimisable(operation))
31822 return false;
31823 else
31824 return !details::is_variable_node(branch[0]) &&
31825 details::is_variable_node(branch[1]) ;
31826 }
31827
31828 inline bool binext_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31829 {
31830 if (!operation_optimisable(operation))
31831 return false;
31832 else
31833 return !details::is_constant_node(branch[0]) ||
31834 !details::is_constant_node(branch[1]) ;
31835 }
31836
31837 inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31838 {
31839 if (is_assignment_operation(operation))
31840 {
31841 const bool b1_is_genstring = details::is_generally_string_node(branch[1]);
31842
31843 if (details::is_string_node(branch[0]))
31844 return !b1_is_genstring;
31845 else if (details::is_literal_node(branch[0]))
31846 return true;
31847 else
31848 return (
31849 !details::is_variable_node (branch[0]) &&
31850 !details::is_vector_elem_node (branch[0]) &&
31851 !details::is_vector_celem_node (branch[0]) &&
31852 !details::is_vector_elem_rtc_node (branch[0]) &&
31853 !details::is_vector_celem_rtc_node (branch[0]) &&
31858 !details::is_vector_node (branch[0])
31859 )
31860 || b1_is_genstring;
31861 }
31862 else
31863 return false;
31864 }
31865
31866 inline bool is_constpow_operation(const details::operator_type& operation, expression_node_ptr(&branch)[2]) const
31867 {
31868 if (
31869 !details::is_constant_node(branch[1]) ||
31870 details::is_constant_node(branch[0]) ||
31871 details::is_variable_node(branch[0]) ||
31872 details::is_vector_node (branch[0]) ||
31874 )
31875 return false;
31876
31877 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
31878
31879 return cardinal_pow_optimisable(operation, c);
31880 }
31881
31883 {
31884 return (
31885 details::is_break_node (branch[0]) ||
31886 details::is_break_node (branch[1]) ||
31887 details::is_continue_node(branch[0]) ||
31888 details::is_continue_node(branch[1])
31889 );
31890 }
31891
31892 inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31893 {
31894 const bool b0_string = is_generally_string_node(branch[0]);
31895 const bool b1_string = is_generally_string_node(branch[1]);
31896
31897 bool result = false;
31898
31899 if (b0_string != b1_string)
31900 result = true;
31901 else if (!valid_string_operation(operation) && b0_string && b1_string)
31902 result = true;
31903
31904 if (result)
31905 {
31906 parser_->set_synthesis_error("Invalid string operation");
31907 }
31908
31909 return result;
31910 }
31911
31912 inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const
31913 {
31914 const bool b0_string = is_generally_string_node(branch[0]);
31915 const bool b1_string = is_generally_string_node(branch[1]);
31916 const bool b2_string = is_generally_string_node(branch[2]);
31917
31918 bool result = false;
31919
31920 if ((b0_string != b1_string) || (b1_string != b2_string))
31921 result = true;
31922 else if ((details::e_inrange != operation) && b0_string && b1_string && b2_string)
31923 result = true;
31924
31925 if (result)
31926 {
31927 parser_->set_synthesis_error("Invalid string operation");
31928 }
31929
31930 return result;
31931 }
31932
31933 inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31934 {
31935 const bool b0_string = is_generally_string_node(branch[0]);
31936 const bool b1_string = is_generally_string_node(branch[1]);
31937
31938 return (b0_string && b1_string && valid_string_operation(operation));
31939 }
31940
31941 inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const
31942 {
31943 const bool b0_string = is_generally_string_node(branch[0]);
31944 const bool b1_string = is_generally_string_node(branch[1]);
31945 const bool b2_string = is_generally_string_node(branch[2]);
31946
31947 return (b0_string && b1_string && b2_string && (details::e_inrange == operation));
31948 }
31949
31950 #ifndef exprtk_disable_sc_andor
31951 inline bool is_shortcircuit_expression(const details::operator_type& operation) const
31952 {
31953 return (
31954 (details::e_scand == operation) ||
31955 (details::e_scor == operation)
31956 );
31957 }
31958 #else
31959 inline bool is_shortcircuit_expression(const details::operator_type&) const
31960 {
31961 return false;
31962 }
31963 #endif
31964
31965 inline bool is_null_present(expression_node_ptr (&branch)[2]) const
31966 {
31967 return (
31968 details::is_null_node(branch[0]) ||
31969 details::is_null_node(branch[1])
31970 );
31971 }
31972
31973 inline bool is_vector_eqineq_logic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31974 {
31975 if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
31976 return false;
31977 else
31978 return (
31979 (details::e_lt == operation) ||
31980 (details::e_lte == operation) ||
31981 (details::e_gt == operation) ||
31982 (details::e_gte == operation) ||
31983 (details::e_eq == operation) ||
31984 (details::e_ne == operation) ||
31985 (details::e_equal == operation) ||
31986 (details::e_and == operation) ||
31987 (details::e_nand == operation) ||
31988 (details::e_or == operation) ||
31989 (details::e_nor == operation) ||
31990 (details::e_xor == operation) ||
31991 (details::e_xnor == operation)
31992 );
31993 }
31994
31995 inline bool is_vector_arithmetic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
31996 {
31997 if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
31998 return false;
31999 else
32000 return (
32001 (details::e_add == operation) ||
32002 (details::e_sub == operation) ||
32003 (details::e_mul == operation) ||
32004 (details::e_div == operation) ||
32005 (details::e_pow == operation)
32006 );
32007 }
32008
32010 {
32011 if ((0 == branch[0]) || (0 == branch[1]))
32012 {
32016 "ERR241 - Invalid branches received for operator '" + details::to_str(operation) + "'",
32018
32019 return error_node();
32020 }
32021 else if (is_invalid_string_op(operation,branch))
32022 {
32026 "ERR242 - Invalid branch pair for string operator '" + details::to_str(operation) + "'",
32028
32029 return error_node();
32030 }
32031 else if (is_invalid_assignment_op(operation,branch))
32032 {
32036 "ERR243 - Invalid branch pair for assignment operator '" + details::to_str(operation) + "'",
32038
32039 return error_node();
32040 }
32041 else if (is_invalid_break_continue_op(branch))
32042 {
32046 "ERR244 - Invalid branch pair for break/continue operator '" + details::to_str(operation) + "'",
32048
32049 return error_node();
32050 }
32051 else if (details::e_assign == operation)
32052 {
32053 return synthesize_assignment_expression(operation, branch);
32054 }
32055 else if (details::e_swap == operation)
32056 {
32057 return synthesize_swap_expression(branch);
32058 }
32059 else if (is_assignment_operation(operation))
32060 {
32061 return synthesize_assignment_operation_expression(operation, branch);
32062 }
32063 else if (is_vector_eqineq_logic_operation(operation, branch))
32064 {
32065 return synthesize_veceqineqlogic_operation_expression(operation, branch);
32066 }
32067 else if (is_vector_arithmetic_operation(operation, branch))
32068 {
32069 return synthesize_vecarithmetic_operation_expression(operation, branch);
32070 }
32071 else if (is_shortcircuit_expression(operation))
32072 {
32073 return synthesize_shortcircuit_expression(operation, branch);
32074 }
32075 else if (is_string_operation(operation, branch))
32076 {
32077 return synthesize_string_expression(operation, branch);
32078 }
32079 else if (is_null_present(branch))
32080 {
32081 return synthesize_null_expression(operation, branch);
32082 }
32083 #ifndef exprtk_disable_cardinal_pow_optimisation
32084 else if (is_constpow_operation(operation, branch))
32085 {
32086 return cardinal_pow_optimisation(branch);
32087 }
32088 #endif
32089
32091
32092 #ifndef exprtk_disable_enhanced_features
32093 if (synthesize_expression(operation, branch, result))
32094 {
32095 return result;
32096 }
32097 else
32098 #endif
32099
32100 {
32101 /*
32102 Possible reductions:
32103 1. c o cob -> cob
32104 2. cob o c -> cob
32105 3. c o boc -> boc
32106 4. boc o c -> boc
32107 */
32108 result = error_node();
32109
32110 if (cocob_optimisable(operation, branch))
32111 {
32112 result = synthesize_cocob_expression::process((*this), operation, branch);
32113 }
32114 else if (coboc_optimisable(operation, branch) && (0 == result))
32115 {
32116 result = synthesize_coboc_expression::process((*this), operation, branch);
32117 }
32118
32119 if (result)
32120 return result;
32121 }
32122
32123 if (uvouv_optimisable(operation, branch))
32124 {
32125 return synthesize_uvouv_expression(operation, branch);
32126 }
32127 else if (vob_optimisable(operation, branch))
32128 {
32129 return synthesize_vob_expression::process((*this), operation, branch);
32130 }
32131 else if (bov_optimisable(operation, branch))
32132 {
32133 return synthesize_bov_expression::process((*this), operation, branch);
32134 }
32135 else if (cob_optimisable(operation, branch))
32136 {
32137 return synthesize_cob_expression::process((*this), operation, branch);
32138 }
32139 else if (boc_optimisable(operation, branch))
32140 {
32141 return synthesize_boc_expression::process((*this), operation, branch);
32142 }
32143 #ifndef exprtk_disable_enhanced_features
32144 else if (cov_optimisable(operation, branch))
32145 {
32146 return synthesize_cov_expression::process((*this), operation, branch);
32147 }
32148 #endif
32149 else if (binext_optimisable(operation, branch))
32150 {
32151 return synthesize_binary_ext_expression::process((*this), operation, branch);
32152 }
32153 else
32154 return synthesize_expression<binary_node_t,2>(operation, branch);
32155 }
32156
32158 {
32159 if (
32160 (0 == branch[0]) ||
32161 (0 == branch[1]) ||
32162 (0 == branch[2])
32163 )
32164 {
32166
32170 "ERR245 - Invalid branches operator '" + details::to_str(operation) + "'",
32172
32173 return error_node();
32174 }
32175 else if (is_invalid_string_op(operation, branch))
32176 {
32180 "ERR246 - Invalid branches for string operator '" + details::to_str(operation) + "'",
32182
32183 return error_node();
32184 }
32185 else if (is_string_operation(operation, branch))
32186 {
32187 return synthesize_string_expression(operation, branch);
32188 }
32189 else
32190 return synthesize_expression<trinary_node_t,3>(operation, branch);
32191 }
32192
32194 {
32195 return synthesize_expression<quaternary_node_t,4>(operation,branch);
32196 }
32197
32199 {
32200 expression_node_ptr branch[1] = { b0 };
32201 return (*this)(operation,branch);
32202 }
32203
32205 {
32207
32208 if ((0 != b0) && (0 != b1))
32209 {
32210 expression_node_ptr branch[2] = { b0, b1 };
32211 result = expression_generator<Type>::operator()(operation, branch);
32212 b0 = branch[0];
32213 b1 = branch[1];
32214 }
32215
32216 return result;
32217 }
32218
32220 expression_node_ptr consequent,
32221 expression_node_ptr alternative) const
32222 {
32223 if ((0 == condition) || (0 == consequent))
32224 {
32225 details::free_node(*node_allocator_, condition );
32226 details::free_node(*node_allocator_, consequent );
32227 details::free_node(*node_allocator_, alternative);
32228
32229 const std::string invalid_branches =
32230 ((0 == condition ) ? std::string("condition ") : "") +
32231 ((0 == consequent) ? std::string("consequent") : "") ;
32232
32236 "ERR247 - Invalid " + invalid_branches + " for conditional statement",
32238
32239 return error_node();
32240 }
32241 // Can the condition be immediately evaluated? if so optimise.
32242 else if (details::is_constant_node(condition))
32243 {
32244 // True branch
32245 if (details::is_true(condition))
32246 {
32247 details::free_node(*node_allocator_, condition );
32248 details::free_node(*node_allocator_, alternative);
32249
32250 return consequent;
32251 }
32252 // False branch
32253 else
32254 {
32255 details::free_node(*node_allocator_, condition );
32256 details::free_node(*node_allocator_, consequent);
32257
32258 if (alternative)
32259 return alternative;
32260 else
32262 }
32263 }
32264
32266 std::string node_name = "Unknown!";
32267
32268 if ((0 != consequent) && (0 != alternative))
32269 {
32270 result = node_allocator_->allocate<conditional_node_t>(condition, consequent, alternative);
32271 node_name = "conditional_node_t";
32272 }
32273 else
32274 {
32275 result = node_allocator_->allocate<cons_conditional_node_t>(condition, consequent);
32276 node_name = "cons_conditional_node_t";
32277 }
32278
32279 if (result && result->valid())
32280 {
32281 return result;
32282 }
32283
32286 token_t(),
32287 "ERR248 - Failed to synthesize node: " + node_name,
32289
32291 return error_node();
32292 }
32293
32294 #ifndef exprtk_disable_string_capabilities
32296 expression_node_ptr consequent,
32297 expression_node_ptr alternative) const
32298 {
32299 if ((0 == condition) || (0 == consequent))
32300 {
32301 details::free_node(*node_allocator_, condition );
32302 details::free_node(*node_allocator_, consequent );
32303 details::free_node(*node_allocator_, alternative);
32304
32305 const std::string invalid_branches =
32306 ((0 == condition ) ? std::string("condition ") : "") +
32307 ((0 == consequent) ? std::string("consequent") : "") ;
32308
32312 "ERR249 - Invalid " + invalid_branches + " for string conditional statement",
32314
32315 return error_node();
32316 }
32317 // Can the condition be immediately evaluated? if so optimise.
32318 else if (details::is_constant_node(condition))
32319 {
32320 // True branch
32321 if (details::is_true(condition))
32322 {
32323 details::free_node(*node_allocator_, condition );
32324 details::free_node(*node_allocator_, alternative);
32325
32326 return consequent;
32327 }
32328 // False branch
32329 else
32330 {
32331 details::free_node(*node_allocator_, condition );
32332 details::free_node(*node_allocator_, consequent);
32333
32334 if (alternative)
32335 return alternative;
32336 else
32337 return node_allocator_->
32338 allocate_c<details::string_literal_node<Type> >("");
32339 }
32340 }
32341 else if ((0 != consequent) && (0 != alternative))
32342 {
32343 expression_node_ptr result =
32344 node_allocator_->allocate<conditional_string_node_t>(condition, consequent, alternative);
32345
32346 if (result && result->valid())
32347 {
32348 return result;
32349 }
32350
32353 token_t(),
32354 "ERR250 - Failed to synthesize node: conditional_string_node_t",
32356
32358 }
32359
32360 return error_node();
32361 }
32362 #else
32365 expression_node_ptr) const
32366 {
32367 return error_node();
32368 }
32369 #endif
32370
32372 expression_node_ptr consequent,
32373 expression_node_ptr alternative) const
32374 {
32375 if ((0 == condition) || (0 == consequent))
32376 {
32377 details::free_node(*node_allocator_, condition );
32378 details::free_node(*node_allocator_, consequent );
32379 details::free_node(*node_allocator_, alternative);
32380
32381 const std::string invalid_branches =
32382 ((0 == condition ) ? std::string("condition ") : "") +
32383 ((0 == consequent) ? std::string("consequent") : "") ;
32384
32388 "ERR251 - Invalid " + invalid_branches + " for vector conditional statement",
32390
32391 return error_node();
32392 }
32393 // Can the condition be immediately evaluated? if so optimise.
32394 else if (details::is_constant_node(condition))
32395 {
32396 // True branch
32397 if (details::is_true(condition))
32398 {
32399 details::free_node(*node_allocator_, condition );
32400 details::free_node(*node_allocator_, alternative);
32401
32402 return consequent;
32403 }
32404 // False branch
32405 else
32406 {
32407 details::free_node(*node_allocator_, condition );
32408 details::free_node(*node_allocator_, consequent);
32409
32410 if (alternative)
32411 return alternative;
32412 else
32414
32415 }
32416 }
32417 else if ((0 != consequent) && (0 != alternative))
32418 {
32419 return node_allocator_->
32420 allocate<conditional_vector_node_t>(condition, consequent, alternative);
32421 }
32422 else
32423 return error_node();
32424 }
32425
32427 {
32428 if (
32430 (loop_type == (parser_->loop_runtime_check_->loop_set & loop_type))
32431 )
32432 {
32434 }
32435
32436 return loop_runtime_check_ptr(0);
32437 }
32438
32443
32445 expression_node_ptr& branch,
32446 const bool break_continue_present = false) const
32447 {
32448 if (
32449 !break_continue_present &&
32451 details::is_constant_node(condition)
32452 )
32453 {
32455 if (details::is_true(condition))
32456 {
32457 // Infinite loops are not allowed.
32458
32462 "ERR252 - Infinite loop condition without 'break' or 'return' not allowed in while-loops",
32464
32465 result = error_node();
32466 }
32467 else
32469
32472
32473 return result;
32474 }
32475 else if (details::is_null_node(condition))
32476 {
32478
32479 return branch;
32480 }
32481
32483
32484 if (!break_continue_present)
32485 {
32486 if (rtc)
32488 (condition, branch, rtc);
32489 else
32491 (condition, branch);
32492 }
32493 #ifndef exprtk_disable_break_continue
32494 else
32495 {
32496 if (rtc)
32498 (condition, branch, rtc);
32499 else
32501 (condition, branch);
32502 }
32503 #else
32504 return error_node();
32505 #endif
32506 }
32507
32509 expression_node_ptr& branch,
32510 const bool break_continue_present = false) const
32511 {
32512 if (!break_continue_present && details::is_constant_node(condition))
32513 {
32514 if (
32515 details::is_true(condition) &&
32517 )
32518 {
32519 free_node(*node_allocator_,condition);
32520
32521 return branch;
32522 }
32523
32526
32527 return error_node();
32528 }
32529 else if (details::is_null_node(condition))
32530 {
32532
32533 return branch;
32534 }
32535
32537
32538 if (!break_continue_present)
32539 {
32540 if (rtc)
32542 (condition, branch, rtc);
32543 else
32545 (condition, branch);
32546 }
32547 #ifndef exprtk_disable_break_continue
32548 else
32549 {
32550 if (rtc)
32552 (condition, branch, rtc);
32553 else
32555 (condition, branch);
32556 }
32557 #else
32558 return error_node();
32559 #endif
32560 }
32561
32563 expression_node_ptr& condition,
32564 expression_node_ptr& incrementor,
32565 expression_node_ptr& loop_body,
32566 bool break_continue_present = false) const
32567 {
32568 if (
32569 !break_continue_present &&
32571 details::is_constant_node(condition)
32572 )
32573 {
32575
32576 if (details::is_true(condition))
32577 {
32578 // Infinite loops are not allowed.
32579
32583 "ERR253 - Infinite loop condition without 'break' or 'return' not allowed in for-loop",
32585
32586 result = error_node();
32587 }
32588 else
32590
32591 details::free_node(*node_allocator_, initialiser);
32592 details::free_node(*node_allocator_, condition );
32593 details::free_node(*node_allocator_, incrementor);
32594 details::free_node(*node_allocator_, loop_body );
32595
32596 return result;
32597 }
32598 else if (details::is_null_node(condition) || (0 == condition))
32599 {
32600 details::free_node(*node_allocator_, initialiser);
32601 details::free_node(*node_allocator_, condition );
32602 details::free_node(*node_allocator_, incrementor);
32603
32604 return loop_body;
32605 }
32606
32608
32609 if (!break_continue_present)
32610 {
32611 if (rtc)
32613 (
32614 initialiser,
32615 condition,
32616 incrementor,
32617 loop_body,
32618 rtc
32619 );
32620 else
32622 (
32623 initialiser,
32624 condition,
32625 incrementor,
32626 loop_body
32627 );
32628 }
32629 #ifndef exprtk_disable_break_continue
32630 else
32631 {
32632 if (rtc)
32634 (
32635 initialiser,
32636 condition,
32637 incrementor,
32638 loop_body,
32639 rtc
32640 );
32641 else
32643 (
32644 initialiser,
32645 condition,
32646 incrementor,
32647 loop_body
32648 );
32649 }
32650 #else
32651 return error_node();
32652 #endif
32653 }
32654
32655 template <typename Allocator,
32656 template <typename, typename> class Sequence>
32657 inline expression_node_ptr const_optimise_switch(Sequence<expression_node_ptr,Allocator>& arg_list)
32658 {
32660
32661 for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
32662 {
32663 expression_node_ptr condition = arg_list[(2 * i) ];
32664 expression_node_ptr consequent = arg_list[(2 * i) + 1];
32665
32666 if ((0 == result) && details::is_true(condition))
32667 {
32668 result = consequent;
32669 break;
32670 }
32671 }
32672
32673 if (0 == result)
32674 {
32675 result = arg_list.back();
32676 }
32677
32678 for (std::size_t i = 0; i < arg_list.size(); ++i)
32679 {
32680 expression_node_ptr current_expr = arg_list[i];
32681
32682 if (current_expr && (current_expr != result))
32683 {
32684 free_node(*node_allocator_,current_expr);
32685 }
32686 }
32687
32688 return result;
32689 }
32690
32691 template <typename Allocator,
32692 template <typename, typename> class Sequence>
32693 inline expression_node_ptr const_optimise_mswitch(Sequence<expression_node_ptr,Allocator>& arg_list)
32694 {
32696
32697 for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
32698 {
32699 expression_node_ptr condition = arg_list[(2 * i) ];
32700 expression_node_ptr consequent = arg_list[(2 * i) + 1];
32701
32702 if (details::is_true(condition))
32703 {
32704 result = consequent;
32705 }
32706 }
32707
32708 if (0 == result)
32709 {
32710 const T zero = T(0);
32711 result = node_allocator_->allocate<literal_node_t>(zero);
32712 }
32713
32714 for (std::size_t i = 0; i < arg_list.size(); ++i)
32715 {
32716 expression_node_ptr& current_expr = arg_list[i];
32717
32718 if (current_expr && (current_expr != result))
32719 {
32720 details::free_node(*node_allocator_,current_expr);
32721 }
32722 }
32723
32724 return result;
32725 }
32726
32728 {
32729 typedef std::vector<std::pair<expression_node_ptr,bool> > arg_list_t;
32730
32731 #define case_stmt(N) \
32732 if (is_true(arg[(2 * N)].first)) { return arg[(2 * N) + 1].first->value(); } \
32733
32735 {
32736 static inline T process(const arg_list_t& arg)
32737 {
32738 case_stmt(0)
32739
32740 assert(arg.size() == ((2 * 1) + 1));
32741
32742 return arg.back().first->value();
32743 }
32744 };
32745
32747 {
32748 static inline T process(const arg_list_t& arg)
32749 {
32750 case_stmt(0) case_stmt(1)
32751
32752 assert(arg.size() == ((2 * 2) + 1));
32753
32754 return arg.back().first->value();
32755 }
32756 };
32757
32759 {
32760 static inline T process(const arg_list_t& arg)
32761 {
32762 case_stmt(0) case_stmt(1)
32763 case_stmt(2)
32764
32765 assert(arg.size() == ((2 * 3) + 1));
32766
32767 return arg.back().first->value();
32768 }
32769 };
32770
32772 {
32773 static inline T process(const arg_list_t& arg)
32774 {
32775 case_stmt(0) case_stmt(1)
32776 case_stmt(2) case_stmt(3)
32777
32778 assert(arg.size() == ((2 * 4) + 1));
32779
32780 return arg.back().first->value();
32781 }
32782 };
32783
32785 {
32786 static inline T process(const arg_list_t& arg)
32787 {
32788 case_stmt(0) case_stmt(1)
32789 case_stmt(2) case_stmt(3)
32790 case_stmt(4)
32791
32792 assert(arg.size() == ((2 * 5) + 1));
32793
32794 return arg.back().first->value();
32795 }
32796 };
32797
32799 {
32800 static inline T process(const arg_list_t& arg)
32801 {
32802 case_stmt(0) case_stmt(1)
32803 case_stmt(2) case_stmt(3)
32804 case_stmt(4) case_stmt(5)
32805
32806 assert(arg.size() == ((2 * 6) + 1));
32807
32808 return arg.back().first->value();
32809 }
32810 };
32811
32813 {
32814 static inline T process(const arg_list_t& arg)
32815 {
32816 case_stmt(0) case_stmt(1)
32817 case_stmt(2) case_stmt(3)
32818 case_stmt(4) case_stmt(5)
32819 case_stmt(6)
32820
32821 assert(arg.size() == ((2 * 7) + 1));
32822
32823 return arg.back().first->value();
32824 }
32825 };
32826
32827 #undef case_stmt
32828 };
32829
32830 template <typename Allocator,
32831 template <typename, typename> class Sequence>
32832 inline expression_node_ptr switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list, const bool default_statement_present)
32833 {
32834 if (arg_list.empty())
32835 return error_node();
32836 else if (
32837 !all_nodes_valid(arg_list) ||
32838 (!default_statement_present && (arg_list.size() < 2))
32839 )
32840 {
32842
32843 return error_node();
32844 }
32845 else if (is_constant_foldable(arg_list))
32846 return const_optimise_switch(arg_list);
32847
32848 switch ((arg_list.size() - 1) / 2)
32849 {
32850 #define case_stmt(N) \
32851 case N : \
32852 return node_allocator_-> \
32853 allocate<details::switch_n_node \
32854 <Type,typename switch_nodes::switch_impl_##N > >(arg_list); \
32855
32856 case_stmt(1)
32857 case_stmt(2)
32858 case_stmt(3)
32859 case_stmt(4)
32860 case_stmt(5)
32861 case_stmt(6)
32862 case_stmt(7)
32863 #undef case_stmt
32864
32865 default : return node_allocator_->allocate<details::switch_node<Type> >(arg_list);
32866 }
32867 }
32868
32869 template <typename Allocator,
32870 template <typename, typename> class Sequence>
32871 inline expression_node_ptr multi_switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list)
32872 {
32873 if (!all_nodes_valid(arg_list))
32874 {
32876
32877 return error_node();
32878 }
32879 else if (is_constant_foldable(arg_list))
32880 return const_optimise_mswitch(arg_list);
32881 else
32883 }
32884
32886 expression_node_ptr& assert_message,
32887 const assert_check::assert_context& context)
32888 {
32889 typedef details::assert_node<Type> alloc_type;
32890
32892 (assert_condition, assert_message, parser_->assert_check_, context);
32893
32894 if (result && result->valid())
32895 {
32896 parser_->state_.activate_side_effect("assert_call()");
32897 return result;
32898 }
32899
32901 details::free_node(*node_allocator_, assert_condition);
32902 details::free_node(*node_allocator_, assert_message );
32903
32904 return error_node();
32905 }
32906
32907 #define unary_opr_switch_statements \
32908 case_stmt(details::e_abs , details::abs_op ) \
32909 case_stmt(details::e_acos , details::acos_op ) \
32910 case_stmt(details::e_acosh , details::acosh_op) \
32911 case_stmt(details::e_asin , details::asin_op ) \
32912 case_stmt(details::e_asinh , details::asinh_op) \
32913 case_stmt(details::e_atan , details::atan_op ) \
32914 case_stmt(details::e_atanh , details::atanh_op) \
32915 case_stmt(details::e_ceil , details::ceil_op ) \
32916 case_stmt(details::e_cos , details::cos_op ) \
32917 case_stmt(details::e_cosh , details::cosh_op ) \
32918 case_stmt(details::e_exp , details::exp_op ) \
32919 case_stmt(details::e_expm1 , details::expm1_op) \
32920 case_stmt(details::e_floor , details::floor_op) \
32921 case_stmt(details::e_log , details::log_op ) \
32922 case_stmt(details::e_log10 , details::log10_op) \
32923 case_stmt(details::e_log2 , details::log2_op ) \
32924 case_stmt(details::e_log1p , details::log1p_op) \
32925 case_stmt(details::e_neg , details::neg_op ) \
32926 case_stmt(details::e_pos , details::pos_op ) \
32927 case_stmt(details::e_round , details::round_op) \
32928 case_stmt(details::e_sin , details::sin_op ) \
32929 case_stmt(details::e_sinc , details::sinc_op ) \
32930 case_stmt(details::e_sinh , details::sinh_op ) \
32931 case_stmt(details::e_sqrt , details::sqrt_op ) \
32932 case_stmt(details::e_tan , details::tan_op ) \
32933 case_stmt(details::e_tanh , details::tanh_op ) \
32934 case_stmt(details::e_cot , details::cot_op ) \
32935 case_stmt(details::e_sec , details::sec_op ) \
32936 case_stmt(details::e_csc , details::csc_op ) \
32937 case_stmt(details::e_r2d , details::r2d_op ) \
32938 case_stmt(details::e_d2r , details::d2r_op ) \
32939 case_stmt(details::e_d2g , details::d2g_op ) \
32940 case_stmt(details::e_g2d , details::g2d_op ) \
32941 case_stmt(details::e_notl , details::notl_op ) \
32942 case_stmt(details::e_sgn , details::sgn_op ) \
32943 case_stmt(details::e_erf , details::erf_op ) \
32944 case_stmt(details::e_erfc , details::erfc_op ) \
32945 case_stmt(details::e_ncdf , details::ncdf_op ) \
32946 case_stmt(details::e_frac , details::frac_op ) \
32947 case_stmt(details::e_trunc , details::trunc_op) \
32948
32950 expression_node_ptr (&branch)[1])
32951 {
32952 T& v = static_cast<details::variable_node<T>*>(branch[0])->ref();
32953
32954 switch (operation)
32955 {
32956 #define case_stmt(op0, op1) \
32957 case op0 : return node_allocator_-> \
32958 allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \
32959
32961 #undef case_stmt
32962 default : return error_node();
32963 }
32964 }
32965
32967 expression_node_ptr (&branch)[1])
32968 {
32969 switch (operation)
32970 {
32971 #define case_stmt(op0, op1) \
32972 case op0 : return node_allocator_-> \
32973 allocate<typename details::unary_vector_node<Type,op1<Type> > > \
32974 (operation, branch[0]); \
32975
32977 #undef case_stmt
32978 default : return error_node();
32979 }
32980 }
32981
32983 expression_node_ptr (&branch)[1])
32984 {
32985 switch (operation)
32986 {
32987 #define case_stmt(op0, op1) \
32988 case op0 : return node_allocator_-> \
32989 allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \
32990
32992 #undef case_stmt
32993 default : return error_node();
32994 }
32995 }
32996
32998 expression_node_ptr (&branch)[3])
32999 {
33000 expression_node_ptr temp_node = error_node();
33001
33002 switch (operation)
33003 {
33004 #define case_stmt(op) \
33005 case details::e_sf##op : temp_node = node_allocator_-> \
33006 allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
33007 (operation, branch); \
33008 break; \
33009
33010 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
33011 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
33012 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
33013 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
33014 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
33015 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
33016 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
33017 case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
33018 case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
33019 case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
33020 case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
33021 case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
33022 #undef case_stmt
33023 default : return error_node();
33024 }
33025
33026 assert(temp_node);
33027
33028 const T v = temp_node->value();
33029
33031
33033 }
33034
33036 {
33037 typedef details::variable_node<Type>* variable_ptr;
33038
33039 const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
33040 const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
33041 const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
33042
33043 switch (operation)
33044 {
33045 #define case_stmt(op) \
33046 case details::e_sf##op : return node_allocator_-> \
33047 allocate_rrr<details::sf3_var_node<Type,details::sf##op##_op<Type> > > \
33048 (v0, v1, v2); \
33049
33050 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
33051 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
33052 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
33053 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
33054 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
33055 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
33056 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
33057 case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
33058 case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
33059 case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
33060 case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
33061 case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
33062 #undef case_stmt
33063 default : return error_node();
33064 }
33065 }
33066
33068 {
33069 if (!all_nodes_valid(branch))
33070 return error_node();
33071 else if (is_constant_foldable(branch))
33072 return const_optimise_sf3(operation,branch);
33073 else if (all_nodes_variables(branch))
33074 return varnode_optimise_sf3(operation,branch);
33075 else
33076 {
33077 switch (operation)
33078 {
33079 #define case_stmt(op) \
33080 case details::e_sf##op : return node_allocator_-> \
33081 allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
33082 (operation, branch); \
33083
33084 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
33085 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
33086 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
33087 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
33088 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
33089 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
33090 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
33091 case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
33092 case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
33093 case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
33094 case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
33095 case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
33096 #undef case_stmt
33097 default : return error_node();
33098 }
33099 }
33100 }
33101
33103 {
33104 expression_node_ptr temp_node = error_node();
33105
33106 switch (operation)
33107 {
33108 #define case_stmt(op) \
33109 case details::e_sf##op : temp_node = node_allocator_-> \
33110 allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
33111 (operation, branch); \
33112 break; \
33113
33114 case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
33115 case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
33116 case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
33117 case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
33118 case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
33119 case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
33120 case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
33121 case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
33122 case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
33123 case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
33124 case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
33125 case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
33126 case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
33127 #undef case_stmt
33128 default : return error_node();
33129 }
33130
33131 assert(temp_node);
33132
33133 const T v = temp_node->value();
33134
33136
33138 }
33139
33141 {
33142 typedef details::variable_node<Type>* variable_ptr;
33143
33144 const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
33145 const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
33146 const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
33147 const Type& v3 = static_cast<variable_ptr>(branch[3])->ref();
33148
33149 switch (operation)
33150 {
33151 #define case_stmt(op) \
33152 case details::e_sf##op : return node_allocator_-> \
33153 allocate_rrrr<details::sf4_var_node<Type,details::sf##op##_op<Type> > > \
33154 (v0, v1, v2, v3); \
33155
33156 case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
33157 case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
33158 case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
33159 case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
33160 case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
33161 case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
33162 case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
33163 case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
33164 case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
33165 case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
33166 case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
33167 case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
33168 case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
33169 #undef case_stmt
33170 default : return error_node();
33171 }
33172 }
33173
33175 {
33176 if (!all_nodes_valid(branch))
33177 return error_node();
33178 else if (is_constant_foldable(branch))
33179 return const_optimise_sf4(operation,branch);
33180 else if (all_nodes_variables(branch))
33181 return varnode_optimise_sf4(operation,branch);
33182 switch (operation)
33183 {
33184 #define case_stmt(op) \
33185 case details::e_sf##op : return node_allocator_-> \
33186 allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
33187 (operation, branch); \
33188
33189 case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
33190 case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
33191 case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
33192 case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
33193 case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
33194 case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
33195 case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
33196 case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
33197 case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
33198 case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
33199 case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
33200 case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
33201 case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
33202 #undef case_stmt
33203 default : return error_node();
33204 }
33205 }
33206
33207 template <typename Allocator,
33208 template <typename, typename> class Sequence>
33209 inline expression_node_ptr const_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
33210 {
33211 expression_node_ptr temp_node = error_node();
33212
33213 switch (operation)
33214 {
33215 #define case_stmt(op0, op1) \
33216 case op0 : temp_node = node_allocator_-> \
33217 allocate<details::vararg_node<Type,op1<Type> > > \
33218 (arg_list); \
33219 break; \
33220
33229 #undef case_stmt
33230 default : return error_node();
33231 }
33232
33233 const T v = temp_node->value();
33234
33236
33238 }
33239
33240 inline bool special_one_parameter_vararg(const details::operator_type& operation) const
33241 {
33242 return (
33243 (details::e_sum == operation) ||
33244 (details::e_prod == operation) ||
33245 (details::e_avg == operation) ||
33246 (details::e_min == operation) ||
33247 (details::e_max == operation)
33248 );
33249 }
33250
33251 template <typename Allocator,
33252 template <typename, typename> class Sequence>
33254 Sequence<expression_node_ptr,Allocator>& arg_list)
33255 {
33256 switch (operation)
33257 {
33258 #define case_stmt(op0, op1) \
33259 case op0 : return node_allocator_-> \
33260 allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \
33261
33270 #undef case_stmt
33271 default : return error_node();
33272 }
33273 }
33274
33275 template <typename Allocator,
33276 template <typename, typename> class Sequence>
33278 Sequence<expression_node_ptr,Allocator>& arg_list)
33279 {
33280 if (1 == arg_list.size())
33281 {
33282 switch (operation)
33283 {
33284 #define case_stmt(op0, op1) \
33285 case op0 : return node_allocator_-> \
33286 allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \
33287
33293 #undef case_stmt
33294 default : return error_node();
33295 }
33296 }
33297 else
33298 return error_node();
33299 }
33300
33301 template <typename Allocator,
33302 template <typename, typename> class Sequence>
33304 Sequence<expression_node_ptr,Allocator>& arg_list)
33305 {
33306 if (!all_nodes_valid(arg_list))
33307 {
33309
33310 return error_node();
33311 }
33312 else if (is_constant_foldable(arg_list))
33313 return const_optimise_varargfunc(operation,arg_list);
33314 else if ((1 == arg_list.size()) && details::is_ivector_node(arg_list[0]))
33315 return vectorize_func(operation,arg_list);
33316 else if ((1 == arg_list.size()) && special_one_parameter_vararg(operation))
33317 return arg_list[0];
33318 else if (all_nodes_variables(arg_list))
33319 return varnode_optimise_varargfunc(operation,arg_list);
33320
33321 #ifndef exprtk_disable_string_capabilities
33322 if (details::e_smulti == operation)
33323 {
33325 allocate<details::str_vararg_node<Type,details::vararg_multi_op<Type> > >(arg_list);
33326 if (result && result->valid())
33327 {
33328 return result;
33329 }
33330
33333 token_t(),
33334 "ERR254 - Failed to synthesize node: str_vararg_node<vararg_multi_op>",
33336
33338 }
33339 else
33340 #endif
33341 {
33343
33344 switch (operation)
33345 {
33346 #define case_stmt(op0, op1) \
33347 case op0 : result = node_allocator_-> \
33348 allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \
33349 break; \
33350
33359 #undef case_stmt
33360 default : return error_node();
33361 }
33362
33363 if (result && result->valid())
33364 {
33365 return result;
33366 }
33367
33370 token_t(),
33371 "ERR255 - Failed to synthesize node: vararg_node",
33373
33375 }
33376
33377 return error_node();
33378 }
33379
33380 template <std::size_t N>
33382 {
33383 typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
33384 expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b);
33385
33386 if (0 == result)
33387 return error_node();
33388 else
33389 {
33390 // Can the function call be completely optimised?
33391 if (details::is_constant_node(result))
33392 return result;
33393 else if (!all_nodes_valid(b))
33394 {
33396 std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0));
33397
33398 return error_node();
33399 }
33400 else if (N != f->param_count)
33401 {
33403 std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0));
33404
33405 return error_node();
33406 }
33407
33408 function_N_node_t* func_node_ptr = reinterpret_cast<function_N_node_t*>(result);
33409
33410 if (!func_node_ptr->init_branches(b))
33411 {
33413 std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0));
33414
33415 return error_node();
33416 }
33417
33418 if (result && result->valid())
33419 {
33420 return result;
33421 }
33422
33425 token_t(),
33426 "ERR256 - Failed to synthesize node: function_N_node_t",
33428
33430 return error_node();
33431 }
33432 }
33433
33435 {
33436 typedef typename details::function_N_node<Type,ifunction_t,0> function_N_node_t;
33437 return node_allocator_->allocate<function_N_node_t>(f);
33438 }
33439
33441 std::vector<expression_node_ptr>& arg_list)
33442 {
33443 if (!all_nodes_valid(arg_list))
33444 {
33446
33447 return error_node();
33448 }
33449
33451
33452 expression_node_ptr result = node_allocator_->allocate<alloc_type>(vaf,arg_list);
33453
33454 if (
33455 !arg_list.empty() &&
33456 !vaf->has_side_effects() &&
33457 is_constant_foldable(arg_list)
33458 )
33459 {
33460 const Type v = result->value();
33463 }
33464
33465 parser_->state_.activate_side_effect("vararg_function_call()");
33466
33467 if (result && result->valid())
33468 {
33469 return result;
33470 }
33471
33474 token_t(),
33475 "ERR257 - Failed to synthesize node: vararg_function_node<ivararg_function_t>",
33477
33479 return error_node();
33480 }
33481
33483 std::vector<expression_node_ptr>& arg_list,
33484 const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
33485 {
33486 if (!all_nodes_valid(arg_list))
33487 {
33489 return error_node();
33490 }
33491
33494
33495 const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
33496
33498 std::string node_name = "Unknown";
33499
33500 if (no_psi == param_seq_index)
33501 {
33502 result = node_allocator_->allocate<alloc_type1>(arg_list,gf);
33503 node_name = "generic_function_node<igeneric_function_t>";
33504 }
33505 else
33506 {
33507 result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
33508 node_name = "multimode_genfunction_node<igeneric_function_t>";
33509 }
33510
33511 alloc_type1* genfunc_node_ptr = static_cast<alloc_type1*>(result);
33512
33513 assert(genfunc_node_ptr);
33514
33515 if (
33516 !arg_list.empty() &&
33517 !gf->has_side_effects() &&
33519 is_constant_foldable(arg_list)
33520 )
33521 {
33522 genfunc_node_ptr->init_branches();
33523
33524 const Type v = result->value();
33525
33527
33529 }
33530 else if (genfunc_node_ptr->init_branches())
33531 {
33532 if (result && result->valid())
33533 {
33534 parser_->state_.activate_side_effect("generic_function_call()");
33535 return result;
33536 }
33537
33540 token_t(),
33541 "ERR258 - Failed to synthesize node: " + node_name,
33543
33545 return error_node();
33546 }
33547 else
33548 {
33551
33552 return error_node();
33553 }
33554 }
33555
33556 #ifndef exprtk_disable_string_capabilities
33558 std::vector<expression_node_ptr>& arg_list,
33559 const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
33560 {
33561 if (!all_nodes_valid(arg_list))
33562 {
33564 return error_node();
33565 }
33566
33569
33570 const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
33571
33573 std::string node_name = "Unknown";
33574
33575 if (no_psi == param_seq_index)
33576 {
33577 result = node_allocator_->allocate<alloc_type1>(gf,arg_list);
33578 node_name = "string_function_node<igeneric_function_t>";
33579 }
33580 else
33581 {
33582 result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
33583 node_name = "multimode_strfunction_node<igeneric_function_t>";
33584 }
33585
33586 alloc_type1* strfunc_node_ptr = static_cast<alloc_type1*>(result);
33587
33588 assert(strfunc_node_ptr);
33589
33590 if (
33591 !arg_list.empty() &&
33592 !gf->has_side_effects() &&
33593 is_constant_foldable(arg_list)
33594 )
33595 {
33596 strfunc_node_ptr->init_branches();
33597
33598 const Type v = result->value();
33599
33601
33603 }
33604 else if (strfunc_node_ptr->init_branches())
33605 {
33606 if (result && result->valid())
33607 {
33608 parser_->state_.activate_side_effect("string_function_call()");
33609 return result;
33610 }
33611
33614 token_t(),
33615 "ERR259 - Failed to synthesize node: " + node_name,
33617
33619 return error_node();
33620 }
33621 else
33622 {
33625
33626 return error_node();
33627 }
33628 }
33629 #endif
33630
33631 #ifndef exprtk_disable_return_statement
33632 inline expression_node_ptr return_call(std::vector<expression_node_ptr>& arg_list)
33633 {
33634 if (!all_nodes_valid(arg_list))
33635 {
33637 return error_node();
33638 }
33639
33640 typedef details::return_node<Type> alloc_type;
33641
33643 allocate_rr<alloc_type>(arg_list,parser_->results_ctx());
33644
33645 alloc_type* return_node_ptr = static_cast<alloc_type*>(result);
33646
33647 assert(return_node_ptr);
33648
33649 if (return_node_ptr->init_branches())
33650 {
33651 if (result && result->valid())
33652 {
33653 parser_->state_.activate_side_effect("return_call()");
33654 return result;
33655 }
33656
33659 token_t(),
33660 "ERR260 - Failed to synthesize node: return_node",
33662
33664 return error_node();
33665 }
33666 else
33667 {
33670
33671 return error_node();
33672 }
33673 }
33674
33677 bool*& return_invoked)
33678 {
33679 typedef details::return_envelope_node<Type> alloc_type;
33680
33682 allocate_cr<alloc_type>(body,(*rc));
33683
33684 return_invoked = static_cast<alloc_type*>(result)->retinvk_ptr();
33685
33686 return result;
33687 }
33688 #else
33689 inline expression_node_ptr return_call(std::vector<expression_node_ptr>&)
33690 {
33691 return error_node();
33692 }
33693
33696 bool*&)
33697 {
33698 return error_node();
33699 }
33700 #endif
33701
33702 inline expression_node_ptr vector_element(const std::string& symbol,
33703 vector_holder_ptr vector_base,
33704 expression_node_ptr vec_node,
33705 expression_node_ptr index)
33706 {
33708 std::string node_name = "Unknown";
33709
33710 if (details::is_constant_node(index))
33711 {
33712 const std::size_t vec_index = static_cast<std::size_t>(details::numeric::to_int64(index->value()));
33713
33715
33716 if (vec_index >= vector_base->size())
33717 {
33720 token_t(),
33721 "ERR261 - Index of " + details::to_str(vec_index) + " out of range for "
33722 "vector '" + symbol + "' of size " + details::to_str(vector_base->size()),
33724
33726
33727 return error_node();
33728 }
33729
33730 if (vector_base->rebaseable())
33731 {
33733
33734 result = (rtc) ?
33735 node_allocator_->allocate<rebasevector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) :
33736 node_allocator_->allocate<rebasevector_celem_node_t >(vec_node, vec_index, vector_base ) ;
33737
33738 node_name = (rtc) ?
33739 "rebasevector_elem_rtc_node_t" :
33740 "rebasevector_elem_node_t" ;
33741
33742 if (result && result->valid())
33743 {
33744 return result;
33745 }
33746
33749 token_t(),
33750 "ERR262 - Failed to synthesize node: " + node_name + " for vector: " + symbol,
33752
33754 return error_node();
33755 }
33756 else if (details::is_ivector_node(vec_node) && !details::is_vector_node(vec_node))
33757 {
33759
33760 result = (rtc) ?
33761 node_allocator_->allocate<vector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) :
33762 node_allocator_->allocate<vector_celem_node_t >(vec_node, vec_index, vector_base ) ;
33763
33764 node_name = (rtc) ?
33765 "vector_elem_rtc_node_t" :
33766 "vector_elem_node_t" ;
33767
33768 if (result && result->valid())
33769 {
33770 return result;
33771 }
33772
33775 token_t(),
33776 "ERR263 - Failed to synthesize node: " + node_name + " for vector: " + symbol,
33778
33780 return error_node();
33781 }
33782
33783 const scope_element& se = parser_->sem_.get_element(symbol,vec_index);
33784
33785 if (se.index == vec_index)
33786 {
33787 result = se.var_node;
33789 }
33790 else
33791 {
33792 scope_element nse;
33793 nse.name = symbol;
33794 nse.active = true;
33795 nse.ref_count = 1;
33797 nse.index = vec_index;
33799 nse.data = 0;
33800 nse.var_node = node_allocator_->allocate<variable_node_t>((*(*vector_base)[vec_index]));
33801
33802 if (!parser_->sem_.add_element(nse))
33803 {
33804 parser_->set_synthesis_error("Failed to add new local vector element to SEM [1]");
33805
33807
33808 result = error_node();
33809 }
33810
33812
33813 exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n", nse.name.c_str()));
33814
33815 parser_->state_.activate_side_effect("vector_element()");
33816
33817 result = nse.var_node;
33818 node_name = "variable_node_t";
33819 }
33820 }
33821 else
33822 {
33824
33825 if (vector_base->rebaseable())
33826 {
33827 result = (rtc) ?
33828 node_allocator_->allocate<rebasevector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) :
33829 node_allocator_->allocate<rebasevector_elem_node_t >(vec_node, index, vector_base ) ;
33830
33831 node_name = (rtc) ?
33832 "rebasevector_elem_rtc_node_t" :
33833 "rebasevector_elem_node_t" ;
33834 }
33835 else
33836 {
33837 result = rtc ?
33838 node_allocator_->allocate<vector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) :
33839 node_allocator_->allocate<vector_elem_node_t >(vec_node, index, vector_base ) ;
33840
33841 node_name = (rtc) ?
33842 "vector_elem_rtc_node_t" :
33843 "vector_elem_node_t" ;
33844 }
33845 }
33846
33847 if (result && result->valid())
33848 {
33849 return result;
33850 }
33851
33854 token_t(),
33855 "ERR264 - Failed to synthesize node: " + node_name,
33857
33859 return error_node();
33860 }
33861
33862 private:
33863
33864 template <std::size_t N, typename NodePtr>
33865 inline bool is_constant_foldable(NodePtr (&b)[N]) const
33866 {
33867 for (std::size_t i = 0; i < N; ++i)
33868 {
33869 if (0 == b[i])
33870 return false;
33871 else if (!details::is_constant_node(b[i]))
33872 return false;
33873 }
33874
33875 return true;
33876 }
33877
33878 template <typename NodePtr,
33879 typename Allocator,
33880 template <typename, typename> class Sequence>
33881 inline bool is_constant_foldable(const Sequence<NodePtr,Allocator>& b) const
33882 {
33883 for (std::size_t i = 0; i < b.size(); ++i)
33884 {
33885 if (0 == b[i])
33886 return false;
33887 else if (!details::is_constant_node(b[i]))
33888 return false;
33889 }
33890
33891 return true;
33892 }
33893
33895 {
33896 parser_->state_.activate_side_effect("lodge_assignment()");
33897
33899 return;
33900
33901 std::string symbol_name;
33902
33903 switch (cst)
33904 {
33905 case e_st_variable : symbol_name = parser_->symtab_store_
33906 .get_variable_name(node);
33907 break;
33908
33909 #ifndef exprtk_disable_string_capabilities
33910 case e_st_string : symbol_name = parser_->symtab_store_
33911 .get_stringvar_name(node);
33912 break;
33913 #endif
33914
33915 case e_st_vector : {
33917
33918 vector_holder_t& vh = static_cast<vector_node_t*>(node)->vec_holder();
33919
33920 symbol_name = parser_->symtab_store_.get_vector_name(&vh);
33921 }
33922 break;
33923
33924 case e_st_vecelem : {
33926
33927 vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder();
33928
33929 symbol_name = parser_->symtab_store_.get_vector_name(&vh);
33930
33931 cst = e_st_vector;
33932 }
33933 break;
33934
33935 default : return;
33936 }
33937
33938 if (!symbol_name.empty())
33939 {
33940 parser_->dec_.add_assignment(symbol_name,cst);
33941 }
33942 }
33943
33945 {
33946 if (node)
33947 {
33948 switch(node->type())
33949 {
33951 return reinterpret_cast<const void*>(&static_cast<variable_node_t*>(node)->ref());
33952
33954 return reinterpret_cast<const void*>(&static_cast<vector_elem_node_t*>(node)->ref());
33955
33957 return reinterpret_cast<const void*>(&static_cast<vector_celem_node_t*>(node)->ref());
33958
33960 return reinterpret_cast<const void*>(&static_cast<vector_elem_rtc_node_t*>(node)->ref());
33961
33963 return reinterpret_cast<const void*>(&static_cast<vector_celem_rtc_node_t*>(node)->ref());
33964
33966 return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_node_t*>(node)->ref());
33967
33969 return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_rtc_node_t*>(node)->ref());
33970
33972 return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_node_t*>(node)->ref());
33973
33975 return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_rtc_node_t*>(node)->ref());
33976
33978 return reinterpret_cast<const void*>(static_cast<vector_node_t*>(node)->vec_holder().data());
33979
33980 #ifndef exprtk_disable_string_capabilities
33982 return reinterpret_cast<const void*>((static_cast<stringvar_node_t*>(node)->base()));
33983
33985 return reinterpret_cast<const void*>((static_cast<string_range_node_t*>(node)->base()));
33986 #endif
33987 default : return reinterpret_cast<const void*>(0);
33988 }
33989 }
33990
33991 return reinterpret_cast<const void*>(0);
33992 }
33993
33995 {
33996 interval_t interval;
33997 const void* baseptr_addr = base_ptr(node);
33998
33999 exprtk_debug(("assign_immutable_symbol - base ptr addr: %p\n", baseptr_addr));
34000
34001 if (parser_->immutable_memory_map_.in_interval(baseptr_addr,interval))
34002 {
34003 typename immutable_symtok_map_t::iterator itr = parser_->immutable_symtok_map_.find(interval);
34004
34005 if (parser_->immutable_symtok_map_.end() != itr)
34006 {
34007 token_t& token = itr->second;
34010 token,
34011 "ERR265 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.",
34013 }
34014 else
34015 parser_->set_synthesis_error("Unable to assign symbol is immutable.");
34016
34017 return true;
34018 }
34019
34020 return false;
34021 }
34022
34024 {
34025 if (assign_immutable_symbol(branch[0]))
34026 {
34027 return error_node();
34028 }
34029 else if (details::is_variable_node(branch[0]))
34030 {
34032 return synthesize_expression<assignment_node_t,2>(operation,branch);
34033 }
34034 else if (details::is_vector_elem_node(branch[0]) || details::is_vector_celem_node(branch[0]))
34035 {
34036 lodge_assignment(e_st_vecelem,branch[0]);
34037 return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch);
34038 }
34040 {
34041 lodge_assignment(e_st_vecelem,branch[0]);
34042 return synthesize_expression<assignment_vec_elem_rtc_node_t, 2>(operation, branch);
34043 }
34044 else if (details::is_rebasevector_elem_node(branch[0]))
34045 {
34046 lodge_assignment(e_st_vecelem,branch[0]);
34047 return synthesize_expression<assignment_rebasevec_elem_node_t, 2>(operation, branch);
34048 }
34049 else if (details::is_rebasevector_elem_rtc_node(branch[0]))
34050 {
34051 lodge_assignment(e_st_vecelem,branch[0]);
34052 return synthesize_expression<assignment_rebasevec_elem_rtc_node_t, 2>(operation, branch);
34053 }
34054 else if (details::is_rebasevector_celem_node(branch[0]))
34055 {
34056 lodge_assignment(e_st_vecelem,branch[0]);
34057 return synthesize_expression<assignment_rebasevec_celem_node_t, 2>(operation, branch);
34058 }
34059 #ifndef exprtk_disable_string_capabilities
34060 else if (details::is_string_node(branch[0]))
34061 {
34062 lodge_assignment(e_st_string,branch[0]);
34063 return synthesize_expression<assignment_string_node_t,2>(operation, branch);
34064 }
34065 else if (details::is_string_range_node(branch[0]))
34066 {
34067 lodge_assignment(e_st_string,branch[0]);
34068 return synthesize_expression<assignment_string_range_node_t,2>(operation, branch);
34069 }
34070 #endif
34071 else if (details::is_vector_node(branch[0]))
34072 {
34073 lodge_assignment(e_st_vector,branch[0]);
34074
34075 if (details::is_ivector_node(branch[1]))
34076 return synthesize_expression<assignment_vecvec_node_t,2>(operation, branch);
34077 else
34078 return synthesize_expression<assignment_vec_node_t,2>(operation, branch);
34079 }
34080 else if (details::is_literal_node(branch[0]))
34081 {
34085 "ERR266 - Cannot assign value to const variable",
34087
34088 return error_node();
34089 }
34090 else
34091 {
34095 "ERR267 - Invalid branches for assignment operator '" + details::to_str(operation) + "'",
34097
34098 return error_node();
34099 }
34100 }
34101
34103 expression_node_ptr (&branch)[2])
34104 {
34105 if (assign_immutable_symbol(branch[0]))
34106 {
34107 return error_node();
34108 }
34109
34111 std::string node_name = "Unknown";
34112
34113 if (details::is_variable_node(branch[0]))
34114 {
34116
34117 switch (operation)
34118 {
34119 #define case_stmt(op0, op1) \
34120 case op0 : result = node_allocator_-> \
34121 template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \
34122 (operation, branch[0], branch[1]); \
34123 node_name = "assignment_op_node"; \
34124 break; \
34125
34131 #undef case_stmt
34132 default : return error_node();
34133 }
34134 }
34135 else if (details::is_vector_elem_node(branch[0]))
34136 {
34137 lodge_assignment(e_st_vecelem,branch[0]);
34138
34139 switch (operation)
34140 {
34141 #define case_stmt(op0, op1) \
34142 case op0 : result = node_allocator_-> \
34143 template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \
34144 (operation, branch[0], branch[1]); \
34145 node_name = "assignment_vec_elem_op_node"; \
34146 break; \
34147
34153 #undef case_stmt
34154 default : return error_node();
34155 }
34156 }
34157 else if (details::is_vector_elem_rtc_node(branch[0]))
34158 {
34159 lodge_assignment(e_st_vecelem,branch[0]);
34160
34161 switch (operation)
34162 {
34163 #define case_stmt(op0, op1) \
34164 case op0 : result = node_allocator_-> \
34165 template allocate_rrr<typename details::assignment_vec_elem_op_rtc_node<Type,op1<Type> > > \
34166 (operation, branch[0], branch[1]); \
34167 node_name = "assignment_vec_elem_op_rtc_node"; \
34168 break; \
34169
34175 #undef case_stmt
34176 default : return error_node();
34177 }
34178 }
34179 else if (details::is_vector_celem_rtc_node(branch[0]))
34180 {
34181 lodge_assignment(e_st_vecelem,branch[0]);
34182
34183 switch (operation)
34184 {
34185 #define case_stmt(op0, op1) \
34186 case op0 : result = node_allocator_-> \
34187 template allocate_rrr<typename details::assignment_vec_celem_op_rtc_node<Type,op1<Type> > > \
34188 (operation, branch[0], branch[1]); \
34189 node_name = "assignment_vec_celem_op_rtc_node"; \
34190 break; \
34191
34197 #undef case_stmt
34198 default : return error_node();
34199 }
34200 }
34201 else if (details::is_rebasevector_elem_node(branch[0]))
34202 {
34203 lodge_assignment(e_st_vecelem,branch[0]);
34204
34205 switch (operation)
34206 {
34207 #define case_stmt(op0, op1) \
34208 case op0 : result = node_allocator_-> \
34209 template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \
34210 (operation, branch[0], branch[1]); \
34211 node_name = "assignment_rebasevec_elem_op_node"; \
34212 break; \
34213
34219 #undef case_stmt
34220 default : return error_node();
34221 }
34222 }
34223 else if (details::is_rebasevector_celem_node(branch[0]))
34224 {
34225 lodge_assignment(e_st_vecelem,branch[0]);
34226
34227 switch (operation)
34228 {
34229 #define case_stmt(op0, op1) \
34230 case op0 : result = node_allocator_-> \
34231 template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \
34232 (operation, branch[0], branch[1]); \
34233 node_name = "assignment_rebasevec_celem_op_node"; \
34234 break; \
34235
34241 #undef case_stmt
34242 default : return error_node();
34243 }
34244 }
34245 else if (details::is_rebasevector_elem_rtc_node(branch[0]))
34246 {
34247 lodge_assignment(e_st_vecelem,branch[0]);
34248
34249 switch (operation)
34250 {
34251 #define case_stmt(op0, op1) \
34252 case op0 : result = node_allocator_-> \
34253 template allocate_rrr<typename details::assignment_rebasevec_elem_op_rtc_node<Type,op1<Type> > > \
34254 (operation, branch[0], branch[1]); \
34255 node_name = "assignment_rebasevec_elem_op_rtc_node"; \
34256 break; \
34257
34263 #undef case_stmt
34264 default : return error_node();
34265 }
34266 }
34267 else if (details::is_rebasevector_celem_rtc_node(branch[0]))
34268 {
34269 lodge_assignment(e_st_vecelem,branch[0]);
34270
34271 switch (operation)
34272 {
34273 #define case_stmt(op0, op1) \
34274 case op0 : result = node_allocator_-> \
34275 template allocate_rrr<typename details::assignment_rebasevec_celem_op_rtc_node<Type,op1<Type> > > \
34276 (operation, branch[0], branch[1]); \
34277 node_name = "assignment_rebasevec_celem_op_rtc_node"; \
34278 break; \
34279
34285 #undef case_stmt
34286 default : return error_node();
34287 }
34288 }
34289 else if (details::is_vector_node(branch[0]))
34290 {
34291 lodge_assignment(e_st_vector,branch[0]);
34292
34293 if (details::is_ivector_node(branch[1]))
34294 {
34295 switch (operation)
34296 {
34297 #define case_stmt(op0, op1) \
34298 case op0 : result = node_allocator_-> \
34299 template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \
34300 (operation, branch[0], branch[1]); \
34301 node_name = "assignment_rebasevec_celem_op_node"; \
34302 break; \
34303
34309 #undef case_stmt
34310 default : return error_node();
34311 }
34312 }
34313 else
34314 {
34315 switch (operation)
34316 {
34317 #define case_stmt(op0, op1) \
34318 case op0 : result = node_allocator_-> \
34319 template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \
34320 (operation, branch[0], branch[1]); \
34321 node_name = "assignment_vec_op_node"; \
34322 break; \
34323
34329 #undef case_stmt
34330 default : return error_node();
34331 }
34332 }
34333 }
34334 #ifndef exprtk_disable_string_capabilities
34335 else if (
34336 (details::e_addass == operation) &&
34337 details::is_string_node(branch[0])
34338 )
34339 {
34341
34342 lodge_assignment(e_st_string,branch[0]);
34343
34344 result = synthesize_expression<addass_t,2>(operation,branch);
34345 node_name = "assignment_string_node<T,details::asn_addassignment>";
34346 }
34347 #endif
34348 else
34349 {
34353 "ERR268 - Invalid branches for assignment operator '" + details::to_str(operation) + "'",
34355
34356 return error_node();
34357 }
34358
34359 if (result && result->valid())
34360 {
34361 return result;
34362 }
34363
34366 token_t(),
34367 "ERR269 - Failed to synthesize node: " + node_name,
34369
34371 return error_node();
34372 }
34373
34375 expression_node_ptr (&branch)[2])
34376 {
34377 const bool is_b0_ivec = details::is_ivector_node(branch[0]);
34378 const bool is_b1_ivec = details::is_ivector_node(branch[1]);
34379
34380 #define batch_eqineq_logic_case \
34381 case_stmt(details::e_lt , details::lt_op ) \
34382 case_stmt(details::e_lte , details::lte_op ) \
34383 case_stmt(details::e_gt , details::gt_op ) \
34384 case_stmt(details::e_gte , details::gte_op ) \
34385 case_stmt(details::e_eq , details::eq_op ) \
34386 case_stmt(details::e_ne , details::ne_op ) \
34387 case_stmt(details::e_equal , details::equal_op) \
34388 case_stmt(details::e_and , details::and_op ) \
34389 case_stmt(details::e_nand , details::nand_op ) \
34390 case_stmt(details::e_or , details::or_op ) \
34391 case_stmt(details::e_nor , details::nor_op ) \
34392 case_stmt(details::e_xor , details::xor_op ) \
34393 case_stmt(details::e_xnor , details::xnor_op ) \
34394
34396 std::string node_name = "Unknown";
34397
34398 if (is_b0_ivec && is_b1_ivec)
34399 {
34400 switch (operation)
34401 {
34402 #define case_stmt(op0, op1) \
34403 case op0 : result = node_allocator_-> \
34404 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
34405 (operation, branch[0], branch[1]); \
34406 node_name = "vec_binop_vecvec_node"; \
34407 break; \
34408
34410 #undef case_stmt
34411 default : return error_node();
34412 }
34413 }
34414 else if (is_b0_ivec && !is_b1_ivec)
34415 {
34416 switch (operation)
34417 {
34418 #define case_stmt(op0, op1) \
34419 case op0 : result = node_allocator_-> \
34420 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
34421 (operation, branch[0], branch[1]); \
34422 node_name = "vec_binop_vecval_node"; \
34423 break; \
34424
34426 #undef case_stmt
34427 default : return error_node();
34428 }
34429 }
34430 else if (!is_b0_ivec && is_b1_ivec)
34431 {
34432 switch (operation)
34433 {
34434 #define case_stmt(op0, op1) \
34435 case op0 : result = node_allocator_-> \
34436 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
34437 (operation, branch[0], branch[1]); \
34438 node_name = "vec_binop_valvec_node"; \
34439 break; \
34440
34442 #undef case_stmt
34443 default : return error_node();
34444 }
34445 }
34446 else
34447 return error_node();
34448
34449 if (result && result->valid())
34450 {
34451 return result;
34452 }
34453
34456 token_t(),
34457 "ERR270 - Failed to synthesize node: " + node_name,
34459
34461 return error_node();
34462
34463 #undef batch_eqineq_logic_case
34464 }
34465
34467 expression_node_ptr (&branch)[2])
34468 {
34469 const bool is_b0_ivec = details::is_ivector_node(branch[0]);
34470 const bool is_b1_ivec = details::is_ivector_node(branch[1]);
34471
34472 #define vector_ops \
34473 case_stmt(details::e_add , details::add_op) \
34474 case_stmt(details::e_sub , details::sub_op) \
34475 case_stmt(details::e_mul , details::mul_op) \
34476 case_stmt(details::e_div , details::div_op) \
34477 case_stmt(details::e_mod , details::mod_op) \
34478
34480 std::string node_name = "Unknown";
34481
34482 if (is_b0_ivec && is_b1_ivec)
34483 {
34484 switch (operation)
34485 {
34486 #define case_stmt(op0, op1) \
34487 case op0 : result = node_allocator_-> \
34488 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
34489 (operation, branch[0], branch[1]); \
34490 node_name = "vec_binop_vecvec_node"; \
34491 break; \
34492
34494 case_stmt(details::e_pow,details:: pow_op)
34495 #undef case_stmt
34496 default : return error_node();
34497 }
34498 }
34499 else if (is_b0_ivec && !is_b1_ivec)
34500 {
34501 switch (operation)
34502 {
34503 #define case_stmt(op0, op1) \
34504 case op0 : result = node_allocator_-> \
34505 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
34506 (operation, branch[0], branch[1]); \
34507 node_name = "vec_binop_vecval_node(b0ivec,!b1ivec)"; \
34508 break; \
34509
34511 case_stmt(details::e_pow,details:: pow_op)
34512 #undef case_stmt
34513 default : return error_node();
34514 }
34515 }
34516 else if (!is_b0_ivec && is_b1_ivec)
34517 {
34518 switch (operation)
34519 {
34520 #define case_stmt(op0, op1) \
34521 case op0 : result = node_allocator_-> \
34522 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
34523 (operation, branch[0], branch[1]); \
34524 node_name = "vec_binop_vecval_node(!b0ivec,b1ivec)"; \
34525 break; \
34526
34528 #undef case_stmt
34529 default : return error_node();
34530 }
34531 }
34532 else
34533 return error_node();
34534
34535 if (result && result->valid())
34536 {
34537 return result;
34538 }
34539
34542 token_t(),
34543 "ERR271 - Failed to synthesize node: " + node_name,
34545
34547 return error_node();
34548
34549 #undef vector_ops
34550 }
34551
34553 {
34554 const bool v0_is_ivar = details::is_ivariable_node(branch[0]);
34555 const bool v1_is_ivar = details::is_ivariable_node(branch[1]);
34556
34557 const bool v0_is_ivec = details::is_ivector_node (branch[0]);
34558 const bool v1_is_ivec = details::is_ivector_node (branch[1]);
34559
34560 #ifndef exprtk_disable_string_capabilities
34561 const bool v0_is_str = details::is_generally_string_node(branch[0]);
34562 const bool v1_is_str = details::is_generally_string_node(branch[1]);
34563 #endif
34564
34566 std::string node_name = "Unknown";
34567
34568 if (v0_is_ivar && v1_is_ivar)
34569 {
34570 typedef details::variable_node<T>* variable_node_ptr;
34571
34572 variable_node_ptr v0 = variable_node_ptr(0);
34573 variable_node_ptr v1 = variable_node_ptr(0);
34574
34575 if (
34576 (0 != (v0 = dynamic_cast<variable_node_ptr>(branch[0]))) &&
34577 (0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1])))
34578 )
34579 {
34581 node_name = "swap_node";
34582 }
34583 else
34584 {
34585 result = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
34586 node_name = "swap_generic_node";
34587 }
34588 }
34589 else if (v0_is_ivec && v1_is_ivec)
34590 {
34591 result = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
34592 node_name = "swap_vecvec_node";
34593 }
34594 #ifndef exprtk_disable_string_capabilities
34595 else if (v0_is_str && v1_is_str)
34596 {
34597 if (is_string_node(branch[0]) && is_string_node(branch[1]))
34598 {
34600 (branch[0], branch[1]);
34601 node_name = "swap_string_node";
34602 }
34603 else
34604 {
34606 (branch[0], branch[1]);
34607 node_name = "swap_genstrings_node";
34608 }
34609 }
34610 #endif
34611 else
34612 {
34613 parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped");
34614 return error_node();
34615 }
34616
34617 if (result && result->valid())
34618 {
34619 parser_->state_.activate_side_effect("synthesize_swap_expression()");
34620 return result;
34621 }
34622
34625 token_t(),
34626 "ERR272 - Failed to synthesize node: " + node_name,
34628
34630 return error_node();
34631 }
34632
34633 #ifndef exprtk_disable_sc_andor
34635 {
34637
34638 if (details::is_constant_node(branch[0]))
34639 {
34640 if (
34641 (details::e_scand == operation) &&
34642 std::equal_to<T>()(T(0),branch[0]->value())
34643 )
34644 result = node_allocator_->allocate_c<literal_node_t>(T(0));
34645 else if (
34646 (details::e_scor == operation) &&
34647 std::not_equal_to<T>()(T(0),branch[0]->value())
34648 )
34649 result = node_allocator_->allocate_c<literal_node_t>(T(1));
34650 }
34651
34652 if (details::is_constant_node(branch[1]) && (0 == result))
34653 {
34654 if (
34655 (details::e_scand == operation) &&
34656 std::equal_to<T>()(T(0),branch[1]->value())
34657 )
34658 result = node_allocator_->allocate_c<literal_node_t>(T(0));
34659 else if (
34660 (details::e_scor == operation) &&
34661 std::not_equal_to<T>()(T(0),branch[1]->value())
34662 )
34663 result = node_allocator_->allocate_c<literal_node_t>(T(1));
34664 }
34665
34666 if (result)
34667 {
34670
34671 return result;
34672 }
34673 else if (details::e_scand == operation)
34674 {
34675 return synthesize_expression<scand_node_t,2>(operation, branch);
34676 }
34677 else if (details::e_scor == operation)
34678 {
34679 return synthesize_expression<scor_node_t,2>(operation, branch);
34680 }
34681 else
34682 return error_node();
34683 }
34684 #else
34686 {
34687 return error_node();
34688 }
34689 #endif
34690
34691 #define basic_opr_switch_statements \
34692 case_stmt(details::e_add , details::add_op) \
34693 case_stmt(details::e_sub , details::sub_op) \
34694 case_stmt(details::e_mul , details::mul_op) \
34695 case_stmt(details::e_div , details::div_op) \
34696 case_stmt(details::e_mod , details::mod_op) \
34697 case_stmt(details::e_pow , details::pow_op) \
34698
34699 #define extended_opr_switch_statements \
34700 case_stmt(details::e_lt , details::lt_op ) \
34701 case_stmt(details::e_lte , details::lte_op ) \
34702 case_stmt(details::e_gt , details::gt_op ) \
34703 case_stmt(details::e_gte , details::gte_op ) \
34704 case_stmt(details::e_eq , details::eq_op ) \
34705 case_stmt(details::e_ne , details::ne_op ) \
34706 case_stmt(details::e_and , details::and_op ) \
34707 case_stmt(details::e_nand , details::nand_op) \
34708 case_stmt(details::e_or , details::or_op ) \
34709 case_stmt(details::e_nor , details::nor_op ) \
34710 case_stmt(details::e_xor , details::xor_op ) \
34711 case_stmt(details::e_xnor , details::xnor_op) \
34712
34713 #ifndef exprtk_disable_cardinal_pow_optimisation
34714 template <typename TType, template <typename, typename> class IPowNode>
34715 inline expression_node_ptr cardinal_pow_optimisation_impl(const TType& v, const unsigned int& p)
34716 {
34717 switch (p)
34718 {
34719 #define case_stmt(cp) \
34720 case cp : return node_allocator_-> \
34721 allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
34722
34723 case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
34724 case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
34725 case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
34726 case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16)
34727 case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20)
34728 case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24)
34729 case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28)
34730 case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32)
34731 case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36)
34732 case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40)
34733 case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44)
34734 case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48)
34735 case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52)
34736 case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56)
34737 case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60)
34738 #undef case_stmt
34739 default : return error_node();
34740 }
34741 }
34742
34743 inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c)
34744 {
34745 const bool not_recipricol = (c >= T(0));
34746 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
34747
34748 if (0 == p)
34750 else if (std::equal_to<T>()(T(2),c))
34751 {
34752 return node_allocator_->
34753 template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v);
34754 }
34755 else
34756 {
34757 if (not_recipricol)
34758 return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p);
34759 else
34760 return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p);
34761 }
34762 }
34763
34764 inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const
34765 {
34766 return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
34767 }
34768
34770 {
34771 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
34772 const bool not_recipricol = (c >= T(0));
34773 const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
34774
34775 node_allocator_->free(branch[1]);
34776
34777 if (0 == p)
34778 {
34780
34782 }
34783 else if (not_recipricol)
34784 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p);
34785 else
34786 return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p);
34787 }
34788 #else
34790 {
34791 return error_node();
34792 }
34793
34794 inline bool cardinal_pow_optimisable(const details::operator_type&, const T&)
34795 {
34796 return false;
34797 }
34798
34800 {
34801 return error_node();
34802 }
34803 #endif
34804
34806 {
34808 const details::operator_type& operation,
34809 expression_node_ptr (&branch)[2])
34810 {
34811 const bool left_neg = is_neg_unary_node(branch[0]);
34812 const bool right_neg = is_neg_unary_node(branch[1]);
34813
34814 if (left_neg && right_neg)
34815 {
34816 if (
34817 (details::e_add == operation) ||
34818 (details::e_sub == operation) ||
34819 (details::e_mul == operation) ||
34820 (details::e_div == operation)
34821 )
34822 {
34823 if (
34824 !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) ||
34825 !expr_gen.parser_->simplify_unary_negation_branch(branch[1])
34826 )
34827 {
34828 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34829
34830 return error_node();
34831 }
34832 }
34833
34834 switch (operation)
34835 {
34836 // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1))
34837 case details::e_add : return expr_gen(details::e_neg,
34838 expr_gen.node_allocator_->
34839 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34840 (branch[0],branch[1]));
34841
34842 // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1)
34843 case details::e_sub : return expr_gen.node_allocator_->
34844 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34845 (branch[1],branch[0]);
34846
34847 default : break;
34848 }
34849 }
34850 else if (left_neg && !right_neg)
34851 {
34852 if (
34853 (details::e_add == operation) ||
34854 (details::e_sub == operation) ||
34855 (details::e_mul == operation) ||
34856 (details::e_div == operation)
34857 )
34858 {
34859 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0]))
34860 {
34861 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34862
34863 return error_node();
34864 }
34865
34866 switch (operation)
34867 {
34868 // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1)
34869 case details::e_add : return expr_gen.node_allocator_->
34870 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34871 (branch[1], branch[0]);
34872
34873 // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1))
34874 case details::e_sub : return expr_gen(details::e_neg,
34875 expr_gen.node_allocator_->
34876 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34877 (branch[0], branch[1]));
34878
34879 // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1))
34880 case details::e_mul : return expr_gen(details::e_neg,
34881 expr_gen.node_allocator_->
34882 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
34883 (branch[0], branch[1]));
34884
34885 // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1))
34886 case details::e_div : return expr_gen(details::e_neg,
34887 expr_gen.node_allocator_->
34888 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
34889 (branch[0], branch[1]));
34890
34891 default : return error_node();
34892 }
34893 }
34894 }
34895 else if (!left_neg && right_neg)
34896 {
34897 if (
34898 (details::e_add == operation) ||
34899 (details::e_sub == operation) ||
34900 (details::e_mul == operation) ||
34901 (details::e_div == operation)
34902 )
34903 {
34904 if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1]))
34905 {
34906 details::free_all_nodes(*expr_gen.node_allocator_,branch);
34907
34908 return error_node();
34909 }
34910
34911 switch (operation)
34912 {
34913 // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1)
34914 case details::e_add : return expr_gen.node_allocator_->
34915 template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
34916 (branch[0], branch[1]);
34917
34918 // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1)
34919 case details::e_sub : return expr_gen.node_allocator_->
34920 template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
34921 (branch[0], branch[1]);
34922
34923 // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1))
34924 case details::e_mul : return expr_gen(details::e_neg,
34925 expr_gen.node_allocator_->
34926 template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
34927 (branch[0], branch[1]));
34928
34929 // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1))
34930 case details::e_div : return expr_gen(details::e_neg,
34931 expr_gen.node_allocator_->
34932 template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
34933 (branch[0], branch[1]));
34934
34935 default : return error_node();
34936 }
34937 }
34938 }
34939
34940 switch (operation)
34941 {
34942 #define case_stmt(op0, op1) \
34943 case op0 : return expr_gen.node_allocator_-> \
34944 template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
34945 (branch[0], branch[1]); \
34946
34949 #undef case_stmt
34950 default : return error_node();
34951 }
34952 }
34953 };
34954
34956 {
34958 const details::operator_type& operation,
34959 expression_node_ptr (&branch)[2])
34960 {
34961 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34962
34963 #ifndef exprtk_disable_enhanced_features
34964 if (details::is_sf3ext_node(branch[1]))
34965 {
34967
34968 const bool synthesis_result =
34969 synthesize_sf4ext_expression::template compile_right<vtype>
34970 (expr_gen, v, operation, branch[1], result);
34971
34972 if (synthesis_result)
34973 {
34974 details::free_node(*expr_gen.node_allocator_,branch[1]);
34975 return result;
34976 }
34977 }
34978 #endif
34979
34980 if (
34981 (details::e_mul == operation) ||
34982 (details::e_div == operation)
34983 )
34984 {
34985 if (details::is_uv_node(branch[1]))
34986 {
34987 typedef details::uv_base_node<Type>* uvbn_ptr_t;
34988
34989 details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation();
34990
34991 if (details::e_neg == o)
34992 {
34993 const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v();
34994
34995 details::free_node(*expr_gen.node_allocator_,branch[1]);
34996
34997 switch (operation)
34998 {
34999 case details::e_mul : return expr_gen(details::e_neg,
35000 expr_gen.node_allocator_->
35001 template allocate_rr<typename details::
35002 vov_node<Type,details::mul_op<Type> > >(v,v1));
35003
35004 case details::e_div : return expr_gen(details::e_neg,
35005 expr_gen.node_allocator_->
35006 template allocate_rr<typename details::
35007 vov_node<Type,details::div_op<Type> > >(v,v1));
35008
35009 default : break;
35010 }
35011 }
35012 }
35013 }
35014
35015 switch (operation)
35016 {
35017 #define case_stmt(op0, op1) \
35018 case op0 : return expr_gen.node_allocator_-> \
35019 template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
35020 (v, branch[1]); \
35021
35024 #undef case_stmt
35025 default : return error_node();
35026 }
35027 }
35028 };
35029
35031 {
35033 const details::operator_type& operation,
35034 expression_node_ptr (&branch)[2])
35035 {
35036 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35037
35038 #ifndef exprtk_disable_enhanced_features
35039 if (details::is_sf3ext_node(branch[0]))
35040 {
35042
35043 const bool synthesis_result =
35044 synthesize_sf4ext_expression::template compile_left<vtype>
35045 (expr_gen, v, operation, branch[0], result);
35046
35047 if (synthesis_result)
35048 {
35049 details::free_node(*expr_gen.node_allocator_, branch[0]);
35050
35051 return result;
35052 }
35053 }
35054 #endif
35055
35056 if (
35057 (details::e_add == operation) ||
35058 (details::e_sub == operation) ||
35059 (details::e_mul == operation) ||
35060 (details::e_div == operation)
35061 )
35062 {
35063 if (details::is_uv_node(branch[0]))
35064 {
35065 typedef details::uv_base_node<Type>* uvbn_ptr_t;
35066
35067 details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation();
35068
35069 if (details::e_neg == o)
35070 {
35071 const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v();
35072
35073 details::free_node(*expr_gen.node_allocator_,branch[0]);
35074
35075 switch (operation)
35076 {
35077 case details::e_add : return expr_gen.node_allocator_->
35078 template allocate_rr<typename details::
35080
35081 case details::e_sub : return expr_gen(details::e_neg,
35082 expr_gen.node_allocator_->
35083 template allocate_rr<typename details::
35084 vov_node<Type,details::add_op<Type> > >(v0,v));
35085
35086 case details::e_mul : return expr_gen(details::e_neg,
35087 expr_gen.node_allocator_->
35088 template allocate_rr<typename details::
35089 vov_node<Type,details::mul_op<Type> > >(v0,v));
35090
35091 case details::e_div : return expr_gen(details::e_neg,
35092 expr_gen.node_allocator_->
35093 template allocate_rr<typename details::
35094 vov_node<Type,details::div_op<Type> > >(v0,v));
35095 default : break;
35096 }
35097 }
35098 }
35099 }
35100
35101 switch (operation)
35102 {
35103 #define case_stmt(op0, op1) \
35104 case op0 : return expr_gen.node_allocator_-> \
35105 template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
35106 (branch[0], v); \
35107
35110 #undef case_stmt
35111 default : return error_node();
35112 }
35113 }
35114 };
35115
35117 {
35119 const details::operator_type& operation,
35120 expression_node_ptr (&branch)[2])
35121 {
35122 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
35123
35124 details::free_node(*expr_gen.node_allocator_,branch[0]);
35125
35126 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35127 {
35128 details::free_node(*expr_gen.node_allocator_,branch[1]);
35129
35130 return expr_gen(T(0));
35131 }
35132 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35133 {
35134 details::free_node(*expr_gen.node_allocator_, branch[1]);
35135
35136 return expr_gen(T(0));
35137 }
35138 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35139 return branch[1];
35140 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35141 return branch[1];
35142
35143 if (details::is_cob_node(branch[1]))
35144 {
35145 // Simplify expressions of the form:
35146 // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x)
35147 // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x
35148 if (
35149 (details::e_mul == operation) ||
35150 (details::e_add == operation)
35151 )
35152 {
35153 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35154
35155 if (operation == cobnode->operation())
35156 {
35157 switch (operation)
35158 {
35159 case details::e_add : cobnode->set_c(c + cobnode->c()); break;
35160 case details::e_mul : cobnode->set_c(c * cobnode->c()); break;
35161 default : return error_node();
35162 }
35163
35164 return cobnode;
35165 }
35166 }
35167
35168 if (operation == details::e_mul)
35169 {
35170 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35171 details::operator_type cob_opr = cobnode->operation();
35172
35173 if (
35174 (details::e_div == cob_opr) ||
35175 (details::e_mul == cob_opr)
35176 )
35177 {
35178 switch (cob_opr)
35179 {
35180 case details::e_div : cobnode->set_c(c * cobnode->c()); break;
35181 case details::e_mul : cobnode->set_c(cobnode->c() / c); break;
35182 default : return error_node();
35183 }
35184
35185 return cobnode;
35186 }
35187 }
35188 else if (operation == details::e_div)
35189 {
35190 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35191 details::operator_type cob_opr = cobnode->operation();
35192
35193 if (
35194 (details::e_div == cob_opr) ||
35195 (details::e_mul == cob_opr)
35196 )
35197 {
35199
35200 switch (cob_opr)
35201 {
35202 case details::e_div : new_cobnode = expr_gen.node_allocator_->
35203 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
35204 (c / cobnode->c(), cobnode->move_branch(0));
35205 break;
35206
35207 case details::e_mul : new_cobnode = expr_gen.node_allocator_->
35208 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35209 (c / cobnode->c(), cobnode->move_branch(0));
35210 break;
35211
35212 default : return error_node();
35213 }
35214
35215 details::free_node(*expr_gen.node_allocator_,branch[1]);
35216
35217 return new_cobnode;
35218 }
35219 }
35220 }
35221 #ifndef exprtk_disable_enhanced_features
35222 else if (details::is_sf3ext_node(branch[1]))
35223 {
35225
35226 const bool synthesis_result =
35227 synthesize_sf4ext_expression::template compile_right<ctype>
35228 (expr_gen, c, operation, branch[1], result);
35229
35230 if (synthesis_result)
35231 {
35232 details::free_node(*expr_gen.node_allocator_,branch[1]);
35233
35234 return result;
35235 }
35236 }
35237 #endif
35238
35239 switch (operation)
35240 {
35241 #define case_stmt(op0, op1) \
35242 case op0 : return expr_gen.node_allocator_-> \
35243 template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
35244 (c, branch[1]); \
35245
35248 #undef case_stmt
35249 default : return error_node();
35250 }
35251 }
35252 };
35253
35255 {
35257 const details::operator_type& operation,
35258 expression_node_ptr (&branch)[2])
35259 {
35260 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
35261
35262 details::free_node(*(expr_gen.node_allocator_), branch[1]);
35263
35264 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35265 {
35266 details::free_node(*expr_gen.node_allocator_, branch[0]);
35267
35268 return expr_gen(T(0));
35269 }
35270 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35271 {
35272 details::free_node(*expr_gen.node_allocator_, branch[0]);
35273
35274 return expr_gen(std::numeric_limits<T>::quiet_NaN());
35275 }
35276 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35277 return branch[0];
35278 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35279 return branch[0];
35280
35281 if (details::is_boc_node(branch[0]))
35282 {
35283 // Simplify expressions of the form:
35284 // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320
35285 // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45
35286 if (
35287 (details::e_mul == operation) ||
35288 (details::e_add == operation)
35289 )
35290 {
35291 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35292
35293 if (operation == bocnode->operation())
35294 {
35295 switch (operation)
35296 {
35297 case details::e_add : bocnode->set_c(c + bocnode->c()); break;
35298 case details::e_mul : bocnode->set_c(c * bocnode->c()); break;
35299 default : return error_node();
35300 }
35301
35302 return bocnode;
35303 }
35304 }
35305 else if (operation == details::e_div)
35306 {
35307 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35308 details::operator_type boc_opr = bocnode->operation();
35309
35310 if (
35311 (details::e_div == boc_opr) ||
35312 (details::e_mul == boc_opr)
35313 )
35314 {
35315 switch (boc_opr)
35316 {
35317 case details::e_div : bocnode->set_c(c * bocnode->c()); break;
35318 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
35319 default : return error_node();
35320 }
35321
35322 return bocnode;
35323 }
35324 }
35325 else if (operation == details::e_pow)
35326 {
35327 // (v ^ c0) ^ c1 --> v ^(c0 * c1)
35328 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35329 details::operator_type boc_opr = bocnode->operation();
35330
35331 if (details::e_pow == boc_opr)
35332 {
35333 bocnode->set_c(bocnode->c() * c);
35334
35335 return bocnode;
35336 }
35337 }
35338 }
35339
35340 #ifndef exprtk_disable_enhanced_features
35341 if (details::is_sf3ext_node(branch[0]))
35342 {
35344
35345 const bool synthesis_result =
35346 synthesize_sf4ext_expression::template compile_left<ctype>
35347 (expr_gen, c, operation, branch[0], result);
35348
35349 if (synthesis_result)
35350 {
35351 free_node(*expr_gen.node_allocator_, branch[0]);
35352
35353 return result;
35354 }
35355 }
35356 #endif
35357
35358 switch (operation)
35359 {
35360 #define case_stmt(op0, op1) \
35361 case op0 : return expr_gen.node_allocator_-> \
35362 template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
35363 (branch[0], c); \
35364
35367 #undef case_stmt
35368 default : return error_node();
35369 }
35370 }
35371 };
35372
35374 {
35376 const details::operator_type& operation,
35377 expression_node_ptr (&branch)[2])
35378 {
35380
35381 // (cob) o c --> cob
35382 if (details::is_cob_node(branch[0]))
35383 {
35384 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
35385
35386 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
35387
35388 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35389 {
35390 details::free_node(*expr_gen.node_allocator_, branch[0]);
35391 details::free_node(*expr_gen.node_allocator_, branch[1]);
35392
35393 return expr_gen(T(0));
35394 }
35395 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35396 {
35397 details::free_node(*expr_gen.node_allocator_, branch[0]);
35398 details::free_node(*expr_gen.node_allocator_, branch[1]);
35399
35400 return expr_gen(T(std::numeric_limits<T>::quiet_NaN()));
35401 }
35402 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35403 {
35404 details::free_node(*expr_gen.node_allocator_, branch[1]);
35405
35406 return branch[0];
35407 }
35408 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35409 {
35410 details::free_node(*expr_gen.node_allocator_, branch[1]);
35411
35412 return branch[0];
35413 }
35414 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
35415 {
35416 details::free_node(*expr_gen.node_allocator_, branch[1]);
35417
35418 return branch[0];
35419 }
35420
35421 const bool op_addsub = (details::e_add == cobnode->operation()) ||
35422 (details::e_sub == cobnode->operation()) ;
35423
35424 if (op_addsub)
35425 {
35426 switch (operation)
35427 {
35428 case details::e_add : cobnode->set_c(cobnode->c() + c); break;
35429 case details::e_sub : cobnode->set_c(cobnode->c() - c); break;
35430 default : return error_node();
35431 }
35432
35433 result = cobnode;
35434 }
35435 else if (details::e_mul == cobnode->operation())
35436 {
35437 switch (operation)
35438 {
35439 case details::e_mul : cobnode->set_c(cobnode->c() * c); break;
35440 case details::e_div : cobnode->set_c(cobnode->c() / c); break;
35441 default : return error_node();
35442 }
35443
35444 result = cobnode;
35445 }
35446 else if (details::e_div == cobnode->operation())
35447 {
35448 if (details::e_mul == operation)
35449 {
35450 cobnode->set_c(cobnode->c() * c);
35451 result = cobnode;
35452 }
35453 else if (details::e_div == operation)
35454 {
35455 result = expr_gen.node_allocator_->
35456 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35457 (cobnode->c() / c, cobnode->move_branch(0));
35458
35459 details::free_node(*expr_gen.node_allocator_, branch[0]);
35460 }
35461 }
35462
35463 if (result)
35464 {
35465 details::free_node(*expr_gen.node_allocator_,branch[1]);
35466 }
35467 }
35468
35469 // c o (cob) --> cob
35470 else if (details::is_cob_node(branch[1]))
35471 {
35472 details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
35473
35474 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
35475
35476 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35477 {
35478 details::free_node(*expr_gen.node_allocator_, branch[0]);
35479 details::free_node(*expr_gen.node_allocator_, branch[1]);
35480
35481 return expr_gen(T(0));
35482 }
35483 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35484 {
35485 details::free_node(*expr_gen.node_allocator_, branch[0]);
35486 details::free_node(*expr_gen.node_allocator_, branch[1]);
35487
35488 return expr_gen(T(0));
35489 }
35490 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35491 {
35492 details::free_node(*expr_gen.node_allocator_, branch[0]);
35493
35494 return branch[1];
35495 }
35496 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35497 {
35498 details::free_node(*expr_gen.node_allocator_, branch[0]);
35499
35500 return branch[1];
35501 }
35502
35503 if (details::e_add == cobnode->operation())
35504 {
35505 if (details::e_add == operation)
35506 {
35507 cobnode->set_c(c + cobnode->c());
35508 result = cobnode;
35509 }
35510 else if (details::e_sub == operation)
35511 {
35512 result = expr_gen.node_allocator_->
35513 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35514 (c - cobnode->c(), cobnode->move_branch(0));
35515
35516 details::free_node(*expr_gen.node_allocator_,branch[1]);
35517 }
35518 }
35519 else if (details::e_sub == cobnode->operation())
35520 {
35521 if (details::e_add == operation)
35522 {
35523 cobnode->set_c(c + cobnode->c());
35524 result = cobnode;
35525 }
35526 else if (details::e_sub == operation)
35527 {
35528 result = expr_gen.node_allocator_->
35529 template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > >
35530 (c - cobnode->c(), cobnode->move_branch(0));
35531
35532 details::free_node(*expr_gen.node_allocator_,branch[1]);
35533 }
35534 }
35535 else if (details::e_mul == cobnode->operation())
35536 {
35537 if (details::e_mul == operation)
35538 {
35539 cobnode->set_c(c * cobnode->c());
35540 result = cobnode;
35541 }
35542 else if (details::e_div == operation)
35543 {
35544 result = expr_gen.node_allocator_->
35545 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35546 (c / cobnode->c(), cobnode->move_branch(0));
35547
35548 details::free_node(*expr_gen.node_allocator_,branch[1]);
35549 }
35550 }
35551 else if (details::e_div == cobnode->operation())
35552 {
35553 if (details::e_mul == operation)
35554 {
35555 cobnode->set_c(c * cobnode->c());
35556 result = cobnode;
35557 }
35558 else if (details::e_div == operation)
35559 {
35560 result = expr_gen.node_allocator_->
35561 template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
35562 (c / cobnode->c(), cobnode->move_branch(0));
35563
35564 details::free_node(*expr_gen.node_allocator_,branch[1]);
35565 }
35566 }
35567
35568 if (result)
35569 {
35570 details::free_node(*expr_gen.node_allocator_,branch[0]);
35571 }
35572 }
35573
35574 return result;
35575 }
35576 };
35577
35579 {
35581 const details::operator_type& operation,
35582 expression_node_ptr (&branch)[2])
35583 {
35585
35586 // (boc) o c --> boc
35587 if (details::is_boc_node(branch[0]))
35588 {
35589 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
35590
35591 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
35592
35593 if (details::e_add == bocnode->operation())
35594 {
35595 switch (operation)
35596 {
35597 case details::e_add : bocnode->set_c(bocnode->c() + c); break;
35598 case details::e_sub : bocnode->set_c(bocnode->c() - c); break;
35599 default : return error_node();
35600 }
35601
35602 result = bocnode;
35603 }
35604 else if (details::e_mul == bocnode->operation())
35605 {
35606 switch (operation)
35607 {
35608 case details::e_mul : bocnode->set_c(bocnode->c() * c); break;
35609 case details::e_div : bocnode->set_c(bocnode->c() / c); break;
35610 default : return error_node();
35611 }
35612
35613 result = bocnode;
35614 }
35615 else if (details::e_sub == bocnode->operation())
35616 {
35617 if (details::e_add == operation)
35618 {
35619 result = expr_gen.node_allocator_->
35620 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
35621 (bocnode->move_branch(0), c - bocnode->c());
35622
35623 details::free_node(*expr_gen.node_allocator_,branch[0]);
35624 }
35625 else if (details::e_sub == operation)
35626 {
35627 bocnode->set_c(bocnode->c() + c);
35628 result = bocnode;
35629 }
35630 }
35631 else if (details::e_div == bocnode->operation())
35632 {
35633 switch (operation)
35634 {
35635 case details::e_div : bocnode->set_c(bocnode->c() * c); break;
35636 case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
35637 default : return error_node();
35638 }
35639
35640 result = bocnode;
35641 }
35642
35643 if (result)
35644 {
35645 details::free_node(*expr_gen.node_allocator_, branch[1]);
35646 }
35647 }
35648
35649 // c o (boc) --> boc
35650 else if (details::is_boc_node(branch[1]))
35651 {
35652 details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]);
35653
35654 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
35655
35656 if (details::e_add == bocnode->operation())
35657 {
35658 if (details::e_add == operation)
35659 {
35660 bocnode->set_c(c + bocnode->c());
35661 result = bocnode;
35662 }
35663 else if (details::e_sub == operation)
35664 {
35665 result = expr_gen.node_allocator_->
35666 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35667 (c - bocnode->c(), bocnode->move_branch(0));
35668
35669 details::free_node(*expr_gen.node_allocator_,branch[1]);
35670 }
35671 }
35672 else if (details::e_sub == bocnode->operation())
35673 {
35674 if (details::e_add == operation)
35675 {
35676 result = expr_gen.node_allocator_->
35677 template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
35678 (bocnode->move_branch(0), c - bocnode->c());
35679
35680 details::free_node(*expr_gen.node_allocator_,branch[1]);
35681 }
35682 else if (details::e_sub == operation)
35683 {
35684 result = expr_gen.node_allocator_->
35685 template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
35686 (c + bocnode->c(), bocnode->move_branch(0));
35687
35688 details::free_node(*expr_gen.node_allocator_,branch[1]);
35689 }
35690 }
35691 else if (details::e_mul == bocnode->operation())
35692 {
35693 if (details::e_mul == operation)
35694 {
35695 bocnode->set_c(c * bocnode->c());
35696 result = bocnode;
35697 }
35698 else if (details::e_div == operation)
35699 {
35700 result = expr_gen.node_allocator_->
35701 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35702 (c / bocnode->c(), bocnode->move_branch(0));
35703
35704 details::free_node(*expr_gen.node_allocator_,branch[1]);
35705 }
35706 }
35707 else if (details::e_div == bocnode->operation())
35708 {
35709 if (details::e_mul == operation)
35710 {
35711 bocnode->set_c(bocnode->c() / c);
35712 result = bocnode;
35713 }
35714 else if (details::e_div == operation)
35715 {
35716 result = expr_gen.node_allocator_->
35717 template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
35718 (c * bocnode->c(), bocnode->move_branch(0));
35719
35720 details::free_node(*expr_gen.node_allocator_,branch[1]);
35721 }
35722 }
35723
35724 if (result)
35725 {
35726 details::free_node(*expr_gen.node_allocator_,branch[0]);
35727 }
35728 }
35729
35730 return result;
35731 }
35732 };
35733
35734 #ifndef exprtk_disable_enhanced_features
35735 inline bool synthesize_expression(const details::operator_type& operation,
35736 expression_node_ptr (&branch)[2],
35737 expression_node_ptr& result)
35738 {
35739 result = error_node();
35740
35741 if (!operation_optimisable(operation))
35742 return false;
35743
35744 const std::string node_id = branch_to_id(branch);
35745
35746 const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id);
35747
35748 if (synthesize_map_.end() != itr)
35749 {
35750 result = itr->second((*this), operation, branch);
35751
35752 return true;
35753 }
35754 else
35755 return false;
35756 }
35757
35759 {
35761 const details::operator_type& operation,
35762 expression_node_ptr (&branch)[2])
35763 {
35764 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
35765 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35766
35767 switch (operation)
35768 {
35769 #define case_stmt(op0, op1) \
35770 case op0 : return expr_gen.node_allocator_-> \
35771 template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
35772 (v1, v2); \
35773
35776 #undef case_stmt
35777 default : return error_node();
35778 }
35779 }
35780 };
35781
35783 {
35785 const details::operator_type& operation,
35786 expression_node_ptr (&branch)[2])
35787 {
35788 const Type c = static_cast<details::literal_node<Type>*> (branch[0])->value();
35789 const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref ();
35790
35791 details::free_node(*(expr_gen.node_allocator_),branch[0]);
35792
35793 if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35794 return expr_gen(T(0));
35795 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35796 return expr_gen(T(0));
35797 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35798 return static_cast<details::variable_node<Type>*>(branch[1]);
35799 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35800 return static_cast<details::variable_node<Type>*>(branch[1]);
35801
35802 switch (operation)
35803 {
35804 #define case_stmt(op0, op1) \
35805 case op0 : return expr_gen.node_allocator_-> \
35806 template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
35807 (c, v); \
35808
35811 #undef case_stmt
35812 default : return error_node();
35813 }
35814 }
35815 };
35816
35818 {
35820 const details::operator_type& operation,
35821 expression_node_ptr (&branch)[2])
35822 {
35823 const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref ();
35824 const Type c = static_cast<details::literal_node<Type>*> (branch[1])->value();
35825
35826 details::free_node(*(expr_gen.node_allocator_), branch[1]);
35827
35828 if (expr_gen.cardinal_pow_optimisable(operation,c))
35829 {
35830 if (std::equal_to<T>()(T(1),c))
35831 return branch[0];
35832 else
35833 return expr_gen.cardinal_pow_optimisation(v,c);
35834 }
35835 else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
35836 return expr_gen(T(0));
35837 else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
35838 return expr_gen(std::numeric_limits<T>::quiet_NaN());
35839 else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
35840 return static_cast<details::variable_node<Type>*>(branch[0]);
35841 else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
35842 return static_cast<details::variable_node<Type>*>(branch[0]);
35843 else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
35844 return static_cast<details::variable_node<Type>*>(branch[0]);
35845
35846 switch (operation)
35847 {
35848 #define case_stmt(op0, op1) \
35849 case op0 : return expr_gen.node_allocator_-> \
35850 template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
35851 (v, c); \
35852
35855 #undef case_stmt
35856 default : return error_node();
35857 }
35858 }
35859 };
35860
35862 {
35863 template <typename T0, typename T1, typename T2>
35865 const details::operator_type& sf3opr,
35866 T0 t0, T1 t1, T2 t2)
35867 {
35868 switch (sf3opr)
35869 {
35870 #define case_stmt(op) \
35871 case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
35872 allocate(*(expr_gen.node_allocator_), t0, t1, t2); \
35873
35874 case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
35875 case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
35876 case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
35877 case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
35878 case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
35879 case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
35880 case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
35881 case_stmt(28) case_stmt(29) case_stmt(30)
35882 #undef case_stmt
35883 default : return error_node();
35884 }
35885 }
35886
35887 template <typename T0, typename T1, typename T2>
35888 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
35889 T0 t0, T1 t1, T2 t2,
35890 expression_node_ptr& result)
35891 {
35893
35894 if (!expr_gen.sf3_optimisable(id,sf3opr))
35895 return false;
35896 else
35897 result = synthesize_sf3ext_expression::template process<T0, T1, T2>
35898 (expr_gen, sf3opr, t0, t1, t2);
35899
35900 return true;
35901 }
35902 };
35903
35905 {
35906 template <typename T0, typename T1, typename T2, typename T3>
35908 const details::operator_type& sf4opr,
35909 T0 t0, T1 t1, T2 t2, T3 t3)
35910 {
35911 switch (sf4opr)
35912 {
35913 #define case_stmt0(op) \
35914 case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
35915 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
35916
35917 #define case_stmt1(op) \
35918 case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
35919 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
35920
35930
35946 case_stmt1(60) case_stmt1(61)
35947
35948 #undef case_stmt0
35949 #undef case_stmt1
35950 default : return error_node();
35951 }
35952 }
35953
35954 template <typename T0, typename T1, typename T2, typename T3>
35955 static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
35956 T0 t0, T1 t1, T2 t2, T3 t3,
35957 expression_node_ptr& result)
35958 {
35960
35961 if (!expr_gen.sf4_optimisable(id,sf4opr))
35962 return false;
35963 else
35964 result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3>
35965 (expr_gen, sf4opr, t0, t1, t2, t3);
35966
35967 return true;
35968 }
35969
35970 // T o (sf3ext)
35971 template <typename ExternalType>
35972 static inline bool compile_right(expression_generator<Type>& expr_gen,
35973 ExternalType t,
35974 const details::operator_type& operation,
35975 expression_node_ptr& sf3node,
35976 expression_node_ptr& result)
35977 {
35978 if (!details::is_sf3ext_node(sf3node))
35979 return false;
35980
35981 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
35982
35983 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
35984 const std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
35985
35986 switch (n->type())
35987 {
35989 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
35990 (expr_gen, id, t, sf3node, result);
35991
35993 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
35994 (expr_gen, id, t, sf3node, result);
35995
35997 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
35998 (expr_gen, id, t, sf3node, result);
35999
36001 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
36002 (expr_gen, id, t, sf3node, result);
36003
36005 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
36006 (expr_gen, id, t, sf3node, result);
36007
36008 default : return false;
36009 }
36010 }
36011
36012 // (sf3ext) o T
36013 template <typename ExternalType>
36014 static inline bool compile_left(expression_generator<Type>& expr_gen,
36015 ExternalType t,
36016 const details::operator_type& operation,
36017 expression_node_ptr& sf3node,
36018 expression_node_ptr& result)
36019 {
36020 if (!details::is_sf3ext_node(sf3node))
36021 return false;
36022
36023 typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
36024
36025 sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
36026
36027 const std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
36028
36029 switch (n->type())
36030 {
36032 <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
36033 (expr_gen, id, t, sf3node, result);
36034
36036 <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
36037 (expr_gen, id, t, sf3node, result);
36038
36040 <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
36041 (expr_gen, id, t, sf3node, result);
36042
36044 <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
36045 (expr_gen, id, t, sf3node, result);
36046
36048 <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
36049 (expr_gen, id, t, sf3node, result);
36050
36051 default : return false;
36052 }
36053 }
36054
36055 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
36057 const std::string& id,
36058 ExternalType t,
36059 expression_node_ptr& node,
36060 expression_node_ptr& result)
36061 {
36062 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
36063
36064 if (n)
36065 {
36066 T0 t0 = n->t0();
36067 T1 t1 = n->t1();
36068 T2 t2 = n->t2();
36069
36070 return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2>
36071 (expr_gen, id, t, t0, t1, t2, result);
36072 }
36073 else
36074 return false;
36075 }
36076
36077 template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
36078 static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
36079 const std::string& id,
36080 ExternalType t,
36081 expression_node_ptr& node,
36082 expression_node_ptr& result)
36083 {
36084 SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
36085
36086 if (n)
36087 {
36088 T0 t0 = n->t0();
36089 T1 t1 = n->t1();
36090 T2 t2 = n->t2();
36091
36092 return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType>
36093 (expr_gen, id, t0, t1, t2, t, result);
36094 }
36095 else
36096 return false;
36097 }
36098 };
36099
36101 {
36102 typedef typename vovov_t::type0 node_type;
36103 typedef typename vovov_t::sf3_type sf3_type;
36104
36106 const details::operator_type& operation,
36107 expression_node_ptr (&branch)[2])
36108 {
36109 // (v0 o0 v1) o1 (v2)
36110 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
36111 const Type& v0 = vov->v0();
36112 const Type& v1 = vov->v1();
36113 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36114 const details::operator_type o0 = vov->operation();
36115 const details::operator_type o1 = operation;
36116
36117 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36118
36120
36122 {
36123 // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)
36124 if ((details::e_div == o0) && (details::e_div == o1))
36125 {
36126 const bool synthesis_result =
36127 synthesize_sf3ext_expression::
36128 template compile<vtype, vtype, vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result);
36129
36130 exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
36131
36132 return (synthesis_result) ? result : error_node();
36133 }
36134 }
36135
36136 const bool synthesis_result =
36137 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
36138 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
36139
36140 if (synthesis_result)
36141 return result;
36142
36143 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36144 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36145
36146 if (!expr_gen.valid_operator(o0,f0))
36147 return error_node();
36148 else if (!expr_gen.valid_operator(o1,f1))
36149 return error_node();
36150 else
36151 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
36152 }
36153
36154 static inline std::string id(expression_generator<Type>& expr_gen,
36155 const details::operator_type o0,
36156 const details::operator_type o1)
36157 {
36158 return details::build_string()
36159 << "(t" << expr_gen.to_str(o0)
36160 << "t)" << expr_gen.to_str(o1)
36161 << "t";
36162 }
36163 };
36164
36166 {
36167 typedef typename vovov_t::type1 node_type;
36168 typedef typename vovov_t::sf3_type sf3_type;
36169
36171 const details::operator_type& operation,
36172 expression_node_ptr (&branch)[2])
36173 {
36174 // (v0) o0 (v1 o1 v2)
36175 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36176 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36177 const Type& v1 = vov->v0();
36178 const Type& v2 = vov->v1();
36179 const details::operator_type o0 = operation;
36180 const details::operator_type o1 = vov->operation();
36181
36182 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36183
36185
36187 {
36188 // v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1
36189 if ((details::e_div == o0) && (details::e_div == o1))
36190 {
36191 const bool synthesis_result =
36192 synthesize_sf3ext_expression::
36193 template compile<vtype, vtype, vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result);
36194
36195 exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
36196
36197 return (synthesis_result) ? result : error_node();
36198 }
36199 }
36200
36201 const bool synthesis_result =
36202 synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
36203 (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
36204
36205 if (synthesis_result)
36206 return result;
36207
36208 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36209 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36210
36211 if (!expr_gen.valid_operator(o0,f0))
36212 return error_node();
36213 else if (!expr_gen.valid_operator(o1,f1))
36214 return error_node();
36215 else
36216 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
36217 }
36218
36219 static inline std::string id(expression_generator<Type>& expr_gen,
36220 const details::operator_type o0,
36221 const details::operator_type o1)
36222 {
36223 return details::build_string()
36224 << "t" << expr_gen.to_str(o0)
36225 << "(t" << expr_gen.to_str(o1)
36226 << "t)";
36227 }
36228 };
36229
36231 {
36232 typedef typename vovoc_t::type0 node_type;
36233 typedef typename vovoc_t::sf3_type sf3_type;
36234
36236 const details::operator_type& operation,
36237 expression_node_ptr (&branch)[2])
36238 {
36239 // (v0 o0 v1) o1 (c)
36240 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
36241 const Type& v0 = vov->v0();
36242 const Type& v1 = vov->v1();
36243 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
36244 const details::operator_type o0 = vov->operation();
36245 const details::operator_type o1 = operation;
36246
36247 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36248 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36249
36251
36253 {
36254 // (v0 / v1) / c --> (vovoc) v0 / (v1 * c)
36255 if ((details::e_div == o0) && (details::e_div == o1))
36256 {
36257 const bool synthesis_result =
36258 synthesize_sf3ext_expression::
36259 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
36260
36261 exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
36262
36263 return (synthesis_result) ? result : error_node();
36264 }
36265 }
36266
36267 const bool synthesis_result =
36268 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
36269 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
36270
36271 if (synthesis_result)
36272 return result;
36273
36274 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36275 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36276
36277 if (!expr_gen.valid_operator(o0,f0))
36278 return error_node();
36279 else if (!expr_gen.valid_operator(o1,f1))
36280 return error_node();
36281 else
36282 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
36283 }
36284
36285 static inline std::string id(expression_generator<Type>& expr_gen,
36286 const details::operator_type o0,
36287 const details::operator_type o1)
36288 {
36289 return details::build_string()
36290 << "(t" << expr_gen.to_str(o0)
36291 << "t)" << expr_gen.to_str(o1)
36292 << "t";
36293 }
36294 };
36295
36297 {
36298 typedef typename vovoc_t::type1 node_type;
36299 typedef typename vovoc_t::sf3_type sf3_type;
36300
36302 const details::operator_type& operation,
36303 expression_node_ptr (&branch)[2])
36304 {
36305 // (v0) o0 (v1 o1 c)
36306 const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]);
36307 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36308 const Type& v1 = voc->v();
36309 const Type c = voc->c();
36310 const details::operator_type o0 = operation;
36311 const details::operator_type o1 = voc->operation();
36312
36313 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36314
36316
36318 {
36319 // v0 / (v1 / c) --> (vocov) (v0 * c) / v1
36320 if ((details::e_div == o0) && (details::e_div == o1))
36321 {
36322 const bool synthesis_result =
36323 synthesize_sf3ext_expression::
36324 template compile<vtype, ctype, vtype>(expr_gen, "(t*t)/t", v0, c, v1, result);
36325
36326 exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
36327
36328 return (synthesis_result) ? result : error_node();
36329 }
36330 }
36331
36332 const bool synthesis_result =
36333 synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
36334 (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
36335
36336 if (synthesis_result)
36337 return result;
36338
36339 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36340 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36341
36342 if (!expr_gen.valid_operator(o0,f0))
36343 return error_node();
36344 else if (!expr_gen.valid_operator(o1,f1))
36345 return error_node();
36346 else
36347 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
36348 }
36349
36350 static inline std::string id(expression_generator<Type>& expr_gen,
36351 const details::operator_type o0,
36352 const details::operator_type o1)
36353 {
36354 return details::build_string()
36355 << "t" << expr_gen.to_str(o0)
36356 << "(t" << expr_gen.to_str(o1)
36357 << "t)";
36358 }
36359 };
36360
36362 {
36363 typedef typename vocov_t::type0 node_type;
36364 typedef typename vocov_t::sf3_type sf3_type;
36365
36367 const details::operator_type& operation,
36368 expression_node_ptr (&branch)[2])
36369 {
36370 // (v0 o0 c) o1 (v1)
36371 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
36372 const Type& v0 = voc->v();
36373 const Type c = voc->c();
36374 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36375 const details::operator_type o0 = voc->operation();
36376 const details::operator_type o1 = operation;
36377
36378 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36379
36381
36383 {
36384 // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c)
36385 if ((details::e_div == o0) && (details::e_div == o1))
36386 {
36387 const bool synthesis_result =
36388 synthesize_sf3ext_expression::
36389 template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
36390
36391 exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
36392
36393 return (synthesis_result) ? result : error_node();
36394 }
36395 }
36396
36397 const bool synthesis_result =
36398 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
36399 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
36400
36401 if (synthesis_result)
36402 return result;
36403
36404 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36405 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36406
36407 if (!expr_gen.valid_operator(o0,f0))
36408 return error_node();
36409 else if (!expr_gen.valid_operator(o1,f1))
36410 return error_node();
36411 else
36412 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
36413 }
36414
36415 static inline std::string id(expression_generator<Type>& expr_gen,
36416 const details::operator_type o0,
36417 const details::operator_type o1)
36418 {
36419 return details::build_string()
36420 << "(t" << expr_gen.to_str(o0)
36421 << "t)" << expr_gen.to_str(o1)
36422 << "t";
36423 }
36424 };
36425
36427 {
36428 typedef typename vocov_t::type1 node_type;
36429 typedef typename vocov_t::sf3_type sf3_type;
36430
36432 const details::operator_type& operation,
36433 expression_node_ptr (&branch)[2])
36434 {
36435 // (v0) o0 (c o1 v1)
36436 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36437 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
36438 const Type c = cov->c();
36439 const Type& v1 = cov->v();
36440 const details::operator_type o0 = operation;
36441 const details::operator_type o1 = cov->operation();
36442
36443 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36444
36446
36448 {
36449 // v0 / (c / v1) --> (vovoc) (v0 * v1) / c
36450 if ((details::e_div == o0) && (details::e_div == o1))
36451 {
36452 const bool synthesis_result =
36453 synthesize_sf3ext_expression::
36454 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result);
36455
36456 exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
36457
36458 return (synthesis_result) ? result : error_node();
36459 }
36460 }
36461
36462 const bool synthesis_result =
36463 synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
36464 (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
36465
36466 if (synthesis_result)
36467 return result;
36468
36469 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36470 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36471
36472 if (!expr_gen.valid_operator(o0,f0))
36473 return error_node();
36474 else if (!expr_gen.valid_operator(o1,f1))
36475 return error_node();
36476 else
36477 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
36478 }
36479
36480 static inline std::string id(expression_generator<Type>& expr_gen,
36481 const details::operator_type o0,
36482 const details::operator_type o1)
36483 {
36484 return details::build_string()
36485 << "t" << expr_gen.to_str(o0)
36486 << "(t" << expr_gen.to_str(o1)
36487 << "t)";
36488 }
36489 };
36490
36492 {
36493 typedef typename covov_t::type0 node_type;
36494 typedef typename covov_t::sf3_type sf3_type;
36495
36497 const details::operator_type& operation,
36498 expression_node_ptr (&branch)[2])
36499 {
36500 // (c o0 v0) o1 (v1)
36501 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36502 const Type c = cov->c();
36503 const Type& v0 = cov->v();
36504 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
36505 const details::operator_type o0 = cov->operation();
36506 const details::operator_type o1 = operation;
36507
36508 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36509
36511
36513 {
36514 // (c / v0) / v1 --> (covov) c / (v0 * v1)
36515 if ((details::e_div == o0) && (details::e_div == o1))
36516 {
36517 const bool synthesis_result =
36518 synthesize_sf3ext_expression::
36519 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result);
36520
36521 exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
36522
36523 return (synthesis_result) ? result : error_node();
36524 }
36525 }
36526
36527 const bool synthesis_result =
36528 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
36529 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
36530
36531 if (synthesis_result)
36532 return result;
36533
36534 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36535 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36536
36537 if (!expr_gen.valid_operator(o0,f0))
36538 return error_node();
36539 else if (!expr_gen.valid_operator(o1,f1))
36540 return error_node();
36541 else
36542 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
36543 }
36544
36545 static inline std::string id(expression_generator<Type>& expr_gen,
36546 const details::operator_type o0,
36547 const details::operator_type o1)
36548 {
36549 return details::build_string()
36550 << "(t" << expr_gen.to_str(o0)
36551 << "t)" << expr_gen.to_str(o1)
36552 << "t";
36553 }
36554 };
36555
36557 {
36558 typedef typename covov_t::type1 node_type;
36559 typedef typename covov_t::sf3_type sf3_type;
36560
36562 const details::operator_type& operation,
36563 expression_node_ptr (&branch)[2])
36564 {
36565 // (c) o0 (v0 o1 v1)
36566 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36567 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
36568 const Type& v0 = vov->v0();
36569 const Type& v1 = vov->v1();
36570 const details::operator_type o0 = operation;
36571 const details::operator_type o1 = vov->operation();
36572
36573 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36574 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36575
36577
36579 {
36580 // c / (v0 / v1) --> (covov) (c * v1) / v0
36581 if ((details::e_div == o0) && (details::e_div == o1))
36582 {
36583 const bool synthesis_result =
36584 synthesize_sf3ext_expression::
36585 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result);
36586
36587 exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
36588
36589 return (synthesis_result) ? result : error_node();
36590 }
36591 }
36592
36593 const bool synthesis_result =
36594 synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
36595 (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
36596
36597 if (synthesis_result)
36598 return result;
36599
36600 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36601 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36602
36603 if (!expr_gen.valid_operator(o0,f0))
36604 return error_node();
36605 else if (!expr_gen.valid_operator(o1,f1))
36606 return error_node();
36607 else
36608 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
36609 }
36610
36611 static inline std::string id(expression_generator<Type>& expr_gen,
36612 const details::operator_type o0,
36613 const details::operator_type o1)
36614 {
36615 return details::build_string()
36616 << "t" << expr_gen.to_str(o0)
36617 << "(t" << expr_gen.to_str(o1)
36618 << "t)";
36619 }
36620 };
36621
36623 {
36624 typedef typename covoc_t::type0 node_type;
36625 typedef typename covoc_t::sf3_type sf3_type;
36626
36628 const details::operator_type& operation,
36629 expression_node_ptr (&branch)[2])
36630 {
36631 // (c0 o0 v) o1 (c1)
36632 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36633 const Type c0 = cov->c();
36634 const Type& v = cov->v();
36635 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
36636 const details::operator_type o0 = cov->operation();
36637 const details::operator_type o1 = operation;
36638
36639 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36640 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36641
36643
36645 {
36646 // (c0 + v) + c1 --> (cov) (c0 + c1) + v
36647 if ((details::e_add == o0) && (details::e_add == o1))
36648 {
36649 exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
36650
36651 return expr_gen.node_allocator_->
36652 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36653 }
36654 // (c0 + v) - c1 --> (cov) (c0 - c1) + v
36655 else if ((details::e_add == o0) && (details::e_sub == o1))
36656 {
36657 exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
36658
36659 return expr_gen.node_allocator_->
36660 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36661 }
36662 // (c0 - v) + c1 --> (cov) (c0 + c1) - v
36663 else if ((details::e_sub == o0) && (details::e_add == o1))
36664 {
36665 exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
36666
36667 return expr_gen.node_allocator_->
36668 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36669 }
36670 // (c0 - v) - c1 --> (cov) (c0 - c1) - v
36671 else if ((details::e_sub == o0) && (details::e_sub == o1))
36672 {
36673 exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
36674
36675 return expr_gen.node_allocator_->
36676 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36677 }
36678 // (c0 * v) * c1 --> (cov) (c0 * c1) * v
36679 else if ((details::e_mul == o0) && (details::e_mul == o1))
36680 {
36681 exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
36682
36683 return expr_gen.node_allocator_->
36684 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36685 }
36686 // (c0 * v) / c1 --> (cov) (c0 / c1) * v
36687 else if ((details::e_mul == o0) && (details::e_div == o1))
36688 {
36689 exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
36690
36691 return expr_gen.node_allocator_->
36692 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36693 }
36694 // (c0 / v) * c1 --> (cov) (c0 * c1) / v
36695 else if ((details::e_div == o0) && (details::e_mul == o1))
36696 {
36697 exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
36698
36699 return expr_gen.node_allocator_->
36700 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36701 }
36702 // (c0 / v) / c1 --> (cov) (c0 / c1) / v
36703 else if ((details::e_div == o0) && (details::e_div == o1))
36704 {
36705 exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
36706
36707 return expr_gen.node_allocator_->
36708 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36709 }
36710 }
36711
36712 const bool synthesis_result =
36713 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
36714 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
36715
36716 if (synthesis_result)
36717 return result;
36718
36719 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36720 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36721
36722 if (!expr_gen.valid_operator(o0,f0))
36723 return error_node();
36724 else if (!expr_gen.valid_operator(o1,f1))
36725 return error_node();
36726 else
36727 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
36728 }
36729
36730 static inline std::string id(expression_generator<Type>& expr_gen,
36731 const details::operator_type o0,
36732 const details::operator_type o1)
36733 {
36734 return details::build_string()
36735 << "(t" << expr_gen.to_str(o0)
36736 << "t)" << expr_gen.to_str(o1)
36737 << "t";
36738 }
36739 };
36740
36742 {
36743 typedef typename covoc_t::type1 node_type;
36744 typedef typename covoc_t::sf3_type sf3_type;
36745
36747 const details::operator_type& operation,
36748 expression_node_ptr (&branch)[2])
36749 {
36750 // (c0) o0 (v o1 c1)
36751 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
36752 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
36753 const Type& v = voc->v();
36754 const Type c1 = voc->c();
36755 const details::operator_type o0 = operation;
36756 const details::operator_type o1 = voc->operation();
36757
36758 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36759 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36760
36762
36764 {
36765 // (c0) + (v + c1) --> (cov) (c0 + c1) + v
36766 if ((details::e_add == o0) && (details::e_add == o1))
36767 {
36768 exprtk_debug(("(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
36769
36770 return expr_gen.node_allocator_->
36771 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36772 }
36773 // (c0) + (v - c1) --> (cov) (c0 - c1) + v
36774 else if ((details::e_add == o0) && (details::e_sub == o1))
36775 {
36776 exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
36777
36778 return expr_gen.node_allocator_->
36779 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36780 }
36781 // (c0) - (v + c1) --> (cov) (c0 - c1) - v
36782 else if ((details::e_sub == o0) && (details::e_add == o1))
36783 {
36784 exprtk_debug(("(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
36785
36786 return expr_gen.node_allocator_->
36787 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36788 }
36789 // (c0) - (v - c1) --> (cov) (c0 + c1) - v
36790 else if ((details::e_sub == o0) && (details::e_sub == o1))
36791 {
36792 exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
36793
36794 return expr_gen.node_allocator_->
36795 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36796 }
36797 // (c0) * (v * c1) --> (voc) v * (c0 * c1)
36798 else if ((details::e_mul == o0) && (details::e_mul == o1))
36799 {
36800 exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
36801
36802 return expr_gen.node_allocator_->
36803 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36804 }
36805 // (c0) * (v / c1) --> (cov) (c0 / c1) * v
36806 else if ((details::e_mul == o0) && (details::e_div == o1))
36807 {
36808 exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
36809
36810 return expr_gen.node_allocator_->
36811 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36812 }
36813 // (c0) / (v * c1) --> (cov) (c0 / c1) / v
36814 else if ((details::e_div == o0) && (details::e_mul == o1))
36815 {
36816 exprtk_debug(("(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
36817
36818 return expr_gen.node_allocator_->
36819 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36820 }
36821 // (c0) / (v / c1) --> (cov) (c0 * c1) / v
36822 else if ((details::e_div == o0) && (details::e_div == o1))
36823 {
36824 exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
36825
36826 return expr_gen.node_allocator_->
36827 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36828 }
36829 }
36830
36831 const bool synthesis_result =
36832 synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
36833 (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
36834
36835 if (synthesis_result)
36836 return result;
36837
36838 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36839 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36840
36841 if (!expr_gen.valid_operator(o0,f0))
36842 return error_node();
36843 else if (!expr_gen.valid_operator(o1,f1))
36844 return error_node();
36845 else
36846 return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
36847 }
36848
36849 static inline std::string id(expression_generator<Type>& expr_gen,
36850 const details::operator_type o0,
36851 const details::operator_type o1)
36852 {
36853 return details::build_string()
36854 << "t" << expr_gen.to_str(o0)
36855 << "(t" << expr_gen.to_str(o1)
36856 << "t)";
36857 }
36858 };
36859
36861 {
36862 typedef typename cocov_t::type0 node_type;
36865 expression_node_ptr (&)[2])
36866 {
36867 // (c0 o0 c1) o1 (v) - Not possible.
36868 return error_node();
36869 }
36870 };
36871
36873 {
36874 typedef typename cocov_t::type1 node_type;
36875 typedef typename cocov_t::sf3_type sf3_type;
36876
36878 const details::operator_type& operation,
36879 expression_node_ptr (&branch)[2])
36880 {
36881 // (c0) o0 (c1 o1 v)
36882 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36883 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
36884 const Type c1 = cov->c();
36885 const Type& v = cov->v();
36886 const details::operator_type o0 = operation;
36887 const details::operator_type o1 = cov->operation();
36888
36889 details::free_node(*(expr_gen.node_allocator_),branch[0]);
36890 details::free_node(*(expr_gen.node_allocator_),branch[1]);
36891
36893
36895 {
36896 // (c0) + (c1 + v) --> (cov) (c0 + c1) + v
36897 if ((details::e_add == o0) && (details::e_add == o1))
36898 {
36899 exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
36900
36901 return expr_gen.node_allocator_->
36902 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
36903 }
36904 // (c0) + (c1 - v) --> (cov) (c0 + c1) - v
36905 else if ((details::e_add == o0) && (details::e_sub == o1))
36906 {
36907 exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
36908
36909 return expr_gen.node_allocator_->
36910 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
36911 }
36912 // (c0) - (c1 + v) --> (cov) (c0 - c1) - v
36913 else if ((details::e_sub == o0) && (details::e_add == o1))
36914 {
36915 exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
36916
36917 return expr_gen.node_allocator_->
36918 template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
36919 }
36920 // (c0) - (c1 - v) --> (cov) (c0 - c1) + v
36921 else if ((details::e_sub == o0) && (details::e_sub == o1))
36922 {
36923 exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
36924
36925 return expr_gen.node_allocator_->
36926 template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
36927 }
36928 // (c0) * (c1 * v) --> (cov) (c0 * c1) * v
36929 else if ((details::e_mul == o0) && (details::e_mul == o1))
36930 {
36931 exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
36932
36933 return expr_gen.node_allocator_->
36934 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
36935 }
36936 // (c0) * (c1 / v) --> (cov) (c0 * c1) / v
36937 else if ((details::e_mul == o0) && (details::e_div == o1))
36938 {
36939 exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
36940
36941 return expr_gen.node_allocator_->
36942 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
36943 }
36944 // (c0) / (c1 * v) --> (cov) (c0 / c1) / v
36945 else if ((details::e_div == o0) && (details::e_mul == o1))
36946 {
36947 exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
36948
36949 return expr_gen.node_allocator_->
36950 template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
36951 }
36952 // (c0) / (c1 / v) --> (cov) (c0 / c1) * v
36953 else if ((details::e_div == o0) && (details::e_div == o1))
36954 {
36955 exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
36956
36957 return expr_gen.node_allocator_->
36958 template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
36959 }
36960 }
36961
36962 const bool synthesis_result =
36963 synthesize_sf3ext_expression::template compile<ctype, ctype, vtype>
36964 (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result);
36965
36966 if (synthesis_result)
36967 return result;
36968
36969 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36970 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36971
36972 if (!expr_gen.valid_operator(o0,f0))
36973 return error_node();
36974 else if (!expr_gen.valid_operator(o1,f1))
36975 return error_node();
36976 else
36977 return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1);
36978 }
36979
36980 static inline std::string id(expression_generator<Type>& expr_gen,
36981 const details::operator_type o0,
36982 const details::operator_type o1)
36983 {
36984 return details::build_string()
36985 << "t" << expr_gen.to_str(o0)
36986 << "(t" << expr_gen.to_str(o1)
36987 << "t)";
36988 }
36989 };
36990
36992 {
36993 typedef typename vococ_t::type0 node_type;
36994 typedef typename vococ_t::sf3_type sf3_type;
36995
36997 const details::operator_type& operation,
36998 expression_node_ptr (&branch)[2])
36999 {
37000 // (v o0 c0) o1 (c1)
37001 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
37002 const Type& v = voc->v();
37003 const Type& c0 = voc->c();
37004 const Type& c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
37005 const details::operator_type o0 = voc->operation();
37006 const details::operator_type o1 = operation;
37007
37008 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37009 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37010
37012
37014 {
37015 // (v + c0) + c1 --> (voc) v + (c0 + c1)
37016 if ((details::e_add == o0) && (details::e_add == o1))
37017 {
37018 exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
37019
37020 return expr_gen.node_allocator_->
37021 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1);
37022 }
37023 // (v + c0) - c1 --> (voc) v + (c0 - c1)
37024 else if ((details::e_add == o0) && (details::e_sub == o1))
37025 {
37026 exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
37027
37028 return expr_gen.node_allocator_->
37029 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1);
37030 }
37031 // (v - c0) + c1 --> (voc) v - (c0 + c1)
37032 else if ((details::e_sub == o0) && (details::e_add == o1))
37033 {
37034 exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
37035
37036 return expr_gen.node_allocator_->
37037 template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0);
37038 }
37039 // (v - c0) - c1 --> (voc) v - (c0 + c1)
37040 else if ((details::e_sub == o0) && (details::e_sub == o1))
37041 {
37042 exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
37043
37044 return expr_gen.node_allocator_->
37045 template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1);
37046 }
37047 // (v * c0) * c1 --> (voc) v * (c0 * c1)
37048 else if ((details::e_mul == o0) && (details::e_mul == o1))
37049 {
37050 exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
37051
37052 return expr_gen.node_allocator_->
37053 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1);
37054 }
37055 // (v * c0) / c1 --> (voc) v * (c0 / c1)
37056 else if ((details::e_mul == o0) && (details::e_div == o1))
37057 {
37058 exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
37059
37060 return expr_gen.node_allocator_->
37061 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1);
37062 }
37063 // (v / c0) * c1 --> (voc) v * (c1 / c0)
37064 else if ((details::e_div == o0) && (details::e_mul == o1))
37065 {
37066 exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
37067
37068 return expr_gen.node_allocator_->
37069 template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0);
37070 }
37071 // (v / c0) / c1 --> (voc) v / (c0 * c1)
37072 else if ((details::e_div == o0) && (details::e_div == o1))
37073 {
37074 exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
37075
37076 return expr_gen.node_allocator_->
37077 template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1);
37078 }
37079 // (v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)
37080 else if ((details::e_pow == o0) && (details::e_pow == o1))
37081 {
37082 exprtk_debug(("(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n"));
37083
37084 return expr_gen.node_allocator_->
37085 template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1);
37086 }
37087 }
37088
37089 const bool synthesis_result =
37090 synthesize_sf3ext_expression::template compile<vtype, ctype, ctype>
37091 (expr_gen, id(expr_gen, o0, o1), v, c0, c1, result);
37092
37093 if (synthesis_result)
37094 return result;
37095
37096 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37097 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37098
37099 if (!expr_gen.valid_operator(o0,f0))
37100 return error_node();
37101 else if (!expr_gen.valid_operator(o1,f1))
37102 return error_node();
37103 else
37104 return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1);
37105 }
37106
37107 static inline std::string id(expression_generator<Type>& expr_gen,
37108 const details::operator_type o0,
37109 const details::operator_type o1)
37110 {
37111 return details::build_string()
37112 << "(t" << expr_gen.to_str(o0)
37113 << "t)" << expr_gen.to_str(o1)
37114 << "t";
37115 }
37116 };
37117
37119 {
37120 typedef typename vococ_t::type0 node_type;
37121
37124 expression_node_ptr (&)[2])
37125 {
37126 // (v) o0 (c0 o1 c1) - Not possible.
37127 exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n"));
37128 return error_node();
37129 }
37130 };
37131
37133 {
37134 typedef typename vovovov_t::type0 node_type;
37136 typedef typename node_type::T0 T0;
37137 typedef typename node_type::T1 T1;
37138 typedef typename node_type::T2 T2;
37139 typedef typename node_type::T3 T3;
37140
37142 const details::operator_type& operation,
37143 expression_node_ptr (&branch)[2])
37144 {
37145 // (v0 o0 v1) o1 (v2 o2 v3)
37146 const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]);
37147 const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]);
37148 const Type& v0 = vov0->v0();
37149 const Type& v1 = vov0->v1();
37150 const Type& v2 = vov1->v0();
37151 const Type& v3 = vov1->v1();
37152 const details::operator_type o0 = vov0->operation();
37153 const details::operator_type o1 = operation;
37154 const details::operator_type o2 = vov1->operation();
37155
37156 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37157 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37158
37160
37162 {
37163 // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)
37164 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37165 {
37166 const bool synthesis_result =
37167 synthesize_sf4ext_expression::
37168 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result);
37169
37170 exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
37171
37172 return (synthesis_result) ? result : error_node();
37173 }
37174 // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)
37175 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37176 {
37177 const bool synthesis_result =
37178 synthesize_sf4ext_expression::
37179 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result);
37180
37181 exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
37182
37183 return (synthesis_result) ? result : error_node();
37184 }
37185 // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
37186 else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2))
37187 {
37188 const bool synthesis_result =
37189 synthesize_sf4ext_expression::
37190 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result);
37191
37192 exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
37193
37194 return (synthesis_result) ? result : error_node();
37195 }
37196 // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
37197 else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2))
37198 {
37199 const bool synthesis_result =
37200 synthesize_sf4ext_expression::
37201 template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result);
37202
37203 exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
37204
37205 return (synthesis_result) ? result : error_node();
37206 }
37207 // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2
37208 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37209 {
37210 const bool synthesis_result =
37211 synthesize_sf4ext_expression::
37212 template compile<vtype, vtype, vtype, vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result);
37213
37214 exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
37215
37216 return (synthesis_result) ? result : error_node();
37217 }
37218 }
37219
37220 const bool synthesis_result =
37221 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37222 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
37223
37224 if (synthesis_result)
37225 return result;
37226
37227 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37228 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37229 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37230
37231 if (!expr_gen.valid_operator(o0,f0))
37232 return error_node();
37233 else if (!expr_gen.valid_operator(o1,f1))
37234 return error_node();
37235 else if (!expr_gen.valid_operator(o2,f2))
37236 return error_node();
37237 else
37238 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
37239 }
37240
37241 static inline std::string id(expression_generator<Type>& expr_gen,
37242 const details::operator_type o0,
37243 const details::operator_type o1,
37244 const details::operator_type o2)
37245 {
37246 return details::build_string()
37247 << "(t" << expr_gen.to_str(o0)
37248 << "t)" << expr_gen.to_str(o1)
37249 << "(t" << expr_gen.to_str(o2)
37250 << "t)";
37251 }
37252 };
37253
37255 {
37256 typedef typename vovovoc_t::type0 node_type;
37258 typedef typename node_type::T0 T0;
37259 typedef typename node_type::T1 T1;
37260 typedef typename node_type::T2 T2;
37261 typedef typename node_type::T3 T3;
37262
37264 const details::operator_type& operation,
37265 expression_node_ptr (&branch)[2])
37266 {
37267 // (v0 o0 v1) o1 (v2 o2 c)
37268 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
37269 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
37270 const Type& v0 = vov->v0();
37271 const Type& v1 = vov->v1();
37272 const Type& v2 = voc->v ();
37273 const Type c = voc->c ();
37274 const details::operator_type o0 = vov->operation();
37275 const details::operator_type o1 = operation;
37276 const details::operator_type o2 = voc->operation();
37277
37278 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37279 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37280
37282
37284 {
37285 // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)
37286 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37287 {
37288 const bool synthesis_result =
37289 synthesize_sf4ext_expression::
37290 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
37291
37292 exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
37293
37294 return (synthesis_result) ? result : error_node();
37295 }
37296 // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)
37297 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37298 {
37299 const bool synthesis_result =
37300 synthesize_sf4ext_expression::
37301 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
37302
37303 exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
37304
37305 return (synthesis_result) ? result : error_node();
37306 }
37307 }
37308
37309 const bool synthesis_result =
37310 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37311 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
37312
37313 if (synthesis_result)
37314 return result;
37315
37316 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37317 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37318 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37319
37320 if (!expr_gen.valid_operator(o0,f0))
37321 return error_node();
37322 else if (!expr_gen.valid_operator(o1,f1))
37323 return error_node();
37324 else if (!expr_gen.valid_operator(o2,f2))
37325 return error_node();
37326 else
37327 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
37328 }
37329
37330 static inline std::string id(expression_generator<Type>& expr_gen,
37331 const details::operator_type o0,
37332 const details::operator_type o1,
37333 const details::operator_type o2)
37334 {
37335 return details::build_string()
37336 << "(t" << expr_gen.to_str(o0)
37337 << "t)" << expr_gen.to_str(o1)
37338 << "(t" << expr_gen.to_str(o2)
37339 << "t)";
37340 }
37341 };
37342
37344 {
37345 typedef typename vovocov_t::type0 node_type;
37347 typedef typename node_type::T0 T0;
37348 typedef typename node_type::T1 T1;
37349 typedef typename node_type::T2 T2;
37350 typedef typename node_type::T3 T3;
37351
37353 const details::operator_type& operation,
37354 expression_node_ptr (&branch)[2])
37355 {
37356 // (v0 o0 v1) o1 (c o2 v2)
37357 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
37358 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
37359 const Type& v0 = vov->v0();
37360 const Type& v1 = vov->v1();
37361 const Type& v2 = cov->v ();
37362 const Type c = cov->c ();
37363 const details::operator_type o0 = vov->operation();
37364 const details::operator_type o1 = operation;
37365 const details::operator_type o2 = cov->operation();
37366
37367 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37368 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37369
37371
37373 {
37374 // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)
37375 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37376 {
37377 const bool synthesis_result =
37378 synthesize_sf4ext_expression::
37379 template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
37380
37381 exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
37382
37383 return (synthesis_result) ? result : error_node();
37384 }
37385 // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)
37386 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37387 {
37388 const bool synthesis_result =
37389 synthesize_sf4ext_expression::
37390 template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
37391
37392 exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
37393
37394 return (synthesis_result) ? result : error_node();
37395 }
37396 }
37397
37398 const bool synthesis_result =
37399 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37400 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
37401
37402 if (synthesis_result)
37403 return result;
37404
37405 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37406 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37407 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37408
37409 if (!expr_gen.valid_operator(o0,f0))
37410 return error_node();
37411 else if (!expr_gen.valid_operator(o1,f1))
37412 return error_node();
37413 else if (!expr_gen.valid_operator(o2,f2))
37414 return error_node();
37415 else
37416 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
37417 }
37418
37419 static inline std::string id(expression_generator<Type>& expr_gen,
37420 const details::operator_type o0,
37421 const details::operator_type o1,
37422 const details::operator_type o2)
37423 {
37424 return details::build_string()
37425 << "(t" << expr_gen.to_str(o0)
37426 << "t)" << expr_gen.to_str(o1)
37427 << "(t" << expr_gen.to_str(o2)
37428 << "t)";
37429 }
37430 };
37431
37433 {
37434 typedef typename vocovov_t::type0 node_type;
37436 typedef typename node_type::T0 T0;
37437 typedef typename node_type::T1 T1;
37438 typedef typename node_type::T2 T2;
37439 typedef typename node_type::T3 T3;
37440
37442 const details::operator_type& operation,
37443 expression_node_ptr (&branch)[2])
37444 {
37445 // (v0 o0 c) o1 (v1 o2 v2)
37446 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
37447 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
37448 const Type c = voc->c ();
37449 const Type& v0 = voc->v ();
37450 const Type& v1 = vov->v0();
37451 const Type& v2 = vov->v1();
37452 const details::operator_type o0 = voc->operation();
37453 const details::operator_type o1 = operation;
37454 const details::operator_type o2 = vov->operation();
37455
37456 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37457 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37458
37460
37462 {
37463 // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)
37464 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37465 {
37466 const bool synthesis_result =
37467 synthesize_sf4ext_expression::
37468 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result);
37469
37470 exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
37471
37472 return (synthesis_result) ? result : error_node();
37473 }
37474 // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)
37475 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37476 {
37477 const bool synthesis_result =
37478 synthesize_sf4ext_expression::
37479 template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result);
37480
37481 exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
37482
37483 return (synthesis_result) ? result : error_node();
37484 }
37485 }
37486
37487 const bool synthesis_result =
37488 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37489 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
37490
37491 if (synthesis_result)
37492 return result;
37493
37494 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37495 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37496 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37497
37498 if (!expr_gen.valid_operator(o0,f0))
37499 return error_node();
37500 else if (!expr_gen.valid_operator(o1,f1))
37501 return error_node();
37502 else if (!expr_gen.valid_operator(o2,f2))
37503 return error_node();
37504 else
37505 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
37506 }
37507
37508 static inline std::string id(expression_generator<Type>& expr_gen,
37509 const details::operator_type o0,
37510 const details::operator_type o1,
37511 const details::operator_type o2)
37512 {
37513 return details::build_string()
37514 << "(t" << expr_gen.to_str(o0)
37515 << "t)" << expr_gen.to_str(o1)
37516 << "(t" << expr_gen.to_str(o2)
37517 << "t)";
37518 }
37519 };
37520
37522 {
37523 typedef typename covovov_t::type0 node_type;
37525 typedef typename node_type::T0 T0;
37526 typedef typename node_type::T1 T1;
37527 typedef typename node_type::T2 T2;
37528 typedef typename node_type::T3 T3;
37529
37531 const details::operator_type& operation,
37532 expression_node_ptr (&branch)[2])
37533 {
37534 // (c o0 v0) o1 (v1 o2 v2)
37535 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
37536 const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
37537 const Type c = cov->c ();
37538 const Type& v0 = cov->v ();
37539 const Type& v1 = vov->v0();
37540 const Type& v2 = vov->v1();
37541 const details::operator_type o0 = cov->operation();
37542 const details::operator_type o1 = operation;
37543 const details::operator_type o2 = vov->operation();
37544
37545 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37546 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37547
37549
37551 {
37552 // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)
37553 if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37554 {
37555 const bool synthesis_result =
37556 synthesize_sf4ext_expression::
37557 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result);
37558
37559 exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
37560
37561 return (synthesis_result) ? result : error_node();
37562 }
37563 // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)
37564 if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37565 {
37566 const bool synthesis_result =
37567 synthesize_sf4ext_expression::
37568 template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result);
37569
37570 exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
37571
37572 return (synthesis_result) ? result : error_node();
37573 }
37574 }
37575
37576 const bool synthesis_result =
37577 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37578 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
37579
37580 if (synthesis_result)
37581 return result;
37582
37583 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37584 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37585 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37586
37587 if (!expr_gen.valid_operator(o0,f0))
37588 return error_node();
37589 else if (!expr_gen.valid_operator(o1,f1))
37590 return error_node();
37591 else if (!expr_gen.valid_operator(o2,f2))
37592 return error_node();
37593 else
37594 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
37595 }
37596
37597 static inline std::string id(expression_generator<Type>& expr_gen,
37598 const details::operator_type o0,
37599 const details::operator_type o1,
37600 const details::operator_type o2)
37601 {
37602 return details::build_string()
37603 << "(t" << expr_gen.to_str(o0)
37604 << "t)" << expr_gen.to_str(o1)
37605 << "(t" << expr_gen.to_str(o2)
37606 << "t)";
37607 }
37608 };
37609
37611 {
37612 typedef typename covocov_t::type0 node_type;
37614 typedef typename node_type::T0 T0;
37615 typedef typename node_type::T1 T1;
37616 typedef typename node_type::T2 T2;
37617 typedef typename node_type::T3 T3;
37618
37620 const details::operator_type& operation,
37621 expression_node_ptr (&branch)[2])
37622 {
37623 // (c0 o0 v0) o1 (c1 o2 v1)
37624 const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]);
37625 const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]);
37626 const Type c0 = cov0->c();
37627 const Type& v0 = cov0->v();
37628 const Type c1 = cov1->c();
37629 const Type& v1 = cov1->v();
37630 const details::operator_type o0 = cov0->operation();
37631 const details::operator_type o1 = operation;
37632 const details::operator_type o2 = cov1->operation();
37633
37634 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37635 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37636
37638
37640 {
37641 // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
37642 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
37643 {
37644 const bool synthesis_result =
37645 synthesize_sf3ext_expression::
37646 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
37647
37648 exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
37649
37650 return (synthesis_result) ? result : error_node();
37651 }
37652 // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
37653 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
37654 {
37655 const bool synthesis_result =
37656 synthesize_sf3ext_expression::
37657 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
37658
37659 exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
37660
37661 return (synthesis_result) ? result : error_node();
37662 }
37663 // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1
37664 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
37665 {
37666 const bool synthesis_result =
37667 synthesize_sf3ext_expression::
37668 template compile<ctype, vtype, vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result);
37669
37670 exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
37671
37672 return (synthesis_result) ? result : error_node();
37673 }
37674 // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
37675 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
37676 {
37677 const bool synthesis_result =
37678 synthesize_sf3ext_expression::
37679 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
37680
37681 exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
37682
37683 return (synthesis_result) ? result : error_node();
37684 }
37685 // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)
37686 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
37687 {
37688 const bool synthesis_result =
37689 synthesize_sf3ext_expression::
37690 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
37691
37692 exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
37693
37694 return (synthesis_result) ? result : error_node();
37695 }
37696 // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)
37697 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37698 {
37699 const bool synthesis_result =
37700 synthesize_sf3ext_expression::
37701 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
37702
37703 exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
37704
37705 return (synthesis_result) ? result : error_node();
37706 }
37707 // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0
37708 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37709 {
37710 const bool synthesis_result =
37711 synthesize_sf3ext_expression::
37712 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result);
37713
37714 exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
37715
37716 return (synthesis_result) ? result : error_node();
37717 }
37718 // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
37719 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37720 {
37721 const bool synthesis_result =
37722 synthesize_sf3ext_expression::
37723 template compile<ctype, vtype, vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result);
37724
37725 exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
37726
37727 return (synthesis_result) ? result : error_node();
37728 }
37729 // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)
37730 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
37731 {
37732 const bool synthesis_result =
37733 synthesize_sf3ext_expression::
37734 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
37735
37736 exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
37737
37738 return (synthesis_result) ? result : error_node();
37739 }
37740 // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)
37741 else if (
37742 (std::equal_to<T>()(c0,c1)) &&
37743 (details::e_mul == o0) &&
37744 (details::e_mul == o2) &&
37745 (
37746 (details::e_add == o1) ||
37747 (details::e_sub == o1)
37748 )
37749 )
37750 {
37751 std::string specfunc;
37752
37753 switch (o1)
37754 {
37755 case details::e_add : specfunc = "t*(t+t)"; break;
37756 case details::e_sub : specfunc = "t*(t-t)"; break;
37757 default : return error_node();
37758 }
37759
37760 const bool synthesis_result =
37761 synthesize_sf3ext_expression::
37762 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
37763
37764 exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
37765
37766 return (synthesis_result) ? result : error_node();
37767 }
37768 }
37769
37770 const bool synthesis_result =
37771 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37772 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
37773
37774 if (synthesis_result)
37775 return result;
37776
37777 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37778 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
37779 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
37780
37781 if (!expr_gen.valid_operator(o0,f0))
37782 return error_node();
37783 else if (!expr_gen.valid_operator(o1,f1))
37784 return error_node();
37785 else if (!expr_gen.valid_operator(o2,f2))
37786 return error_node();
37787 else
37788 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
37789 }
37790
37791 static inline std::string id(expression_generator<Type>& expr_gen,
37792 const details::operator_type o0,
37793 const details::operator_type o1,
37794 const details::operator_type o2)
37795 {
37796 return details::build_string()
37797 << "(t" << expr_gen.to_str(o0)
37798 << "t)" << expr_gen.to_str(o1)
37799 << "(t" << expr_gen.to_str(o2)
37800 << "t)";
37801 }
37802 };
37803
37805 {
37806 typedef typename vocovoc_t::type0 node_type;
37808 typedef typename node_type::T0 T0;
37809 typedef typename node_type::T1 T1;
37810 typedef typename node_type::T2 T2;
37811 typedef typename node_type::T3 T3;
37812
37814 const details::operator_type& operation,
37815 expression_node_ptr (&branch)[2])
37816 {
37817 // (v0 o0 c0) o1 (v1 o2 c1)
37818 const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]);
37819 const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]);
37820 const Type c0 = voc0->c();
37821 const Type& v0 = voc0->v();
37822 const Type c1 = voc1->c();
37823 const Type& v1 = voc1->v();
37824 const details::operator_type o0 = voc0->operation();
37825 const details::operator_type o1 = operation;
37826 const details::operator_type o2 = voc1->operation();
37827
37828 details::free_node(*(expr_gen.node_allocator_),branch[0]);
37829 details::free_node(*(expr_gen.node_allocator_),branch[1]);
37830
37832
37834 {
37835 // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
37836 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
37837 {
37838 const bool synthesis_result =
37839 synthesize_sf3ext_expression::
37840 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
37841
37842 exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
37843
37844 return (synthesis_result) ? result : error_node();
37845 }
37846 // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
37847 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
37848 {
37849 const bool synthesis_result =
37850 synthesize_sf3ext_expression::
37851 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
37852
37853 exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
37854
37855 return (synthesis_result) ? result : error_node();
37856 }
37857 // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1
37858 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
37859 {
37860 const bool synthesis_result =
37861 synthesize_sf3ext_expression::
37862 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result);
37863
37864 exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
37865
37866 return (synthesis_result) ? result : error_node();
37867 }
37868 // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
37869 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
37870 {
37871 const bool synthesis_result =
37872 synthesize_sf3ext_expression::
37873 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
37874
37875 exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
37876
37877 return (synthesis_result) ? result : error_node();
37878 }
37879 // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
37880 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
37881 {
37882 const bool synthesis_result =
37883 synthesize_sf3ext_expression::
37884 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
37885
37886 exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
37887
37888 return (synthesis_result) ? result : error_node();
37889 }
37890 // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1
37891 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
37892 {
37893 const bool synthesis_result =
37894 synthesize_sf3ext_expression::
37895 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result);
37896
37897 exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
37898
37899 return (synthesis_result) ? result : error_node();
37900 }
37901 // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1
37902 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
37903 {
37904 const bool synthesis_result =
37905 synthesize_sf3ext_expression::
37906 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
37907
37908 exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
37909
37910 return (synthesis_result) ? result : error_node();
37911 }
37912 // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
37913 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
37914 {
37915 const bool synthesis_result =
37916 synthesize_sf3ext_expression::
37917 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result);
37918
37919 exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
37920
37921 return (synthesis_result) ? result : error_node();
37922 }
37923 // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1
37924 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
37925 {
37926 const bool synthesis_result =
37927 synthesize_sf3ext_expression::
37928 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result);
37929
37930 exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
37931
37932 return (synthesis_result) ? result : error_node();
37933 }
37934 // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)
37935 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2))
37936 {
37937 const bool synthesis_result =
37938 synthesize_sf4ext_expression::
37939 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result);
37940
37941 exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
37942
37943 return (synthesis_result) ? result : error_node();
37944 }
37945 // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)
37946 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2))
37947 {
37948 const bool synthesis_result =
37949 synthesize_sf4ext_expression::
37950 template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result);
37951
37952 exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
37953
37954 return (synthesis_result) ? result : error_node();
37955 }
37956 // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
37957 else if (
37958 (std::equal_to<T>()(c0,c1)) &&
37959 (details::e_mul == o0) &&
37960 (details::e_mul == o2) &&
37961 (
37962 (details::e_add == o1) ||
37963 (details::e_sub == o1)
37964 )
37965 )
37966 {
37967 std::string specfunc;
37968
37969 switch (o1)
37970 {
37971 case details::e_add : specfunc = "t*(t+t)"; break;
37972 case details::e_sub : specfunc = "t*(t-t)"; break;
37973 default : return error_node();
37974 }
37975
37976 const bool synthesis_result =
37977 synthesize_sf3ext_expression::
37978 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
37979
37980 exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
37981
37982 return (synthesis_result) ? result : error_node();
37983 }
37984 // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c
37985 else if (
37986 (std::equal_to<T>()(c0,c1)) &&
37987 (details::e_div == o0) &&
37988 (details::e_div == o2) &&
37989 (
37990 (details::e_add == o1) ||
37991 (details::e_sub == o1)
37992 )
37993 )
37994 {
37995 std::string specfunc;
37996
37997 switch (o1)
37998 {
37999 case details::e_add : specfunc = "(t+t)/t"; break;
38000 case details::e_sub : specfunc = "(t-t)/t"; break;
38001 default : return error_node();
38002 }
38003
38004 const bool synthesis_result =
38005 synthesize_sf3ext_expression::
38006 template compile<vtype, vtype, ctype>(expr_gen, specfunc, v0, v1, c0, result);
38007
38008 exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
38009
38010 return (synthesis_result) ? result : error_node();
38011 }
38012 }
38013
38014 const bool synthesis_result =
38015 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38016 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38017
38018 if (synthesis_result)
38019 return result;
38020
38021 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38022 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38023 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38024
38025 if (!expr_gen.valid_operator(o0,f0))
38026 return error_node();
38027 else if (!expr_gen.valid_operator(o1,f1))
38028 return error_node();
38029 else if (!expr_gen.valid_operator(o2,f2))
38030 return error_node();
38031 else
38032 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38033 }
38034
38035 static inline std::string id(expression_generator<Type>& expr_gen,
38036 const details::operator_type o0,
38037 const details::operator_type o1,
38038 const details::operator_type o2)
38039 {
38040 return details::build_string()
38041 << "(t" << expr_gen.to_str(o0)
38042 << "t)" << expr_gen.to_str(o1)
38043 << "(t" << expr_gen.to_str(o2)
38044 << "t)";
38045 }
38046 };
38047
38049 {
38050 typedef typename covovoc_t::type0 node_type;
38052 typedef typename node_type::T0 T0;
38053 typedef typename node_type::T1 T1;
38054 typedef typename node_type::T2 T2;
38055 typedef typename node_type::T3 T3;
38056
38058 const details::operator_type& operation,
38059 expression_node_ptr (&branch)[2])
38060 {
38061 // (c0 o0 v0) o1 (v1 o2 c1)
38062 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
38063 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
38064 const Type c0 = cov->c();
38065 const Type& v0 = cov->v();
38066 const Type c1 = voc->c();
38067 const Type& v1 = voc->v();
38068 const details::operator_type o0 = cov->operation();
38069 const details::operator_type o1 = operation;
38070 const details::operator_type o2 = voc->operation();
38071
38072 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38073 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38074
38076
38078 {
38079 // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
38080 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
38081 {
38082 const bool synthesis_result =
38083 synthesize_sf3ext_expression::
38084 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
38085
38086 exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
38087
38088 return (synthesis_result) ? result : error_node();
38089 }
38090 // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
38091 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
38092 {
38093 const bool synthesis_result =
38094 synthesize_sf3ext_expression::
38095 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
38096
38097 exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
38098
38099 return (synthesis_result) ? result : error_node();
38100 }
38101 // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1
38102 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
38103 {
38104 const bool synthesis_result =
38105 synthesize_sf3ext_expression::
38106 template compile<ctype, vtype, vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result);
38107
38108 exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
38109
38110 return (synthesis_result) ? result : error_node();
38111 }
38112 // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
38113 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
38114 {
38115 const bool synthesis_result =
38116 synthesize_sf3ext_expression::
38117 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
38118
38119 exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
38120
38121 return (synthesis_result) ? result : error_node();
38122 }
38123 // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
38124 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
38125 {
38126 const bool synthesis_result =
38127 synthesize_sf3ext_expression::
38128 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
38129
38130 exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
38131
38132 return (synthesis_result) ? result : error_node();
38133 }
38134 // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)
38135 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
38136 {
38137 const bool synthesis_result =
38138 synthesize_sf3ext_expression::
38139 template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result);
38140
38141 exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
38142
38143 return (synthesis_result) ? result : error_node();
38144 }
38145 // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)
38146 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
38147 {
38148 const bool synthesis_result =
38149 synthesize_sf3ext_expression::
38150 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
38151
38152 exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
38153
38154 return (synthesis_result) ? result : error_node();
38155 }
38156 // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
38157 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
38158 {
38159 const bool synthesis_result =
38160 synthesize_sf3ext_expression::
38161 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result);
38162
38163 exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
38164
38165 return (synthesis_result) ? result : error_node();
38166 }
38167 // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)
38168 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
38169 {
38170 const bool synthesis_result =
38171 synthesize_sf3ext_expression::
38172 template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
38173
38174 exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
38175
38176 return (synthesis_result) ? result : error_node();
38177 }
38178 // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
38179 else if (
38180 (std::equal_to<T>()(c0,c1)) &&
38181 (details::e_mul == o0) &&
38182 (details::e_mul == o2) &&
38183 (
38184 (details::e_add == o1) ||
38185 (details::e_sub == o1)
38186 )
38187 )
38188 {
38189 std::string specfunc;
38190
38191 switch (o1)
38192 {
38193 case details::e_add : specfunc = "t*(t+t)"; break;
38194 case details::e_sub : specfunc = "t*(t-t)"; break;
38195 default : return error_node();
38196 }
38197
38198 const bool synthesis_result =
38199 synthesize_sf3ext_expression::
38200 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
38201
38202 exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
38203
38204 return (synthesis_result) ? result : error_node();
38205 }
38206 }
38207
38208 const bool synthesis_result =
38209 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38210 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38211
38212 if (synthesis_result)
38213 return result;
38214
38215 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38216 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38217 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38218
38219 if (!expr_gen.valid_operator(o0,f0))
38220 return error_node();
38221 else if (!expr_gen.valid_operator(o1,f1))
38222 return error_node();
38223 else if (!expr_gen.valid_operator(o2,f2))
38224 return error_node();
38225 else
38226 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38227 }
38228
38229 static inline std::string id(expression_generator<Type>& expr_gen,
38230 const details::operator_type o0,
38231 const details::operator_type o1,
38232 const details::operator_type o2)
38233 {
38234 return details::build_string()
38235 << "(t" << expr_gen.to_str(o0)
38236 << "t)" << expr_gen.to_str(o1)
38237 << "(t" << expr_gen.to_str(o2)
38238 << "t)";
38239 }
38240 };
38241
38243 {
38244 typedef typename vococov_t::type0 node_type;
38246 typedef typename node_type::T0 T0;
38247 typedef typename node_type::T1 T1;
38248 typedef typename node_type::T2 T2;
38249 typedef typename node_type::T3 T3;
38250
38252 const details::operator_type& operation,
38253 expression_node_ptr (&branch)[2])
38254 {
38255 // (v0 o0 c0) o1 (c1 o2 v1)
38256 const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
38257 const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
38258 const Type c0 = voc->c();
38259 const Type& v0 = voc->v();
38260 const Type c1 = cov->c();
38261 const Type& v1 = cov->v();
38262 const details::operator_type o0 = voc->operation();
38263 const details::operator_type o1 = operation;
38264 const details::operator_type o2 = cov->operation();
38265
38266 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38267 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38268
38270
38272 {
38273 // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
38274 if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
38275 {
38276 const bool synthesis_result =
38277 synthesize_sf3ext_expression::
38278 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
38279
38280 exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
38281
38282 return (synthesis_result) ? result : error_node();
38283 }
38284 // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
38285 else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
38286 {
38287 const bool synthesis_result =
38288 synthesize_sf3ext_expression::
38289 template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
38290
38291 exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
38292
38293 return (synthesis_result) ? result : error_node();
38294 }
38295 // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)
38296 else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
38297 {
38298 const bool synthesis_result =
38299 synthesize_sf3ext_expression::
38300 template compile<vtype, vtype, ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result);
38301
38302 exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
38303
38304 return (synthesis_result) ? result : error_node();
38305 }
38306 // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
38307 else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
38308 {
38309 const bool synthesis_result =
38310 synthesize_sf3ext_expression::
38311 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
38312
38313 exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
38314
38315 return (synthesis_result) ? result : error_node();
38316 }
38317 // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)
38318 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
38319 {
38320 const bool synthesis_result =
38321 synthesize_sf3ext_expression::
38322 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
38323
38324 exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
38325
38326 return (synthesis_result) ? result : error_node();
38327 }
38328 // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)
38329 else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
38330 {
38331 const bool synthesis_result =
38332 synthesize_sf3ext_expression::
38333 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
38334
38335 exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
38336
38337 return (synthesis_result) ? result : error_node();
38338 }
38339 // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
38340 else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
38341 {
38342 const bool synthesis_result =
38343 synthesize_sf3ext_expression::
38344 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result);
38345
38346 exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
38347
38348 return (synthesis_result) ? result : error_node();
38349 }
38350 // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)
38351 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
38352 {
38353 const bool synthesis_result =
38354 synthesize_sf3ext_expression::
38355 template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result);
38356
38357 exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
38358
38359 return (synthesis_result) ? result : error_node();
38360 }
38361 // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))
38362 else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
38363 {
38364 const bool synthesis_result =
38365 synthesize_sf3ext_expression::
38366 template compile<vtype, vtype, ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result);
38367
38368 exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
38369
38370 return (synthesis_result) ? result : error_node();
38371 }
38372 // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)
38373 else if (
38374 (std::equal_to<T>()(c0,c1)) &&
38375 (details::e_mul == o0) &&
38376 (details::e_mul == o2) &&
38377 (
38378 (details::e_add == o1) || (details::e_sub == o1)
38379 )
38380 )
38381 {
38382 std::string specfunc;
38383
38384 switch (o1)
38385 {
38386 case details::e_add : specfunc = "t*(t+t)"; break;
38387 case details::e_sub : specfunc = "t*(t-t)"; break;
38388 default : return error_node();
38389 }
38390
38391 const bool synthesis_result =
38392 synthesize_sf3ext_expression::
38393 template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
38394
38395 exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
38396
38397 return (synthesis_result) ? result : error_node();
38398 }
38399 }
38400
38401 const bool synthesis_result =
38402 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38403 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38404
38405 if (synthesis_result)
38406 return result;
38407
38408 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38409 binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
38410 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38411
38412 if (!expr_gen.valid_operator(o0,f0))
38413 return error_node();
38414 else if (!expr_gen.valid_operator(o1,f1))
38415 return error_node();
38416 else if (!expr_gen.valid_operator(o2,f2))
38417 return error_node();
38418 else
38419 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38420 }
38421
38422 static inline std::string id(expression_generator<Type>& expr_gen,
38423 const details::operator_type o0,
38424 const details::operator_type o1,
38425 const details::operator_type o2)
38426 {
38427 return details::build_string()
38428 << "(t" << expr_gen.to_str(o0)
38429 << "t)" << expr_gen.to_str(o1)
38430 << "(t" << expr_gen.to_str(o2)
38431 << "t)";
38432 }
38433 };
38434
38436 {
38437 typedef typename vovovov_t::type1 node_type;
38439 typedef typename node_type::T0 T0;
38440 typedef typename node_type::T1 T1;
38441 typedef typename node_type::T2 T2;
38442 typedef typename node_type::T3 T3;
38443
38445 const details::operator_type& operation,
38446 expression_node_ptr (&branch)[2])
38447 {
38448 // v0 o0 (v1 o1 (v2 o2 v3))
38449 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38450
38451 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38452 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38453 const Type& v1 = vovov->t0();
38454 const Type& v2 = vovov->t1();
38455 const Type& v3 = vovov->t2();
38456 const details::operator_type o0 = operation;
38457 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
38458 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
38459
38460 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38461 binary_functor_t f1 = vovov->f0();
38462 binary_functor_t f2 = vovov->f1();
38463
38464 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38465
38467
38468 const bool synthesis_result =
38469 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38470 (expr_gen,id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
38471
38472 if (synthesis_result)
38473 return result;
38474 else if (!expr_gen.valid_operator(o0,f0))
38475 return error_node();
38476
38477 exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n"));
38478
38479 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
38480 }
38481
38482 static inline std::string id(expression_generator<Type>& expr_gen,
38483 const details::operator_type o0,
38484 const details::operator_type o1,
38485 const details::operator_type o2)
38486 {
38487 return details::build_string()
38488 << "t" << expr_gen.to_str(o0)
38489 << "(t" << expr_gen.to_str(o1)
38490 << "(t" << expr_gen.to_str(o2)
38491 << "t))";
38492 }
38493 };
38494
38496 {
38497 typedef typename vovovoc_t::type1 node_type;
38499 typedef typename node_type::T0 T0;
38500 typedef typename node_type::T1 T1;
38501 typedef typename node_type::T2 T2;
38502 typedef typename node_type::T3 T3;
38503
38505 const details::operator_type& operation,
38506 expression_node_ptr (&branch)[2])
38507 {
38508 // v0 o0 (v1 o1 (v2 o2 c))
38509 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38510
38511 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
38512 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38513 const Type& v1 = vovoc->t0();
38514 const Type& v2 = vovoc->t1();
38515 const Type c = vovoc->t2();
38516 const details::operator_type o0 = operation;
38517 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
38518 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
38519
38520 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38521 binary_functor_t f1 = vovoc->f0();
38522 binary_functor_t f2 = vovoc->f1();
38523
38524 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38525
38527
38528 const bool synthesis_result =
38529 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38530 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
38531
38532 if (synthesis_result)
38533 return result;
38534 else if (!expr_gen.valid_operator(o0,f0))
38535 return error_node();
38536
38537 exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n"));
38538
38539 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
38540 }
38541
38542 static inline std::string id(expression_generator<Type>& expr_gen,
38543 const details::operator_type o0,
38544 const details::operator_type o1,
38545 const details::operator_type o2)
38546 {
38547 return details::build_string()
38548 << "t" << expr_gen.to_str(o0)
38549 << "(t" << expr_gen.to_str(o1)
38550 << "(t" << expr_gen.to_str(o2)
38551 << "t))";
38552 }
38553 };
38554
38556 {
38557 typedef typename vovocov_t::type1 node_type;
38559 typedef typename node_type::T0 T0;
38560 typedef typename node_type::T1 T1;
38561 typedef typename node_type::T2 T2;
38562 typedef typename node_type::T3 T3;
38563
38565 const details::operator_type& operation,
38566 expression_node_ptr (&branch)[2])
38567 {
38568 // v0 o0 (v1 o1 (c o2 v2))
38569 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38570
38571 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
38572 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38573 const Type& v1 = vocov->t0();
38574 const Type c = vocov->t1();
38575 const Type& v2 = vocov->t2();
38576 const details::operator_type o0 = operation;
38577 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
38578 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
38579
38580 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38581 binary_functor_t f1 = vocov->f0();
38582 binary_functor_t f2 = vocov->f1();
38583
38584 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38585
38587
38588 const bool synthesis_result =
38589 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38590 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
38591
38592 if (synthesis_result)
38593 return result;
38594 if (!expr_gen.valid_operator(o0,f0))
38595 return error_node();
38596
38597 exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n"));
38598
38599 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
38600 }
38601
38602 static inline std::string id(expression_generator<Type>& expr_gen,
38603 const details::operator_type o0,
38604 const details::operator_type o1,
38605 const details::operator_type o2)
38606 {
38607 return details::build_string()
38608 << "t" << expr_gen.to_str(o0)
38609 << "(t" << expr_gen.to_str(o1)
38610 << "(t" << expr_gen.to_str(o2)
38611 << "t))";
38612 }
38613 };
38614
38616 {
38617 typedef typename vocovov_t::type1 node_type;
38619 typedef typename node_type::T0 T0;
38620 typedef typename node_type::T1 T1;
38621 typedef typename node_type::T2 T2;
38622 typedef typename node_type::T3 T3;
38623
38625 const details::operator_type& operation,
38626 expression_node_ptr (&branch)[2])
38627 {
38628 // v0 o0 (c o1 (v1 o2 v2))
38629 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
38630
38631 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
38632 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38633 const Type c = covov->t0();
38634 const Type& v1 = covov->t1();
38635 const Type& v2 = covov->t2();
38636 const details::operator_type o0 = operation;
38637 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
38638 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
38639
38640 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38641 binary_functor_t f1 = covov->f0();
38642 binary_functor_t f2 = covov->f1();
38643
38644 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38645
38647
38648 const bool synthesis_result =
38649 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38650 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
38651
38652 if (synthesis_result)
38653 return result;
38654 else if (!expr_gen.valid_operator(o0,f0))
38655 return error_node();
38656
38657 exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n"));
38658
38659 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
38660 }
38661
38662 static inline std::string id(expression_generator<Type>& expr_gen,
38663 const details::operator_type o0,
38664 const details::operator_type o1,
38665 const details::operator_type o2)
38666 {
38667 return details::build_string()
38668 << "t" << expr_gen.to_str(o0)
38669 << "(t" << expr_gen.to_str(o1)
38670 << "(t" << expr_gen.to_str(o2)
38671 << "t))";
38672 }
38673 };
38674
38676 {
38677 typedef typename covovov_t::type1 node_type;
38679 typedef typename node_type::T0 T0;
38680 typedef typename node_type::T1 T1;
38681 typedef typename node_type::T2 T2;
38682 typedef typename node_type::T3 T3;
38683
38685 const details::operator_type& operation,
38686 expression_node_ptr (&branch)[2])
38687 {
38688 // c o0 (v0 o1 (v1 o2 v2))
38689 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38690
38691 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38692 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
38693 const Type& v0 = vovov->t0();
38694 const Type& v1 = vovov->t1();
38695 const Type& v2 = vovov->t2();
38696 const details::operator_type o0 = operation;
38697 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
38698 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
38699
38700 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38701 binary_functor_t f1 = vovov->f0();
38702 binary_functor_t f2 = vovov->f1();
38703
38704 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38705 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38706
38708
38709 const bool synthesis_result =
38710 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38711 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
38712
38713 if (synthesis_result)
38714 return result;
38715 if (!expr_gen.valid_operator(o0,f0))
38716 return error_node();
38717
38718 exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n"));
38719
38720 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
38721 }
38722
38723 static inline std::string id(expression_generator<Type>& expr_gen,
38724 const details::operator_type o0,
38725 const details::operator_type o1,
38726 const details::operator_type o2)
38727 {
38728 return details::build_string()
38729 << "t" << expr_gen.to_str(o0)
38730 << "(t" << expr_gen.to_str(o1)
38731 << "(t" << expr_gen.to_str(o2)
38732 << "t))";
38733 }
38734 };
38735
38737 {
38738 typedef typename covocov_t::type1 node_type;
38740 typedef typename node_type::T0 T0;
38741 typedef typename node_type::T1 T1;
38742 typedef typename node_type::T2 T2;
38743 typedef typename node_type::T3 T3;
38744
38746 const details::operator_type& operation,
38747 expression_node_ptr (&branch)[2])
38748 {
38749 // c0 o0 (v0 o1 (c1 o2 v1))
38750 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38751
38752 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
38753 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
38754 const Type& v0 = vocov->t0();
38755 const Type c1 = vocov->t1();
38756 const Type& v1 = vocov->t2();
38757 const details::operator_type o0 = operation;
38758 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
38759 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
38760
38761 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38762 binary_functor_t f1 = vocov->f0();
38763 binary_functor_t f2 = vocov->f1();
38764
38765 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38766 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38767
38769
38770 const bool synthesis_result =
38771 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38772 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
38773
38774 if (synthesis_result)
38775 return result;
38776 else if (!expr_gen.valid_operator(o0,f0))
38777 return error_node();
38778
38779 exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n"));
38780
38781 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
38782 }
38783
38784 static inline std::string id(expression_generator<Type>& expr_gen,
38785 const details::operator_type o0,
38786 const details::operator_type o1,
38787 const details::operator_type o2)
38788 {
38789 return details::build_string()
38790 << "t" << expr_gen.to_str(o0)
38791 << "(t" << expr_gen.to_str(o1)
38792 << "(t" << expr_gen.to_str(o2)
38793 << "t))";
38794 }
38795 };
38796
38798 {
38799 typedef typename vocovoc_t::type1 node_type;
38801 typedef typename node_type::T0 T0;
38802 typedef typename node_type::T1 T1;
38803 typedef typename node_type::T2 T2;
38804 typedef typename node_type::T3 T3;
38805
38807 const details::operator_type& operation,
38808 expression_node_ptr (&branch)[2])
38809 {
38810 // v0 o0 (c0 o1 (v1 o2 c2))
38811 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
38812
38813 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
38814 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38815 const Type c0 = covoc->t0();
38816 const Type& v1 = covoc->t1();
38817 const Type c1 = covoc->t2();
38818 const details::operator_type o0 = operation;
38819 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
38820 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
38821
38822 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38823 binary_functor_t f1 = covoc->f0();
38824 binary_functor_t f2 = covoc->f1();
38825
38826 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38827
38829
38830 const bool synthesis_result =
38831 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38832 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38833
38834 if (synthesis_result)
38835 return result;
38836 else if (!expr_gen.valid_operator(o0,f0))
38837 return error_node();
38838
38839 exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n"));
38840
38841 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38842 }
38843
38844 static inline std::string id(expression_generator<Type>& expr_gen,
38845 const details::operator_type o0,
38846 const details::operator_type o1,
38847 const details::operator_type o2)
38848 {
38849 return details::build_string()
38850 << "t" << expr_gen.to_str(o0)
38851 << "(t" << expr_gen.to_str(o1)
38852 << "(t" << expr_gen.to_str(o2)
38853 << "t))";
38854 }
38855 };
38856
38858 {
38859 typedef typename covovoc_t::type1 node_type;
38861 typedef typename node_type::T0 T0;
38862 typedef typename node_type::T1 T1;
38863 typedef typename node_type::T2 T2;
38864 typedef typename node_type::T3 T3;
38866 const details::operator_type& operation,
38867 expression_node_ptr (&branch)[2])
38868 {
38869 // c0 o0 (v0 o1 (v1 o2 c1))
38870 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38871
38872 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
38873 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
38874 const Type& v0 = vovoc->t0();
38875 const Type& v1 = vovoc->t1();
38876 const Type c1 = vovoc->t2();
38877 const details::operator_type o0 = operation;
38878 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
38879 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
38880
38881 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38882 binary_functor_t f1 = vovoc->f0();
38883 binary_functor_t f2 = vovoc->f1();
38884
38885 details::free_node(*(expr_gen.node_allocator_),branch[0]);
38886 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38887
38889
38890 const bool synthesis_result =
38891 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38892 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38893
38894 if (synthesis_result)
38895 return result;
38896 else if (!expr_gen.valid_operator(o0,f0))
38897 return error_node();
38898
38899 exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n"));
38900
38901 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38902 }
38903
38904 static inline std::string id(expression_generator<Type>& expr_gen,
38905 const details::operator_type o0,
38906 const details::operator_type o1,
38907 const details::operator_type o2)
38908 {
38909 return details::build_string()
38910 << "t" << expr_gen.to_str(o0)
38911 << "(t" << expr_gen.to_str(o1)
38912 << "(t" << expr_gen.to_str(o2)
38913 << "t))";
38914 }
38915 };
38916
38918 {
38919 typedef typename vococov_t::type1 node_type;
38921 typedef typename node_type::T0 T0;
38922 typedef typename node_type::T1 T1;
38923 typedef typename node_type::T2 T2;
38924 typedef typename node_type::T3 T3;
38925
38927 const details::operator_type& operation,
38928 expression_node_ptr (&branch)[2])
38929 {
38930 // v0 o0 (c0 o1 (c1 o2 v1))
38931 typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t;
38932
38933 const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]);
38934 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38935 const Type c0 = cocov->t0();
38936 const Type c1 = cocov->t1();
38937 const Type& v1 = cocov->t2();
38938 const details::operator_type o0 = operation;
38939 const details::operator_type o1 = expr_gen.get_operator(cocov->f0());
38940 const details::operator_type o2 = expr_gen.get_operator(cocov->f1());
38941
38942 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38943 binary_functor_t f1 = cocov->f0();
38944 binary_functor_t f2 = cocov->f1();
38945
38946 details::free_node(*(expr_gen.node_allocator_),branch[1]);
38947
38949
38950 const bool synthesis_result =
38951 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38952 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38953
38954 if (synthesis_result)
38955 return result;
38956 else if (!expr_gen.valid_operator(o0,f0))
38957 return error_node();
38958
38959 exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n"));
38960
38961 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38962 }
38963
38964 static inline std::string id(expression_generator<Type>& expr_gen,
38965 const details::operator_type o0,
38966 const details::operator_type o1,
38967 const details::operator_type o2)
38968 {
38969 return details::build_string()
38970 << "t" << expr_gen.to_str(o0)
38971 << "(t" << expr_gen.to_str(o1)
38972 << "(t" << expr_gen.to_str(o2)
38973 << "t))";
38974 }
38975 };
38976
38978 {
38979 typedef typename vovovov_t::type2 node_type;
38981 typedef typename node_type::T0 T0;
38982 typedef typename node_type::T1 T1;
38983 typedef typename node_type::T2 T2;
38984 typedef typename node_type::T3 T3;
38985
38987 const details::operator_type& operation,
38988 expression_node_ptr (&branch)[2])
38989 {
38990 // v0 o0 ((v1 o1 v2) o2 v3)
38991 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
38992
38993 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
38994 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
38995 const Type& v1 = vovov->t0();
38996 const Type& v2 = vovov->t1();
38997 const Type& v3 = vovov->t2();
38998 const details::operator_type o0 = operation;
38999 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
39000 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
39001
39002 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39003 binary_functor_t f1 = vovov->f0();
39004 binary_functor_t f2 = vovov->f1();
39005
39006 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39007
39009
39010 const bool synthesis_result =
39011 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39012 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
39013
39014 if (synthesis_result)
39015 return result;
39016 else if (!expr_gen.valid_operator(o0,f0))
39017 return error_node();
39018
39019 exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n"));
39020
39021 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
39022 }
39023
39024 static inline std::string id(expression_generator<Type>& expr_gen,
39025 const details::operator_type o0,
39026 const details::operator_type o1,
39027 const details::operator_type o2)
39028 {
39029 return details::build_string()
39030 << "t" << expr_gen.to_str(o0)
39031 << "((t" << expr_gen.to_str(o1)
39032 << "t)" << expr_gen.to_str(o2)
39033 << "t)";
39034 }
39035 };
39036
39038 {
39039 typedef typename vovovoc_t::type2 node_type;
39041 typedef typename node_type::T0 T0;
39042 typedef typename node_type::T1 T1;
39043 typedef typename node_type::T2 T2;
39044 typedef typename node_type::T3 T3;
39045
39047 const details::operator_type& operation,
39048 expression_node_ptr (&branch)[2])
39049 {
39050 // v0 o0 ((v1 o1 v2) o2 c)
39051 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39052
39053 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
39054 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39055 const Type& v1 = vovoc->t0();
39056 const Type& v2 = vovoc->t1();
39057 const Type c = vovoc->t2();
39058 const details::operator_type o0 = operation;
39059 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
39060 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
39061
39062 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39063 binary_functor_t f1 = vovoc->f0();
39064 binary_functor_t f2 = vovoc->f1();
39065
39066 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39067
39069
39070 const bool synthesis_result =
39071 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39072 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
39073
39074 if (synthesis_result)
39075 return result;
39076 else if (!expr_gen.valid_operator(o0,f0))
39077 return error_node();
39078
39079 exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n"));
39080
39081 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
39082 }
39083
39084 static inline std::string id(expression_generator<Type>& expr_gen,
39085 const details::operator_type o0,
39086 const details::operator_type o1,
39087 const details::operator_type o2)
39088 {
39089 return details::build_string()
39090 << "t" << expr_gen.to_str(o0)
39091 << "((t" << expr_gen.to_str(o1)
39092 << "t)" << expr_gen.to_str(o2)
39093 << "t)";
39094 }
39095 };
39096
39098 {
39099 typedef typename vovocov_t::type2 node_type;
39101 typedef typename node_type::T0 T0;
39102 typedef typename node_type::T1 T1;
39103 typedef typename node_type::T2 T2;
39104 typedef typename node_type::T3 T3;
39105
39107 const details::operator_type& operation,
39108 expression_node_ptr (&branch)[2])
39109 {
39110 // v0 o0 ((v1 o1 c) o2 v2)
39111 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39112
39113 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
39114 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39115 const Type& v1 = vocov->t0();
39116 const Type c = vocov->t1();
39117 const Type& v2 = vocov->t2();
39118 const details::operator_type o0 = operation;
39119 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
39120 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
39121
39122 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39123 binary_functor_t f1 = vocov->f0();
39124 binary_functor_t f2 = vocov->f1();
39125
39126 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39127
39129
39130 const bool synthesis_result =
39131 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39132 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
39133
39134 if (synthesis_result)
39135 return result;
39136 else if (!expr_gen.valid_operator(o0,f0))
39137 return error_node();
39138
39139 exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n"));
39140
39141 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
39142 }
39143
39144 static inline std::string id(expression_generator<Type>& expr_gen,
39145 const details::operator_type o0,
39146 const details::operator_type o1,
39147 const details::operator_type o2)
39148 {
39149 return details::build_string()
39150 << "t" << expr_gen.to_str(o0)
39151 << "((t" << expr_gen.to_str(o1)
39152 << "t)" << expr_gen.to_str(o2)
39153 << "t)";
39154 }
39155 };
39156
39158 {
39159 typedef typename vocovov_t::type2 node_type;
39161 typedef typename node_type::T0 T0;
39162 typedef typename node_type::T1 T1;
39163 typedef typename node_type::T2 T2;
39164 typedef typename node_type::T3 T3;
39165
39167 const details::operator_type& operation,
39168 expression_node_ptr (&branch)[2])
39169 {
39170 // v0 o0 ((c o1 v1) o2 v2)
39171 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39172
39173 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
39174 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39175 const Type c = covov->t0();
39176 const Type& v1 = covov->t1();
39177 const Type& v2 = covov->t2();
39178 const details::operator_type o0 = operation;
39179 const details::operator_type o1 = expr_gen.get_operator(covov->f0());
39180 const details::operator_type o2 = expr_gen.get_operator(covov->f1());
39181
39182 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39183 binary_functor_t f1 = covov->f0();
39184 binary_functor_t f2 = covov->f1();
39185
39186 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39187
39189
39190 const bool synthesis_result =
39191 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39192 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
39193
39194 if (synthesis_result)
39195 return result;
39196 else if (!expr_gen.valid_operator(o0,f0))
39197 return error_node();
39198
39199 exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n"));
39200
39201 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
39202 }
39203
39204 static inline std::string id(expression_generator<Type>& expr_gen,
39205 const details::operator_type o0,
39206 const details::operator_type o1,
39207 const details::operator_type o2)
39208 {
39209 return details::build_string()
39210 << "t" << expr_gen.to_str(o0)
39211 << "((t" << expr_gen.to_str(o1)
39212 << "t)" << expr_gen.to_str(o2)
39213 << "t)";
39214 }
39215 };
39216
39218 {
39219 typedef typename covovov_t::type2 node_type;
39221 typedef typename node_type::T0 T0;
39222 typedef typename node_type::T1 T1;
39223 typedef typename node_type::T2 T2;
39224 typedef typename node_type::T3 T3;
39225
39227 const details::operator_type& operation,
39228 expression_node_ptr (&branch)[2])
39229 {
39230 // c o0 ((v1 o1 v2) o2 v3)
39231 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39232
39233 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
39234 const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
39235 const Type& v0 = vovov->t0();
39236 const Type& v1 = vovov->t1();
39237 const Type& v2 = vovov->t2();
39238 const details::operator_type o0 = operation;
39239 const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
39240 const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
39241
39242 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39243 binary_functor_t f1 = vovov->f0();
39244 binary_functor_t f2 = vovov->f1();
39245
39246 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39247 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39248
39250
39251 const bool synthesis_result =
39252 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39253 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
39254
39255 if (synthesis_result)
39256 return result;
39257 else if (!expr_gen.valid_operator(o0,f0))
39258 return error_node();
39259
39260 exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n"));
39261
39262 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
39263 }
39264
39265 static inline std::string id(expression_generator<Type>& expr_gen,
39266 const details::operator_type o0,
39267 const details::operator_type o1,
39268 const details::operator_type o2)
39269 {
39270 return details::build_string()
39271 << "t" << expr_gen.to_str(o0)
39272 << "((t" << expr_gen.to_str(o1)
39273 << "t)" << expr_gen.to_str(o2)
39274 << "t)";
39275 }
39276 };
39277
39279 {
39280 typedef typename covocov_t::type2 node_type;
39282 typedef typename node_type::T0 T0;
39283 typedef typename node_type::T1 T1;
39284 typedef typename node_type::T2 T2;
39285 typedef typename node_type::T3 T3;
39286
39288 const details::operator_type& operation,
39289 expression_node_ptr (&branch)[2])
39290 {
39291 // c0 o0 ((v0 o1 c1) o2 v1)
39292 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39293
39294 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
39295 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
39296 const Type& v0 = vocov->t0();
39297 const Type c1 = vocov->t1();
39298 const Type& v1 = vocov->t2();
39299 const details::operator_type o0 = operation;
39300 const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
39301 const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
39302
39303 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39304 binary_functor_t f1 = vocov->f0();
39305 binary_functor_t f2 = vocov->f1();
39306
39307 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39308 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39309
39311
39312 const bool synthesis_result =
39313 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39314 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
39315
39316 if (synthesis_result)
39317 return result;
39318 else if (!expr_gen.valid_operator(o0,f0))
39319 return error_node();
39320
39321 exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n"));
39322
39323 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
39324 }
39325
39326 static inline std::string id(expression_generator<Type>& expr_gen,
39327 const details::operator_type o0,
39328 const details::operator_type o1,
39329 const details::operator_type o2)
39330 {
39331 return details::build_string()
39332 << "t" << expr_gen.to_str(o0)
39333 << "((t" << expr_gen.to_str(o1)
39334 << "t)" << expr_gen.to_str(o2)
39335 << "t)";
39336 }
39337 };
39338
39340 {
39341 typedef typename vocovoc_t::type2 node_type;
39343 typedef typename node_type::T0 T0;
39344 typedef typename node_type::T1 T1;
39345 typedef typename node_type::T2 T2;
39346 typedef typename node_type::T3 T3;
39347
39349 const details::operator_type& operation,
39350 expression_node_ptr (&branch)[2])
39351 {
39352 // v0 o0 ((c0 o1 v1) o2 c1)
39353 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
39354
39355 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
39356 const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
39357 const Type c0 = covoc->t0();
39358 const Type& v1 = covoc->t1();
39359 const Type c1 = covoc->t2();
39360 const details::operator_type o0 = operation;
39361 const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
39362 const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
39363
39364 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39365 binary_functor_t f1 = covoc->f0();
39366 binary_functor_t f2 = covoc->f1();
39367
39368 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39369
39371
39372 const bool synthesis_result =
39373 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39374 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
39375
39376 if (synthesis_result)
39377 return result;
39378 else if (!expr_gen.valid_operator(o0,f0))
39379 return error_node();
39380
39381 exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n"));
39382
39383 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
39384 }
39385
39386 static inline std::string id(expression_generator<Type>& expr_gen,
39387 const details::operator_type o0,
39388 const details::operator_type o1,
39389 const details::operator_type o2)
39390 {
39391 return details::build_string()
39392 << "t" << expr_gen.to_str(o0)
39393 << "((t" << expr_gen.to_str(o1)
39394 << "t)" << expr_gen.to_str(o2)
39395 << "t)";
39396 }
39397 };
39398
39400 {
39401 typedef typename covovoc_t::type2 node_type;
39403 typedef typename node_type::T0 T0;
39404 typedef typename node_type::T1 T1;
39405 typedef typename node_type::T2 T2;
39406 typedef typename node_type::T3 T3;
39407
39409 const details::operator_type& operation,
39410 expression_node_ptr (&branch)[2])
39411 {
39412 // c0 o0 ((v0 o1 v1) o2 c1)
39413 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39414
39415 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
39416 const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
39417 const Type& v0 = vovoc->t0();
39418 const Type& v1 = vovoc->t1();
39419 const Type c1 = vovoc->t2();
39420 const details::operator_type o0 = operation;
39421 const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
39422 const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
39423
39424 binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
39425 binary_functor_t f1 = vovoc->f0();
39426 binary_functor_t f2 = vovoc->f1();
39427
39428 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39429 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39430
39432
39433 const bool synthesis_result =
39434 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39435 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39436
39437 if (synthesis_result)
39438 return result;
39439 else if (!expr_gen.valid_operator(o0,f0))
39440 return error_node();
39441
39442 exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n"));
39443
39444 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39445 }
39446
39447 static inline std::string id(expression_generator<Type>& expr_gen,
39448 const details::operator_type o0,
39449 const details::operator_type o1,
39450 const details::operator_type o2)
39451 {
39452 return details::build_string()
39453 << "t" << expr_gen.to_str(o0)
39454 << "((t" << expr_gen.to_str(o1)
39455 << "t)" << expr_gen.to_str(o2)
39456 << "t)";
39457 }
39458 };
39459
39461 {
39462 typedef typename vococov_t::type2 node_type;
39465 expression_node_ptr (&)[2])
39466 {
39467 // v0 o0 ((c0 o1 c1) o2 v1) - Not possible
39468 exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
39469 return error_node();
39470 }
39471
39472 static inline std::string id(expression_generator<Type>&,
39476 {
39477 return "INVALID";
39478 }
39479 };
39480
39482 {
39483 typedef typename vovovov_t::type3 node_type;
39485 typedef typename node_type::T0 T0;
39486 typedef typename node_type::T1 T1;
39487 typedef typename node_type::T2 T2;
39488 typedef typename node_type::T3 T3;
39489
39491 const details::operator_type& operation,
39492 expression_node_ptr (&branch)[2])
39493 {
39494 // ((v0 o0 v1) o1 v2) o2 v3
39495 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39496
39497 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
39498 const Type& v0 = vovov->t0();
39499 const Type& v1 = vovov->t1();
39500 const Type& v2 = vovov->t2();
39501 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39502 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
39503 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
39504 const details::operator_type o2 = operation;
39505
39506 binary_functor_t f0 = vovov->f0();
39507 binary_functor_t f1 = vovov->f1();
39508 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39509
39510 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39511
39513
39514 const bool synthesis_result =
39515 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39516 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
39517
39518 if (synthesis_result)
39519 return result;
39520 else if (!expr_gen.valid_operator(o2,f2))
39521 return error_node();
39522
39523 exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n"));
39524
39525 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
39526 }
39527
39528 static inline std::string id(expression_generator<Type>& expr_gen,
39529 const details::operator_type o0,
39530 const details::operator_type o1,
39531 const details::operator_type o2)
39532 {
39533 return details::build_string()
39534 << "((t" << expr_gen.to_str(o0)
39535 << "t)" << expr_gen.to_str(o1)
39536 << "t)" << expr_gen.to_str(o2)
39537 << "t";
39538 }
39539 };
39540
39542 {
39543 typedef typename vovovoc_t::type3 node_type;
39545 typedef typename node_type::T0 T0;
39546 typedef typename node_type::T1 T1;
39547 typedef typename node_type::T2 T2;
39548 typedef typename node_type::T3 T3;
39549
39551 const details::operator_type& operation,
39552 expression_node_ptr (&branch)[2])
39553 {
39554 // ((v0 o0 v1) o1 v2) o2 c
39555 typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
39556
39557 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
39558 const Type& v0 = vovov->t0();
39559 const Type& v1 = vovov->t1();
39560 const Type& v2 = vovov->t2();
39561 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
39562 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
39563 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
39564 const details::operator_type o2 = operation;
39565
39566 binary_functor_t f0 = vovov->f0();
39567 binary_functor_t f1 = vovov->f1();
39568 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39569
39570 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39571 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39572
39574
39575 const bool synthesis_result =
39576 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39577 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
39578
39579 if (synthesis_result)
39580 return result;
39581 else if (!expr_gen.valid_operator(o2,f2))
39582 return error_node();
39583
39584 exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n"));
39585
39586 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
39587 }
39588
39589 static inline std::string id(expression_generator<Type>& expr_gen,
39590 const details::operator_type o0,
39591 const details::operator_type o1,
39592 const details::operator_type o2)
39593 {
39594 return details::build_string()
39595 << "((t" << expr_gen.to_str(o0)
39596 << "t)" << expr_gen.to_str(o1)
39597 << "t)" << expr_gen.to_str(o2)
39598 << "t";
39599 }
39600 };
39601
39603 {
39604 typedef typename vovocov_t::type3 node_type;
39606 typedef typename node_type::T0 T0;
39607 typedef typename node_type::T1 T1;
39608 typedef typename node_type::T2 T2;
39609 typedef typename node_type::T3 T3;
39610
39612 const details::operator_type& operation,
39613 expression_node_ptr (&branch)[2])
39614 {
39615 // ((v0 o0 v1) o1 c) o2 v2
39616 typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
39617
39618 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
39619 const Type& v0 = vovoc->t0();
39620 const Type& v1 = vovoc->t1();
39621 const Type c = vovoc->t2();
39622 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39623 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
39624 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
39625 const details::operator_type o2 = operation;
39626
39627 binary_functor_t f0 = vovoc->f0();
39628 binary_functor_t f1 = vovoc->f1();
39629 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39630
39631 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39632
39634
39635 const bool synthesis_result =
39636 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39637 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
39638
39639 if (synthesis_result)
39640 return result;
39641 else if (!expr_gen.valid_operator(o2,f2))
39642 return error_node();
39643
39644 exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n"));
39645
39646 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
39647 }
39648
39649 static inline std::string id(expression_generator<Type>& expr_gen,
39650 const details::operator_type o0,
39651 const details::operator_type o1,
39652 const details::operator_type o2)
39653 {
39654 return details::build_string()
39655 << "((t" << expr_gen.to_str(o0)
39656 << "t)" << expr_gen.to_str(o1)
39657 << "t)" << expr_gen.to_str(o2)
39658 << "t";
39659 }
39660 };
39661
39663 {
39664 typedef typename vocovov_t::type3 node_type;
39666 typedef typename node_type::T0 T0;
39667 typedef typename node_type::T1 T1;
39668 typedef typename node_type::T2 T2;
39669 typedef typename node_type::T3 T3;
39670
39672 const details::operator_type& operation,
39673 expression_node_ptr (&branch)[2])
39674 {
39675 // ((v0 o0 c) o1 v1) o2 v2
39676 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39677
39678 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
39679 const Type& v0 = vocov->t0();
39680 const Type c = vocov->t1();
39681 const Type& v1 = vocov->t2();
39682 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39683 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
39684 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
39685 const details::operator_type o2 = operation;
39686
39687 binary_functor_t f0 = vocov->f0();
39688 binary_functor_t f1 = vocov->f1();
39689 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39690
39691 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39692
39694
39695 const bool synthesis_result =
39696 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39697 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
39698
39699 if (synthesis_result)
39700 return result;
39701 else if (!expr_gen.valid_operator(o2,f2))
39702 return error_node();
39703
39704 exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n"));
39705
39706 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
39707 }
39708
39709 static inline std::string id(expression_generator<Type>& expr_gen,
39710 const details::operator_type o0,
39711 const details::operator_type o1,
39712 const details::operator_type o2)
39713 {
39714 return details::build_string()
39715 << "((t" << expr_gen.to_str(o0)
39716 << "t)" << expr_gen.to_str(o1)
39717 << "t)" << expr_gen.to_str(o2)
39718 << "t";
39719 }
39720 };
39721
39723 {
39724 typedef typename covovov_t::type3 node_type;
39726 typedef typename node_type::T0 T0;
39727 typedef typename node_type::T1 T1;
39728 typedef typename node_type::T2 T2;
39729 typedef typename node_type::T3 T3;
39730
39732 const details::operator_type& operation,
39733 expression_node_ptr (&branch)[2])
39734 {
39735 // ((c o0 v0) o1 v1) o2 v2
39736 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39737
39738 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
39739 const Type c = covov->t0();
39740 const Type& v0 = covov->t1();
39741 const Type& v1 = covov->t2();
39742 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39743 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
39744 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
39745 const details::operator_type o2 = operation;
39746
39747 binary_functor_t f0 = covov->f0();
39748 binary_functor_t f1 = covov->f1();
39749 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39750
39751 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39752
39754
39755 const bool synthesis_result =
39756 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39757 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
39758
39759 if (synthesis_result)
39760 return result;
39761 else if (!expr_gen.valid_operator(o2,f2))
39762 return error_node();
39763
39764 exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n"));
39765
39766 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
39767 }
39768
39769 static inline std::string id(expression_generator<Type>& expr_gen,
39770 const details::operator_type o0,
39771 const details::operator_type o1,
39772 const details::operator_type o2)
39773 {
39774 return details::build_string()
39775 << "((t" << expr_gen.to_str(o0)
39776 << "t)" << expr_gen.to_str(o1)
39777 << "t)" << expr_gen.to_str(o2)
39778 << "t";
39779 }
39780 };
39781
39783 {
39784 typedef typename covocov_t::type3 node_type;
39786 typedef typename node_type::T0 T0;
39787 typedef typename node_type::T1 T1;
39788 typedef typename node_type::T2 T2;
39789 typedef typename node_type::T3 T3;
39790
39792 const details::operator_type& operation,
39793 expression_node_ptr (&branch)[2])
39794 {
39795 // ((c0 o0 v0) o1 c1) o2 v1
39796 typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
39797
39798 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
39799 const Type c0 = covoc->t0();
39800 const Type& v0 = covoc->t1();
39801 const Type c1 = covoc->t2();
39802 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39803 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
39804 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
39805 const details::operator_type o2 = operation;
39806
39807 binary_functor_t f0 = covoc->f0();
39808 binary_functor_t f1 = covoc->f1();
39809 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39810
39811 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39812
39814
39815 const bool synthesis_result =
39816 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39817 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
39818
39819 if (synthesis_result)
39820 return result;
39821 else if (!expr_gen.valid_operator(o2,f2))
39822 return error_node();
39823
39824 exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n"));
39825
39826 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
39827 }
39828
39829 static inline std::string id(expression_generator<Type>& expr_gen,
39830 const details::operator_type o0,
39831 const details::operator_type o1,
39832 const details::operator_type o2)
39833 {
39834 return details::build_string()
39835 << "((t" << expr_gen.to_str(o0)
39836 << "t)" << expr_gen.to_str(o1)
39837 << "t)" << expr_gen.to_str(o2)
39838 << "t";
39839 }
39840 };
39841
39843 {
39844 typedef typename vocovoc_t::type3 node_type;
39846 typedef typename node_type::T0 T0;
39847 typedef typename node_type::T1 T1;
39848 typedef typename node_type::T2 T2;
39849 typedef typename node_type::T3 T3;
39850
39852 const details::operator_type& operation,
39853 expression_node_ptr (&branch)[2])
39854 {
39855 // ((v0 o0 c0) o1 v1) o2 c1
39856 typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
39857
39858 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
39859 const Type& v0 = vocov->t0();
39860 const Type c0 = vocov->t1();
39861 const Type& v1 = vocov->t2();
39862 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
39863 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
39864 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
39865 const details::operator_type o2 = operation;
39866
39867 binary_functor_t f0 = vocov->f0();
39868 binary_functor_t f1 = vocov->f1();
39869 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39870
39871 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39872 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39873
39875
39876 const bool synthesis_result =
39877 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39878 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
39879
39880 if (synthesis_result)
39881 return result;
39882 else if (!expr_gen.valid_operator(o2,f2))
39883 return error_node();
39884
39885 exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n"));
39886
39887 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
39888 }
39889
39890 static inline std::string id(expression_generator<Type>& expr_gen,
39891 const details::operator_type o0,
39892 const details::operator_type o1,
39893 const details::operator_type o2)
39894 {
39895 return details::build_string()
39896 << "((t" << expr_gen.to_str(o0)
39897 << "t)" << expr_gen.to_str(o1)
39898 << "t)" << expr_gen.to_str(o2)
39899 << "t";
39900 }
39901 };
39902
39904 {
39905 typedef typename covovoc_t::type3 node_type;
39907 typedef typename node_type::T0 T0;
39908 typedef typename node_type::T1 T1;
39909 typedef typename node_type::T2 T2;
39910 typedef typename node_type::T3 T3;
39911
39913 const details::operator_type& operation,
39914 expression_node_ptr (&branch)[2])
39915 {
39916 // ((c0 o0 v0) o1 v1) o2 c1
39917 typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
39918
39919 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
39920 const Type c0 = covov->t0();
39921 const Type& v0 = covov->t1();
39922 const Type& v1 = covov->t2();
39923 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
39924 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
39925 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
39926 const details::operator_type o2 = operation;
39927
39928 binary_functor_t f0 = covov->f0();
39929 binary_functor_t f1 = covov->f1();
39930 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39931
39932 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39933 details::free_node(*(expr_gen.node_allocator_),branch[1]);
39934
39936
39937 const bool synthesis_result =
39938 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39939 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39940
39941 if (synthesis_result)
39942 return result;
39943 else if (!expr_gen.valid_operator(o2,f2))
39944 return error_node();
39945
39946 exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n"));
39947
39948 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39949 }
39950
39951 static inline std::string id(expression_generator<Type>& expr_gen,
39952 const details::operator_type o0,
39953 const details::operator_type o1,
39954 const details::operator_type o2)
39955 {
39956 return details::build_string()
39957 << "((t" << expr_gen.to_str(o0)
39958 << "t)" << expr_gen.to_str(o1)
39959 << "t)" << expr_gen.to_str(o2)
39960 << "t";
39961 }
39962 };
39963
39965 {
39966 typedef typename vococov_t::type3 node_type;
39968 typedef typename node_type::T0 T0;
39969 typedef typename node_type::T1 T1;
39970 typedef typename node_type::T2 T2;
39971 typedef typename node_type::T3 T3;
39972
39974 const details::operator_type& operation,
39975 expression_node_ptr (&branch)[2])
39976 {
39977 // ((v0 o0 c0) o1 c1) o2 v1
39978 typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t;
39979
39980 const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]);
39981 const Type& v0 = vococ->t0();
39982 const Type c0 = vococ->t1();
39983 const Type c1 = vococ->t2();
39984 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
39985 const details::operator_type o0 = expr_gen.get_operator(vococ->f0());
39986 const details::operator_type o1 = expr_gen.get_operator(vococ->f1());
39987 const details::operator_type o2 = operation;
39988
39989 binary_functor_t f0 = vococ->f0();
39990 binary_functor_t f1 = vococ->f1();
39991 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39992
39993 details::free_node(*(expr_gen.node_allocator_),branch[0]);
39994
39996
39997 const bool synthesis_result =
39998 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39999 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
40000
40001 if (synthesis_result)
40002 return result;
40003 else if (!expr_gen.valid_operator(o2,f2))
40004 return error_node();
40005
40006 exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n"));
40007
40008 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
40009 }
40010
40011 static inline std::string id(expression_generator<Type>& expr_gen,
40012 const details::operator_type o0,
40013 const details::operator_type o1,
40014 const details::operator_type o2)
40015 {
40016 return details::build_string()
40017 << "((t" << expr_gen.to_str(o0)
40018 << "t)" << expr_gen.to_str(o1)
40019 << "t)" << expr_gen.to_str(o2)
40020 << "t";
40021 }
40022 };
40023
40025 {
40026 typedef typename vovovov_t::type4 node_type;
40028 typedef typename node_type::T0 T0;
40029 typedef typename node_type::T1 T1;
40030 typedef typename node_type::T2 T2;
40031 typedef typename node_type::T3 T3;
40032
40034 const details::operator_type& operation,
40035 expression_node_ptr (&branch)[2])
40036 {
40037 // (v0 o0 (v1 o1 v2)) o2 v3
40038 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
40039
40040 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
40041 const Type& v0 = vovov->t0();
40042 const Type& v1 = vovov->t1();
40043 const Type& v2 = vovov->t2();
40044 const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40045 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
40046 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
40047 const details::operator_type o2 = operation;
40048
40049 binary_functor_t f0 = vovov->f0();
40050 binary_functor_t f1 = vovov->f1();
40051 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40052
40053 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40054
40056
40057 const bool synthesis_result =
40058 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40059 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
40060
40061 if (synthesis_result)
40062 return result;
40063 else if (!expr_gen.valid_operator(o2,f2))
40064 return error_node();
40065
40066 exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n"));
40067
40068 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
40069 }
40070
40071 static inline std::string id(expression_generator<Type>& expr_gen,
40072 const details::operator_type o0,
40073 const details::operator_type o1,
40074 const details::operator_type o2)
40075 {
40076 return details::build_string()
40077 << "(t" << expr_gen.to_str(o0)
40078 << "(t" << expr_gen.to_str(o1)
40079 << "t)" << expr_gen.to_str(o2)
40080 << "t";
40081 }
40082 };
40083
40085 {
40086 typedef typename vovovoc_t::type4 node_type;
40088 typedef typename node_type::T0 T0;
40089 typedef typename node_type::T1 T1;
40090 typedef typename node_type::T2 T2;
40091 typedef typename node_type::T3 T3;
40092
40094 const details::operator_type& operation,
40095 expression_node_ptr (&branch)[2])
40096 {
40097 // ((v0 o0 (v1 o1 v2)) o2 c)
40098 typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
40099
40100 const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
40101 const Type& v0 = vovov->t0();
40102 const Type& v1 = vovov->t1();
40103 const Type& v2 = vovov->t2();
40104 const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
40105 const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
40106 const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
40107 const details::operator_type o2 = operation;
40108
40109 binary_functor_t f0 = vovov->f0();
40110 binary_functor_t f1 = vovov->f1();
40111 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40112
40113 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40114 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40115
40117
40118 const bool synthesis_result =
40119 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40120 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
40121
40122 if (synthesis_result)
40123 return result;
40124 else if (!expr_gen.valid_operator(o2,f2))
40125 return error_node();
40126
40127 exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n"));
40128
40129 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
40130 }
40131
40132 static inline std::string id(expression_generator<Type>& expr_gen,
40133 const details::operator_type o0,
40134 const details::operator_type o1,
40135 const details::operator_type o2)
40136 {
40137 return details::build_string()
40138 << "(t" << expr_gen.to_str(o0)
40139 << "(t" << expr_gen.to_str(o1)
40140 << "t)" << expr_gen.to_str(o2)
40141 << "t";
40142 }
40143 };
40144
40146 {
40147 typedef typename vovocov_t::type4 node_type;
40149 typedef typename node_type::T0 T0;
40150 typedef typename node_type::T1 T1;
40151 typedef typename node_type::T2 T2;
40152 typedef typename node_type::T3 T3;
40153
40155 const details::operator_type& operation,
40156 expression_node_ptr (&branch)[2])
40157 {
40158 // ((v0 o0 (v1 o1 c)) o2 v1)
40159 typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
40160
40161 const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
40162 const Type& v0 = vovoc->t0();
40163 const Type& v1 = vovoc->t1();
40164 const Type c = vovoc->t2();
40165 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40166 const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
40167 const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
40168 const details::operator_type o2 = operation;
40169
40170 binary_functor_t f0 = vovoc->f0();
40171 binary_functor_t f1 = vovoc->f1();
40172 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40173
40174 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40175
40177
40178 const bool synthesis_result =
40179 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40180 (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
40181
40182 if (synthesis_result)
40183 return result;
40184 else if (!expr_gen.valid_operator(o2,f2))
40185 return error_node();
40186
40187 exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n"));
40188
40189 return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
40190 }
40191
40192 static inline std::string id(expression_generator<Type>& expr_gen,
40193 const details::operator_type o0,
40194 const details::operator_type o1,
40195 const details::operator_type o2)
40196 {
40197 return details::build_string()
40198 << "(t" << expr_gen.to_str(o0)
40199 << "(t" << expr_gen.to_str(o1)
40200 << "t)" << expr_gen.to_str(o2)
40201 << "t";
40202 }
40203 };
40204
40206 {
40207 typedef typename vocovov_t::type4 node_type;
40209 typedef typename node_type::T0 T0;
40210 typedef typename node_type::T1 T1;
40211 typedef typename node_type::T2 T2;
40212 typedef typename node_type::T3 T3;
40213
40215 const details::operator_type& operation,
40216 expression_node_ptr (&branch)[2])
40217 {
40218 // ((v0 o0 (c o1 v1)) o2 v2)
40219 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
40220
40221 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
40222 const Type& v0 = vocov->t0();
40223 const Type c = vocov->t1();
40224 const Type& v1 = vocov->t2();
40225 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40226 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
40227 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
40228 const details::operator_type o2 = operation;
40229
40230 binary_functor_t f0 = vocov->f0();
40231 binary_functor_t f1 = vocov->f1();
40232 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40233
40234 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40236
40237 const bool synthesis_result =
40238 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40239 (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
40240
40241 if (synthesis_result)
40242 return result;
40243 else if (!expr_gen.valid_operator(o2,f2))
40244 return error_node();
40245
40246 exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n"));
40247
40248 return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
40249 }
40250
40251 static inline std::string id(expression_generator<Type>& expr_gen,
40252 const details::operator_type o0,
40253 const details::operator_type o1,
40254 const details::operator_type o2)
40255 {
40256 return details::build_string()
40257 << "(t" << expr_gen.to_str(o0)
40258 << "(t" << expr_gen.to_str(o1)
40259 << "t)" << expr_gen.to_str(o2)
40260 << "t";
40261 }
40262 };
40263
40265 {
40266 typedef typename covovov_t::type4 node_type;
40268 typedef typename node_type::T0 T0;
40269 typedef typename node_type::T1 T1;
40270 typedef typename node_type::T2 T2;
40271 typedef typename node_type::T3 T3;
40272
40274 const details::operator_type& operation,
40275 expression_node_ptr (&branch)[2])
40276 {
40277 // ((c o0 (v0 o1 v1)) o2 v2)
40278 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
40279
40280 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
40281 const Type c = covov->t0();
40282 const Type& v0 = covov->t1();
40283 const Type& v1 = covov->t2();
40284 const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40285 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
40286 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
40287 const details::operator_type o2 = operation;
40288
40289 binary_functor_t f0 = covov->f0();
40290 binary_functor_t f1 = covov->f1();
40291 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40292
40293 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40294
40296
40297 const bool synthesis_result =
40298 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40299 (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
40300
40301 if (synthesis_result)
40302 return result;
40303 else if (!expr_gen.valid_operator(o2,f2))
40304 return error_node();
40305
40306 exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n"));
40307
40308 return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
40309 }
40310
40311 static inline std::string id(expression_generator<Type>& expr_gen,
40312 const details::operator_type o0,
40313 const details::operator_type o1,
40314 const details::operator_type o2)
40315 {
40316 return details::build_string()
40317 << "(t" << expr_gen.to_str(o0)
40318 << "(t" << expr_gen.to_str(o1)
40319 << "t)" << expr_gen.to_str(o2)
40320 << "t";
40321 }
40322 };
40323
40325 {
40326 typedef typename covocov_t::type4 node_type;
40328 typedef typename node_type::T0 T0;
40329 typedef typename node_type::T1 T1;
40330 typedef typename node_type::T2 T2;
40331 typedef typename node_type::T3 T3;
40332
40334 const details::operator_type& operation,
40335 expression_node_ptr (&branch)[2])
40336 {
40337 // ((c0 o0 (v0 o1 c1)) o2 v1)
40338 typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
40339
40340 const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
40341 const Type c0 = covoc->t0();
40342 const Type& v0 = covoc->t1();
40343 const Type c1 = covoc->t2();
40344 const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
40345 const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
40346 const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
40347 const details::operator_type o2 = operation;
40348
40349 binary_functor_t f0 = covoc->f0();
40350 binary_functor_t f1 = covoc->f1();
40351 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40352
40353 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40354
40356
40357 const bool synthesis_result =
40358 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40359 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
40360
40361 if (synthesis_result)
40362 return result;
40363 else if (!expr_gen.valid_operator(o2,f2))
40364 return error_node();
40365
40366 exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n"));
40367
40368 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
40369 }
40370
40371 static inline std::string id(expression_generator<Type>& expr_gen,
40372 const details::operator_type o0,
40373 const details::operator_type o1,
40374 const details::operator_type o2)
40375 {
40376 return details::build_string()
40377 << "(t" << expr_gen.to_str(o0)
40378 << "(t" << expr_gen.to_str(o1)
40379 << "t)" << expr_gen.to_str(o2)
40380 << "t";
40381 }
40382 };
40383
40385 {
40386 typedef typename vocovoc_t::type4 node_type;
40388 typedef typename node_type::T0 T0;
40389 typedef typename node_type::T1 T1;
40390 typedef typename node_type::T2 T2;
40391 typedef typename node_type::T3 T3;
40392
40394 const details::operator_type& operation,
40395 expression_node_ptr (&branch)[2])
40396 {
40397 // ((v0 o0 (c0 o1 v1)) o2 c1)
40398 typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
40399
40400 const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
40401 const Type& v0 = vocov->t0();
40402 const Type c0 = vocov->t1();
40403 const Type& v1 = vocov->t2();
40404 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
40405 const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
40406 const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
40407 const details::operator_type o2 = operation;
40408
40409 binary_functor_t f0 = vocov->f0();
40410 binary_functor_t f1 = vocov->f1();
40411 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40412
40413 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40414 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40415
40417
40418 const bool synthesis_result =
40419 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40420 (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
40421
40422 if (synthesis_result)
40423 return result;
40424 else if (!expr_gen.valid_operator(o2,f2))
40425 return error_node();
40426
40427 exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n"));
40428
40429 return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
40430 }
40431
40432 static inline std::string id(expression_generator<Type>& expr_gen,
40433 const details::operator_type o0,
40434 const details::operator_type o1,
40435 const details::operator_type o2)
40436 {
40437 return details::build_string()
40438 << "(t" << expr_gen.to_str(o0)
40439 << "(t" << expr_gen.to_str(o1)
40440 << "t)" << expr_gen.to_str(o2)
40441 << "t";
40442 }
40443 };
40444
40446 {
40447 typedef typename covovoc_t::type4 node_type;
40449 typedef typename node_type::T0 T0;
40450 typedef typename node_type::T1 T1;
40451 typedef typename node_type::T2 T2;
40452 typedef typename node_type::T3 T3;
40453
40455 const details::operator_type& operation,
40456 expression_node_ptr (&branch)[2])
40457 {
40458 // ((c0 o0 (v0 o1 v1)) o2 c1)
40459 typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
40460
40461 const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
40462 const Type c0 = covov->t0();
40463 const Type& v0 = covov->t1();
40464 const Type& v1 = covov->t2();
40465 const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
40466 const details::operator_type o0 = expr_gen.get_operator(covov->f0());
40467 const details::operator_type o1 = expr_gen.get_operator(covov->f1());
40468 const details::operator_type o2 = operation;
40469
40470 binary_functor_t f0 = covov->f0();
40471 binary_functor_t f1 = covov->f1();
40472 binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
40473
40474 details::free_node(*(expr_gen.node_allocator_),branch[0]);
40475 details::free_node(*(expr_gen.node_allocator_),branch[1]);
40476
40478
40479 const bool synthesis_result =
40480 synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
40481 (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
40482
40483 if (synthesis_result)
40484 return result;
40485 else if (!expr_gen.valid_operator(o2,f2))
40486 return error_node();
40487
40488 exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n"));
40489
40490 return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
40491 }
40492
40493 static inline std::string id(expression_generator<Type>& expr_gen,
40494 const details::operator_type o0,
40495 const details::operator_type o1,
40496 const details::operator_type o2)
40497 {
40498 return details::build_string()
40499 << "(t" << expr_gen.to_str(o0)
40500 << "(t" << expr_gen.to_str(o1)
40501 << "t)" << expr_gen.to_str(o2)
40502 << "t";
40503 }
40504 };
40505
40507 {
40508 typedef typename vococov_t::type4 node_type;
40511 expression_node_ptr (&)[2])
40512 {
40513 // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible
40514 exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
40515 return error_node();
40516 }
40517
40518 static inline std::string id(expression_generator<Type>&,
40522 {
40523 return "INVALID";
40524 }
40525 };
40526 #endif
40527
40529 {
40530 // Definition: uv o uv
40531 details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
40532 details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
40533 const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
40534 const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
40535 unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0);
40536 unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0);
40537 binary_functor_t f = reinterpret_cast<binary_functor_t>(0);
40538
40539 if (!valid_operator(o0,u0))
40540 return error_node();
40541 else if (!valid_operator(o1,u1))
40542 return error_node();
40543 else if (!valid_operator(operation,f))
40544 return error_node();
40545
40547
40548 if (
40549 (details::e_neg == o0) &&
40550 (details::e_neg == o1)
40551 )
40552 {
40553 switch (operation)
40554 {
40555 // (-v0 + -v1) --> -(v0 + v1)
40556 case details::e_add : result = (*this)(details::e_neg,
40558 allocate_rr<typename details::
40560 exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n"));
40561 break;
40562
40563 // (-v0 - -v1) --> (v1 - v0)
40564 case details::e_sub : result = node_allocator_->
40565 allocate_rr<typename details::
40567 exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n"));
40568 break;
40569
40570 // (-v0 * -v1) --> (v0 * v1)
40571 case details::e_mul : result = node_allocator_->
40572 allocate_rr<typename details::
40574 exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n"));
40575 break;
40576
40577 // (-v0 / -v1) --> (v0 / v1)
40578 case details::e_div : result = node_allocator_->
40579 allocate_rr<typename details::
40581 exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n"));
40582 break;
40583
40584 default : break;
40585 }
40586 }
40587
40588 if (0 == result)
40589 {
40590 result = node_allocator_->
40591 allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f);
40592 }
40593
40595 return result;
40596 }
40597
40598 #undef basic_opr_switch_statements
40599 #undef extended_opr_switch_statements
40600 #undef unary_opr_switch_statements
40601
40602 #ifndef exprtk_disable_string_capabilities
40603
40604 #define string_opr_switch_statements \
40605 case_stmt(details::e_lt , details::lt_op ) \
40606 case_stmt(details::e_lte , details::lte_op ) \
40607 case_stmt(details::e_gt , details::gt_op ) \
40608 case_stmt(details::e_gte , details::gte_op ) \
40609 case_stmt(details::e_eq , details::eq_op ) \
40610 case_stmt(details::e_ne , details::ne_op ) \
40611 case_stmt(details::e_in , details::in_op ) \
40612 case_stmt(details::e_like , details::like_op ) \
40613 case_stmt(details::e_ilike , details::ilike_op) \
40614
40615 template <typename T0, typename T1>
40617 T0 s0, T1 s1,
40618 range_t rp0)
40619 {
40620 switch (opr)
40621 {
40622 #define case_stmt(op0, op1) \
40623 case op0 : return node_allocator_-> \
40624 allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40625 (s0, s1, rp0); \
40626
40628 #undef case_stmt
40629 default : return error_node();
40630 }
40631 }
40632
40633 template <typename T0, typename T1>
40635 T0 s0, T1 s1,
40636 range_t rp1)
40637 {
40638 switch (opr)
40639 {
40640 #define case_stmt(op0, op1) \
40641 case op0 : return node_allocator_-> \
40642 allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40643 (s0, s1, rp1); \
40644
40646 #undef case_stmt
40647 default : return error_node();
40648 }
40649 }
40650
40651 template <typename T0, typename T1>
40653 T0 s0, T1 s1,
40654 range_t rp0, range_t rp1)
40655 {
40656 switch (opr)
40657 {
40658 #define case_stmt(op0, op1) \
40659 case op0 : return node_allocator_-> \
40660 allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
40661 (s0, s1, rp0, rp1); \
40662
40664 #undef case_stmt
40665 default : return error_node();
40666 }
40667 }
40668
40669 template <typename T0, typename T1>
40671 {
40672 switch (opr)
40673 {
40674 #define case_stmt(op0, op1) \
40675 case op0 : return node_allocator_-> \
40676 allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \
40677
40679 #undef case_stmt
40680 default : return error_node();
40681 }
40682 }
40683
40685 {
40686 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
40687 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
40688
40689 return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1);
40690 }
40691
40693 {
40694 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
40695 std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
40696 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
40697
40698 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40699
40701
40702 return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0);
40703 }
40704
40706 {
40707 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
40708 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
40709 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
40710
40711 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40712
40714
40715 return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1);
40716 }
40717
40719 {
40720 std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
40721 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40722 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40723
40724 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40725
40727
40728 return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1);
40729 }
40730
40732 {
40733 std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
40734 std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
40735 range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
40736 range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
40737
40738 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40739 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40740
40743
40744 return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1);
40745 }
40746
40748 {
40749 std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
40750 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
40751
40753
40754 return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1);
40755 }
40756
40758 {
40759 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
40760 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
40761
40763
40764 return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1);
40765 }
40766
40768 {
40769 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str ();
40770 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
40771 range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
40772
40773 static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
40774
40777
40778 return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1);
40779 }
40780
40782 {
40783 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
40784 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str ();
40785 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
40786
40787 static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
40788
40791
40792 return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0);
40793 }
40794
40796 {
40797 std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
40798 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40799 range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
40800 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40801
40802 static_cast<details::string_range_node<Type>*> (branch[0])->range_ref().clear();
40803 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40804
40807
40808 return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1);
40809 }
40810
40812 {
40813 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
40814 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
40815
40817
40818 if (details::e_add == opr)
40820 else if (details::e_in == opr)
40822 else if (details::e_like == opr)
40824 else if (details::e_ilike == opr)
40826 else
40827 {
40828 expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1);
40829
40830 const Type v = temp->value();
40831
40833
40835 }
40836
40838
40839 return result;
40840 }
40841
40843 {
40844 const std::string s0 = static_cast<details::string_literal_node<Type>* >(branch[0])->str ();
40845 std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40846 range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40847
40848 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40849
40852
40853 return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1);
40854 }
40855
40857 {
40858 std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40859 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref ();
40860 range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40861
40862 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40863
40865
40866 return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0);
40867 }
40868
40870 {
40871 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40872 std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
40873 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40874 const range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
40875
40876 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40877 static_cast<details::string_range_node<Type>*> (branch[1])->range_ref().clear();
40878
40881
40882 return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1);
40883 }
40884
40886 {
40887 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40888 const std::string s1 = static_cast<details::string_literal_node<Type>* >(branch[1])->str ();
40889 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40890
40891 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40892
40894
40895 return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0);
40896 }
40897
40899 {
40900 const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
40901 const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
40902 const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
40903 const range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
40904
40905 static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
40906 static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
40907
40909
40910 return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1);
40911 }
40912
40914 {
40915 switch (opr)
40916 {
40917 #define case_stmt(op0, op1) \
40918 case op0 : return node_allocator_-> \
40919 allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
40920 (opr, branch[0], branch[1]); \
40921
40923 #undef case_stmt
40924 default : return error_node();
40925 }
40926 }
40927
40928 #undef string_opr_switch_statements
40929 #endif
40930
40931 #ifndef exprtk_disable_string_capabilities
40933 {
40934 if ((0 == branch[0]) || (0 == branch[1]))
40935 {
40937
40938 return error_node();
40939 }
40940
40941 const bool b0_is_s = details::is_string_node (branch[0]);
40942 const bool b0_is_cs = details::is_const_string_node (branch[0]);
40943 const bool b0_is_sr = details::is_string_range_node (branch[0]);
40944 const bool b0_is_csr = details::is_const_string_range_node(branch[0]);
40945
40946 const bool b1_is_s = details::is_string_node (branch[1]);
40947 const bool b1_is_cs = details::is_const_string_node (branch[1]);
40948 const bool b1_is_sr = details::is_string_range_node (branch[1]);
40949 const bool b1_is_csr = details::is_const_string_range_node(branch[1]);
40950
40951 const bool b0_is_gen = details::is_string_assignment_node (branch[0]) ||
40953 details::is_string_concat_node (branch[0]) ||
40957 details::is_string_vararg_node (branch[0]) ;
40958
40959 const bool b1_is_gen = details::is_string_assignment_node (branch[1]) ||
40961 details::is_string_concat_node (branch[1]) ||
40965 details::is_string_vararg_node (branch[1]) ;
40966
40967 if (details::e_add == opr)
40968 {
40969 if (!b0_is_cs || !b1_is_cs)
40970 {
40971 return synthesize_expression<string_concat_node_t,2>(opr,branch);
40972 }
40973 }
40974
40975 if (b0_is_gen || b1_is_gen)
40976 {
40977 return synthesize_strogen_expression(opr,branch);
40978 }
40979 else if (b0_is_s)
40980 {
40981 if (b1_is_s ) return synthesize_sos_expression (opr,branch);
40982 else if (b1_is_cs ) return synthesize_socs_expression (opr,branch);
40983 else if (b1_is_sr ) return synthesize_sosr_expression (opr,branch);
40984 else if (b1_is_csr) return synthesize_socsr_expression (opr,branch);
40985 }
40986 else if (b0_is_cs)
40987 {
40988 if (b1_is_s ) return synthesize_csos_expression (opr,branch);
40989 else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch);
40990 else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch);
40991 else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch);
40992 }
40993 else if (b0_is_sr)
40994 {
40995 if (b1_is_s ) return synthesize_sros_expression (opr,branch);
40996 else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch);
40997 else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch);
40998 else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch);
40999 }
41000 else if (b0_is_csr)
41001 {
41002 if (b1_is_s ) return synthesize_csros_expression (opr,branch);
41003 else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch);
41004 else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch);
41005 else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch);
41006 }
41007
41008 return error_node();
41009 }
41010 #else
41012 {
41014 return error_node();
41015 }
41016 #endif
41017
41018 #ifndef exprtk_disable_string_capabilities
41020 {
41021 if (details::e_inrange != opr)
41022 return error_node();
41023 else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
41024 {
41026
41027 return error_node();
41028 }
41029 else if (
41030 details::is_const_string_node(branch[0]) &&
41031 details::is_const_string_node(branch[1]) &&
41033 )
41034 {
41035 const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41036 const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
41037 const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41038
41039 const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
41040
41042
41044 }
41045 else if (
41046 details::is_string_node(branch[0]) &&
41047 details::is_string_node(branch[1]) &&
41048 details::is_string_node(branch[2])
41049 )
41050 {
41051 std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
41052 std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
41053 std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
41054
41056
41057 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2);
41058 }
41059 else if (
41060 details::is_const_string_node(branch[0]) &&
41061 details::is_string_node(branch[1]) &&
41063 )
41064 {
41065 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41066 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41067 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41068
41070
41073
41074 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2);
41075 }
41076 else if (
41077 details::is_string_node(branch[0]) &&
41078 details::is_const_string_node(branch[1]) &&
41079 details::is_string_node(branch[2])
41080 )
41081 {
41082 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
41083 std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
41084 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
41085
41087
41089
41090 return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2);
41091 }
41092 else if (
41093 details::is_string_node(branch[0]) &&
41094 details::is_string_node(branch[1]) &&
41096 )
41097 {
41098 std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
41099 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41100 std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
41101
41103
41105
41106 return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2);
41107 }
41108 else if (
41109 details::is_const_string_node(branch[0]) &&
41110 details:: is_string_node(branch[1]) &&
41111 details:: is_string_node(branch[2])
41112 )
41113 {
41114 std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
41115 std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
41116 std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
41117
41119
41121
41122 return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2);
41123 }
41124 else
41125 return error_node();
41126 }
41127 #else
41129 {
41131 return error_node();
41132 }
41133 #endif
41134
41136 {
41137 /*
41138 Note: The following are the type promotion rules
41139 that relate to operations that include 'null':
41140 0. null ==/!= null --> true false
41141 1. null operation null --> null
41142 2. x ==/!= null --> true/false
41143 3. null ==/!= x --> true/false
41144 4. x operation null --> x
41145 5. null operation x --> x
41146 */
41147
41148 typedef typename details::null_eq_node<T> nulleq_node_t;
41149
41150 const bool b0_null = details::is_null_node(branch[0]);
41151 const bool b1_null = details::is_null_node(branch[1]);
41152
41153 if (b0_null && b1_null)
41154 {
41156
41157 if (details::e_eq == operation)
41158 result = node_allocator_->allocate_c<literal_node_t>(T(1));
41159 else if (details::e_ne == operation)
41160 result = node_allocator_->allocate_c<literal_node_t>(T(0));
41161
41162 if (result)
41163 {
41166
41167 return result;
41168 }
41169
41171
41172 return branch[0];
41173 }
41174 else if (details::e_eq == operation)
41175 {
41177 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true);
41178
41179 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
41180
41181 return result;
41182 }
41183 else if (details::e_ne == operation)
41184 {
41186 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false);
41187
41188 details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
41189
41190 return result;
41191 }
41192 else if (b0_null)
41193 {
41195 branch[0] = branch[1];
41196 branch[1] = error_node();
41197 }
41198 else if (b1_null)
41199 {
41201 branch[1] = error_node();
41202 }
41203
41204 if (
41205 (details::e_add == operation) || (details::e_sub == operation) ||
41206 (details::e_mul == operation) || (details::e_div == operation) ||
41207 (details::e_mod == operation) || (details::e_pow == operation)
41208 )
41209 {
41210 return branch[0];
41211 }
41212
41214
41215 if (
41216 (details::e_lt == operation) || (details::e_lte == operation) ||
41217 (details::e_gt == operation) || (details::e_gte == operation) ||
41218 (details::e_and == operation) || (details::e_nand == operation) ||
41219 (details::e_or == operation) || (details::e_nor == operation) ||
41220 (details::e_xor == operation) || (details::e_xnor == operation) ||
41221 (details::e_in == operation) || (details::e_like == operation) ||
41222 (details::e_ilike == operation)
41223 )
41224 {
41226 }
41227
41229 }
41230
41231 template <typename NodeType, std::size_t N>
41233 {
41234 if (
41235 (details::e_in == operation) ||
41236 (details::e_like == operation) ||
41237 (details::e_ilike == operation)
41238 )
41239 {
41240 free_all_nodes(*node_allocator_,branch);
41241
41242 return error_node();
41243 }
41244 else if (!details::all_nodes_valid<N>(branch))
41245 {
41246 free_all_nodes(*node_allocator_,branch);
41247
41248 return error_node();
41249 }
41250 else if ((details::e_default != operation))
41251 {
41252 // Attempt simple constant folding optimisation.
41253 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
41254
41255 if (is_constant_foldable<N>(branch))
41256 {
41257 const Type v = expression_point->value();
41258 details::free_node(*node_allocator_,expression_point);
41259
41261 }
41262
41263 if (expression_point && expression_point->valid())
41264 {
41265 return expression_point;
41266 }
41267
41270 token_t(),
41271 "ERR273 - Failed to synthesize node: NodeType",
41273
41274 details::free_node(*node_allocator_, expression_point);
41275 }
41276
41277 return error_node();
41278 }
41279
41280 template <typename NodeType, std::size_t N>
41282 {
41283 if (!details::all_nodes_valid<N>(branch))
41284 {
41285 free_all_nodes(*node_allocator_,branch);
41286
41287 return error_node();
41288 }
41289
41290 typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
41291
41292 // Attempt simple constant folding optimisation.
41293
41294 expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
41295 function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point);
41296
41297 if (0 == func_node_ptr)
41298 {
41299 free_all_nodes(*node_allocator_,branch);
41300
41301 return error_node();
41302 }
41303 else
41304 func_node_ptr->init_branches(branch);
41305
41306 if (is_constant_foldable<N>(branch) && !f->has_side_effects())
41307 {
41308 Type v = expression_point->value();
41309 details::free_node(*node_allocator_,expression_point);
41310
41312 }
41313
41314 parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)");
41315
41316 return expression_point;
41317 }
41318
41328 }; // class expression_generator
41329
41330 inline void set_error(const parser_error::type& error_type)
41331 {
41332 error_list_.push_back(error_type);
41333 }
41334
41335 inline void remove_last_error()
41336 {
41337 if (!error_list_.empty())
41338 {
41339 error_list_.pop_back();
41340 }
41341 }
41342
41343 inline void set_synthesis_error(const std::string& synthesis_error_message)
41344 {
41345 if (synthesis_error_.empty())
41346 {
41347 synthesis_error_ = synthesis_error_message;
41348 }
41349 }
41350
41352 {
41353 for (std::size_t i = 0; i < sem_.size(); ++i)
41354 {
41356
41357 exprtk_debug(("register_local_vars() - se[%s]\n", se.name.c_str()));
41358
41359 if (
41363 )
41364 {
41365 if (se.var_node)
41366 {
41367 e.register_local_var(se.var_node);
41368 }
41369
41370 if (se.data)
41371 {
41372 e.register_local_data(se.data, 1, 0);
41373 }
41374 }
41375 else if (scope_element::e_vector == se.type)
41376 {
41377 if (se.vec_node)
41378 {
41379 e.register_local_var(se.vec_node);
41380 }
41381
41382 if (se.data)
41383 {
41384 e.register_local_data(se.data, se.size, 1);
41385 }
41386 }
41387 #ifndef exprtk_disable_string_capabilities
41388 else if (scope_element::e_string == se.type)
41389 {
41390 if (se.str_node)
41391 {
41392 e.register_local_var(se.str_node);
41393 }
41394
41395 if (se.data)
41396 {
41397 e.register_local_data(se.data, se.size, 2);
41398 }
41399 }
41400 #endif
41401
41402 se.var_node = 0;
41403 se.vec_node = 0;
41404 #ifndef exprtk_disable_string_capabilities
41405 se.str_node = 0;
41406 #endif
41407 se.data = 0;
41408 se.ref_count = 0;
41409 se.active = false;
41410 }
41411 }
41412
41414 {
41415 e.register_return_results(results_context_);
41416 results_context_ = 0;
41417 }
41418
41420 {
41421 #define register_unary_op(Op, UnaryFunctor) \
41422 m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
41423
41463 #undef register_unary_op
41464 }
41465
41493
41521
41522 inline void load_sf3_map(sf3_map_t& sf3_map)
41523 {
41524 typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
41525
41526 #define register_sf3(Op) \
41527 sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41528
41537 #undef register_sf3
41538
41539 #define register_sf3_extid(Id, Op) \
41540 sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41541
41542 register_sf3_extid("(t-t)-t",23) // (t-t)-t --> t-(t+t)
41543 #undef register_sf3_extid
41544 }
41545
41546 inline void load_sf4_map(sf4_map_t& sf4_map)
41547 {
41548 typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
41549
41550 #define register_sf4(Op) \
41551 sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
41552
41562 #undef register_sf4
41563
41564 #define register_sf4ext(Op) \
41565 sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
41566
41583 #undef register_sf4ext
41584 }
41585
41587 {
41588 if (0 == results_context_)
41589 {
41591 }
41592
41593 return (*results_context_);
41594 }
41595
41596 inline void return_cleanup()
41597 {
41598 #ifndef exprtk_disable_return_statement
41599 if (results_context_)
41600 {
41601 delete results_context_;
41602 results_context_ = 0;
41603 }
41604
41606 #endif
41607 }
41608
41609 private:
41610
41613
41619 std::deque<parser_error::type> error_list_;
41620 std::deque<bool> brkcnt_list_;
41632 std::string synthesis_error_;
41634 std::vector<state_t> current_state_stack_;
41635
41638
41640
41649
41654 std::set<std::string> assert_ids_;
41655
41656 template <typename ParserType>
41657 friend void details::disable_type_checking(ParserType& p);
41658 }; // class parser
41659
41660 namespace details
41661 {
41662 template <typename T>
41664 {
41668 typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
41670
41671 struct resolve_as_vector : public usr_t
41672 {
41674
41675 using usr_t::process;
41676
41680
41681 virtual bool process(const std::string& unknown_symbol,
41683 std::string&) exprtk_override
41684 {
41685 static T v[1];
41687 return true;
41688 }
41689 };
41690
41691 static inline bool collection_pass(const std::string& expression_string,
41692 std::set<std::string>& symbol_set,
41693 const bool collect_variables,
41694 const bool collect_functions,
41695 const bool vector_pass,
41697 {
41701
41703
41706
41707 if (vector_pass)
41709 else
41711
41713 parser.dec().collect_variables() = true;
41714
41716 parser.dec().collect_functions() = true;
41717
41718 bool pass_result = false;
41719
41721
41723 {
41724 pass_result = true;
41725
41726 std::deque<symbol_t> symb_list;
41728
41729 for (std::size_t i = 0; i < symb_list.size(); ++i)
41730 {
41731 symbol_set.insert(symb_list[i].first);
41732 }
41733 }
41734
41735 return pass_result;
41736 }
41737 };
41738 }
41739
41740 template <typename Allocator,
41741 template <typename, typename> class Sequence>
41742 inline bool collect_variables(const std::string& expression,
41743 Sequence<std::string, Allocator>& symbol_list)
41744 {
41745 typedef double T;
41746 typedef details::collector_helper<T> collect_t;
41747
41748 collect_t::symbol_table_t null_symbol_table;
41749
41750 std::set<std::string> symbol_set;
41751
41752 const bool variable_pass = collect_t::collection_pass
41753 (expression, symbol_set, true, false, false, null_symbol_table);
41754 const bool vector_pass = collect_t::collection_pass
41755 (expression, symbol_set, true, false, true, null_symbol_table);
41756
41757 if (!variable_pass && !vector_pass)
41758 return false;
41759
41760 std::set<std::string>::iterator itr = symbol_set.begin();
41761
41762 while (symbol_set.end() != itr)
41763 {
41764 symbol_list.push_back(*itr);
41765 ++itr;
41766 }
41767
41768 return true;
41769 }
41770
41771 template <typename T,
41772 typename Allocator,
41773 template <typename, typename> class Sequence>
41774 inline bool collect_variables(const std::string& expression,
41775 exprtk::symbol_table<T>& extrnl_symbol_table,
41776 Sequence<std::string, Allocator>& symbol_list)
41777 {
41778 typedef details::collector_helper<T> collect_t;
41779
41780 std::set<std::string> symbol_set;
41781
41782 const bool variable_pass = collect_t::collection_pass
41783 (expression, symbol_set, true, false, false, extrnl_symbol_table);
41784 const bool vector_pass = collect_t::collection_pass
41785 (expression, symbol_set, true, false, true, extrnl_symbol_table);
41786
41787 if (!variable_pass && !vector_pass)
41788 return false;
41789
41790 std::set<std::string>::iterator itr = symbol_set.begin();
41791
41792 while (symbol_set.end() != itr)
41793 {
41794 symbol_list.push_back(*itr);
41795 ++itr;
41796 }
41797
41798 return true;
41799 }
41800
41801 template <typename Allocator,
41802 template <typename, typename> class Sequence>
41803 inline bool collect_functions(const std::string& expression,
41804 Sequence<std::string, Allocator>& symbol_list)
41805 {
41806 typedef double T;
41807 typedef details::collector_helper<T> collect_t;
41808
41809 collect_t::symbol_table_t null_symbol_table;
41810
41811 std::set<std::string> symbol_set;
41812
41813 const bool variable_pass = collect_t::collection_pass
41814 (expression, symbol_set, false, true, false, null_symbol_table);
41815 const bool vector_pass = collect_t::collection_pass
41816 (expression, symbol_set, false, true, true, null_symbol_table);
41817
41818 if (!variable_pass && !vector_pass)
41819 return false;
41820
41821 std::set<std::string>::iterator itr = symbol_set.begin();
41822
41823 while (symbol_set.end() != itr)
41824 {
41825 symbol_list.push_back(*itr);
41826 ++itr;
41827 }
41828
41829 return true;
41830 }
41831
41832 template <typename T,
41833 typename Allocator,
41834 template <typename, typename> class Sequence>
41835 inline bool collect_functions(const std::string& expression,
41836 exprtk::symbol_table<T>& extrnl_symbol_table,
41837 Sequence<std::string, Allocator>& symbol_list)
41838 {
41839 typedef details::collector_helper<T> collect_t;
41840
41841 std::set<std::string> symbol_set;
41842
41843 const bool variable_pass = collect_t::collection_pass
41844 (expression, symbol_set, false, true, false, extrnl_symbol_table);
41845 const bool vector_pass = collect_t::collection_pass
41846 (expression, symbol_set, false, true, true, extrnl_symbol_table);
41847
41848 if (!variable_pass && !vector_pass)
41849 return false;
41850
41851 std::set<std::string>::iterator itr = symbol_set.begin();
41852
41853 while (symbol_set.end() != itr)
41854 {
41855 symbol_list.push_back(*itr);
41856 ++itr;
41857 }
41858
41859 return true;
41860 }
41861
41862 template <typename T>
41863 inline T integrate(const expression<T>& e,
41864 T& x,
41865 const T& r0, const T& r1,
41866 const std::size_t number_of_intervals = 1000000)
41867 {
41868 if (r0 > r1)
41869 return T(0);
41870
41871 const T h = (r1 - r0) / (T(2) * number_of_intervals);
41872 T total_area = T(0);
41873
41874 for (std::size_t i = 0; i < number_of_intervals; ++i)
41875 {
41876 x = r0 + T(2) * i * h;
41877 const T y0 = e.value(); x += h;
41878 const T y1 = e.value(); x += h;
41879 const T y2 = e.value(); x += h;
41880 total_area += h * (y0 + T(4) * y1 + y2) / T(3);
41881 }
41882
41883 return total_area;
41884 }
41885
41886 template <typename T>
41887 inline T integrate(const expression<T>& e,
41888 const std::string& variable_name,
41889 const T& r0, const T& r1,
41890 const std::size_t number_of_intervals = 1000000)
41891 {
41892 const symbol_table<T>& sym_table = e.get_symbol_table();
41893
41894 if (!sym_table.valid())
41895 {
41896 return std::numeric_limits<T>::quiet_NaN();
41897 }
41898
41899 details::variable_node<T>* var = sym_table.get_variable(variable_name);
41900
41901 if (var)
41902 {
41903 T& x = var->ref();
41904 const T x_original = x;
41905 const T result = integrate(e, x, r0, r1, number_of_intervals);
41906 x = x_original;
41907
41908 return result;
41909 }
41910
41911 return std::numeric_limits<T>::quiet_NaN();
41912 }
41913
41914 template <typename T>
41915 inline T derivative(const expression<T>& e,
41916 T& x,
41917 const T& h = T(0.00000001))
41918 {
41919 const T x_init = x;
41920 const T _2h = T(2) * h;
41921
41922 x = x_init + _2h;
41923 const T y0 = e.value();
41924 x = x_init + h;
41925 const T y1 = e.value();
41926 x = x_init - h;
41927 const T y2 = e.value();
41928 x = x_init - _2h;
41929 const T y3 = e.value();
41930 x = x_init;
41931
41932 return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h);
41933 }
41934
41935 template <typename T>
41937 T& x,
41938 const T& h = T(0.00001))
41939 {
41940 const T x_init = x;
41941 const T _2h = T(2) * h;
41942
41943 const T y = e.value();
41944 x = x_init + _2h;
41945 const T y0 = e.value();
41946 x = x_init + h;
41947 const T y1 = e.value();
41948 x = x_init - h;
41949 const T y2 = e.value();
41950 x = x_init - _2h;
41951 const T y3 = e.value();
41952 x = x_init;
41953
41954 return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h);
41955 }
41956
41957 template <typename T>
41959 T& x,
41960 const T& h = T(0.0001))
41961 {
41962 const T x_init = x;
41963 const T _2h = T(2) * h;
41964
41965 x = x_init + _2h;
41966 const T y0 = e.value();
41967 x = x_init + h;
41968 const T y1 = e.value();
41969 x = x_init - h;
41970 const T y2 = e.value();
41971 x = x_init - _2h;
41972 const T y3 = e.value();
41973 x = x_init;
41974
41975 return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h);
41976 }
41977
41978 template <typename T>
41979 inline T derivative(const expression<T>& e,
41980 const std::string& variable_name,
41981 const T& h = T(0.00000001))
41982 {
41983 const symbol_table<T>& sym_table = e.get_symbol_table();
41984
41985 if (!sym_table.valid())
41986 {
41987 return std::numeric_limits<T>::quiet_NaN();
41988 }
41989
41990 details::variable_node<T>* var = sym_table.get_variable(variable_name);
41991
41992 if (var)
41993 {
41994 T& x = var->ref();
41995 const T x_original = x;
41996 const T result = derivative(e, x, h);
41997 x = x_original;
41998
41999 return result;
42000 }
42001
42002 return std::numeric_limits<T>::quiet_NaN();
42003 }
42004
42005 template <typename T>
42007 const std::string& variable_name,
42008 const T& h = T(0.00001))
42009 {
42010 const symbol_table<T>& sym_table = e.get_symbol_table();
42011
42012 if (!sym_table.valid())
42013 {
42014 return std::numeric_limits<T>::quiet_NaN();
42015 }
42016
42017 details::variable_node<T>* var = sym_table.get_variable(variable_name);
42018
42019 if (var)
42020 {
42021 T& x = var->ref();
42022 const T x_original = x;
42023 const T result = second_derivative(e, x, h);
42024 x = x_original;
42025
42026 return result;
42027 }
42028
42029 return std::numeric_limits<T>::quiet_NaN();
42030 }
42031
42032 template <typename T>
42034 const std::string& variable_name,
42035 const T& h = T(0.0001))
42036 {
42037 const symbol_table<T>& sym_table = e.get_symbol_table();
42038
42039 if (!sym_table.valid())
42040 {
42041 return std::numeric_limits<T>::quiet_NaN();
42042 }
42043
42044 details::variable_node<T>* var = sym_table.get_variable(variable_name);
42045
42046 if (var)
42047 {
42048 T& x = var->ref();
42049 const T x_original = x;
42050 const T result = third_derivative(e, x, h);
42051 x = x_original;
42052
42053 return result;
42054 }
42055
42056 return std::numeric_limits<T>::quiet_NaN();
42057 }
42058
42059 /*
42060 Note: The following 'compute' routines are simple helpers,
42061 for quickly setting up the required pieces of code in order
42062 to evaluate an expression. By virtue of how they operate
42063 there will be an overhead with regards to their setup and
42064 teardown and hence should not be used in time critical
42065 sections of code.
42066 Furthermore they only assume a small sub set of variables,
42067 no string variables or user defined functions.
42068 */
42069 template <typename T>
42070 inline bool compute(const std::string& expression_string, T& result)
42071 {
42072 // No variables
42075
42078
42080
42081 if (parser.compile(expression_string,expression))
42082 {
42083 result = expression.value();
42084
42085 return true;
42086 }
42087 else
42088 return false;
42089 }
42090
42091 template <typename T>
42092 inline bool compute(const std::string& expression_string,
42093 const T& x,
42094 T& result)
42095 {
42096 // Only 'x'
42097 static const std::string x_var("x");
42098
42101 symbol_table.add_constant(x_var,x);
42102
42105
42107
42108 if (parser.compile(expression_string,expression))
42109 {
42110 result = expression.value();
42111
42112 return true;
42113 }
42114 else
42115 return false;
42116 }
42117
42118 template <typename T>
42119 inline bool compute(const std::string& expression_string,
42120 const T&x, const T& y,
42121 T& result)
42122 {
42123 // Only 'x' and 'y'
42124 static const std::string x_var("x");
42125 static const std::string y_var("y");
42126
42129 symbol_table.add_constant(x_var,x);
42130 symbol_table.add_constant(y_var,y);
42131
42134
42136
42137 if (parser.compile(expression_string,expression))
42138 {
42139 result = expression.value();
42140
42141 return true;
42142 }
42143 else
42144 return false;
42145 }
42146
42147 template <typename T>
42148 inline bool compute(const std::string& expression_string,
42149 const T& x, const T& y, const T& z,
42150 T& result)
42151 {
42152 // Only 'x', 'y' or 'z'
42153 static const std::string x_var("x");
42154 static const std::string y_var("y");
42155 static const std::string z_var("z");
42156
42159 symbol_table.add_constant(x_var,x);
42160 symbol_table.add_constant(y_var,y);
42161 symbol_table.add_constant(z_var,z);
42162
42165
42167
42168 if (parser.compile(expression_string,expression))
42169 {
42170 result = expression.value();
42171
42172 return true;
42173 }
42174 else
42175 return false;
42176 }
42177
42178 template <typename T, std::size_t N>
42179 class polynomial : public ifunction<T>
42180 {
42181 private:
42182
42183 template <typename Type, std::size_t NumberOfCoefficients>
42184 struct poly_impl { };
42185
42186 template <typename Type>
42187 struct poly_impl <Type,12>
42188 {
42189 static inline T evaluate(const Type x,
42190 const Type c12, const Type c11, const Type c10, const Type c9, const Type c8,
42191 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
42192 const Type c2, const Type c1, const Type c0)
42193 {
42194 // 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
42195 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);
42196 }
42197 };
42198
42199 template <typename Type>
42200 struct poly_impl <Type,11>
42201 {
42202 static inline T evaluate(const Type x,
42203 const Type c11, const Type c10, const Type c9, const Type c8, const Type c7,
42204 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
42205 const Type c1, const Type c0)
42206 {
42207 // 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
42208 return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42209 }
42210 };
42211
42212 template <typename Type>
42213 struct poly_impl <Type,10>
42214 {
42215 static inline T evaluate(const Type x,
42216 const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
42217 const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
42218 const Type c0)
42219 {
42220 // 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
42221 return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42222 }
42223 };
42224
42225 template <typename Type>
42226 struct poly_impl <Type,9>
42227 {
42228 static inline T evaluate(const Type x,
42229 const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
42230 const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
42231 {
42232 // 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
42233 return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42234 }
42235 };
42236
42237 template <typename Type>
42238 struct poly_impl <Type,8>
42239 {
42240 static inline T evaluate(const Type x,
42241 const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
42242 const Type c3, const Type c2, const Type c1, const Type c0)
42243 {
42244 // 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
42245 return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42246 }
42247 };
42248
42249 template <typename Type>
42250 struct poly_impl <Type,7>
42251 {
42252 static inline T evaluate(const Type x,
42253 const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
42254 const Type c2, const Type c1, const Type c0)
42255 {
42256 // 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
42257 return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42258 }
42259 };
42260
42261 template <typename Type>
42262 struct poly_impl <Type,6>
42263 {
42264 static inline T evaluate(const Type x,
42265 const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
42266 const Type c1, const Type c0)
42267 {
42268 // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42269 return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42270 }
42271 };
42272
42273 template <typename Type>
42274 struct poly_impl <Type,5>
42275 {
42276 static inline T evaluate(const Type x,
42277 const Type c5, const Type c4, const Type c3, const Type c2,
42278 const Type c1, const Type c0)
42279 {
42280 // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42281 return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
42282 }
42283 };
42284
42285 template <typename Type>
42286 struct poly_impl <Type,4>
42287 {
42288 static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
42289 {
42290 // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42291 return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
42292 }
42293 };
42294
42295 template <typename Type>
42296 struct poly_impl <Type,3>
42297 {
42298 static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
42299 {
42300 // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
42301 return (((c3 * x + c2) * x + c1) * x + c0);
42302 }
42303 };
42304
42305 template <typename Type>
42306 struct poly_impl <Type,2>
42307 {
42308 static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
42309 {
42310 // p(x) = c_2x^2 + c_1x^1 + c_0x^0
42311 return ((c2 * x + c1) * x + c0);
42312 }
42313 };
42314
42315 template <typename Type>
42316 struct poly_impl <Type,1>
42317 {
42318 static inline T evaluate(const Type x, const Type c1, const Type c0)
42319 {
42320 // p(x) = c_1x^1 + c_0x^0
42321 return (c1 * x + c0);
42322 }
42323 };
42324
42325 public:
42326
42327 using ifunction<T>::operator();
42328
42330 : ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max())
42331 {
42333 }
42334
42335 virtual ~polynomial()
42336 {}
42337
42338 #define poly_rtrn(NN) \
42339 return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
42340
42341 inline virtual T operator() (const T& x, const T& c1, const T& c0) exprtk_override
42342 {
42343 poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0));
42344 }
42345
42346 inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) exprtk_override
42347 {
42348 poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0));
42349 }
42350
42351 inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42352 {
42353 poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0));
42354 }
42355
42356 inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1,
42357 const T& c0) exprtk_override
42358 {
42359 poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0));
42360 }
42361
42362 inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2,
42363 const T& c1, const T& c0) exprtk_override
42364 {
42365 poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0));
42366 }
42367
42368 inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3,
42369 const T& c2, const T& c1, const T& c0) exprtk_override
42370 {
42371 poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0));
42372 }
42373
42374 inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4,
42375 const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42376 {
42377 poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0));
42378 }
42379
42380 inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5,
42381 const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42382 {
42383 poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42384 }
42385
42386 inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6,
42387 const T& c5, const T& c4, const T& c3, const T& c2, const T& c1,
42388 const T& c0) exprtk_override
42389 {
42390 poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42391 }
42392
42393 inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7,
42394 const T& c6, const T& c5, const T& c4, const T& c3, const T& c2,
42395 const T& c1, const T& c0) exprtk_override
42396 {
42397 poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42398 }
42399
42400 inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8,
42401 const T& c7, const T& c6, const T& c5, const T& c4, const T& c3,
42402 const T& c2, const T& c1, const T& c0) exprtk_override
42403 {
42404 poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42405 }
42406
42407 inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9,
42408 const T& c8, const T& c7, const T& c6, const T& c5, const T& c4,
42409 const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
42410 {
42411 poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
42412 }
42413
42414 #undef poly_rtrn
42415
42416 inline virtual T operator() () exprtk_override
42417 {
42418 return std::numeric_limits<T>::quiet_NaN();
42419 }
42420
42421 inline virtual T operator() (const T&) exprtk_override
42422 {
42423 return std::numeric_limits<T>::quiet_NaN();
42424 }
42425
42426 inline virtual T operator() (const T&, const T&) exprtk_override
42427 {
42428 return std::numeric_limits<T>::quiet_NaN();
42429 }
42430 };
42431
42432 template <typename T>
42434 {
42435 public:
42436
42441
42443 {
42445 {}
42446
42447 function(const std::string& n)
42448 : name_(n)
42449 {}
42450
42451 function(const std::string& name,
42452 const std::string& expression)
42453 : name_(name)
42455 {}
42456
42457 function(const std::string& name,
42458 const std::string& expression,
42459 const std::string& v0)
42460 : name_(name)
42462 {
42463 v_.push_back(v0);
42464 }
42465
42466 function(const std::string& name,
42467 const std::string& expression,
42468 const std::string& v0, const std::string& v1)
42469 : name_(name)
42471 {
42472 v_.push_back(v0); v_.push_back(v1);
42473 }
42474
42475 function(const std::string& name,
42476 const std::string& expression,
42477 const std::string& v0, const std::string& v1,
42478 const std::string& v2)
42479 : name_(name)
42481 {
42482 v_.push_back(v0); v_.push_back(v1);
42483 v_.push_back(v2);
42484 }
42485
42486 function(const std::string& name,
42487 const std::string& expression,
42488 const std::string& v0, const std::string& v1,
42489 const std::string& v2, const std::string& v3)
42490 : name_(name)
42492 {
42493 v_.push_back(v0); v_.push_back(v1);
42494 v_.push_back(v2); v_.push_back(v3);
42495 }
42496
42497 function(const std::string& name,
42498 const std::string& expression,
42499 const std::string& v0, const std::string& v1,
42500 const std::string& v2, const std::string& v3,
42501 const std::string& v4)
42502 : name_(name)
42504 {
42505 v_.push_back(v0); v_.push_back(v1);
42506 v_.push_back(v2); v_.push_back(v3);
42507 v_.push_back(v4);
42508 }
42509
42510 inline function& name(const std::string& n)
42511 {
42512 name_ = n;
42513 return (*this);
42514 }
42515
42516 inline function& expression(const std::string& e)
42517 {
42518 expression_ = e;
42519 return (*this);
42520 }
42521
42522 inline function& var(const std::string& v)
42523 {
42524 v_.push_back(v);
42525 return (*this);
42526 }
42527
42528 inline function& vars(const std::string& v0,
42529 const std::string& v1)
42530 {
42531 v_.push_back(v0);
42532 v_.push_back(v1);
42533 return (*this);
42534 }
42535
42536 inline function& vars(const std::string& v0,
42537 const std::string& v1,
42538 const std::string& v2)
42539 {
42540 v_.push_back(v0);
42541 v_.push_back(v1);
42542 v_.push_back(v2);
42543 return (*this);
42544 }
42545
42546 inline function& vars(const std::string& v0,
42547 const std::string& v1,
42548 const std::string& v2,
42549 const std::string& v3)
42550 {
42551 v_.push_back(v0);
42552 v_.push_back(v1);
42553 v_.push_back(v2);
42554 v_.push_back(v3);
42555 return (*this);
42556 }
42557
42558 inline function& vars(const std::string& v0,
42559 const std::string& v1,
42560 const std::string& v2,
42561 const std::string& v3,
42562 const std::string& v4)
42563 {
42564 v_.push_back(v0);
42565 v_.push_back(v1);
42566 v_.push_back(v2);
42567 v_.push_back(v3);
42568 v_.push_back(v4);
42569 return (*this);
42570 }
42571
42572 std::string name_;
42573 std::string expression_;
42574 std::deque<std::string> v_;
42575 };
42576
42577 private:
42578
42579 struct base_func : public exprtk::ifunction<T>
42580 {
42581 typedef const T& type;
42583 typedef std::vector<T*> varref_t;
42584 typedef std::vector<T> var_t;
42585 typedef std::vector<std::string> str_t;
42586 typedef std::pair<T*,std::size_t> lvarref_t;
42587 typedef std::vector<lvarref_t> lvr_vec_t;
42588 typedef std::vector<std::string*> lstr_vec_t;
42589
42590 using exprtk::ifunction<T>::operator();
42591
42592 base_func(const std::size_t& pc = 0)
42593 : exprtk::ifunction<T>(pc)
42595 , stack_depth(0)
42596 {
42597 v.resize(pc);
42598 }
42599
42600 virtual ~base_func()
42601 {}
42602
42603 #define exprtk_assign(Index) \
42604 (*v[Index]) = v##Index; \
42605
42606 inline void update(const T& v0)
42607 {
42608 exprtk_assign(0)
42609 }
42610
42611 inline void update(const T& v0, const T& v1)
42612 {
42614 }
42615
42616 inline void update(const T& v0, const T& v1, const T& v2)
42617 {
42619 exprtk_assign(2)
42620 }
42621
42622 inline void update(const T& v0, const T& v1, const T& v2, const T& v3)
42623 {
42626 }
42627
42628 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
42629 {
42632 exprtk_assign(4)
42633 }
42634
42635 inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
42636 {
42640 }
42641
42642 #ifdef exprtk_assign
42643 #undef exprtk_assign
42644 #endif
42645
42647 {
42648 expression = expr;
42649
42650 typedef typename expression_t::control_block ctrlblk_t;
42651 typedef typename ctrlblk_t::local_data_list_t ldl_t;
42652 typedef typename ctrlblk_t::data_type data_t;
42653 typedef typename ldl_t::value_type ldl_value_type;
42654
42655 const ldl_t ldl = expr.local_data_list();
42656
42657 std::vector<std::pair<std::size_t,data_t> > index_list;
42658
42659 for (std::size_t i = 0; i < ldl.size(); ++i)
42660 {
42661 exprtk_debug(("base_func::setup() - element[%02d] type: %s size: %d\n",
42662 static_cast<int>(i),
42663 expression_t::control_block::to_str(ldl[i].type).c_str(),
42664 static_cast<int>(ldl[i].size)));
42665
42666 switch (ldl[i].type)
42667 {
42668 case ctrlblk_t::e_unknown : continue;
42669 case ctrlblk_t::e_expr : continue;
42670 case ctrlblk_t::e_vecholder : continue;
42671 default : break;
42672 }
42673
42674 if (ldl[i].size)
42675 {
42676 index_list.push_back(std::make_pair(i,ldl[i].type));
42677 }
42678 }
42679
42680 std::size_t input_param_count = 0;
42681
42682 for (std::size_t i = 0; i < index_list.size(); ++i)
42683 {
42684 const std::size_t index = index_list[i].first;
42685 const ldl_value_type& local_var = ldl[index];
42686
42687 assert(local_var.pointer);
42688
42689 if (i < (index_list.size() - v.size()))
42690 {
42691 if (local_var.type == ctrlblk_t::e_string)
42692 {
42693 local_str_vars.push_back(
42694 reinterpret_cast<std::string*>(local_var.pointer));
42695 }
42696 else if (
42697 (local_var.type == ctrlblk_t::e_data ) ||
42698 (local_var.type == ctrlblk_t::e_vecdata)
42699 )
42700 {
42701 local_vars.push_back(std::make_pair(
42702 reinterpret_cast<T*>(local_var.pointer),
42703 local_var.size));
42704
42705 local_var_stack_size += local_var.size;
42706 }
42707 }
42708 else
42709 {
42710 v[input_param_count++] = reinterpret_cast<T*>(local_var.pointer);
42711 }
42712 }
42713
42714 clear_stack();
42715
42716 return (*this);
42717 }
42718
42719 inline void pre()
42720 {
42721 if (stack_depth++)
42722 {
42723 if (!v.empty())
42724 {
42725 var_t var_stack(v.size(),T(0));
42726 copy(v,var_stack);
42727 input_params_stack.push_back(var_stack);
42728 }
42729
42730 if (!local_vars.empty())
42731 {
42732 var_t local_vec_frame(local_var_stack_size,T(0));
42733 copy(local_vars,local_vec_frame);
42734 local_var_stack.push_back(local_vec_frame);
42735 }
42736
42737 if (!local_str_vars.empty())
42738 {
42739 str_t local_str_frame(local_str_vars.size());
42740 copy(local_str_vars,local_str_frame);
42741 local_str_stack.push_back(local_str_frame);
42742 }
42743 }
42744 }
42745
42746 inline void post()
42747 {
42748 if (--stack_depth)
42749 {
42750 if (!v.empty())
42751 {
42752 copy(input_params_stack.back(), v);
42753 input_params_stack.pop_back();
42754 }
42755
42756 if (!local_vars.empty())
42757 {
42759 local_var_stack.pop_back();
42760 }
42761
42762 if (!local_str_vars.empty())
42763 {
42765 local_str_stack.pop_back();
42766 }
42767 }
42768 }
42769
42770 void copy(const varref_t& src_v, var_t& dest_v)
42771 {
42772 for (std::size_t i = 0; i < src_v.size(); ++i)
42773 {
42774 dest_v[i] = (*src_v[i]);
42775 }
42776 }
42777
42778 void copy(const lstr_vec_t& src_v, str_t& dest_v)
42779 {
42780 for (std::size_t i = 0; i < src_v.size(); ++i)
42781 {
42782 dest_v[i] = (*src_v[i]);
42783 }
42784 }
42785
42786 void copy(const var_t& src_v, varref_t& dest_v)
42787 {
42788 for (std::size_t i = 0; i < src_v.size(); ++i)
42789 {
42790 (*dest_v[i]) = src_v[i];
42791 }
42792 }
42793
42794 void copy(const lvr_vec_t& src_v, var_t& dest_v)
42795 {
42796 typename var_t::iterator itr = dest_v.begin();
42797 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
42798
42799 for (std::size_t i = 0; i < src_v.size(); ++i)
42800 {
42801 lvarref_t vr = src_v[i];
42802
42803 if (1 == vr.second)
42804 *itr++ = (*vr.first);
42805 else
42806 {
42807 std::copy(vr.first, vr.first + vr.second, itr);
42808 itr += static_cast<diff_t>(vr.second);
42809 }
42810 }
42811 }
42812
42813 void copy(const var_t& src_v, lvr_vec_t& dest_v)
42814 {
42815 typename var_t::const_iterator itr = src_v.begin();
42816 typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
42817
42818 for (std::size_t i = 0; i < dest_v.size(); ++i)
42819 {
42820 lvarref_t& vr = dest_v[i];
42821
42822 assert(vr.first != 0);
42823 assert(vr.second > 0);
42824
42825 if (1 == vr.second)
42826 (*vr.first) = *itr++;
42827 else
42828 {
42829 std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first);
42830 itr += static_cast<diff_t>(vr.second);
42831 }
42832 }
42833 }
42834
42835 void copy(const str_t& src_str, lstr_vec_t& dest_str)
42836 {
42837 assert(src_str.size() == dest_str.size());
42838
42839 for (std::size_t i = 0; i < dest_str.size(); ++i)
42840 {
42841 *dest_str[i] = src_str[i];
42842 }
42843 }
42844
42845 inline void clear_stack()
42846 {
42847 for (std::size_t i = 0; i < v.size(); ++i)
42848 {
42849 (*v[i]) = 0;
42850 }
42851 }
42852
42853 inline virtual T value(expression_t& e)
42854 {
42855 return e.value();
42856 }
42857
42863 std::size_t stack_depth;
42864 std::deque<var_t> input_params_stack;
42865 std::deque<var_t> local_var_stack;
42866 std::deque<str_t> local_str_stack;
42867 };
42868
42869 typedef std::map<std::string,base_func*> funcparam_t;
42870
42871 typedef const T& type;
42872
42873 template <typename BaseFuncType>
42875 {
42876 explicit scoped_bft(BaseFuncType& bft)
42877 : bft_(bft)
42878 {
42879 bft_.pre ();
42880 }
42881
42883 {
42884 bft_.post();
42885 }
42886
42887 BaseFuncType& bft_;
42888
42889 private:
42890
42893 };
42894
42895 struct func_0param : public base_func
42896 {
42897 using exprtk::ifunction<T>::operator();
42898
42900
42902 {
42903 scoped_bft<func_0param> sb(*this);
42904 return this->value(base_func::expression);
42905 }
42906 };
42907
42908 struct func_1param : public base_func
42909 {
42910 using exprtk::ifunction<T>::operator();
42911
42913
42915 {
42916 scoped_bft<func_1param> sb(*this);
42918 return this->value(base_func::expression);
42919 }
42920 };
42921
42922 struct func_2param : public base_func
42923 {
42924 using exprtk::ifunction<T>::operator();
42925
42927
42929 {
42930 scoped_bft<func_2param> sb(*this);
42931 base_func::update(v0, v1);
42932 return this->value(base_func::expression);
42933 }
42934 };
42935
42936 struct func_3param : public base_func
42937 {
42938 using exprtk::ifunction<T>::operator();
42939
42941
42943 {
42944 scoped_bft<func_3param> sb(*this);
42945 base_func::update(v0, v1, v2);
42946 return this->value(base_func::expression);
42947 }
42948 };
42949
42950 struct func_4param : public base_func
42951 {
42952 using exprtk::ifunction<T>::operator();
42953
42955
42957 {
42958 scoped_bft<func_4param> sb(*this);
42959 base_func::update(v0, v1, v2, v3);
42960 return this->value(base_func::expression);
42961 }
42962 };
42963
42964 struct func_5param : public base_func
42965 {
42966 using exprtk::ifunction<T>::operator();
42967
42969
42970 inline T operator() (type v0, type v1, type v2, type v3, type v4) exprtk_override
42971 {
42972 scoped_bft<func_5param> sb(*this);
42973 base_func::update(v0, v1, v2, v3, v4);
42974 return this->value(base_func::expression);
42975 }
42976 };
42977
42978 struct func_6param : public base_func
42979 {
42980 using exprtk::ifunction<T>::operator();
42981
42983
42984 inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) exprtk_override
42985 {
42986 scoped_bft<func_6param> sb(*this);
42987 base_func::update(v0, v1, v2, v3, v4, v5);
42988 return this->value(base_func::expression);
42989 }
42990 };
42991
42993 {
42994 typedef exprtk::results_context<T> results_context_t;
42995 typedef typename results_context_t::type_store_t type_t;
42996 typedef typename type_t::scalar_view scalar_t;
42997
42998 const T result = e.value();
42999
43000 if (e.return_invoked())
43001 {
43002 // Due to the post compilation checks, it can be safely
43003 // assumed that there will be at least one parameter
43004 // and that the first parameter will always be scalar.
43005 return scalar_t(e.results()[0])();
43006 }
43007
43008 return result;
43009 }
43010
43011 #define def_fp_retval(N) \
43012 struct func_##N##param_retval exprtk_final : public func_##N##param \
43013 { \
43014 inline T value(expression_t& e) exprtk_override \
43015 { \
43016 return return_value(e); \
43017 } \
43018 }; \
43019
43027
43028 #undef def_fp_retval
43029
43030 template <typename Allocator,
43031 template <typename, typename> class Sequence>
43032 inline bool add(const std::string& name,
43033 const std::string& expression,
43034 const Sequence<std::string,Allocator>& var_list,
43035 const bool override = false)
43036 {
43037 const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name);
43038
43039 if (expr_map_.end() != itr)
43040 {
43041 if (!override)
43042 {
43043 exprtk_debug(("Compositor error(add): function '%s' already defined\n",
43044 name.c_str()));
43045
43046 return false;
43047 }
43048
43049 remove(name, var_list.size());
43050 }
43051
43052 if (compile_expression(name, expression, var_list))
43053 {
43054 const std::size_t n = var_list.size();
43055
43056 fp_map_[n][name]->setup(expr_map_[name]);
43057
43058 return true;
43059 }
43060 else
43061 {
43062 exprtk_debug(("Compositor error(add): Failed to compile function '%s'\n",
43063 name.c_str()));
43064
43065 return false;
43066 }
43067 }
43068
43069 public:
43070
43072 : parser_(settings_t::default_compile_all_opts +
43073 settings_t::e_disable_zero_return)
43074 , fp_map_(7)
43075 , load_variables_(false)
43076 , load_vectors_(false)
43077 {}
43078
43080 : symbol_table_(st)
43081 , parser_(settings_t::default_compile_all_opts +
43082 settings_t::e_disable_zero_return)
43083 , fp_map_(7)
43084 , load_variables_(false)
43085 , load_vectors_(false)
43086 {}
43087
43089 {
43090 clear();
43091 }
43092
43094 {
43095 return symbol_table_;
43096 }
43097
43098 inline const symbol_table_t& symbol_table() const
43099 {
43100 return symbol_table_;
43101 }
43102
43104 {
43105 auxiliary_symtab_list_.push_back(&symtab);
43106 }
43107
43108 void load_variables(const bool load = true)
43109 {
43110 load_variables_ = load;
43111 }
43112
43113 void load_vectors(const bool load = true)
43114 {
43115 load_vectors_ = load;
43116 }
43117
43119 {
43121 }
43122
43127
43132
43134 {
43136 }
43137
43142
43147
43148 void clear()
43149 {
43151 expr_map_ .clear();
43152
43153 for (std::size_t i = 0; i < fp_map_.size(); ++i)
43154 {
43155 typename funcparam_t::iterator itr = fp_map_[i].begin();
43156 typename funcparam_t::iterator end = fp_map_[i].end ();
43157
43158 while (itr != end)
43159 {
43160 delete itr->second;
43161 ++itr;
43162 }
43163
43164 fp_map_[i].clear();
43165 }
43166
43170 }
43171
43172 inline bool add(const function& f, const bool override = false)
43173 {
43174 return add(f.name_, f.expression_, f.v_,override);
43175 }
43176
43177 inline std::string error() const
43178 {
43179 if (!error_list_.empty())
43180 {
43181 return error_list_[0].diagnostic;
43182 }
43183 else
43184 return std::string("No Error");
43185 }
43186
43187 inline std::size_t error_count() const
43188 {
43189 return error_list_.size();
43190 }
43191
43192 inline parser_error::type get_error(const std::size_t& index) const
43193 {
43194 if (index < error_list_.size())
43195 {
43196 return error_list_[index];
43197 }
43198
43199 throw std::invalid_argument("compositor::get_error() - Invalid error index specified");
43200 }
43201
43202 private:
43203
43204 template <typename Allocator,
43205 template <typename, typename> class Sequence>
43206 bool compile_expression(const std::string& name,
43207 const std::string& expression,
43208 const Sequence<std::string,Allocator>& input_var_list,
43209 bool return_present = false)
43210 {
43211 expression_t compiled_expression;
43212 symbol_table_t local_symbol_table;
43213
43214 local_symbol_table.load_from(symbol_table_);
43215 local_symbol_table.add_constants();
43216
43217 if (load_variables_)
43218 {
43219 local_symbol_table.load_variables_from(symbol_table_);
43220 }
43221
43222 if (load_vectors_)
43223 {
43224 local_symbol_table.load_vectors_from(symbol_table_);
43225 }
43226
43227 error_list_.clear();
43228
43229 if (!valid(name,input_var_list.size()))
43230 {
43234 lexer::token(),
43235 "ERR274 - Function '" + name + "' is an invalid overload",
43237
43238 error_list_.push_back(error);
43239 return false;
43240 }
43241
43242 if (!forward(name,
43243 input_var_list.size(),
43244 local_symbol_table,
43245 return_present))
43246 return false;
43247
43248 compiled_expression.register_symbol_table(local_symbol_table);
43249
43250 for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i)
43251 {
43252 compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i]));
43253 }
43254
43255 std::string mod_expression;
43256
43257 for (std::size_t i = 0; i < input_var_list.size(); ++i)
43258 {
43259 mod_expression += " var " + input_var_list[i] + "{};\n";
43260 }
43261
43262 if (
43263 ('{' == details::front(expression)) &&
43264 ('}' == details::back (expression))
43265 )
43266 mod_expression += "~" + expression + ";";
43267 else
43268 mod_expression += "~{" + expression + "};";
43269
43270 if (!parser_.compile(mod_expression,compiled_expression))
43271 {
43272 exprtk_debug(("Compositor Error: %s\n", parser_.error().c_str()));
43273 exprtk_debug(("Compositor modified expression: \n%s\n", mod_expression.c_str()));
43274
43275 remove(name,input_var_list.size());
43276
43277 for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index)
43278 {
43279 error_list_.push_back(parser_.get_error(err_index));
43280 }
43281
43282 return false;
43283 }
43284
43285 if (!return_present && parser_.dec().return_present())
43286 {
43287 remove(name,input_var_list.size());
43288 return compile_expression(name, expression, input_var_list, true);
43289 }
43290
43291 // Make sure every return point has a scalar as its first parameter
43292 if (parser_.dec().return_present())
43293 {
43294 typedef std::vector<std::string> str_list_t;
43295
43296 str_list_t ret_param_list = parser_.dec().return_param_type_list();
43297
43298 for (std::size_t i = 0; i < ret_param_list.size(); ++i)
43299 {
43300 const std::string& params = ret_param_list[i];
43301
43302 if (params.empty() || ('T' != params[0]))
43303 {
43304 exprtk_debug(("Compositor Error: Return statement in function '%s' is invalid\n",
43305 name.c_str()));
43306
43307 remove(name,input_var_list.size());
43308
43309 return false;
43310 }
43311 }
43312 }
43313
43314 expr_map_[name] = compiled_expression;
43315
43316 exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]);
43317
43318 if (symbol_table_.add_function(name,ifunc))
43319 return true;
43320 else
43321 {
43322 exprtk_debug(("Compositor Error: Failed to add function '%s' to symbol table\n",
43323 name.c_str()));
43324 return false;
43325 }
43326 }
43327
43328 inline bool symbol_used(const std::string& symbol) const
43329 {
43330 return (
43331 symbol_table_.is_variable (symbol) ||
43332 symbol_table_.is_stringvar (symbol) ||
43333 symbol_table_.is_function (symbol) ||
43334 symbol_table_.is_vector (symbol) ||
43336 );
43337 }
43338
43339 inline bool valid(const std::string& name,
43340 const std::size_t& arg_count) const
43341 {
43342 if (arg_count > 6)
43343 return false;
43344 else if (symbol_used(name))
43345 return false;
43346 else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
43347 return false;
43348 else
43349 return true;
43350 }
43351
43352 inline bool forward(const std::string& name,
43353 const std::size_t& arg_count,
43354 symbol_table_t& sym_table,
43355 const bool ret_present = false)
43356 {
43357 switch (arg_count)
43358 {
43359 #define case_stmt(N) \
43360 case N : (fp_map_[arg_count])[name] = \
43361 (!ret_present) ? static_cast<base_func*> \
43362 (new func_##N##param) : \
43363 static_cast<base_func*> \
43364 (new func_##N##param_retval) ; \
43365 break; \
43366
43369 case_stmt(6)
43370 #undef case_stmt
43371 }
43372
43373 exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]);
43374
43375 return sym_table.add_function(name,ifunc);
43376 }
43377
43378 inline void remove(const std::string& name, const std::size_t& arg_count)
43379 {
43380 if (arg_count > 6)
43381 return;
43382
43383 const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name);
43384
43385 if (expr_map_.end() != em_itr)
43386 {
43387 expr_map_.erase(em_itr);
43388 }
43389
43390 const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
43391
43392 if (fp_map_[arg_count].end() != fp_itr)
43393 {
43394 delete fp_itr->second;
43395 fp_map_[arg_count].erase(fp_itr);
43396 }
43397
43399 }
43400
43401 private:
43402
43405 std::map<std::string,expression_t> expr_map_;
43406 std::vector<funcparam_t> fp_map_;
43407 std::vector<symbol_table_t*> auxiliary_symtab_list_;
43408 std::deque<parser_error::type> error_list_;
43411 }; // class function_compositor
43412
43413} // namespace exprtk
43414
43415#if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43416# ifndef NOMINMAX
43417# define NOMINMAX
43418# endif
43419# ifndef WIN32_LEAN_AND_MEAN
43420# define WIN32_LEAN_AND_MEAN
43421# endif
43422# include <windows.h>
43423# include <ctime>
43424#else
43425# include <ctime>
43426# include <sys/time.h>
43427# include <sys/types.h>
43428#endif
43429
43430namespace exprtk
43431{
43432 class timer
43433 {
43434 public:
43435
43436 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43437 timer()
43438 : in_use_(false)
43439 , start_time_{ 0 }
43440 , stop_time_ { 0 }
43441 {
43442 QueryPerformanceFrequency(&clock_frequency_);
43443 }
43444
43445 inline void start()
43446 {
43447 in_use_ = true;
43448 QueryPerformanceCounter(&start_time_);
43449 }
43450
43451 inline void stop()
43452 {
43453 QueryPerformanceCounter(&stop_time_);
43454 in_use_ = false;
43455 }
43456
43457 inline double time() const
43458 {
43459 return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
43460 }
43461
43462 #else
43463
43465 : in_use_(false)
43466 {
43467 start_time_.tv_sec = 0;
43468 start_time_.tv_usec = 0;
43469
43470 stop_time_.tv_sec = 0;
43471 stop_time_.tv_usec = 0;
43472 }
43473
43474 inline void start()
43475 {
43476 in_use_ = true;
43477 gettimeofday(&start_time_,0);
43478 }
43479
43480 inline void stop()
43481 {
43482 gettimeofday(&stop_time_, 0);
43483 in_use_ = false;
43484 }
43485
43486 inline unsigned long long int usec_time() const
43487 {
43488 if (!in_use_)
43489 {
43490 if (stop_time_.tv_sec >= start_time_.tv_sec)
43491 {
43492 return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec - start_time_.tv_sec ) +
43493 static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ;
43494 }
43495 else
43496 return std::numeric_limits<details::_uint64_t>::max();
43497 }
43498 else
43499 return std::numeric_limits<details::_uint64_t>::max();
43500 }
43501
43502 inline double time() const
43503 {
43504 return usec_time() * 0.000001;
43505 }
43506
43507 #endif
43508
43509 inline bool in_use() const
43510 {
43511 return in_use_;
43512 }
43513
43514 private:
43515
43517
43518 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43519 LARGE_INTEGER start_time_;
43520 LARGE_INTEGER stop_time_;
43521 LARGE_INTEGER clock_frequency_;
43522 #else
43523 struct timeval start_time_;
43524 struct timeval stop_time_;
43525 #endif
43526 };
43527
43528 template <typename T>
43538
43539} // namespace exprtk
43540
43541#ifndef exprtk_disable_rtl_io
43542namespace exprtk
43543{
43544 namespace rtl { namespace io { namespace details
43545 {
43546 template <typename T>
43547 inline void print_type(const std::string& fmt,
43548 const T v,
43550 {
43551 #if defined(__clang__)
43552 #pragma clang diagnostic push
43553 #pragma clang diagnostic ignored "-Wformat-nonliteral"
43554 #elif defined(__GNUC__) || defined(__GNUG__)
43555 #pragma GCC diagnostic push
43556 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
43557 #elif defined(_MSC_VER)
43558 #endif
43559
43560 printf(fmt.c_str(), v);
43561
43562 #if defined(__clang__)
43563 #pragma clang diagnostic pop
43564 #elif defined(__GNUC__) || defined(__GNUG__)
43565 #pragma GCC diagnostic pop
43566 #elif defined(_MSC_VER)
43567 #endif
43568 }
43569
43570 template <typename T>
43572 {
43579
43580 static void process(const std::string& scalar_format, parameter_list_t parameters)
43581 {
43582 for (std::size_t i = 0; i < parameters.size(); ++i)
43583 {
43584 generic_type& gt = parameters[i];
43585
43586 switch (gt.type)
43587 {
43588 case generic_type::e_scalar : print(scalar_format,scalar_t(gt));
43589 break;
43590
43591 case generic_type::e_vector : print(scalar_format,vector_t(gt));
43592 break;
43593
43595 break;
43596
43597 default : continue;
43598 }
43599 }
43600 }
43601
43602 static inline void print(const std::string& scalar_format, const scalar_t& s)
43603 {
43604 print_type(scalar_format,s(),num_type());
43605 }
43606
43607 static inline void print(const std::string& scalar_format, const vector_t& v)
43608 {
43609 for (std::size_t i = 0; i < v.size(); ++i)
43610 {
43611 print_type(scalar_format,v[i],num_type());
43612
43613 if ((i + 1) < v.size())
43614 printf(" ");
43615 }
43616 }
43617
43618 static inline void print(const string_t& s)
43619 {
43620 printf("%s",to_str(s).c_str());
43621 }
43622 };
43623
43624 } // namespace exprtk::rtl::io::details
43625
43626 template <typename T>
43628 {
43630
43631 using exprtk::igeneric_function<T>::operator();
43632
43633 explicit print(const std::string& scalar_format = "%10.5f")
43634 : scalar_format_(scalar_format)
43635 {
43637 }
43638
43640 {
43642 return T(0);
43643 }
43644
43645 std::string scalar_format_;
43646 };
43647
43648 template <typename T>
43650 {
43652
43653 using exprtk::igeneric_function<T>::operator();
43654
43655 explicit println(const std::string& scalar_format = "%10.5f")
43656 : scalar_format_(scalar_format)
43657 {
43659 }
43660
43662 {
43664 printf("\n");
43665 return T(0);
43666 }
43667
43668 std::string scalar_format_;
43669 };
43670
43671 template <typename T>
43672 struct package
43673 {
43674 print <T> p;
43676
43678 {
43679 #define exprtk_register_function(FunctionName, FunctionType) \
43680 if (!symtab.add_function(FunctionName,FunctionType)) \
43681 { \
43682 exprtk_debug(( \
43683 "exprtk::rtl::io::register_package - Failed to add function: %s\n", \
43684 FunctionName)); \
43685 return false; \
43686 } \
43687
43688 exprtk_register_function("print" , p )
43689 exprtk_register_function("println", pl)
43690 #undef exprtk_register_function
43691
43692 return true;
43693 }
43694 };
43695
43696 } // namespace exprtk::rtl::io
43697 } // namespace exprtk::rtl
43698} // namespace exprtk
43699#endif
43700
43701#ifndef exprtk_disable_rtl_io_file
43702#include <fstream>
43703namespace exprtk
43704{
43705 namespace rtl { namespace io { namespace file { namespace details
43706 {
43707 using ::exprtk::details::char_ptr;
43708 using ::exprtk::details::char_cptr;
43709
43711 {
43715 e_rdwrt = 4
43717
43719 {
43720 file_descriptor(const std::string& fname, const std::string& access)
43721 : stream_ptr(0)
43722 , mode(get_file_mode(access))
43723 , file_name(fname)
43724 {}
43725
43728 std::string file_name;
43729
43730 bool open()
43731 {
43732 if (e_read == mode)
43733 {
43734 std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary);
43735
43736 if (!(*stream))
43737 {
43738 file_name.clear();
43739 delete stream;
43740
43741 return false;
43742 }
43743
43744 stream_ptr = stream;
43745
43746 return true;
43747 }
43748 else if (e_write == mode)
43749 {
43750 std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary);
43751
43752 if (!(*stream))
43753 {
43754 file_name.clear();
43755 delete stream;
43756
43757 return false;
43758 }
43759
43760 stream_ptr = stream;
43761
43762 return true;
43763 }
43764 else if (e_rdwrt == mode)
43765 {
43766 std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary);
43767
43768 if (!(*stream))
43769 {
43770 file_name.clear();
43771 delete stream;
43772
43773 return false;
43774 }
43775
43776 stream_ptr = stream;
43777
43778 return true;
43779 }
43780
43781 return false;
43782 }
43783
43784 template <typename Stream, typename Ptr>
43785 void close(Ptr& p)
43786 {
43787 Stream* stream = reinterpret_cast<Stream*>(p);
43788 stream->close();
43789 delete stream;
43790 p = reinterpret_cast<Ptr>(0);
43791 }
43792
43793 bool close()
43794 {
43795 switch (mode)
43796 {
43798 break;
43799
43801 break;
43802
43804 break;
43805
43806 default : return false;
43807 }
43808
43809 return true;
43810 }
43811
43812 template <typename View>
43813 bool write(const View& view, const std::size_t amount, const std::size_t offset = 0)
43814 {
43815 switch (mode)
43816 {
43817 case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)->
43818 write(reinterpret_cast<char_cptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
43819 break;
43820
43821 case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
43822 write(reinterpret_cast<char_cptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
43823 break;
43824
43825 default : return false;
43826 }
43827
43828 return true;
43829 }
43830
43831 template <typename View>
43832 bool read(View& view, const std::size_t amount, const std::size_t offset = 0)
43833 {
43834 switch (mode)
43835 {
43836 case e_read : reinterpret_cast<std::ifstream*>(stream_ptr)->
43837 read(reinterpret_cast<char_ptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
43838 break;
43839
43840 case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
43841 read(reinterpret_cast<char_ptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
43842 break;
43843
43844 default : return false;
43845 }
43846
43847 return true;
43848 }
43849
43850 bool getline(std::string& s)
43851 {
43852 switch (mode)
43853 {
43854 case e_read : return (!!std::getline(*reinterpret_cast<std::ifstream*>(stream_ptr),s));
43855 case e_rdwrt : return (!!std::getline(*reinterpret_cast<std::fstream* >(stream_ptr),s));
43856 default : return false;
43857 }
43858 }
43859
43860 bool eof() const
43861 {
43862 switch (mode)
43863 {
43864 case e_read : return reinterpret_cast<std::ifstream*>(stream_ptr)->eof();
43865 case e_write : return reinterpret_cast<std::ofstream*>(stream_ptr)->eof();
43866 case e_rdwrt : return reinterpret_cast<std::fstream* >(stream_ptr)->eof();
43867 default : return true;
43868 }
43869 }
43870
43871 file_mode get_file_mode(const std::string& access) const
43872 {
43873 if (access.empty() || access.size() > 2)
43874 return e_error;
43875
43876 std::size_t w_cnt = 0;
43877 std::size_t r_cnt = 0;
43878
43879 for (std::size_t i = 0; i < access.size(); ++i)
43880 {
43881 switch (std::tolower(access[i]))
43882 {
43883 case 'r' : r_cnt++; break;
43884 case 'w' : w_cnt++; break;
43885 default : return e_error;
43886 }
43887 }
43888
43889 if ((0 == r_cnt) && (0 == w_cnt))
43890 return e_error;
43891 else if ((r_cnt > 1) || (w_cnt > 1))
43892 return e_error;
43893 else if ((1 == r_cnt) && (1 == w_cnt))
43894 return e_rdwrt;
43895 else if (1 == r_cnt)
43896 return e_read;
43897 else
43898 return e_write;
43899 }
43900 };
43901
43902 template <typename T>
43904 {
43905 const std::size_t fd_size = sizeof(details::file_descriptor*);
43906 details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0);
43907
43908 std::memcpy(reinterpret_cast<char_ptr >(&fd),
43909 reinterpret_cast<char_cptr>(&v ),
43910 fd_size);
43911 return fd;
43912 }
43913
43914 template <typename T>
43916 {
43917 #ifdef _MSC_VER
43918 #pragma warning(push)
43919 #pragma warning(disable: 4127)
43920 #endif
43921 if (sizeof(T) < sizeof(void*))
43922 {
43923 throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder.");
43924 }
43925 #ifdef _MSC_VER
43926 #pragma warning(pop)
43927 #endif
43928 assert(sizeof(T) <= sizeof(void*));
43929 }
43930
43931 } // namespace exprtk::rtl::io::file::details
43932
43933 template <typename T>
43935 {
43936 public:
43937
43942
43943 using igfun_t::operator();
43944
43946 : exprtk::igeneric_function<T>("S|SS")
43948
43949 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43950 {
43951 const std::string file_name = to_str(string_t(parameters[0]));
43952
43953 if (file_name.empty())
43954 {
43955 return T(0);
43956 }
43957
43958 if ((1 == ps_index) && (0 == string_t(parameters[1]).size()))
43959 {
43960 return T(0);
43961 }
43962
43963 const std::string access =
43964 (0 == ps_index) ? "r" : to_str(string_t(parameters[1]));
43965
43966 details::file_descriptor* fd = new details::file_descriptor(file_name,access);
43967
43968 if (fd->open())
43969 {
43970 T t = T(0);
43971
43972 const std::size_t fd_size = sizeof(details::file_descriptor*);
43973
43974 std::memcpy(reinterpret_cast<char*>(&t ),
43975 reinterpret_cast<char*>(&fd),
43976 fd_size);
43977 return t;
43978 }
43979 else
43980 {
43981 delete fd;
43982 return T(0);
43983 }
43984 }
43985 };
43986
43987 template <typename T>
43989 {
43990 using exprtk::ifunction<T>::operator();
43991
43993 : exprtk::ifunction<T>(1)
43995
43996 inline T operator() (const T& v) exprtk_override
43997 {
43999
44000 if (!fd->close())
44001 return T(0);
44002
44003 delete fd;
44004
44005 return T(1);
44006 }
44007 };
44008
44009 template <typename T>
44011 {
44012 public:
44013
44020
44021 using igfun_t::operator();
44022
44024 : igfun_t("TS|TST|TV|TVT")
44026
44027 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44028 {
44030
44031 switch (ps_index)
44032 {
44033 case 0 : {
44034 const string_t buffer(parameters[1]);
44035 const std::size_t amount = buffer.size();
44036 return T(fd->write(buffer, amount) ? 1 : 0);
44037 }
44038
44039 case 1 : {
44040 const string_t buffer(parameters[1]);
44041 const std::size_t amount =
44042 std::min(buffer.size(),
44043 static_cast<std::size_t>(scalar_t(parameters[2])()));
44044 return T(fd->write(buffer, amount) ? 1 : 0);
44045 }
44046
44047 case 2 : {
44048 const vector_t vec(parameters[1]);
44049 const std::size_t amount = vec.size();
44050 return T(fd->write(vec, amount) ? 1 : 0);
44051 }
44052
44053 case 3 : {
44054 const vector_t vec(parameters[1]);
44055 const std::size_t amount =
44056 std::min(vec.size(),
44057 static_cast<std::size_t>(scalar_t(parameters[2])()));
44058 return T(fd->write(vec, amount) ? 1 : 0);
44059 }
44060 }
44061
44062 return T(0);
44063 }
44064 };
44065
44066 template <typename T>
44068 {
44069 public:
44070
44077
44078 using igfun_t::operator();
44079
44081 : igfun_t("TS|TST|TV|TVT")
44083
44084 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44085 {
44087
44088 switch (ps_index)
44089 {
44090 case 0 : {
44091 string_t buffer(parameters[1]);
44092 const std::size_t amount = buffer.size();
44093 return T(fd->read(buffer,amount) ? 1 : 0);
44094 }
44095
44096 case 1 : {
44097 string_t buffer(parameters[1]);
44098 const std::size_t amount =
44099 std::min(buffer.size(),
44100 static_cast<std::size_t>(scalar_t(parameters[2])()));
44101 return T(fd->read(buffer,amount) ? 1 : 0);
44102 }
44103
44104 case 2 : {
44105 vector_t vec(parameters[1]);
44106 const std::size_t amount = vec.size();
44107 return T(fd->read(vec,amount) ? 1 : 0);
44108 }
44109
44110 case 3 : {
44111 vector_t vec(parameters[1]);
44112 const std::size_t amount =
44113 std::min(vec.size(),
44114 static_cast<std::size_t>(scalar_t(parameters[2])()));
44115 return T(fd->read(vec,amount) ? 1 : 0);
44116 }
44117 }
44118
44119 return T(0);
44120 }
44121 };
44122
44123 template <typename T>
44125 {
44126 public:
44127
44133
44134 using igfun_t::operator();
44135
44139
44140 inline T operator() (std::string& result, parameter_list_t parameters) exprtk_override
44141 {
44143 return T(fd->getline(result) ? 1 : 0);
44144 }
44145 };
44146
44147 template <typename T>
44149 {
44150 using exprtk::ifunction<T>::operator();
44151
44153 : exprtk::ifunction<T>(1)
44155
44156 inline T operator() (const T& v) exprtk_override
44157 {
44159 return (fd->eof() ? T(1) : T(0));
44160 }
44161 };
44162
44163 template <typename T>
44164 struct package
44165 {
44166 open <T> o;
44167 close <T> c;
44168 write <T> w;
44169 read <T> r;
44171 eof <T> e;
44172
44174 {
44175 #define exprtk_register_function(FunctionName, FunctionType) \
44176 if (!symtab.add_function(FunctionName,FunctionType)) \
44177 { \
44178 exprtk_debug(( \
44179 "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
44180 FunctionName)); \
44181 return false; \
44182 } \
44183
44184 exprtk_register_function("open" , o)
44185 exprtk_register_function("close" , c)
44186 exprtk_register_function("write" , w)
44187 exprtk_register_function("read" , r)
44188 exprtk_register_function("getline" , g)
44190 #undef exprtk_register_function
44191
44192 return true;
44193 }
44194 };
44195
44196 } // namespace exprtk::rtl::io::file
44197 } // namespace exprtk::rtl::io
44198 } // namespace exprtk::rtl
44199} // namespace exprtk
44200#endif
44201
44202#ifndef exprtk_disable_rtl_vecops
44203namespace exprtk
44204{
44205 namespace rtl { namespace vecops {
44206
44207 namespace helper
44208 {
44209 template <typename Vector>
44210 inline bool invalid_range(const Vector& v, const std::size_t r0, const std::size_t r1)
44211 {
44212 if (r0 > (v.size() - 1))
44213 return true;
44214 else if (r1 > (v.size() - 1))
44215 return true;
44216 else if (r1 < r0)
44217 return true;
44218 else
44219 return false;
44220 }
44221
44222 template <typename T>
44224 {
44230
44231 static inline bool process(parameter_list_t& parameters,
44232 std::size_t& r0, std::size_t& r1,
44233 const std::size_t& r0_prmidx,
44234 const std::size_t& r1_prmidx,
44235 const std::size_t vec_idx = 0)
44236 {
44237 if (r0_prmidx >= parameters.size())
44238 return false;
44239
44240 if (r1_prmidx >= parameters.size())
44241 return false;
44242
44243 if (!scalar_t(parameters[r0_prmidx]).to_uint(r0))
44244 return false;
44245
44246 if (!scalar_t(parameters[r1_prmidx]).to_uint(r1))
44247 return false;
44248
44249 return !invalid_range(vector_t(parameters[vec_idx]), r0, r1);
44250 }
44251 };
44252 }
44253
44254 namespace details
44255 {
44256 template <typename T>
44257 inline void kahan_sum(T& sum, T& error, const T v)
44258 {
44259 const T x = v - error;
44260 const T y = sum + x;
44261 error = (y - sum) - x;
44262 sum = y;
44263 }
44264
44265 } // namespace exprtk::rtl::details
44266
44267 template <typename T>
44269 {
44270 public:
44271
44277
44278 using igfun_t::operator();
44279
44281 : exprtk::igeneric_function<T>("V|VTT|T*")
44282 /*
44283 Overloads:
44284 0. V - vector
44285 1. VTT - vector, r0, r1
44286 2. T* - T....T
44287 */
44288 {}
44289
44290 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44291 {
44292 if (2 == ps_index)
44293 {
44294 for (std::size_t i = 0; i < parameters.size(); ++i)
44295 {
44296 if (scalar_t(parameters[i])() == T(0))
44297 {
44298 return T(0);
44299 }
44300 }
44301 }
44302 else
44303 {
44304 const vector_t vec(parameters[0]);
44305
44306 std::size_t r0 = 0;
44307 std::size_t r1 = vec.size() - 1;
44308
44309 if (
44310 (1 == ps_index) &&
44311 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44312 )
44313 {
44314 return std::numeric_limits<T>::quiet_NaN();
44315 }
44316
44317 for (std::size_t i = r0; i <= r1; ++i)
44318 {
44319 if (vec[i] == T(0))
44320 {
44321 return T(0);
44322 }
44323 }
44324 }
44325
44326 return T(1);
44327 }
44328 };
44329
44330 template <typename T>
44332 {
44333 public:
44334
44340
44341 using igfun_t::operator();
44342
44344 : exprtk::igeneric_function<T>("V|VTT|T*")
44345 /*
44346 Overloads:
44347 0. V - vector
44348 1. VTT - vector, r0, r1
44349 2. T* - T....T
44350 */
44351 {}
44352
44353 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44354 {
44355 if (2 == ps_index)
44356 {
44357 for (std::size_t i = 0; i < parameters.size(); ++i)
44358 {
44359 if (scalar_t(parameters[i])() != T(0))
44360 {
44361 return T(0);
44362 }
44363 }
44364 }
44365 else
44366 {
44367 const vector_t vec(parameters[0]);
44368
44369 std::size_t r0 = 0;
44370 std::size_t r1 = vec.size() - 1;
44371
44372 if (
44373 (1 == ps_index) &&
44374 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44375 )
44376 {
44377 return std::numeric_limits<T>::quiet_NaN();
44378 }
44379
44380 for (std::size_t i = r0; i <= r1; ++i)
44381 {
44382 if (vec[i] != T(0))
44383 {
44384 return T(0);
44385 }
44386 }
44387 }
44388
44389 return T(1);
44390 }
44391 };
44392
44393 template <typename T>
44395 {
44396 public:
44397
44403
44404 using igfun_t::operator();
44405
44407 : exprtk::igeneric_function<T>("V|VTT|T*")
44408 /*
44409 Overloads:
44410 0. V - vector
44411 1. VTT - vector, r0, r1
44412 2. T* - T....T
44413 */
44414 {}
44415
44416 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44417 {
44418 if (2 == ps_index)
44419 {
44420 for (std::size_t i = 0; i < parameters.size(); ++i)
44421 {
44422 if (scalar_t(parameters[i])() != T(0))
44423 {
44424 return T(1);
44425 }
44426 }
44427 }
44428 else
44429 {
44430 const vector_t vec(parameters[0]);
44431
44432 std::size_t r0 = 0;
44433 std::size_t r1 = vec.size() - 1;
44434
44435 if (
44436 (1 == ps_index) &&
44437 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44438 )
44439 {
44440 return std::numeric_limits<T>::quiet_NaN();
44441 }
44442
44443 for (std::size_t i = r0; i <= r1; ++i)
44444 {
44445 if (vec[i] != T(0))
44446 {
44447 return T(1);
44448 }
44449 }
44450 }
44451
44452 return T(0);
44453 }
44454 };
44455
44456 template <typename T>
44458 {
44459 public:
44460
44466
44467 using igfun_t::operator();
44468
44470 : exprtk::igeneric_function<T>("V|VTT|T*")
44471 /*
44472 Overloads:
44473 0. V - vector
44474 1. VTT - vector, r0, r1
44475 2. T* - T....T
44476 */
44477 {}
44478
44479 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44480 {
44481 if (2 == ps_index)
44482 {
44483 for (std::size_t i = 0; i < parameters.size(); ++i)
44484 {
44485 if (scalar_t(parameters[i])() == T(0))
44486 {
44487 return T(1);
44488 }
44489 }
44490 }
44491 else
44492 {
44493 const vector_t vec(parameters[0]);
44494
44495 std::size_t r0 = 0;
44496 std::size_t r1 = vec.size() - 1;
44497
44498 if (
44499 (1 == ps_index) &&
44500 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44501 )
44502 {
44503 return std::numeric_limits<T>::quiet_NaN();
44504 }
44505
44506 for (std::size_t i = r0; i <= r1; ++i)
44507 {
44508 if (vec[i] == T(0))
44509 {
44510 return T(1);
44511 }
44512 }
44513 }
44514
44515 return T(0);
44516 }
44517 };
44518
44519 template <typename T>
44521 {
44522 public:
44523
44529
44530 using igfun_t::operator();
44531
44533 : exprtk::igeneric_function<T>("V|VTT|T*")
44534 /*
44535 Overloads:
44536 0. V - vector
44537 1. VTT - vector, r0, r1
44538 2. T* - T....T
44539 */
44540 {}
44541
44542 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44543 {
44544 std::size_t cnt = 0;
44545
44546 if (2 == ps_index)
44547 {
44548 for (std::size_t i = 0; i < parameters.size(); ++i)
44549 {
44550 if (scalar_t(parameters[i])() != T(0)) ++cnt;
44551 }
44552 }
44553 else
44554 {
44555 const vector_t vec(parameters[0]);
44556
44557 std::size_t r0 = 0;
44558 std::size_t r1 = vec.size() - 1;
44559
44560 if (
44561 (1 == ps_index) &&
44562 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44563 )
44564 {
44565 return std::numeric_limits<T>::quiet_NaN();
44566 }
44567
44568 for (std::size_t i = r0; i <= r1; ++i)
44569 {
44570 if (vec[i] != T(0)) ++cnt;
44571 }
44572 }
44573
44574 return T(cnt);
44575 }
44576 };
44577
44578 template <typename T>
44580 {
44581 public:
44582
44588
44589 using igfun_t::operator();
44590
44592 : exprtk::igeneric_function<T>("VV|VTTVTT")
44593 /*
44594 Overloads:
44595 0. VV - x(vector), y(vector)
44596 1. VTTVTT - x(vector), xr0, xr1, y(vector), yr0, yr1,
44597 */
44598 {}
44599
44600 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44601 {
44602 const vector_t x(parameters[0]);
44603 vector_t y(parameters[(0 == ps_index) ? 1 : 3]);
44604
44605 std::size_t xr0 = 0;
44606 std::size_t xr1 = x.size() - 1;
44607
44608 std::size_t yr0 = 0;
44609 std::size_t yr1 = y.size() - 1;
44610
44611 if (1 == ps_index)
44612 {
44613 if (
44614 !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) ||
44615 !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3)
44616 )
44617 return T(0);
44618 }
44619
44620 const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1);
44621
44622 std::copy(
44623 x.begin() + xr0,
44624 x.begin() + xr0 + n,
44625 y.begin() + yr0);
44626
44627 return T(n);
44628 }
44629 };
44630
44631 template <typename T>
44633 {
44634 public:
44635
44641
44642 using igfun_t::operator();
44643
44645 : exprtk::igeneric_function<T>("VT|VTTT")
44646 /*
44647 Overloads:
44648 0. VT - vector, N
44649 1. VTTT - vector, N, r0, r1
44650 */
44651 {}
44652
44653 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44654 {
44655 vector_t vec(parameters[0]);
44656
44657 std::size_t n = 0;
44658 std::size_t r0 = 0;
44659 std::size_t r1 = vec.size() - 1;
44660
44661 if (!scalar_t(parameters[1]).to_uint(n))
44662 return T(0);
44663
44664 if (
44665 (1 == ps_index) &&
44666 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44667 )
44668 return T(0);
44669
44670 const std::size_t dist = r1 - r0 + 1;
44671 const std::size_t shift = n % dist;
44672
44673 std::rotate(
44674 vec.begin() + r0,
44675 vec.begin() + r0 + shift,
44676 vec.begin() + r1 + 1);
44677
44678 return T(1);
44679 }
44680 };
44681
44682 template <typename T>
44684 {
44685 public:
44686
44692
44693 using igfun_t::operator();
44694
44696 : exprtk::igeneric_function<T>("VT|VTTT")
44697 /*
44698 Overloads:
44699 0. VT - vector, N
44700 1. VTTT - vector, N, r0, r1
44701 */
44702 {}
44703
44704 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44705 {
44706 vector_t vec(parameters[0]);
44707
44708 std::size_t n = 0;
44709 std::size_t r0 = 0;
44710 std::size_t r1 = vec.size() - 1;
44711
44712 if (!scalar_t(parameters[1]).to_uint(n))
44713 return T(0);
44714
44715 if (
44716 (1 == ps_index) &&
44717 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44718 )
44719 return T(0);
44720
44721 const std::size_t dist = r1 - r0 + 1;
44722 const std::size_t shift = (dist - (n % dist)) % dist;
44723
44724 std::rotate(
44725 vec.begin() + r0,
44726 vec.begin() + r0 + shift,
44727 vec.begin() + r1 + 1);
44728
44729 return T(1);
44730 }
44731 };
44732
44733 template <typename T>
44735 {
44736 public:
44737
44743
44744 using igfun_t::operator();
44745
44747 : exprtk::igeneric_function<T>("V|VTT")
44748 /*
44749 Overloads:
44750 0. V - vector
44751 1. VTT - vector, r0, r1
44752 */
44753 {}
44754
44755 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44756 {
44757 vector_t vec(parameters[0]);
44758
44759 std::size_t r0 = 0;
44760 std::size_t r1 = vec.size() - 1;
44761
44762 if (
44763 (1 == ps_index) &&
44764 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44765 )
44766 return T(0);
44767
44768 std::reverse(vec.begin() + r0, vec.begin() + r1 + 1);
44769
44770 return T(1);
44771 }
44772 };
44773
44774 template <typename T>
44776 {
44777 public:
44778
44784
44785 using igfun_t::operator();
44786
44788 : exprtk::igeneric_function<T>("VT|VTTT")
44789 /*
44790 Overloads:
44791 0. VT - vector, N
44792 1. VTTT - vector, N, r0, r1
44793 */
44794 {}
44795
44796 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44797 {
44798 vector_t vec(parameters[0]);
44799
44800 std::size_t n = 0;
44801 std::size_t r0 = 0;
44802 std::size_t r1 = vec.size() - 1;
44803
44804 if (!scalar_t(parameters[1]).to_uint(n))
44805 return T(0);
44806
44807 if (
44808 (1 == ps_index) &&
44809 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44810 )
44811 return T(0);
44812
44813 const std::size_t dist = r1 - r0 + 1;
44814
44815 if (n > dist)
44816 return T(0);
44817
44818 std::rotate(
44819 vec.begin() + r0,
44820 vec.begin() + r0 + n,
44821 vec.begin() + r1 + 1);
44822
44823 for (std::size_t i = r1 - n + 1; i <= r1; ++i)
44824 {
44825 vec[i] = T(0);
44826 }
44827
44828 return T(1);
44829 }
44830 };
44831
44832 template <typename T>
44834 {
44835 public:
44836
44842
44843 using igfun_t::operator();
44844
44846 : exprtk::igeneric_function<T>("VT|VTTT")
44847 /*
44848 Overloads:
44849 0. VT - vector, N
44850 1. VTTT - vector, N, r0, r1
44851 */
44852 {}
44853
44854 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44855 {
44856 vector_t vec(parameters[0]);
44857
44858 std::size_t n = 0;
44859 std::size_t r0 = 0;
44860 std::size_t r1 = vec.size() - 1;
44861
44862 if (!scalar_t(parameters[1]).to_uint(n))
44863 return T(0);
44864
44865 if (
44866 (1 == ps_index) &&
44867 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
44868 )
44869 return T(0);
44870
44871 const std::size_t dist = r1 - r0 + 1;
44872
44873 if (n > dist)
44874 return T(0);
44875
44876 const std::size_t shift = (dist - (n % dist)) % dist;
44877
44878 std::rotate(
44879 vec.begin() + r0,
44880 vec.begin() + r0 + shift,
44881 vec.begin() + r1 + 1);
44882
44883 for (std::size_t i = r0; i < r0 + n; ++i)
44884 {
44885 vec[i] = T(0);
44886 }
44887
44888 return T(1);
44889 }
44890 };
44891
44892 template <typename T>
44894 {
44895 public:
44896
44902
44903 using igfun_t::operator();
44904
44906 : exprtk::igeneric_function<T>("V|VTT|VS|VSTT")
44907 /*
44908 Overloads:
44909 0. V - vector
44910 1. VTT - vector, r0, r1
44911 2. VS - vector, string
44912 3. VSTT - vector, string, r0, r1
44913 */
44914 {}
44915
44916 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44917 {
44918 vector_t vec(parameters[0]);
44919
44920 std::size_t r0 = 0;
44921 std::size_t r1 = vec.size() - 1;
44922
44923 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
44924 return T(0);
44925 if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
44926 return T(0);
44927
44928 bool ascending = true;
44929
44930 if ((2 == ps_index) || (3 == ps_index))
44931 {
44932 if (exprtk::details::imatch(to_str(string_t(parameters[1])),"ascending"))
44933 ascending = true;
44934 else if (exprtk::details::imatch(to_str(string_t(parameters[1])),"descending"))
44935 ascending = false;
44936 else
44937 return T(0);
44938 }
44939
44940 if (ascending)
44941 std::sort(
44942 vec.begin() + r0,
44943 vec.begin() + r1 + 1,
44944 std::less<T>());
44945 else
44946 std::sort(
44947 vec.begin() + r0,
44948 vec.begin() + r1 + 1,
44949 std::greater<T>());
44950
44951 return T(1);
44952 }
44953 };
44954
44955 template <typename T>
44957 {
44958 public:
44959
44965
44966 using igfun_t::operator();
44967
44969 : exprtk::igeneric_function<T>("VT|VTTT")
44970 /*
44971 Overloads:
44972 0. VT - vector, nth-element
44973 1. VTTT - vector, nth-element, r0, r1
44974 */
44975 {}
44976
44977 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44978 {
44979 vector_t vec(parameters[0]);
44980
44981 std::size_t n = 0;
44982 std::size_t r0 = 0;
44983 std::size_t r1 = vec.size() - 1;
44984
44985 if (!scalar_t(parameters[1]).to_uint(n))
44986 return T(0);
44987
44988 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
44989 {
44990 return std::numeric_limits<T>::quiet_NaN();
44991 }
44992
44993 std::nth_element(
44994 vec.begin() + r0,
44995 vec.begin() + r0 + n ,
44996 vec.begin() + r1 + 1);
44997
44998 return T(1);
44999 }
45000 };
45001
45002 template <typename T>
45004 {
45005 public:
45006
45012
45013 using igfun_t::operator();
45014
45016 : exprtk::igeneric_function<T>("VT|VTTT|VTTTT")
45017 /*
45018 Overloads:
45019 0. VT - vector, V
45020 1. VTTT - vector, V, r0, r1
45021 2. VTTTT - vector, V, r0, r1, SS
45022 */
45023 {}
45024
45025 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45026 {
45027 vector_t vec(parameters[0]);
45028
45029 const T assign_value = scalar_t(parameters[1]);
45030
45031 const std::size_t step_size = (2 != ps_index) ? 1 :
45032 static_cast<std::size_t>(scalar_t(parameters.back())());
45033
45034 std::size_t r0 = 0;
45035 std::size_t r1 = vec.size() - 1;
45036
45037 if (
45038 ((ps_index == 1) || (ps_index == 2)) &&
45039 !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
45040 )
45041 {
45042 return T(0);
45043 }
45044
45045 for (std::size_t i = r0; i <= r1; i += step_size)
45046 {
45047 vec[i] = assign_value;
45048 }
45049
45050 return T(1);
45051 }
45052 };
45053
45054 template <typename T>
45056 {
45057 public:
45058
45064
45065 using igfun_t::operator();
45066
45068 : exprtk::igeneric_function<T>("VTT|VT|VTTTT|VTTT")
45069 /*
45070 Overloads:
45071 0. VTT - vector, SV, SS
45072 1. VT - vector, SV, SS (+1)
45073 2. VTTT - vector, r0, r1, SV, SS
45074 3. VTT - vector, r0, r1, SV, SS (+1)
45075
45076 Where:
45077 1. SV - Start value
45078 2. SS - Step size
45079 */
45080 {}
45081
45082 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45083 {
45084 vector_t vec(parameters[0]);
45085
45086 const T start_value = (ps_index <= 1) ?
45087 scalar_t(parameters[1]) :
45088 scalar_t(parameters[3]) ;
45089
45090 const T step_size = ((0 == ps_index) || (2 == ps_index)) ?
45091 scalar_t(parameters.back())() :
45092 T(1) ;
45093
45094 std::size_t r0 = 0;
45095 std::size_t r1 = vec.size() - 1;
45096
45097 if (
45098 ((ps_index == 2) || (ps_index == 3)) &&
45099 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45100 )
45101 {
45102 return T(0);
45103 }
45104
45105 for (std::size_t i = r0; i <= r1; ++i)
45106 {
45107 vec[i] = start_value + ((i - r0) * step_size);
45108 }
45109
45110 return T(1);
45111 }
45112 };
45113
45114 template <typename T>
45116 {
45117 public:
45118
45124
45125 using igfun_t::operator();
45126
45128 : exprtk::igeneric_function<T>("V|VTT|VTTT")
45129 /*
45130 Overloads:
45131 0. V - vector
45132 1. VTT - vector, r0, r1
45133 2. VTTT - vector, r0, r1, stride
45134 */
45135 {}
45136
45137 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45138 {
45139 const vector_t vec(parameters[0]);
45140
45141 const std::size_t stride = (2 != ps_index) ? 1 :
45142 static_cast<std::size_t>(scalar_t(parameters[3])());
45143
45144 std::size_t r0 = 0;
45145 std::size_t r1 = vec.size() - 1;
45146
45147 if (
45148 ((1 == ps_index) || (2 == ps_index)) &&
45149 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45150 )
45151 {
45152 return std::numeric_limits<T>::quiet_NaN();
45153 }
45154
45155 T result = T(0);
45156 T error = T(0);
45157
45158 for (std::size_t i = r0; i <= r1; i += stride)
45159 {
45160 details::kahan_sum(result, error, vec[i]);
45161 }
45162
45163 return result;
45164 }
45165 };
45166
45167 template <typename T>
45169 {
45170 public:
45171
45177
45178 using igfun_t::operator();
45179
45181 : exprtk::igeneric_function<T>("TVV|TVVTT")
45182 /*
45183 y <- ax + y
45184 Overloads:
45185 0. TVV - a, x(vector), y(vector)
45186 1. TVVTT - a, x(vector), y(vector), r0, r1
45187 */
45188 {}
45189
45190 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45191 {
45192 const vector_t x(parameters[1]);
45193 vector_t y(parameters[2]);
45194
45195 std::size_t r0 = 0;
45196 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45197
45198 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
45199 return std::numeric_limits<T>::quiet_NaN();
45200 else if (helper::invalid_range(y, r0, r1))
45201 return std::numeric_limits<T>::quiet_NaN();
45202
45203 const T a = scalar_t(parameters[0])();
45204
45205 for (std::size_t i = r0; i <= r1; ++i)
45206 {
45207 y[i] = (a * x[i]) + y[i];
45208 }
45209
45210 return T(1);
45211 }
45212 };
45213
45214 template <typename T>
45216 {
45217 public:
45218
45224
45225 using igfun_t::operator();
45226
45228 : exprtk::igeneric_function<T>("TVTV|TVTVTT")
45229 /*
45230 y <- ax + by
45231 Overloads:
45232 0. TVTV - a, x(vector), b, y(vector)
45233 1. TVTVTT - a, x(vector), b, y(vector), r0, r1
45234 */
45235 {}
45236
45237 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45238 {
45239 const vector_t x(parameters[1]);
45240 vector_t y(parameters[3]);
45241
45242 std::size_t r0 = 0;
45243 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45244
45245 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45246 return std::numeric_limits<T>::quiet_NaN();
45247 else if (helper::invalid_range(y, r0, r1))
45248 return std::numeric_limits<T>::quiet_NaN();
45249
45250 const T a = scalar_t(parameters[0])();
45251 const T b = scalar_t(parameters[2])();
45252
45253 for (std::size_t i = r0; i <= r1; ++i)
45254 {
45255 y[i] = (a * x[i]) + (b * y[i]);
45256 }
45257
45258 return T(1);
45259 }
45260 };
45261
45262 template <typename T>
45264 {
45265 public:
45266
45272
45273 using igfun_t::operator();
45274
45276 : exprtk::igeneric_function<T>("TVVV|TVVVTT")
45277 /*
45278 z <- ax + y
45279 Overloads:
45280 0. TVVV - a, x(vector), y(vector), z(vector)
45281 1. TVVVTT - a, x(vector), y(vector), z(vector), r0, r1
45282 */
45283 {}
45284
45285 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45286 {
45287 const vector_t x(parameters[1]);
45288 const vector_t y(parameters[2]);
45289 vector_t z(parameters[3]);
45290
45291 std::size_t r0 = 0;
45292 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45293
45294 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45295 return std::numeric_limits<T>::quiet_NaN();
45296 else if (helper::invalid_range(y, r0, r1))
45297 return std::numeric_limits<T>::quiet_NaN();
45298 else if (helper::invalid_range(z, r0, r1))
45299 return std::numeric_limits<T>::quiet_NaN();
45300
45301 const T a = scalar_t(parameters[0])();
45302
45303 for (std::size_t i = r0; i <= r1; ++i)
45304 {
45305 z[i] = (a * x[i]) + y[i];
45306 }
45307
45308 return T(1);
45309 }
45310 };
45311
45312 template <typename T>
45314 {
45315 public:
45316
45322
45323 using igfun_t::operator();
45324
45326 : exprtk::igeneric_function<T>("TVTVV|TVTVVTT")
45327 /*
45328 z <- ax + by
45329 Overloads:
45330 0. TVTVV - a, x(vector), b, y(vector), z(vector)
45331 1. TVTVVTT - a, x(vector), b, y(vector), z(vector), r0, r1
45332 */
45333 {}
45334
45335 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45336 {
45337 const vector_t x(parameters[1]);
45338 const vector_t y(parameters[3]);
45339 vector_t z(parameters[4]);
45340
45341 std::size_t r0 = 0;
45342 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45343
45344 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
45345 return std::numeric_limits<T>::quiet_NaN();
45346 else if (helper::invalid_range(y, r0, r1))
45347 return std::numeric_limits<T>::quiet_NaN();
45348 else if (helper::invalid_range(z, r0, r1))
45349 return std::numeric_limits<T>::quiet_NaN();
45350
45351 const T a = scalar_t(parameters[0])();
45352 const T b = scalar_t(parameters[2])();
45353
45354 for (std::size_t i = r0; i <= r1; ++i)
45355 {
45356 z[i] = (a * x[i]) + (b * y[i]);
45357 }
45358
45359 return T(1);
45360 }
45361 };
45362
45363 template <typename T>
45365 {
45366 public:
45367
45373
45374 using igfun_t::operator();
45375
45377 : exprtk::igeneric_function<T>("TVTTV|TVTTVTT")
45378 /*
45379 y <- ax + by
45380 Overloads:
45381 0. TVTVV - a, x(vector), b, shift, y(vector), z(vector)
45382 1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
45383 */
45384 {}
45385
45386 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45387 {
45388 const vector_t x(parameters[1]);
45389 vector_t y(parameters[4]);
45390
45391 std::size_t r0 = 0;
45392 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45393
45394 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
45395 return std::numeric_limits<T>::quiet_NaN();
45396 else if (helper::invalid_range(y, r0, r1))
45397 return std::numeric_limits<T>::quiet_NaN();
45398
45399 const T a = scalar_t(parameters[0])();
45400 const T b = scalar_t(parameters[2])();
45401
45402 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
45403
45404 for (std::size_t i = r0; i <= r1; ++i)
45405 {
45406 y[i] = (a * x[i]) + (b * y[i + s]);
45407 }
45408
45409 return T(1);
45410 }
45411 };
45412
45413 template <typename T>
45415 {
45416 public:
45417
45423
45424 using igfun_t::operator();
45425
45427 : exprtk::igeneric_function<T>("TVTTVV|TVTTVVTT")
45428 /*
45429 z <- ax + by
45430 Overloads:
45431 0. TVTVV - a, x(vector), b, shift, y(vector), z(vector)
45432 1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
45433 */
45434 {}
45435
45436 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45437 {
45438 const vector_t x(parameters[1]);
45439 const vector_t y(parameters[4]);
45440 vector_t z(parameters[5]);
45441
45442 std::size_t r0 = 0;
45443 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45444
45445 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1))
45446 return std::numeric_limits<T>::quiet_NaN();
45447 else if (helper::invalid_range(y, r0, r1))
45448 return std::numeric_limits<T>::quiet_NaN();
45449 else if (helper::invalid_range(z, r0, r1))
45450 return std::numeric_limits<T>::quiet_NaN();
45451
45452 const T a = scalar_t(parameters[0])();
45453 const T b = scalar_t(parameters[2])();
45454
45455 const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
45456
45457 for (std::size_t i = r0; i <= r1; ++i)
45458 {
45459 z[i] = (a * x[i]) + (b * y[i + s]);
45460 }
45461
45462 return T(1);
45463 }
45464 };
45465
45466 template <typename T>
45468 {
45469 public:
45470
45476
45477 using igfun_t::operator();
45478
45480 : exprtk::igeneric_function<T>("TVTV|TVTVTT")
45481 /*
45482 z <- ax + b
45483 Overloads:
45484 0. TVTV - a, x(vector), b, z(vector)
45485 1. TVTVTT - a, x(vector), b, z(vector), r0, r1
45486 */
45487 {}
45488
45489 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45490 {
45491 const vector_t x(parameters[1]);
45492 vector_t z(parameters[3]);
45493
45494 std::size_t r0 = 0;
45495 std::size_t r1 = x.size() - 1;
45496
45497 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
45498 return std::numeric_limits<T>::quiet_NaN();
45499 else if (helper::invalid_range(z, r0, r1))
45500 return std::numeric_limits<T>::quiet_NaN();
45501
45502 const T a = scalar_t(parameters[0])();
45503 const T b = scalar_t(parameters[2])();
45504
45505 for (std::size_t i = r0; i <= r1; ++i)
45506 {
45507 z[i] = (a * x[i]) + b;
45508 }
45509
45510 return T(1);
45511 }
45512 };
45513
45514 template <typename T>
45516 {
45517 public:
45518
45524
45525 using igfun_t::operator();
45526
45528 : exprtk::igeneric_function<T>("VV|VVT")
45529 /*
45530 x_(i - stride) - x_i
45531 Overloads:
45532 0. VV - x(vector), y(vector)
45533 1. VVT - x(vector), y(vector), stride
45534 */
45535 {}
45536
45537 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45538 {
45539 const vector_t x(parameters[0]);
45540 vector_t y(parameters[1]);
45541
45542 const std::size_t r0 = 0;
45543 const std::size_t r1 = std::min(x.size(),y.size()) - 1;
45544
45545 const std::size_t stride = (1 != ps_index) ? 1 :
45546 std::min(r1,static_cast<std::size_t>(scalar_t(parameters[2])()));
45547
45548 for (std::size_t i = 0; i < stride; ++i)
45549 {
45550 y[i] = std::numeric_limits<T>::quiet_NaN();
45551 }
45552
45553 for (std::size_t i = (r0 + stride); i <= r1; ++i)
45554 {
45555 y[i] = x[i] - x[i - stride];
45556 }
45557
45558 return T(1);
45559 }
45560 };
45561
45562 template <typename T>
45564 {
45565 public:
45566
45572
45573 using igfun_t::operator();
45574
45576 : exprtk::igeneric_function<T>("VV|VVTT")
45577 /*
45578 Overloads:
45579 0. VV - x(vector), y(vector)
45580 1. VVTT - x(vector), y(vector), r0, r1
45581 */
45582 {}
45583
45584 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45585 {
45586 const vector_t x(parameters[0]);
45587 const vector_t y(parameters[1]);
45588
45589 std::size_t r0 = 0;
45590 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45591
45592 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
45593 return std::numeric_limits<T>::quiet_NaN();
45594 else if (helper::invalid_range(y, r0, r1))
45595 return std::numeric_limits<T>::quiet_NaN();
45596
45597 T result = T(0);
45598
45599 for (std::size_t i = r0; i <= r1; ++i)
45600 {
45601 result += (x[i] * y[i]);
45602 }
45603
45604 return result;
45605 }
45606 };
45607
45608 template <typename T>
45610 {
45611 public:
45612
45618
45619 using igfun_t::operator();
45620
45622 : exprtk::igeneric_function<T>("VV|VVTT")
45623 /*
45624 Overloads:
45625 0. VV - x(vector), y(vector)
45626 1. VVTT - x(vector), y(vector), r0, r1
45627 */
45628 {}
45629
45630 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45631 {
45632 const vector_t x(parameters[0]);
45633 const vector_t y(parameters[1]);
45634
45635 std::size_t r0 = 0;
45636 std::size_t r1 = std::min(x.size(),y.size()) - 1;
45637
45638 if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
45639 return std::numeric_limits<T>::quiet_NaN();
45640 else if (helper::invalid_range(y, r0, r1))
45641 return std::numeric_limits<T>::quiet_NaN();
45642
45643 T result = T(0);
45644 T error = T(0);
45645
45646 for (std::size_t i = r0; i <= r1; ++i)
45647 {
45648 details::kahan_sum(result, error, (x[i] * y[i]));
45649 }
45650
45651 return result;
45652 }
45653 };
45654
45655 template <typename T>
45657 {
45658 public:
45659
45665
45666 using igfun_t::operator();
45667
45669 : exprtk::igeneric_function<T>("VTT|VTTTT")
45670 /*
45671 Overloads:
45672 0. VTT - vector, TV, SV
45673 1. VTTTT - vector, r0, r1, TV, SV
45674
45675 Where:
45676 TV - Threshold value
45677 SV - Snap-to value
45678 */
45679 {}
45680
45681 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45682 {
45683 vector_t vec(parameters[0]);
45684
45685 const T threshold_value = (0 == ps_index) ?
45686 scalar_t(parameters[1]) :
45687 scalar_t(parameters[3]) ;
45688
45689 const T snap_value = scalar_t(parameters.back());
45690
45691 std::size_t r0 = 0;
45692 std::size_t r1 = vec.size() - 1;
45693
45694 if (
45695 (1 == ps_index) &&
45696 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45697 )
45698 {
45699 return T(0);
45700 }
45701
45702 for (std::size_t i = r0; i <= r1; ++i)
45703 {
45704 if (vec[i] < threshold_value)
45705 {
45706 vec[i] = snap_value;
45707 }
45708 }
45709
45710 return T(1);
45711 }
45712 };
45713
45714 template <typename T>
45716 {
45717 public:
45718
45724
45725 using igfun_t::operator();
45726
45728 : exprtk::igeneric_function<T>("VTT|VTTTT")
45729 /*
45730 Overloads:
45731 0. VTT - vector, TV, SV
45732 1. VTTTT - vector, r0, r1, TV, SV
45733
45734 Where:
45735 TV - Threshold value
45736 SV - Snap-to value
45737 */
45738 {}
45739
45740 inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
45741 {
45742 vector_t vec(parameters[0]);
45743
45744 const T threshold_value = (0 == ps_index) ?
45745 scalar_t(parameters[1]) :
45746 scalar_t(parameters[3]) ;
45747
45748 const T snap_value = scalar_t(parameters.back());
45749
45750 std::size_t r0 = 0;
45751 std::size_t r1 = vec.size() - 1;
45752
45753 if (
45754 (1 == ps_index) &&
45755 !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
45756 )
45757 {
45758 return T(0);
45759 }
45760
45761 for (std::size_t i = r0; i <= r1; ++i)
45762 {
45763 if (vec[i] > threshold_value)
45764 {
45765 vec[i] = snap_value;
45766 }
45767 }
45768
45769 return T(1);
45770 }
45771 };
45772
45773 template <typename T>
45774 struct package
45775 {
45776 all_true <T> at;
45777 all_false <T> af;
45778 any_true <T> nt;
45779 any_false <T> nf;
45780 count <T> c;
45781 copy <T> cp;
45782 rol <T> rl;
45783 ror <T> rr;
45784 reverse <T> rev;
45785 shift_left <T> sl;
45786 shift_right <T> sr;
45787 sort <T> st;
45788 nthelement <T> ne;
45789 assign <T> an;
45790 iota <T> ia;
45791 sumk <T> sk;
45792 axpy <T> b1_axpy;
45793 axpby <T> b1_axpby;
45794 axpyz <T> b1_axpyz;
45795 axpbyz <T> b1_axpbyz;
45796 axpbsy <T> b1_axpbsy;
45797 axpbsyz <T> b1_axpbsyz;
45798 axpbz <T> b1_axpbz;
45799 diff <T> df;
45800 dot <T> dt;
45801 dotk <T> dtk;
45804
45806 {
45807 #define exprtk_register_function(FunctionName, FunctionType) \
45808 if (!symtab.add_function(FunctionName,FunctionType)) \
45809 { \
45810 exprtk_debug(( \
45811 "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
45812 FunctionName)); \
45813 return false; \
45814 } \
45815
45816 exprtk_register_function("all_true" , at )
45817 exprtk_register_function("all_false" , af )
45818 exprtk_register_function("any_true" , nt )
45819 exprtk_register_function("any_false" , nf )
45820 exprtk_register_function("count" , c )
45821 exprtk_register_function("copy" , cp )
45822 exprtk_register_function("rotate_left" , rl )
45824 exprtk_register_function("rotate_right" , rr )
45826 exprtk_register_function("reverse" , rev )
45827 exprtk_register_function("shftl" , sl )
45828 exprtk_register_function("shftr" , sr )
45829 exprtk_register_function("sort" , st )
45830 exprtk_register_function("nth_element" , ne )
45831 exprtk_register_function("assign" , an )
45832 exprtk_register_function("iota" , ia )
45833 exprtk_register_function("sumk" , sk )
45841 exprtk_register_function("diff" , df )
45843 exprtk_register_function("dotk" , dtk )
45844 exprtk_register_function("threshold_above" , ta )
45845 exprtk_register_function("threshold_below" , tb )
45846 #undef exprtk_register_function
45847
45848 return true;
45849 }
45850 };
45851
45852 } // namespace exprtk::rtl::vecops
45853 } // namespace exprtk::rtl
45854} // namespace exprtk
45855#endif
45856
45857namespace exprtk
45858{
45859 namespace information
45860 {
45861 using ::exprtk::details::char_cptr;
45862
45863 static char_cptr library = "Mathematical Expression Toolkit";
45864 static char_cptr version = "2.7182818284590452353602874713526624977"
45865 "572470936999595749669676277240766303535"
45866 "475945713821785251664274274663919320030"
45867 "599218174135966290435729003342952605956";
45868 static char_cptr date = "20240101";
45869 static char_cptr min_cpp = "199711L";
45870
45871 static inline std::string data()
45872 {
45873 static const std::string info_str = std::string(library) +
45874 std::string(" v") + std::string(version) +
45875 std::string(" (") + date + std::string(")") +
45876 std::string(" (") + min_cpp + std::string(")");
45877 return info_str;
45878 }
45879
45880 } // namespace information
45881
45882 #ifdef exprtk_debug
45883 #undef exprtk_debug
45884 #endif
45885
45886 #ifdef exprtk_error_location
45887 #undef exprtk_error_location
45888 #endif
45889
45890 #ifdef exprtk_fallthrough
45891 #undef exprtk_fallthrough
45892 #endif
45893
45894 #ifdef exprtk_override
45895 #undef exprtk_override
45896 #endif
45897
45898 #ifdef exprtk_final
45899 #undef exprtk_final
45900 #endif
45901
45902 #ifdef exprtk_delete
45903 #undef exprtk_delete
45904 #endif
45905
45906} // namespace exprtk
45907
45908#endif
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, bfunc_t p2)
Definition exprtk.hpp:17277
expression_node< T >::node_type type() const
Definition exprtk.hpp:17245
details::functor_t< T > functor_t
Definition exprtk.hpp:17234
T0oT1< T, T0, T1 > & operator=(const T0oT1< T, T0, T1 > &)
Definition exprtk.hpp:17289
T0oT1(const T0oT1< T, T0, T1 > &)
functor_t::bfunc_t bfunc_t
Definition exprtk.hpp:17235
T0oT1(T0 p0, T1 p1, const bfunc_t p2)
Definition exprtk.hpp:17239
operator_type operation() const
Definition exprtk.hpp:17251
bfunc_t f() const
Definition exprtk.hpp:17271
T0oT1< T, T0, T1 > node_type
Definition exprtk.hpp:17237
virtual std::string type_id() const =0
node_type & operator=(const node_type &)
functor_t::tfunc_t tfunc_t
Definition exprtk.hpp:17491
T0oT1oT2_sf3< T, T0, T1, T2 > node_type
Definition exprtk.hpp:17493
operator_type operation() const
Definition exprtk.hpp:17508
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
Definition exprtk.hpp:17549
std::string type_id() const
Definition exprtk.hpp:17538
expression_node< T >::node_type type() const
Definition exprtk.hpp:17502
details::functor_t< T > functor_t
Definition exprtk.hpp:17490
static std::string id()
Definition exprtk.hpp:17543
T0oT1oT2_sf3(const node_type &)
T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
Definition exprtk.hpp:17495
T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
Definition exprtk.hpp:17590
T0oT1oT2_sf3ext(const node_type &)
node_type & operator=(const node_type &)
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2)
Definition exprtk.hpp:17638
T0oT1oT2_sf3ext< T, T0, T1, T2, SF3Operation > node_type
Definition exprtk.hpp:17588
std::string type_id() const
Definition exprtk.hpp:17627
expression_node< T >::node_type type() const
Definition exprtk.hpp:17596
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
Definition exprtk.hpp:17367
T0oT1oT2< T, T0, T1, T2, ProcessMode > node_type
Definition exprtk.hpp:17304
T0oT1oT2(const node_type &)
details::functor_t< T > functor_t
Definition exprtk.hpp:17301
static std::string id()
Definition exprtk.hpp:17361
functor_t::bfunc_t bfunc_t
Definition exprtk.hpp:17302
std::string type_id() const
Definition exprtk.hpp:17356
node_type & operator=(const node_type &)
T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
Definition exprtk.hpp:17307
operator_type operation()
Definition exprtk.hpp:17321
expression_node< T >::node_type type() const
Definition exprtk.hpp:17315
virtual std::string type_id() const =0
T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
Definition exprtk.hpp:17679
T0oT1oT2oT3_sf4< T, T0, T1, T2, T3 > node_type
Definition exprtk.hpp:17677
node_type & operator=(const node_type &)
operator_type operation() const
Definition exprtk.hpp:17693
T0oT1oT2oT3_sf4(const node_type &)
details::functor_t< T > functor_t
Definition exprtk.hpp:17674
expression_node< T >::node_type type() const
Definition exprtk.hpp:17687
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
Definition exprtk.hpp:17739
std::string type_id() const
Definition exprtk.hpp:17728
expression_node< T >::node_type type() const
Definition exprtk.hpp:17773
T0oT1oT2oT3_sf4ext< T, T0, T1, T2, T3, SF4Operation > node_type
Definition exprtk.hpp:17764
T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
Definition exprtk.hpp:17766
node_type & operator=(const node_type &)
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3)
Definition exprtk.hpp:17815
T0oT1oT2oT3_sf4ext(const node_type &)
T0oT1oT2oT3< T, T0, T1, T2, T3, ProcessMode > node_type
Definition exprtk.hpp:17398
T0oT1oT2oT3(const node_type &)
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
Definition exprtk.hpp:17462
std::string type_id() const
Definition exprtk.hpp:17451
functor_t::bfunc_t bfunc_t
Definition exprtk.hpp:17392
T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
Definition exprtk.hpp:17401
details::functor_t< T > functor_t
Definition exprtk.hpp:17391
node_type & operator=(const node_type &)
static std::string id()
Definition exprtk.hpp:17456
std::size_t node_depth() const
Definition exprtk.hpp:11753
expression_node< T > * expression_ptr
Definition exprtk.hpp:11675
assert_node(expression_ptr assert_condition_node, expression_ptr assert_message_node, assert_check_ptr assert_check, assert_context_t context)
Definition exprtk.hpp:11680
assert_check_ptr assert_check_
Definition exprtk.hpp:11764
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:11747
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:11676
assert_context_t context_
Definition exprtk.hpp:11765
assert_check::assert_context assert_context_t
Definition exprtk.hpp:11678
expression_node< T >::node_type type() const
Definition exprtk.hpp:11724
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:11677
str_base_ptr assert_message_str_base_
Definition exprtk.hpp:11763
variable_node< T > * var_node_ptr_
Definition exprtk.hpp:12322
assignment_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12295
expression_node< T > * expression_ptr
Definition exprtk.hpp:12292
variable_node< T > * var_node_ptr_
Definition exprtk.hpp:12862
assignment_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12833
expression_node< T > * expression_ptr
Definition exprtk.hpp:12830
assignment_rebasevec_celem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12493
rebasevector_celem_node< T > * rbvec_node_ptr_
Definition exprtk.hpp:12522
rebasevector_celem_node< T > * rbvec_node_ptr_
Definition exprtk.hpp:13062
assignment_rebasevec_celem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13033
rebasevector_celem_rtc_node< T > * rbvec_node_ptr_
Definition exprtk.hpp:13142
assignment_rebasevec_celem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13113
assignment_rebasevec_elem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12413
rebasevector_elem_node< T > * rbvec_node_ptr_
Definition exprtk.hpp:12442
rebasevector_elem_node< T > * rbvec_node_ptr_
Definition exprtk.hpp:13022
assignment_rebasevec_elem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12993
rebasevector_elem_rtc_node< T > * rbvec_node_ptr_
Definition exprtk.hpp:13102
assignment_rebasevec_elem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13073
rebasevector_elem_rtc_node< T > * rbvec_node_ptr_
Definition exprtk.hpp:12482
assignment_rebasevec_elem_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12453
stringvar_node< T > * strvar_node_ptr
Definition exprtk.hpp:10989
assignment_string_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:10994
const range_t & range_ref() const
Definition exprtk.hpp:11074
expression_node< T >::node_type type() const
Definition exprtk.hpp:11079
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:10990
range_interface< T >::range_t range_t
Definition exprtk.hpp:10984
expression_node< T > * expression_ptr
Definition exprtk.hpp:10988
expression_node< T >::node_type type() const
Definition exprtk.hpp:11219
assignment_string_range_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:11117
range_interface< T >::range_t range_t
Definition exprtk.hpp:11106
assignment_vec_celem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12953
assignment_vec_elem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12333
vector_elem_node< T > * vec_node_ptr_
Definition exprtk.hpp:12362
assignment_vec_elem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12873
assignment_vec_elem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12913
vector_elem_rtc_node< T > * vec_node_ptr_
Definition exprtk.hpp:12402
assignment_vec_elem_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12373
assignment_vec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12538
expression_node< T >::node_type type() const
Definition exprtk.hpp:12615
expression_node< T > * expression_ptr
Definition exprtk.hpp:12532
vector_node_ptr vec() const
Definition exprtk.hpp:12605
expression_node< T >::node_type type() const
Definition exprtk.hpp:13235
assignment_vec_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13158
expression_node< T > * expression_ptr
Definition exprtk.hpp:13152
expression_node< T >::node_type type() const
Definition exprtk.hpp:12782
assignment_vecvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:12667
expression_node< T > * expression_ptr
Definition exprtk.hpp:12661
expression_node< T >::node_type type() const
Definition exprtk.hpp:13400
assignment_vecvec_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13292
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:6986
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7024
expression_node< T > * expression_ptr
Definition exprtk.hpp:6985
expression_node< T > * branch(const std::size_t &index=0) const
Definition exprtk.hpp:7011
binary_ext_node(expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:6988
expression_node< T >::node_type type() const
Definition exprtk.hpp:7001
std::size_t node_depth() const
Definition exprtk.hpp:7029
expression_node< T >::node_type type() const
Definition exprtk.hpp:6941
binary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:6922
expression_node< T > * branch(const std::size_t &index=0) const
Definition exprtk.hpp:6951
operator_type operation()
Definition exprtk.hpp:6946
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:6964
std::size_t node_depth() const
Definition exprtk.hpp:6969
expression_node< T > * expression_ptr
Definition exprtk.hpp:6919
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:6920
expression_node< T >::node_type type() const
Definition exprtk.hpp:18764
std::size_t node_depth() const
Definition exprtk.hpp:18779
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:18774
bipow_node(expression_ptr branch)
Definition exprtk.hpp:18753
bipow_node(const bipow_node< T, PowOp > &)
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:18750
bipow_node< T, PowOp > & operator=(const bipow_node< T, PowOp > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:18749
bipowinv_node(expression_ptr branch)
Definition exprtk.hpp:18831
expression_node< T >::node_type type() const
Definition exprtk.hpp:18842
bipowinv_node< T, PowOp > & operator=(const bipowinv_node< T, PowOp > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:18827
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:18852
bipowinv_node(const bipowinv_node< T, PowOp > &)
std::size_t node_depth() const
Definition exprtk.hpp:18857
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:18828
virtual operator_type operation() const
Definition exprtk.hpp:16736
virtual void set_c(const T)=0
virtual expression_node< T > * move_branch(const std::size_t &index)=0
virtual const T c() const =0
boc_node(const expression_ptr branch, const T const_var)
Definition exprtk.hpp:18216
std::size_t node_depth() const
Definition exprtk.hpp:18264
operator_type operation() const
Definition exprtk.hpp:18228
expression_node< T > * move_branch(const std::size_t &)
Definition exprtk.hpp:18253
void set_c(const T new_c)
Definition exprtk.hpp:18238
boc_node< T, Operation > & operator=(const boc_node< T, Operation > &)
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:18248
boc_node(const boc_node< T, Operation > &)
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:18212
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:18259
expression_node< T > * expression_ptr
Definition exprtk.hpp:18211
virtual const T & v() const =0
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:18084
bov_node< T, Operation > & operator=(const bov_node< T, Operation > &)
bov_node(const expression_ptr branch, const T &var)
Definition exprtk.hpp:18088
std::size_t node_depth() const
Definition exprtk.hpp:18120
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:18110
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:18115
expression_node< T > * expression_ptr
Definition exprtk.hpp:18083
const T & v() const
Definition exprtk.hpp:18100
bov_node(const bov_node< T, Operation > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:7295
std::size_t node_depth() const
Definition exprtk.hpp:7326
expression_node< T >::node_type type() const
Definition exprtk.hpp:7316
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7321
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7296
break_node(expression_ptr ret=expression_ptr(0))
Definition exprtk.hpp:7298
build_string & operator<<(const std::string &s)
Definition exprtk.hpp:406
build_string(const std::size_t &initial_size=64)
Definition exprtk.hpp:401
std::string as_string() const
Definition exprtk.hpp:423
virtual const T c() const =0
virtual operator_type operation() const
Definition exprtk.hpp:16716
virtual void set_c(const T)=0
virtual expression_node< T > * move_branch(const std::size_t &index)=0
std::size_t node_depth() const
Definition exprtk.hpp:18192
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:18176
expression_node< T > * move_branch(const std::size_t &)
Definition exprtk.hpp:18181
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:18140
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:18187
cob_node< T, Operation > & operator=(const cob_node< T, Operation > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:18139
cob_node(const T const_var, const expression_ptr branch)
Definition exprtk.hpp:18144
cob_node(const cob_node< T, Operation > &)
void set_c(const T new_c)
Definition exprtk.hpp:18166
operator_type operation() const
Definition exprtk.hpp:18156
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7167
conditional_node(expression_ptr condition, expression_ptr consequent, expression_ptr alternative)
Definition exprtk.hpp:7169
expression_node< T >::node_type type() const
Definition exprtk.hpp:7187
expression_node< T > * expression_ptr
Definition exprtk.hpp:7166
std::size_t node_depth() const
Definition exprtk.hpp:7207
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7200
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:11252
expression_node< T >::node_type type() const
Definition exprtk.hpp:11377
conditional_string_node(expression_ptr condition, expression_ptr consequent, expression_ptr alternative)
Definition exprtk.hpp:11254
expression_node< T > * expression_ptr
Definition exprtk.hpp:11251
range_interface< T >::range_t range_t
Definition exprtk.hpp:11247
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:14343
expression_node< T >::node_type type() const
Definition exprtk.hpp:14306
conditional_vector_node(expression_ptr condition, expression_ptr consequent, expression_ptr alternative)
Definition exprtk.hpp:14212
vector_interface< T > * vec_interface_ptr
Definition exprtk.hpp:14204
expression_node< T > * expression_ptr
Definition exprtk.hpp:14203
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:14210
expression_node< T > * expression_ptr
Definition exprtk.hpp:7226
cons_conditional_node(expression_ptr condition, expression_ptr consequent)
Definition exprtk.hpp:7229
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7227
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7257
expression_node< T >::node_type type() const
Definition exprtk.hpp:7245
expression_node< T >::node_type type() const
Definition exprtk.hpp:11507
range_interface< T >::range_t range_t
Definition exprtk.hpp:11414
cons_conditional_str_node(expression_ptr condition, expression_ptr consequent)
Definition exprtk.hpp:11423
range_interface< T >::range_t range_t
Definition exprtk.hpp:10283
const_string_range_node(const std::string &v, const range_t &rp)
Definition exprtk.hpp:10285
const_string_range_node(const const_string_range_node< T > &)
const_string_range_node< T > & operator=(const const_string_range_node< T > &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:10330
expression_node< T >::node_type type() const
Definition exprtk.hpp:7349
virtual const T c() const =0
virtual const T & v() const =0
virtual operator_type operation() const
Definition exprtk.hpp:16658
cov_node< T, Operation > & operator=(const cov_node< T, Operation > &)
cov_node(const T &const_var, const T &var)
Definition exprtk.hpp:17936
const T & v() const
Definition exprtk.hpp:17961
operator_type operation() const
Definition exprtk.hpp:17951
expression_node< T >::node_type type() const
Definition exprtk.hpp:17946
cov_node(const cov_node< T, Operation > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:17932
virtual expression_node< T > * branch(const std::size_t &index=0) const
Definition exprtk.hpp:5596
virtual node_type type() const
Definition exprtk.hpp:5601
nci_t::noderef_list_t noderef_list_t
Definition exprtk.hpp:5585
expression_node< T > * expression_ptr
Definition exprtk.hpp:5583
node_depth_base< expression_node< T > > ndb_t
Definition exprtk.hpp:5586
node_collector_interface< expression_node< T > > nci_t
Definition exprtk.hpp:5584
virtual bool valid() const
Definition exprtk.hpp:5606
for_loop_bc_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body)
Definition exprtk.hpp:7929
expression_node< T > * expression_ptr
Definition exprtk.hpp:7927
expression_node< T > * expression_ptr
Definition exprtk.hpp:7992
for_loop_bc_rtc_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition exprtk.hpp:7994
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7612
expression_node< T >::node_type type() const
Definition exprtk.hpp:7652
for_loop_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body)
Definition exprtk.hpp:7614
expression_node< T > * expression_ptr
Definition exprtk.hpp:7611
std::size_t node_depth() const
Definition exprtk.hpp:7670
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7662
expression_node< T > * expression_ptr
Definition exprtk.hpp:7692
for_loop_rtc_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition exprtk.hpp:7694
expression_node< T >::node_type type() const
Definition exprtk.hpp:14770
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:14432
std::size_t node_depth() const
Definition exprtk.hpp:14509
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:14504
bool init_branches(expression_ptr(&b)[NumBranches])
Definition exprtk.hpp:14442
expression_node< T >::node_type type() const
Definition exprtk.hpp:14494
expression_node< T > * expression_ptr
Definition exprtk.hpp:14431
bool operator<(const function_N_node< T, IFunction, N > &fn) const
Definition exprtk.hpp:14472
std::vector< expression_ptr > arg_list_
Definition exprtk.hpp:15084
std::vector< range_data_type_t > range_list_t
Definition exprtk.hpp:14874
range_interface< T > range_interface_t
Definition exprtk.hpp:14864
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:14868
std::vector< type_store_t > typestore_list_t
Definition exprtk.hpp:14873
std::vector< vecview_t > vv_list_
Definition exprtk.hpp:15086
range_data_type< T > range_data_type_t
Definition exprtk.hpp:14865
std::vector< branch_t > branch_
Definition exprtk.hpp:15085
virtual bool populate_value_list() const
Definition exprtk.hpp:15032
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:14895
bool operator<(const generic_function_node< T, GenericFunction > &fn) const
Definition exprtk.hpp:15003
range_interface< T >::range_t range_t
Definition exprtk.hpp:14866
std::vector< std::size_t > range_param_list_
Definition exprtk.hpp:15089
expression_node< T > * expression_ptr
Definition exprtk.hpp:14859
expression_node< T >::node_type type() const
Definition exprtk.hpp:15020
generic_function_node(const std::vector< expression_ptr > &arg_list, GenericFunction *func=reinterpret_cast< GenericFunction * >(0))
Definition exprtk.hpp:14876
range_interface< T >::range_t range_t
Definition exprtk.hpp:10355
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:10359
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:10461
generic_string_range_node(expression_ptr str_branch, const range_t &brange)
Definition exprtk.hpp:10361
expression_node< T >::node_type type() const
Definition exprtk.hpp:10451
ipow_node(const ipow_node< T, PowOp > &)
ipow_node< T, PowOp > & operator=(const ipow_node< T, PowOp > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:18719
expression_node< T >::node_type type() const
Definition exprtk.hpp:18731
ipowinv_node(const ipowinv_node< T, PowOp > &)
ipowinv_node< T, PowOp > & operator=(const ipowinv_node< T, PowOp > &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:18809
expression_node< T > * expression_ptr
Definition exprtk.hpp:18797
virtual const T & ref() const =0
expression_node< T >::node_type type() const
Definition exprtk.hpp:6726
literal_node(const literal_node< T > &)
literal_node< T > & operator=(const literal_node< T > &)
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:6731
expression_node< T >::node_type type() const
Definition exprtk.hpp:8210
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:8163
std::size_t node_depth() const
Definition exprtk.hpp:8225
multi_switch_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition exprtk.hpp:8167
expression_node< T > * expression_ptr
Definition exprtk.hpp:8162
std::vector< branch_t > arg_list_
Definition exprtk.hpp:8232
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:8220
generic_function_node< T, GenericFunction > gen_function_t
Definition exprtk.hpp:15188
multimode_genfunction_node(GenericFunction *func, const std::size_t &param_seq_index, const std::vector< typename gen_function_t::expression_ptr > &arg_list)
Definition exprtk.hpp:15191
expression_node< T >::node_type type() const
Definition exprtk.hpp:15217
expression_node< T >::node_type type() const
Definition exprtk.hpp:15266
multimode_strfunction_node(StringFunction *func, const std::size_t &param_seq_index, const std::vector< typename str_function_t::expression_ptr > &arg_list)
Definition exprtk.hpp:15236
string_function_node< T, StringFunction > str_function_t
Definition exprtk.hpp:15233
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10) const
Definition exprtk.hpp:19306
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3) const
Definition exprtk.hpp:19320
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[1])
Definition exprtk.hpp:19014
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4) const
Definition exprtk.hpp:19331
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[6])
Definition exprtk.hpp:19059
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[5])
Definition exprtk.hpp:19050
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[4])
Definition exprtk.hpp:19041
expression_node< typename node_type::value_type > * allocate_tt(T1 t1, T2 t2) const
Definition exprtk.hpp:19145
expression_node< typename node_type::value_type > * allocate(const Sequence< Type, Allocator > &seq) const
Definition exprtk.hpp:19077
expression_node< typename node_type::value_type > * allocate_c(const T1 &t1) const
Definition exprtk.hpp:19095
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) const
Definition exprtk.hpp:19217
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[3])
Definition exprtk.hpp:19032
expression_node< typename node_type::value_type > * allocate_rrrr(T1 &t1, T2 &t2, T3 &t3, T4 &t4) const
Definition exprtk.hpp:19185
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[2])
Definition exprtk.hpp:19023
expression_node< typename node_type::value_type > * allocate_rr(T1 &t1, T2 &t2) const
Definition exprtk.hpp:19135
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9) const
Definition exprtk.hpp:19288
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7) const
Definition exprtk.hpp:19256
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) const
Definition exprtk.hpp:19344
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8) const
Definition exprtk.hpp:19272
expression_node< typename node_type::value_type > * allocate_cr(const T1 &t1, T2 &t2) const
Definition exprtk.hpp:19115
expression_node< typename node_type::value_type > * allocate(T1 &t1) const
Definition exprtk.hpp:19086
expression_node< typename node_type::value_type > * allocate_rc(T1 &t1, const T2 &t2) const
Definition exprtk.hpp:19125
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5) const
Definition exprtk.hpp:19229
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) const
Definition exprtk.hpp:19372
expression_node< typename node_type::value_type > * allocate_ttt(T1 t1, T2 t2, T3 t3) const
Definition exprtk.hpp:19155
expression_node< typename node_type::value_type > * allocate_rrrrr(T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5) const
Definition exprtk.hpp:19195
void free(expression_node< T > *&e) const
Definition exprtk.hpp:19384
expression_node< typename node_type::value_type > * allocate() const
Definition exprtk.hpp:19068
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3) const
Definition exprtk.hpp:19205
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6) const
Definition exprtk.hpp:19242
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) const
Definition exprtk.hpp:19358
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2) const
Definition exprtk.hpp:19105
expression_node< typename node_type::value_type > * allocate_rrr(T1 &t1, T2 &t2, T3 &t3) const
Definition exprtk.hpp:19175
expression_node< typename node_type::value_type > * allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
Definition exprtk.hpp:19165
static void collect_nodes(node_ptr_t &root, noderef_list_t &node_delete_list)
Definition exprtk.hpp:5942
static void delete_nodes(node_ptr_t &root)
Definition exprtk.hpp:5924
node_collector_interface< Node > nci_t
Definition exprtk.hpp:5918
null_eq_node(expression_ptr branch, const bool equality=true)
Definition exprtk.hpp:6663
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:6696
expression_node< T > * expression_ptr
Definition exprtk.hpp:6660
expression_node< T >::node_type type() const
Definition exprtk.hpp:6681
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:6661
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:6686
std::size_t node_depth() const
Definition exprtk.hpp:6701
virtual T operator()(parameter_list_t)
Definition exprtk.hpp:15290
generic_type::parameter_list parameter_list_t
Definition exprtk.hpp:15288
expression_node< T >::node_type type() const
Definition exprtk.hpp:6604
expression_node< T > * expression_ptr
Definition exprtk.hpp:7113
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7136
quaternary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3)
Definition exprtk.hpp:7116
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7114
std::size_t node_depth() const
Definition exprtk.hpp:7141
expression_node< T >::node_type type() const
Definition exprtk.hpp:7131
virtual const range_t & range_ref() const =0
virtual range_t & range_ref()=0
expression_node< T > * expression_ptr
Definition exprtk.hpp:9090
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9139
rebasevector_celem_node(expression_ptr vec_node, const std::size_t index, vector_holder_ptr vec_holder)
Definition exprtk.hpp:9095
expression_node< T >::node_type type() const
Definition exprtk.hpp:9121
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:9093
rebasevector_celem_rtc_node(expression_ptr vec_node, const std::size_t index, vector_holder_ptr vec_holder, vector_access_runtime_check_ptr vec_rt_chk)
Definition exprtk.hpp:9270
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:9268
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9316
expression_node< T >::node_type type() const
Definition exprtk.hpp:9298
vector_access_runtime_check_ptr vec_rt_chk_
Definition exprtk.hpp:9354
rebasevector_elem_node(expression_ptr vec_node, expression_ptr index, vector_holder_ptr vec_holder)
Definition exprtk.hpp:9013
expression_node< T >::node_type type() const
Definition exprtk.hpp:9038
expression_node< T > * expression_ptr
Definition exprtk.hpp:9007
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9058
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:9011
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9215
expression_node< T >::node_type type() const
Definition exprtk.hpp:9195
rebasevector_elem_rtc_node(expression_ptr vec_node, expression_ptr index, vector_holder_ptr vec_holder, vector_access_runtime_check_ptr vec_rt_chk)
Definition exprtk.hpp:9168
vector_access_runtime_check_ptr vec_rt_chk_
Definition exprtk.hpp:9255
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:9166
repeat_until_loop_node< T > parent_t
Definition exprtk.hpp:7836
repeat_until_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
Definition exprtk.hpp:7839
repeat_until_loop_bc_node< T > parent_t
Definition exprtk.hpp:7876
repeat_until_loop_bc_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition exprtk.hpp:7879
expression_node< T >::node_type type() const
Definition exprtk.hpp:7534
repeat_until_loop_node(expression_ptr condition, expression_ptr loop_body)
Definition exprtk.hpp:7513
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7511
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7546
expression_node< T > * expression_ptr
Definition exprtk.hpp:7510
repeat_until_loop_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition exprtk.hpp:7573
repeat_until_loop_node< T > parent_t
Definition exprtk.hpp:7570
expression_node< T > * expression_ptr
Definition exprtk.hpp:15350
results_context< T > results_context_t
Definition exprtk.hpp:15351
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:15352
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:15394
return_envelope_node(expression_ptr body, results_context_t &rc)
Definition exprtk.hpp:15354
expression_node< T >::node_type type() const
Definition exprtk.hpp:15379
results_context< T > results_context_t
Definition exprtk.hpp:15302
results_context_t * results_context_
Definition exprtk.hpp:15342
null_igenfunc< T > igeneric_function_t
Definition exprtk.hpp:15303
generic_function_node< T, igeneric_function_t > gen_function_t
Definition exprtk.hpp:15305
expression_node< T >::node_type type() const
Definition exprtk.hpp:15330
igeneric_function_t * igeneric_function_ptr
Definition exprtk.hpp:15304
return_node(const std::vector< typename gen_function_t::expression_ptr > &arg_list, results_context_t &rc)
Definition exprtk.hpp:15307
scand_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:14379
expression_node< T > * expression_ptr
Definition exprtk.hpp:14376
scor_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:14406
expression_node< T > * expression_ptr
Definition exprtk.hpp:14403
sf3_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2)
Definition exprtk.hpp:11999
expression_node< T > * expression_ptr
Definition exprtk.hpp:11997
sf3_var_node(const sf3_var_node< T, SpecialFunction > &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:12060
sf3_var_node(const T &v0, const T &v1, const T &v2)
Definition exprtk.hpp:12049
sf3_var_node< T, SpecialFunction > & operator=(const sf3_var_node< T, SpecialFunction > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:12047
expression_node< T > * expression_ptr
Definition exprtk.hpp:12021
sf4_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3)
Definition exprtk.hpp:12023
expression_node< T > * expression_ptr
Definition exprtk.hpp:12080
sf4_var_node< T, SpecialFunction > & operator=(const sf4_var_node< T, SpecialFunction > &)
sf4_var_node(const T &v0, const T &v1, const T &v2, const T &v3)
Definition exprtk.hpp:12082
expression_node< T >::node_type type() const
Definition exprtk.hpp:12094
sf4_var_node(const sf4_var_node< T, SpecialFunction > &)
virtual operator_type operation() const
Definition exprtk.hpp:16772
sos_node(const sos_node< T, SType0, SType1, Operation > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:18284
expression_node< T >::node_type type() const
Definition exprtk.hpp:18298
sos_node(SType0 p0, SType1 p1)
Definition exprtk.hpp:18288
operator_type operation() const
Definition exprtk.hpp:18303
sos_node< T, SType0, SType1, Operation > & operator=(const sos_node< T, SType0, SType1, Operation > &)
virtual operator_type operation() const
Definition exprtk.hpp:16786
node_type & operator=(const node_type &)
sosos_node(SType0 p0, SType1 p1, SType2 p2)
Definition exprtk.hpp:18665
sosos_node< T, SType0, SType1, SType2, Operation > node_type
Definition exprtk.hpp:18662
expression_node< T > * expression_ptr
Definition exprtk.hpp:18660
operator_type operation() const
Definition exprtk.hpp:18681
expression_node< T >::node_type type() const
Definition exprtk.hpp:18676
sosos_node(const node_type &)
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:18547
str_sogens_node< T, Operation > & operator=(const str_sogens_node< T, Operation > &)
str_sogens_node(const str_sogens_node< T, Operation > &)
str_sogens_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:18555
expression_node< T > * expression_ptr
Definition exprtk.hpp:18546
expression_node< T >::node_type type() const
Definition exprtk.hpp:18633
range_interface< T > irange_t
Definition exprtk.hpp:18550
std::vector< branch_t > arg_list_
Definition exprtk.hpp:11666
str_vararg_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition exprtk.hpp:11550
const range_t & range_ref() const
Definition exprtk.hpp:11630
std::size_t node_depth() const
Definition exprtk.hpp:11653
range_interface< T >::range_t range_t
Definition exprtk.hpp:11540
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:11545
expression_node< T >::node_type type() const
Definition exprtk.hpp:11635
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:11647
expression_node< T > * expression_ptr
Definition exprtk.hpp:11544
range_interface< T > irange_t
Definition exprtk.hpp:11542
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:11546
str_xoxr_node< T, SType0, SType1, RangePack, Operation > node_type
Definition exprtk.hpp:18400
str_xoxr_node(const node_type &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:18431
node_type & operator=(const node_type &)
str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
Definition exprtk.hpp:18403
expression_node< T > * expression_ptr
Definition exprtk.hpp:18398
operator_type operation() const
Definition exprtk.hpp:18436
str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
Definition exprtk.hpp:18339
str_xrox_node(const node_type &)
operator_type operation() const
Definition exprtk.hpp:18366
node_type & operator=(const node_type &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:18361
expression_node< T > * expression_ptr
Definition exprtk.hpp:18334
str_xrox_node< T, SType0, SType1, RangePack, Operation > node_type
Definition exprtk.hpp:18336
str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
Definition exprtk.hpp:18473
expression_node< T > * expression_ptr
Definition exprtk.hpp:18468
expression_node< T >::node_type type() const
Definition exprtk.hpp:18508
str_xroxr_node< T, SType0, SType1, RangePack, Operation > node_type
Definition exprtk.hpp:18470
str_xroxr_node(const node_type &)
operator_type operation() const
Definition exprtk.hpp:18513
node_type & operator=(const node_type &)
virtual std::string str() const =0
virtual char_cptr base() const =0
range_data_type< T > range_data_type_t
Definition exprtk.hpp:6771
virtual std::size_t size() const =0
range_interface< T >::range_t range_t
Definition exprtk.hpp:10490
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:10495
expression_node< T >::node_type type() const
Definition exprtk.hpp:10606
string_concat_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:10499
const range_t & range_ref() const
Definition exprtk.hpp:10601
expression_node< T > * expression_ptr
Definition exprtk.hpp:10494
string_function_node(StringFunction *func, const std::vector< typename gen_function_t::expression_ptr > &arg_list)
Definition exprtk.hpp:15103
bool operator<(const string_function_node< T, StringFunction > &fn) const
Definition exprtk.hpp:15114
const range_t & range_ref() const
Definition exprtk.hpp:15171
range_interface< T >::range_t range_t
Definition exprtk.hpp:15101
generic_function_node< T, StringFunction > gen_function_t
Definition exprtk.hpp:15100
expression_node< T >::node_type type() const
Definition exprtk.hpp:15141
string_literal_node(const std::string &v)
Definition exprtk.hpp:6793
const range_t & range_ref() const
Definition exprtk.hpp:6837
string_literal_node< T > & operator=(const string_literal_node< T > &)
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:6812
string_literal_node(const string_literal_node< T > &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:6807
virtual std::string & ref()
Definition exprtk.hpp:10241
range_interface< T >::range_t range_t
Definition exprtk.hpp:10197
expression_node< T >::node_type type() const
Definition exprtk.hpp:10261
const range_t & range_ref() const
Definition exprtk.hpp:10256
virtual const std::string & ref() const
Definition exprtk.hpp:10246
string_range_node(std::string &v, const range_t &rp)
Definition exprtk.hpp:10201
bool operator<(const string_range_node< T > &v) const
Definition exprtk.hpp:10211
expression_node< T > * expression_ptr
Definition exprtk.hpp:10915
std::size_t node_depth() const
Definition exprtk.hpp:10953
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:10917
expression_node< T >::node_type type() const
Definition exprtk.hpp:10938
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:10948
string_size_node(expression_ptr branch)
Definition exprtk.hpp:10919
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:10916
bool operator<(const stringvar_node< T > &v) const
Definition exprtk.hpp:10118
const range_t & range_ref() const
Definition exprtk.hpp:10161
const std::string & ref() const
Definition exprtk.hpp:10151
void rebase(std::string &s)
Definition exprtk.hpp:10171
expression_node< T >::node_type type() const
Definition exprtk.hpp:10166
range_interface< T >::range_t range_t
Definition exprtk.hpp:10101
static std::string null_value
Definition exprtk.hpp:10103
static const std::string null_value
Definition exprtk.hpp:10882
expression_node< T >::node_type type() const
Definition exprtk.hpp:10897
swap_generic_node(expression_ptr var0, expression_ptr var1)
Definition exprtk.hpp:9949
expression_node< T > * expression_ptr
Definition exprtk.hpp:9946
expression_node< T >::node_type type() const
Definition exprtk.hpp:9961
swap_genstrings_node< T > & operator=(const swap_genstrings_node< T > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:10726
expression_node< T >::node_type type() const
Definition exprtk.hpp:10855
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:10727
swap_genstrings_node(const swap_genstrings_node< T > &)
swap_genstrings_node(expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:10731
range_interface< T >::range_t range_t
Definition exprtk.hpp:10722
swap_node(variable_node_ptr var0, variable_node_ptr var1)
Definition exprtk.hpp:9919
expression_node< T >::node_type type() const
Definition exprtk.hpp:9930
variable_node< T > * variable_node_ptr
Definition exprtk.hpp:9917
variable_node_ptr var0_
Definition exprtk.hpp:9937
variable_node_ptr var1_
Definition exprtk.hpp:9938
expression_node< T > * expression_ptr
Definition exprtk.hpp:9916
range_interface< T >::range_t range_t
Definition exprtk.hpp:10635
swap_string_node(expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:10645
const range_t & range_ref() const
Definition exprtk.hpp:10695
expression_node< T > * expression_ptr
Definition exprtk.hpp:10639
stringvar_node< T > * strvar_node_ptr
Definition exprtk.hpp:10640
expression_node< T >::node_type type() const
Definition exprtk.hpp:10700
string_base_node< T > * str_base_ptr
Definition exprtk.hpp:10641
range_interface< T > irange_t
Definition exprtk.hpp:10637
const vds_t & vds() const
Definition exprtk.hpp:10079
expression_node< T >::node_type type() const
Definition exprtk.hpp:10050
vector_node_ptr vec() const
Definition exprtk.hpp:10040
swap_vecvec_node(expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:9985
vector_node< T > * vector_node_ptr
Definition exprtk.hpp:9980
std::size_t base_size() const
Definition exprtk.hpp:10067
vector_node< T > * vec0_node_ptr_
Definition exprtk.hpp:10086
expression_node< T > * expression_ptr
Definition exprtk.hpp:9979
vector_node< T > * vec1_node_ptr_
Definition exprtk.hpp:10087
expression_node< T > * expression_ptr
Definition exprtk.hpp:8143
switch_n_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition exprtk.hpp:8147
std::size_t node_depth() const
Definition exprtk.hpp:8128
expression_node< T > * expression_ptr
Definition exprtk.hpp:8067
switch_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition exprtk.hpp:8072
std::vector< branch_t > arg_list_
Definition exprtk.hpp:8135
expression_node< T >::node_type type() const
Definition exprtk.hpp:8113
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:8123
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:8068
expression_node< T > * expression_ptr
Definition exprtk.hpp:7044
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7092
trinary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2)
Definition exprtk.hpp:7047
std::size_t node_depth() const
Definition exprtk.hpp:7097
expression_node< T >::node_type type() const
Definition exprtk.hpp:7079
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7045
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:16928
unary_branch_node(const unary_branch_node< T, Operation > &)
unary_branch_node< T, Operation > & operator=(const unary_branch_node< T, Operation > &)
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:16965
expression_node< T > * expression_ptr
Definition exprtk.hpp:16927
unary_branch_node(expression_ptr branch)
Definition exprtk.hpp:16930
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:16955
expression_node< T >::node_type type() const
Definition exprtk.hpp:16940
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:6883
std::size_t node_depth() const
Definition exprtk.hpp:6903
unary_node(const operator_type &opr, expression_ptr branch)
Definition exprtk.hpp:6860
expression_node< T > * expression_ptr
Definition exprtk.hpp:6857
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:6898
expression_node< T >::node_type type() const
Definition exprtk.hpp:6873
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:6858
operator_type operation()
Definition exprtk.hpp:6878
expression_node< T >::node_type type() const
Definition exprtk.hpp:16831
unary_variable_node< T, Operation > & operator=(const unary_variable_node< T, Operation > &)
expression_node< T > * expression_ptr
Definition exprtk.hpp:16819
unary_variable_node(const unary_variable_node< T, Operation > &)
operator_type operation() const
Definition exprtk.hpp:16836
unary_vector_node(const operator_type &opr, expression_ptr branch0)
Definition exprtk.hpp:14053
memory_context_t< T > memory_context
Definition exprtk.hpp:14049
expression_node< T > * expression_ptr
Definition exprtk.hpp:14044
vector_holder_t * vector_holder_ptr
Definition exprtk.hpp:14047
vector_holder< T > vector_holder_t
Definition exprtk.hpp:14046
expression_node< T >::node_type type() const
Definition exprtk.hpp:14159
vector_node_ptr vec() const
Definition exprtk.hpp:14149
vector_node< T > * vector_node_ptr
Definition exprtk.hpp:14045
virtual operator_type operation() const
Definition exprtk.hpp:16756
virtual const T & v() const =0
uvouv_node< T > & operator=(const uvouv_node< T > &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:16879
uvouv_node(const uvouv_node< T > &)
uvouv_node(const T &var0, const T &var1, ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
Definition exprtk.hpp:16865
functor_t::ufunc_t ufunc_t
Definition exprtk.hpp:16862
functor_t::bfunc_t bfunc_t
Definition exprtk.hpp:16861
details::functor_t< T > functor_t
Definition exprtk.hpp:16860
expression_node< T > * expression_ptr
Definition exprtk.hpp:16863
bool operator<(const vararg_function_node< T, VarArgFunction > &fn) const
Definition exprtk.hpp:14801
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:14822
expression_node< T >::node_type type() const
Definition exprtk.hpp:14812
vararg_function_node(VarArgFunction *func, const std::vector< expression_ptr > &arg_list)
Definition exprtk.hpp:14792
std::vector< expression_ptr > arg_list_
Definition exprtk.hpp:14849
expression_node< T > * expression_ptr
Definition exprtk.hpp:14790
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:12116
std::vector< branch_t > arg_list_
Definition exprtk.hpp:12179
expression_node< T >::node_type type() const
Definition exprtk.hpp:12147
vararg_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition exprtk.hpp:12120
std::size_t node_depth() const
Definition exprtk.hpp:12162
expression_ptr operator[](const std::size_t &index) const
Definition exprtk.hpp:12172
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:12157
std::size_t size() const
Definition exprtk.hpp:12167
expression_node< T > * expression_ptr
Definition exprtk.hpp:12115
expression_node< T >::node_type type() const
Definition exprtk.hpp:12220
std::vector< const T * > arg_list_
Definition exprtk.hpp:12232
expression_node< T > * expression_ptr
Definition exprtk.hpp:12188
vararg_varnode(const Sequence< expression_ptr, Allocator > &arg_list)
Definition exprtk.hpp:12192
bool operator<(const variable_node< T > &v) const
Definition exprtk.hpp:8264
expression_node< T >::node_type type() const
Definition exprtk.hpp:8284
expression_node< T >::node_type type() const
Definition exprtk.hpp:13996
vec_binop_valvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13888
memory_context_t< T > memory_context
Definition exprtk.hpp:13884
expression_node< T > * expression_ptr
Definition exprtk.hpp:13879
memory_context_t< T > memory_context
Definition exprtk.hpp:13720
expression_node< T >::node_type type() const
Definition exprtk.hpp:13832
expression_node< T > * expression_ptr
Definition exprtk.hpp:13715
vec_binop_vecval_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13724
vec_binop_vecvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition exprtk.hpp:13521
expression_node< T >::node_type type() const
Definition exprtk.hpp:13665
expression_node< T > * expression_ptr
Definition exprtk.hpp:13512
memory_context_t< T > memory_context
Definition exprtk.hpp:13517
type & operator=(const type &vds)
Definition exprtk.hpp:5286
vec_data_store(const std::size_t &size)
Definition exprtk.hpp:5267
vec_data_store(const std::size_t &size, data_t data, bool dstrct=false)
Definition exprtk.hpp:5271
vec_data_store(const type &vds)
Definition exprtk.hpp:5275
static std::size_t min_size(const control_block *cb0, const control_block *cb1)
Definition exprtk.hpp:5355
std::size_t size() const
Definition exprtk.hpp:5317
static void match_sizes(type &vds0, type &vds1)
Definition exprtk.hpp:5346
vec_data_store< T > type
Definition exprtk.hpp:5175
vector_holder_t * vector_holder_ptr
Definition exprtk.hpp:8722
expression_node< T > * expression_ptr
Definition exprtk.hpp:8720
std::size_t node_depth() const
Definition exprtk.hpp:8774
vector_holder_t & vec_holder()
Definition exprtk.hpp:8764
expression_node< T >::node_type type() const
Definition exprtk.hpp:8751
vector_holder< T > vector_holder_t
Definition exprtk.hpp:8721
vector_celem_node(expression_ptr vec_node, const std::size_t index, vector_holder_ptr vec_holder)
Definition exprtk.hpp:8725
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:8723
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:8769
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:8958
vector_celem_rtc_node(expression_ptr vec_node, const std::size_t index, vector_holder_ptr vec_holder, vector_access_runtime_check_ptr vec_rt_chk)
Definition exprtk.hpp:8911
expression_node< T >::node_type type() const
Definition exprtk.hpp:8940
expression_node< T > * expression_ptr
Definition exprtk.hpp:8906
vector_access_runtime_check_ptr vec_rt_chk_
Definition exprtk.hpp:8997
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:8909
vector_elem_node(expression_ptr vec_node, expression_ptr index, vector_holder_ptr vec_holder)
Definition exprtk.hpp:8641
vector_holder_t * vector_holder_ptr
Definition exprtk.hpp:8638
vector_holder_ptr vector_holder_
Definition exprtk.hpp:8707
vector_holder< T > vector_holder_t
Definition exprtk.hpp:8637
std::size_t node_depth() const
Definition exprtk.hpp:8693
vector_holder_t & vec_holder()
Definition exprtk.hpp:8682
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:8687
expression_node< T >::node_type type() const
Definition exprtk.hpp:8667
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:8639
expression_node< T > * expression_ptr
Definition exprtk.hpp:8636
vector_access_runtime_check_ptr vec_rt_chk_
Definition exprtk.hpp:8895
expression_node< T >::node_type type() const
Definition exprtk.hpp:8834
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:8854
expression_node< T > * expression_ptr
Definition exprtk.hpp:8800
vector_elem_rtc_node(expression_ptr vec_node, expression_ptr index, vector_holder_ptr vec_holder, vector_access_runtime_check_ptr vec_rt_chk)
Definition exprtk.hpp:8805
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:8803
array_vector_impl & operator=(const array_vector_impl &)
array_vector_impl(const Type *vec, const std::size_t &vec_size)
Definition exprtk.hpp:6330
value_ptr value_at(const std::size_t &index) const
Definition exprtk.hpp:6337
value_ptr value_at(const std::size_t &index) const
Definition exprtk.hpp:6478
resizable_vector_impl(const resizable_vector_impl &)
resizable_vector_impl & operator=(const resizable_vector_impl &)
virtual vector_view< Type > * rebaseable_instance()
Definition exprtk.hpp:6499
resizable_vector_impl(vector_holder &vec_view_holder, const Type *vec, const std::size_t &vec_size)
Definition exprtk.hpp:6462
sequence_vector_impl(const sequence_vector_impl &)
sequence_vector_impl & operator=(const sequence_vector_impl &)
value_ptr value_at(const std::size_t &index) const
Definition exprtk.hpp:6376
virtual std::size_t vector_size() const =0
virtual std::size_t vector_base_size() const =0
virtual vector_view< Type > * rebaseable_instance()
Definition exprtk.hpp:6314
value_ptr operator[](const std::size_t &index) const
Definition exprtk.hpp:6283
virtual value_ptr value_at(const std::size_t &) const =0
value_ptr value_at(const std::size_t &index) const
Definition exprtk.hpp:6434
vector_view_impl & operator=(const vector_view_impl &)
exprtk::vector_view< Type > vector_view_t
Definition exprtk.hpp:6404
vector_holder_base * vector_holder_base_
Definition exprtk.hpp:6590
std::size_t base_size() const
Definition exprtk.hpp:6549
vector_holder(const vector_holder< Type > &)
vector_holder(Type *vec, const std::size_t &vec_size)
Definition exprtk.hpp:6518
void remove_ref(value_ptr *ref)
Definition exprtk.hpp:6567
vector_holder< Type > & operator=(const vector_holder< Type > &)
vector_holder(std::vector< Type, Allocator > &vec)
Definition exprtk.hpp:6527
const value_ptr const_value_ptr
Definition exprtk.hpp:6273
details::vec_data_store< Type > vds_t
Definition exprtk.hpp:6516
vector_holder(exprtk::vector_view< Type > &vec)
Definition exprtk.hpp:6531
std::size_t size() const
Definition exprtk.hpp:6544
vector_holder(const vds_t &vds)
Definition exprtk.hpp:6522
vector_holder(vector_holder_t &vec_holder, const vds_t &vds)
Definition exprtk.hpp:6535
vector_view< Type > * rebaseable_instance()
Definition exprtk.hpp:6580
vector_holder< Type > vector_holder_t
Definition exprtk.hpp:6274
value_ptr operator[](const std::size_t &index) const
Definition exprtk.hpp:6539
void set_ref(value_ptr *ref)
Definition exprtk.hpp:6559
vector_init_iota_constconst_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list)
Definition exprtk.hpp:9660
vector_init_iota_constconst_node< T > & operator=(const vector_init_iota_constconst_node< T > &)
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9715
expression_node< T >::node_type type() const
Definition exprtk.hpp:9685
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9698
vector_init_iota_constconst_node(const vector_init_iota_constconst_node< T > &)
vector_init_iota_constnconst_node(const vector_init_iota_constnconst_node< T > &)
vector_init_iota_constnconst_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list)
Definition exprtk.hpp:9727
vector_init_iota_constnconst_node< T > & operator=(const vector_init_iota_constnconst_node< T > &)
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9764
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9781
expression_node< T >::node_type type() const
Definition exprtk.hpp:9751
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9845
vector_init_iota_nconstconst_node< T > & operator=(const vector_init_iota_nconstconst_node< T > &)
vector_init_iota_nconstconst_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list)
Definition exprtk.hpp:9792
expression_node< T >::node_type type() const
Definition exprtk.hpp:9815
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9828
vector_init_iota_nconstconst_node(const vector_init_iota_nconstconst_node< T > &)
vector_init_iota_nconstnconst_node(const vector_init_iota_nconstnconst_node< T > &)
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9891
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9908
expression_node< T >::node_type type() const
Definition exprtk.hpp:9878
vector_init_iota_nconstnconst_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list)
Definition exprtk.hpp:9855
vector_init_iota_nconstnconst_node< T > & operator=(const vector_init_iota_nconstnconst_node< T > &)
vector_init_single_constvalue_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list)
Definition exprtk.hpp:9537
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9588
expression_node< T >::node_type type() const
Definition exprtk.hpp:9558
vector_init_single_constvalue_node< T > & operator=(const vector_init_single_constvalue_node< T > &)
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9571
vector_init_single_constvalue_node(const vector_init_single_constvalue_node< T > &)
vector_init_single_value_node< T > & operator=(const vector_init_single_value_node< T > &)
vector_init_single_value_node(const vector_init_single_value_node< T > &)
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9650
vector_init_single_value_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list)
Definition exprtk.hpp:9599
expression_node< T >::node_type type() const
Definition exprtk.hpp:9621
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9633
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9510
vector_init_zero_value_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list)
Definition exprtk.hpp:9486
vector_init_zero_value_node< T > & operator=(const vector_init_zero_value_node< T > &)
expression_node< T >::node_type type() const
Definition exprtk.hpp:9500
vector_init_zero_value_node(const vector_init_zero_value_node< T > &)
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9527
vector_initialisation_node< T > & operator=(const vector_initialisation_node< T > &)
vector_initialisation_node(const vector_initialisation_node< T > &)
vector_initialisation_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list, const bool single_value_initialse)
Definition exprtk.hpp:9364
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:9455
expression_node< T >::node_type type() const
Definition exprtk.hpp:9445
std::vector< expression_ptr > initialiser_list_
Definition exprtk.hpp:9471
virtual vector_node_ptr vec() const =0
virtual bool side_effect() const
Definition exprtk.hpp:8491
vector_node< T > * vector_node_ptr
Definition exprtk.hpp:8473
virtual vector_node_ptr vec()=0
virtual std::size_t size() const =0
virtual const vds_t & vds() const =0
virtual std::size_t base_size() const =0
vector_node(const vds_t &vds, vector_holder_t *vh)
Definition exprtk.hpp:8513
vector_holder_t & vec_holder() const
Definition exprtk.hpp:8574
vector_node_ptr vec() const
Definition exprtk.hpp:8529
vec_data_store< T > vds_t
Definition exprtk.hpp:8504
vector_holder_t * vector_holder_
Definition exprtk.hpp:8581
std::size_t base_size() const
Definition exprtk.hpp:8554
vector_node(vector_holder_t *vh)
Definition exprtk.hpp:8506
std::size_t size() const
Definition exprtk.hpp:8549
vector_node< T > * vector_node_ptr
Definition exprtk.hpp:8503
vector_node_ptr vec()
Definition exprtk.hpp:8534
expression_node< T > * expression_ptr
Definition exprtk.hpp:8501
expression_node< T >::node_type type() const
Definition exprtk.hpp:8539
vector_holder_t & vec_holder()
Definition exprtk.hpp:8569
const vds_t & vds() const
Definition exprtk.hpp:8564
vector_holder< T > vector_holder_t
Definition exprtk.hpp:8502
vector_holder< T > vector_holder_t
Definition exprtk.hpp:8592
expression_node< T > * expression_ptr
Definition exprtk.hpp:8591
vector_size_node(vector_holder_t *vh)
Definition exprtk.hpp:8594
vector_holder_t * vector_holder_
Definition exprtk.hpp:8626
vector_holder_t * vec_holder()
Definition exprtk.hpp:8619
expression_node< T >::node_type type() const
Definition exprtk.hpp:8609
expression_node< T > * expression_ptr
Definition exprtk.hpp:12241
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:12242
vector_interface< T > * ivec_ptr_
Definition exprtk.hpp:12283
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:12271
std::size_t node_depth() const
Definition exprtk.hpp:12276
vectorize_node(const expression_ptr v)
Definition exprtk.hpp:12244
expression_node< T >::node_type type() const
Definition exprtk.hpp:12261
virtual const T & v() const =0
vob_node< T, Operation > & operator=(const vob_node< T, Operation > &)
const T & v() const
Definition exprtk.hpp:18044
expression_node< T > * expression_ptr
Definition exprtk.hpp:18027
vob_node(const T &var, const expression_ptr branch)
Definition exprtk.hpp:18032
expression_node< T > * branch(const std::size_t &) const
Definition exprtk.hpp:18054
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:18028
std::size_t node_depth() const
Definition exprtk.hpp:18064
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:18059
vob_node(const vob_node< T, Operation > &)
virtual const T & v() const =0
virtual const T c() const =0
virtual operator_type operation() const
Definition exprtk.hpp:16676
const T & v() const
Definition exprtk.hpp:18006
expression_node< T > * expression_ptr
Definition exprtk.hpp:17982
voc_node< T, Operation > & operator=(const voc_node< T, Operation > &)
voc_node(const voc_node< T, Operation > &)
voc_node(const T &var, const T &const_var)
Definition exprtk.hpp:17986
operator_type operation() const
Definition exprtk.hpp:17996
virtual const T & v0() const =0
virtual const T & v1() const =0
virtual operator_type operation() const
Definition exprtk.hpp:16640
vov_node(const T &var0, const T &var1)
Definition exprtk.hpp:17886
expression_node< T > * expression_ptr
Definition exprtk.hpp:17882
operator_type operation() const
Definition exprtk.hpp:17901
expression_node< T >::node_type type() const
Definition exprtk.hpp:17896
vov_node(const vov_node< T, Operation > &)
const T & v0() const
Definition exprtk.hpp:17906
vov_node< T, Operation > & operator=(const vov_node< T, Operation > &)
const T & v1() const
Definition exprtk.hpp:17911
while_loop_node< T > parent_t
Definition exprtk.hpp:7748
expression_node< T > * expression_ptr
Definition exprtk.hpp:7749
while_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
Definition exprtk.hpp:7751
while_loop_bc_node< T > parent_t
Definition exprtk.hpp:7787
expression_node< T > * expression_ptr
Definition exprtk.hpp:7788
while_loop_bc_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition exprtk.hpp:7790
std::size_t node_depth() const
Definition exprtk.hpp:7451
std::pair< expression_ptr, bool > branch_t
Definition exprtk.hpp:7411
expression_node< T >::node_type type() const
Definition exprtk.hpp:7433
while_loop_node(expression_ptr condition, expression_ptr loop_body)
Definition exprtk.hpp:7413
expression_node< T > * expression_ptr
Definition exprtk.hpp:7410
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list)
Definition exprtk.hpp:7445
while_loop_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition exprtk.hpp:7472
expression_node< T > * expression_ptr
Definition exprtk.hpp:7470
static bool is_type(const expression< T > &expr, const node_types node_type)
Definition exprtk.hpp:21963
static bool is_assert(const expression< T > &expr)
Definition exprtk.hpp:21948
static bool is_sf4ext(const expression< T > &expr)
Definition exprtk.hpp:21958
static bool is_variable(const expression< T > &expr)
Definition exprtk.hpp:21913
static bool is_binary(const expression< T > &expr)
Definition exprtk.hpp:21928
static bool match_type_sequence(const expression< T > &expr, const std::vector< node_types > &type_seq)
Definition exprtk.hpp:21987
static bool is_literal(const expression< T > &expr)
Definition exprtk.hpp:21908
static bool is_function(const expression< T > &expr)
Definition exprtk.hpp:21933
static bool is_sf3ext(const expression< T > &expr)
Definition exprtk.hpp:21953
static bool is_string(const expression< T > &expr)
Definition exprtk.hpp:21918
static bool is_unary(const expression< T > &expr)
Definition exprtk.hpp:21923
static bool is_vararg(const expression< T > &expr)
Definition exprtk.hpp:21938
static bool is_null(const expression< T > &expr)
Definition exprtk.hpp:21943
const symbol_table< T > & get_symbol_table(const std::size_t &index=0) const
Definition exprtk.hpp:21740
symbol_table< T > & get_symbol_table(const std::size_t &index=0)
Definition exprtk.hpp:21745
std::size_t num_symbol_tables() const
Definition exprtk.hpp:21750
expression< T > & release()
Definition exprtk.hpp:21690
details::vector_holder< T > * vector_holder_ptr
Definition exprtk.hpp:21491
T operator()() const
Definition exprtk.hpp:21711
expression(const expression< T > &e)
Definition exprtk.hpp:21638
void set_expression(const expression_ptr expr)
Definition exprtk.hpp:21780
bool register_symbol_table(symbol_table< T > &st)
Definition exprtk.hpp:21726
void register_local_var(expression_ptr expr)
Definition exprtk.hpp:21796
bool operator!() const
Definition exprtk.hpp:21682
bool operator==(const expression< T > &e) const
Definition exprtk.hpp:21677
const results_context_t & results() const
Definition exprtk.hpp:21757
expression(const symbol_table< T > &symbol_table)
Definition exprtk.hpp:21645
symtab_list_t get_symbol_table_list() const
Definition exprtk.hpp:21775
std::vector< symbol_table< T > > symtab_list_t
Definition exprtk.hpp:21492
void register_local_var(vector_holder_ptr vec_holder)
Definition exprtk.hpp:21811
bool return_invoked() const
Definition exprtk.hpp:21768
friend bool is_valid(const expression< TT > &expr)
results_context< T > results_context_t
Definition exprtk.hpp:21755
const control_block::local_data_list_t & local_data_list()
Definition exprtk.hpp:21849
void set_retinvk(bool *retinvk_ptr)
Definition exprtk.hpp:21870
expression< T > & operator=(const expression< T > &e)
Definition exprtk.hpp:21652
void register_local_data(void *data, const std::size_t &size=0, const std::size_t data_mode=0)
Definition exprtk.hpp:21826
symtab_list_t symbol_table_list_
Definition exprtk.hpp:21879
control_block * control_block_
Definition exprtk.hpp:21878
void register_return_results(results_context_t *rc)
Definition exprtk.hpp:21862
details::expression_node< T > * expression_ptr
Definition exprtk.hpp:21490
symbol_table_t & symbol_table()
Definition exprtk.hpp:43093
bool forward(const std::string &name, const std::size_t &arg_count, symbol_table_t &sym_table, const bool ret_present=false)
Definition exprtk.hpp:43352
exprtk::symbol_table< T > symbol_table_t
Definition exprtk.hpp:42438
std::vector< symbol_table_t * > auxiliary_symtab_list_
Definition exprtk.hpp:43407
std::vector< funcparam_t > fp_map_
Definition exprtk.hpp:43406
exprtk::parser< T > parser_t
Definition exprtk.hpp:42439
void register_vector_access_runtime_check(vector_access_runtime_check &vartchk)
Definition exprtk.hpp:43123
void add_auxiliary_symtab(symbol_table_t &symtab)
Definition exprtk.hpp:43103
bool add(const std::string &name, const std::string &expression, const Sequence< std::string, Allocator > &var_list, const bool override=false)
Definition exprtk.hpp:43032
std::string error() const
Definition exprtk.hpp:43177
bool add(const function &f, const bool override=false)
Definition exprtk.hpp:43172
parser_error::type get_error(const std::size_t &index) const
Definition exprtk.hpp:43192
void register_loop_runtime_check(loop_runtime_check &lrtchk)
Definition exprtk.hpp:43118
static T return_value(expression_t &e)
Definition exprtk.hpp:42992
std::map< std::string, expression_t > expr_map_
Definition exprtk.hpp:43405
std::map< std::string, base_func * > funcparam_t
Definition exprtk.hpp:42869
parser_t::settings_store settings_t
Definition exprtk.hpp:42440
std::deque< parser_error::type > error_list_
Definition exprtk.hpp:43408
void load_vectors(const bool load=true)
Definition exprtk.hpp:43113
bool compile_expression(const std::string &name, const std::string &expression, const Sequence< std::string, Allocator > &input_var_list, bool return_present=false)
Definition exprtk.hpp:43206
void remove(const std::string &name, const std::size_t &arg_count)
Definition exprtk.hpp:43378
void load_variables(const bool load=true)
Definition exprtk.hpp:43108
function_compositor(const symbol_table_t &st)
Definition exprtk.hpp:43079
symbol_table_t symbol_table_
Definition exprtk.hpp:43403
exprtk::expression< T > expression_t
Definition exprtk.hpp:42437
std::size_t error_count() const
Definition exprtk.hpp:43187
bool valid(const std::string &name, const std::size_t &arg_count) const
Definition exprtk.hpp:43339
void register_compilation_timeout_check(compilation_check &compchk)
Definition exprtk.hpp:43128
const symbol_table_t & symbol_table() const
Definition exprtk.hpp:43098
bool symbol_used(const std::string &symbol) const
Definition exprtk.hpp:43328
std::size_t & max_num_args()
Definition exprtk.hpp:19483
std::size_t max_num_args_
Definition exprtk.hpp:19493
std::size_t min_num_args_
Definition exprtk.hpp:19492
std::size_t & min_num_args()
Definition exprtk.hpp:19478
std::size_t param_count
Definition exprtk.hpp:19633
virtual T operator()()
Definition exprtk.hpp:19558
virtual ~ifunction()
Definition exprtk.hpp:19549
ifunction(const std::size_t &pc)
Definition exprtk.hpp:19545
generic_type::parameter_list parameter_list_t
Definition exprtk.hpp:19665
std::string parameter_sequence
Definition exprtk.hpp:19699
igeneric_function(const std::string &param_seq="", const return_type rtr_type=e_rtrn_scalar)
Definition exprtk.hpp:19667
virtual T operator()(parameter_list_t)
Definition exprtk.hpp:19682
type_store< T > generic_type
Definition exprtk.hpp:19664
virtual T operator()(const std::vector< T > &)
Definition exprtk.hpp:19644
std::string substr(const std::size_t &begin, const std::size_t &end) const
Definition exprtk.hpp:2535
token_t & operator[](const std::size_t &index)
Definition exprtk.hpp:2496
token_t & peek_next_token()
Definition exprtk.hpp:2486
token_t operator[](const std::size_t &index) const
Definition exprtk.hpp:2506
void insert_front(token_t::token_type tk_type)
Definition exprtk.hpp:2521
bool is_comment_start(details::char_cptr itr) const
Definition exprtk.hpp:2561
token_list_itr_t store_token_itr_
Definition exprtk.hpp:3089
bool process(const std::string &str)
Definition exprtk.hpp:2430
token_list_t::iterator token_list_itr_t
Definition exprtk.hpp:2409
details::char_t char_t
Definition exprtk.hpp:2410
token_list_itr_t token_itr_
Definition exprtk.hpp:3088
bool next_is_digit(const details::char_cptr itr) const
Definition exprtk.hpp:2667
token_list_t token_list_
Definition exprtk.hpp:3087
details::char_cptr base_itr_
Definition exprtk.hpp:3091
details::char_cptr s_itr_
Definition exprtk.hpp:3092
std::size_t size() const
Definition exprtk.hpp:2455
bool is_end(details::char_cptr itr) const
Definition exprtk.hpp:2555
std::vector< token_t > token_list_t
Definition exprtk.hpp:2408
details::char_cptr s_end_
Definition exprtk.hpp:3093
std::string remaining() const
Definition exprtk.hpp:2543
std::stack< std::pair< char, std::size_t > > stack_
Definition exprtk.hpp:3796
bool operator()(const lexer::token &t)
Definition exprtk.hpp:3755
void ignore_symbol(const std::string &symbol)
Definition exprtk.hpp:3487
std::set< std::string, details::ilesscompare > ignore_set_
Definition exprtk.hpp:3536
int insert(const lexer::token &t0, const lexer::token &t1, lexer::token &new_token)
Definition exprtk.hpp:3492
std::vector< std::size_t > error_list_
Definition exprtk.hpp:3861
bool operator()(const lexer::token &t)
Definition exprtk.hpp:3823
std::size_t error_index(const std::size_t &i)
Definition exprtk.hpp:3845
operator_joiner(const std::size_t &stride)
Definition exprtk.hpp:3543
bool join(const lexer::token &t0, const lexer::token &t1, lexer::token &t)
Definition exprtk.hpp:3547
bool join(const lexer::token &t0, const lexer::token &t1, const lexer::token &t2, lexer::token &t)
Definition exprtk.hpp:3692
std::pair< lexer::token, lexer::token > error(const std::size_t index)
Definition exprtk.hpp:4159
std::vector< std::pair< lexer::token, lexer::token > > error_list_
Definition exprtk.hpp:4185
std::pair< token_t, std::pair< token_t, token_t > > token_triplet_t
Definition exprtk.hpp:4108
bool operator()(const lexer::token &t0, const lexer::token &t1, const lexer::token &t2)
Definition exprtk.hpp:4142
void add_invalid(const token_t t0, const token_t t1, const token_t t2)
Definition exprtk.hpp:4179
std::pair< lexer::token, lexer::token > error(const std::size_t index)
Definition exprtk.hpp:3996
void add_invalid(const lexer::token::token_type base, const lexer::token::token_type t)
Definition exprtk.hpp:4016
void add_invalid_set1(const lexer::token::token_type t)
Definition exprtk.hpp:4021
std::vector< std::pair< lexer::token, lexer::token > > error_list_
Definition exprtk.hpp:4100
std::pair< lexer::token::token_type, lexer::token::token_type > token_pair_t
Definition exprtk.hpp:3935
bool operator()(const lexer::token &t0, const lexer::token &t1)
Definition exprtk.hpp:3975
bool invalid_bracket_check(const lexer::token::token_type base, const lexer::token::token_type t)
Definition exprtk.hpp:4040
bool remove(const std::string &target_symbol)
Definition exprtk.hpp:3872
std::map< std::string, std::pair< std::string, token::token_type >, details::ilesscompare > replace_map_t
Definition exprtk.hpp:3868
bool add_replace(const std::string &target_symbol, const std::string &replace_symbol, const lexer::token::token_type token_type=lexer::token::e_symbol)
Definition exprtk.hpp:3884
virtual std::size_t process(generator &)
Definition exprtk.hpp:3108
bool token_is_loop(const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4526
void advance_token(const token_advance_mode mode)
Definition exprtk.hpp:4410
bool token_is_arithmetic_opr(const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4460
bool token_is_left_bracket(const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4496
bool token_is_right_bracket(const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4511
bool token_is_ineq_opr(const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4478
const generator_t & lexer() const
Definition exprtk.hpp:4372
bool token_is(const std::string &value, const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4447
bool peek_token_is(const token_t::token_type &ttype)
Definition exprtk.hpp:4533
const token_t & peek_next_token()
Definition exprtk.hpp:4399
bool peek_token_is(const std::string &s)
Definition exprtk.hpp:4538
bool init(const std::string &str)
Definition exprtk.hpp:4353
bool token_is(const token_t::token_type &ttype, const std::string &value, const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4430
const token_t & current_token() const
Definition exprtk.hpp:4394
bool token_is(const token_t::token_type &ttype, const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4418
virtual int insert(const token &, const token &, const token &, const token &, token &)
Definition exprtk.hpp:3334
virtual int insert(const token &, token &)
Definition exprtk.hpp:3325
virtual int insert(const token &, const token &, const token &, const token &, const token &, token &)
Definition exprtk.hpp:3337
std::size_t process(generator &g)
Definition exprtk.hpp:3251
token_inserter(const std::size_t &stride)
Definition exprtk.hpp:3242
const std::size_t stride_
Definition exprtk.hpp:3344
virtual int insert(const token &, const token &, const token &, token &)
Definition exprtk.hpp:3331
virtual int insert(const token &, const token &, token &)
Definition exprtk.hpp:3328
const std::size_t stride_
Definition exprtk.hpp:3458
virtual bool join(const token &, const token &, token &)
Definition exprtk.hpp:3368
token_joiner(const std::size_t &stride)
Definition exprtk.hpp:3351
std::size_t process(generator &g)
Definition exprtk.hpp:3355
std::size_t process_stride_3(generator &g)
Definition exprtk.hpp:3415
std::size_t process_stride_2(generator &g)
Definition exprtk.hpp:3373
virtual bool join(const token &, const token &, const token &, token &)
Definition exprtk.hpp:3369
std::size_t process(generator &g)
Definition exprtk.hpp:3223
virtual bool modify(token &t)=0
token_scanner(const std::size_t &stride)
Definition exprtk.hpp:3119
virtual bool operator()(const token &)
Definition exprtk.hpp:3194
std::size_t process(generator &g)
Definition exprtk.hpp:3128
const std::size_t stride_
Definition exprtk.hpp:3216
std::pair< std::string, symbol_type > symbol_t
Definition exprtk.hpp:23499
std::vector< std::string > retparam_list_t
Definition exprtk.hpp:23597
void add_assignment(const std::string &symbol, const symbol_type st)
Definition exprtk.hpp:23629
void add_symbol(const std::string &symbol, const symbol_type st)
Definition exprtk.hpp:23606
std::size_t assignment_symbols(Sequence< symbol_t, Allocator > &assignment_list)
Definition exprtk.hpp:23539
retparam_list_t return_param_type_list() const
Definition exprtk.hpp:23599
dependent_entity_collector(const std::size_t options=e_ct_none)
Definition exprtk.hpp:23502
std::size_t symbols(Sequence< symbol_t, Allocator > &symbols_list)
Definition exprtk.hpp:23513
expression_node_ptr repeat_until_loop(expression_node_ptr &condition, expression_node_ptr &branch, const bool break_continue_present=false) const
Definition exprtk.hpp:32508
void lodge_assignment(symbol_type cst, expression_node_ptr node)
Definition exprtk.hpp:33894
bool sf4_optimisable(const std::string &sf4id, quaternary_functor_t &qfunc) const
Definition exprtk.hpp:31524
expression_node_ptr conditional(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition exprtk.hpp:32219
std::string branch_to_id(expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31719
bool coboc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31785
details::expression_node< Type > * expression_node_ptr
Definition exprtk.hpp:31302
bool assign_immutable_symbol(expression_node_ptr node)
Definition exprtk.hpp:33994
bool boc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31760
bool special_one_parameter_vararg(const details::operator_type &operation) const
Definition exprtk.hpp:33240
expression_node_ptr conditional_vector(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition exprtk.hpp:32371
expression_node_ptr const_optimise_varargfunc(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition exprtk.hpp:33209
bool cov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31724
expression_node_ptr generic_function_call(igeneric_function_t *gf, std::vector< expression_node_ptr > &arg_list, const std::size_t &param_seq_index=std::numeric_limits< std::size_t >::max())
Definition exprtk.hpp:33482
expression_node_ptr synthesize_uvec_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition exprtk.hpp:32966
bool is_invalid_string_op(const details::operator_type &operation, expression_node_ptr(&branch)[3]) const
Definition exprtk.hpp:31912
expression_node_ptr synthesize_sosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40705
expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34374
expression_node_ptr synthesize_expression(F *f, expression_node_ptr(&branch)[N])
Definition exprtk.hpp:41281
expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34769
expression_node_ptr synthesize_uv_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition exprtk.hpp:32949
expression_node_ptr vararg_function(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition exprtk.hpp:33303
bool is_invalid_string_op(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31892
expression_node_ptr varnode_optimise_varargfunc(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition exprtk.hpp:33253
expression_node_ptr operator()(const Type &v) const
Definition exprtk.hpp:31458
expression_node_ptr switch_statement(Sequence< expression_node_ptr, Allocator > &arg_list, const bool default_statement_present)
Definition exprtk.hpp:32832
void set_allocator(details::node_allocator &na)
Definition exprtk.hpp:31414
bool is_invalid_assignment_op(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31837
expression_node_ptr multi_switch_statement(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition exprtk.hpp:32871
expression_node_ptr synthesize_swap_expression(expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34552
bool is_null_present(expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31965
expression_node_ptr synthesize_srosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40731
void set_ibom(inv_binary_op_map_t &inv_binary_op_map)
Definition exprtk.hpp:31399
expression_node_ptr const_optimise_switch(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition exprtk.hpp:32657
bool synthesize_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2], expression_node_ptr &result)
Definition exprtk.hpp:35735
expression_node_ptr special_function(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition exprtk.hpp:33174
bool valid_operator(const details::operator_type &operation, binary_functor_t &bop)
Definition exprtk.hpp:31429
expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp0, range_t rp1)
Definition exprtk.hpp:40652
expression_node_ptr synthesize_csros_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40856
bool is_vector_eqineq_logic_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31973
void set_bom(binary_op_map_t &binary_op_map)
Definition exprtk.hpp:31394
bool is_string_operation(const details::operator_type &operation, expression_node_ptr(&branch)[3]) const
Definition exprtk.hpp:31941
bool binext_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31828
std::string to_str(const details::operator_type &operation) const
Definition exprtk.hpp:31630
bool is_constant_foldable(const Sequence< NodePtr, Allocator > &b) const
Definition exprtk.hpp:33881
expression_node_ptr synthesize_csosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40767
details::operator_type get_operator(const binary_functor_t &bop) const
Definition exprtk.hpp:31453
expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34634
expression_node_ptr varnode_optimise_sf3(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition exprtk.hpp:33035
expression_node_ptr synthesize_sos_expression_impl(const details::operator_type &opr, T0 s0, T1 s1)
Definition exprtk.hpp:40670
expression_node_ptr synthesize_uvouv_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40528
bool is_string_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31933
void set_uom(unary_op_map_t &unary_op_map)
Definition exprtk.hpp:31389
bool is_constpow_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31866
expression_node_ptr synthesize_csocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40811
expression_node_ptr return_envelope(expression_node_ptr body, results_context_t *rc, bool *&return_invoked)
Definition exprtk.hpp:33675
bool is_vector_arithmetic_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31995
bool valid_string_operation(const details::operator_type &operation) const
Definition exprtk.hpp:31607
bool is_invalid_break_continue_op(expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31882
vector_access_runtime_check_ptr get_vector_access_runtime_check() const
Definition exprtk.hpp:32439
expression_node_ptr synthesize_string_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40932
exprtk::parser< Type > parser_t
Definition exprtk.hpp:31305
expression_node_ptr for_loop(expression_node_ptr &initialiser, expression_node_ptr &condition, expression_node_ptr &incrementor, expression_node_ptr &loop_body, bool break_continue_present=false) const
Definition exprtk.hpp:32562
bool valid_operator(const details::operator_type &operation, unary_functor_t &uop)
Definition exprtk.hpp:31441
expression_node_ptr synthesize_srocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40781
expression_node_ptr synthesize_assignment_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34023
expression_node_ptr return_call(std::vector< expression_node_ptr > &arg_list)
Definition exprtk.hpp:33632
bool vob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31810
expression_node_ptr synthesize_csos_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40757
expression_node_ptr synthesize_null_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:41135
expression_node_ptr while_loop(expression_node_ptr &condition, expression_node_ptr &branch, const bool break_continue_present=false) const
Definition exprtk.hpp:32444
expression_node_ptr synthesize_unary_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition exprtk.hpp:32982
void set_strength_reduction_state(const bool enabled)
Definition exprtk.hpp:31419
expression_node_ptr synthesize_srocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40795
bool sf3_optimisable(const std::string &sf3id, trinary_functor_t &tfunc) const
Definition exprtk.hpp:31512
expression_node_ptr vector_element(const std::string &symbol, vector_holder_ptr vector_base, expression_node_ptr vec_node, expression_node_ptr index)
Definition exprtk.hpp:33702
expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34102
expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp1)
Definition exprtk.hpp:40634
expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34466
expression_node_ptr special_function(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition exprtk.hpp:33067
bool cardinal_pow_optimisable(const details::operator_type &operation, const T &c) const
Definition exprtk.hpp:34764
expression_node_ptr synthesize_string_expression(const details::operator_type &opr, expression_node_ptr(&branch)[3])
Definition exprtk.hpp:41019
expression_node_ptr synthesize_sros_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40692
expression_node_ptr synthesize_csocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40842
expression_node_ptr varnode_optimise_sf4(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition exprtk.hpp:33140
details::node_allocator * node_allocator_
Definition exprtk.hpp:41320
bool operation_optimisable(const details::operator_type &operation) const
Definition exprtk.hpp:31656
expression_node_ptr synthesize_csrocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40885
expression_node_ptr(* synthesize_functor_t)(expression_generator< T > &, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:31303
expression_node_ptr synthesize_socsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40718
expression_node_ptr synthesize_csrocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40898
expression_node_ptr vectorize_func(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition exprtk.hpp:33277
bool cob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31751
expression_node_ptr assert_call(expression_node_ptr &assert_condition, expression_node_ptr &assert_message, const assert_check::assert_context &context)
Definition exprtk.hpp:32885
expression_node_ptr synthesize_expression(const details::operator_type &operation, expression_node_ptr(&branch)[N])
Definition exprtk.hpp:41232
bool unary_optimisable(const details::operator_type &operation) const
Definition exprtk.hpp:31488
expression_node_ptr cardinal_pow_optimisation(const T &v, const T &c)
Definition exprtk.hpp:34743
bool is_constant_foldable(NodePtr(&b)[N]) const
Definition exprtk.hpp:33865
expression_node_ptr const_optimise_sf3(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition exprtk.hpp:32997
expression_node_ptr function(ifunction_t *f)
Definition exprtk.hpp:33434
expression_node_ptr const_optimise_sf4(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition exprtk.hpp:33102
expression_node_ptr synthesize_strogen_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40913
std::string branch_to_id(expression_node_ptr branch) const
Definition exprtk.hpp:31678
expression_node_ptr function(ifunction_t *f, expression_node_ptr(&b)[N])
Definition exprtk.hpp:33381
bool bov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31819
expression_node_ptr synthesize_csrosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40869
bool voc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31733
expression_node_ptr string_function_call(igeneric_function_t *gf, std::vector< expression_node_ptr > &arg_list, const std::size_t &param_seq_index=std::numeric_limits< std::size_t >::max())
Definition exprtk.hpp:33557
inv_binary_op_map_t * inv_binary_op_map_
Definition exprtk.hpp:41324
bool sf3_optimisable(const std::string &sf3id, details::operator_type &operation) const
Definition exprtk.hpp:31536
loop_runtime_check_ptr get_loop_runtime_check(const loop_runtime_check::loop_types loop_type) const
Definition exprtk.hpp:32426
expression_node_ptr vararg_function_call(ivararg_function_t *vaf, std::vector< expression_node_ptr > &arg_list)
Definition exprtk.hpp:33440
bool is_shortcircuit_expression(const details::operator_type &operation) const
Definition exprtk.hpp:31951
expression_node_ptr cardinal_pow_optimisation_impl(const TType &v, const unsigned int &p)
Definition exprtk.hpp:34715
void set_sf3m(sf3_map_t &sf3_map)
Definition exprtk.hpp:31404
bool uvouv_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31801
bool is_assignment_operation(const details::operator_type &operation) const
Definition exprtk.hpp:31594
bool sf4_optimisable(const std::string &sf4id, details::operator_type &operation) const
Definition exprtk.hpp:31548
std::map< std::string, synthesize_functor_t > synthesize_map_t
Definition exprtk.hpp:31304
bool cocob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31769
const void * base_ptr(expression_node_ptr node)
Definition exprtk.hpp:33944
expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp0)
Definition exprtk.hpp:40616
bool vov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition exprtk.hpp:31742
expression_node_ptr conditional_string(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition exprtk.hpp:32295
expression_node_ptr const_optimise_mswitch(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition exprtk.hpp:32693
expression_node_ptr synthesize_socs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40747
void set_sf4m(sf4_map_t &sf4_map)
Definition exprtk.hpp:31409
expression_node_ptr synthesize_sos_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40684
bool add_interval(const interval_point_t begin, const interval_point_t end)
Definition exprtk.hpp:22757
bool in_interval(const interval_point_t point, interval_t &interval) const
Definition exprtk.hpp:22726
std::map< interval_point_t, interval_t > interval_map_t
Definition exprtk.hpp:22713
std::pair< interval_point_t, interval_point_t > interval_t
Definition exprtk.hpp:22712
interval_map_t::const_iterator interval_map_citr_t
Definition exprtk.hpp:22714
bool add_interval(const interval_t interval)
Definition exprtk.hpp:22769
bool in_interval(const interval_point_t point) const
Definition exprtk.hpp:22751
scope_element & get_element(const std::size_t &index)
Definition exprtk.hpp:22419
scope_element & get_element(const std::string &var_name, const std::size_t index=std::numeric_limits< std::size_t >::max())
Definition exprtk.hpp:22427
bool add_element(const scope_element &se)
Definition exprtk.hpp:22470
expression_node_ptr get_variable(const T &v)
Definition exprtk.hpp:22563
void free_element(scope_element &se)
Definition exprtk.hpp:22513
expression_node_t * expression_node_ptr
Definition exprtk.hpp:22400
scope_element_manager & operator=(const scope_element_manager &)
scope_element_manager(const scope_element_manager &)
std::string get_vector_name(const T *data)
Definition exprtk.hpp:22587
std::vector< scope_element > element_
Definition exprtk.hpp:22612
scope_element & get_active_element(const std::string &var_name, const std::size_t index=std::numeric_limits< std::size_t >::max())
Definition exprtk.hpp:22448
void deactivate(const std::size_t &scope_depth)
Definition exprtk.hpp:22493
scope_handler(parser< T > &p)
Definition exprtk.hpp:22623
scope_handler(const scope_handler &)
scope_handler & operator=(const scope_handler &)
settings_store & enable_strength_reduction()
Definition exprtk.hpp:23810
settings_store & disable_all_arithmetic_ops()
Definition exprtk.hpp:23843
bool collect_functions_enabled() const
Definition exprtk.hpp:23896
settings_store & enable_all_control_structures()
Definition exprtk.hpp:23768
settings_store & disable_all_inequality_ops()
Definition exprtk.hpp:23861
settings_store & enable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
Definition exprtk.hpp:24145
settings_store & enable_all_arithmetic_ops()
Definition exprtk.hpp:23780
bool control_struct_disabled(const std::string &control_struct) const
Definition exprtk.hpp:23961
bool function_disabled(const std::string &function_name) const
Definition exprtk.hpp:23953
settings_store & enable_base_function(const settings_base_funcs bf)
Definition exprtk.hpp:24091
bool collect_variables_enabled() const
Definition exprtk.hpp:23895
settings_store & disable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
Definition exprtk.hpp:24052
bool assignment_enabled(const details::operator_type &assignment) const
Definition exprtk.hpp:23935
settings_store & disable_strength_reduction()
Definition exprtk.hpp:23882
settings_store & disable_assignment_operation(const settings_assignment_opr assignment)
Definition exprtk.hpp:24065
std::size_t max_local_vector_size() const
Definition exprtk.hpp:24224
settings_store & enable_all_inequality_ops()
Definition exprtk.hpp:23792
settings_store & disable_all_base_functions()
Definition exprtk.hpp:23816
disabled_entity_set_t::iterator des_itr_t
Definition exprtk.hpp:23662
settings_store & disable_commutative_check()
Definition exprtk.hpp:23876
settings_store & enable_control_structure(const settings_control_structs ctrl_struct)
Definition exprtk.hpp:24109
disabled_entity_set_t disabled_arithmetic_set_
Definition exprtk.hpp:24324
std::set< std::string, details::ilesscompare > disabled_entity_set_t
Definition exprtk.hpp:23661
std::string inequality_opr_to_string(details::operator_type opr) const
Definition exprtk.hpp:24276
settings_store & disable_all_logic_ops()
Definition exprtk.hpp:23834
disabled_entity_set_t disabled_assignment_set_
Definition exprtk.hpp:24325
settings_store & enable_assignment_operation(const settings_assignment_opr assignment)
Definition exprtk.hpp:24163
bool assignment_disabled(const details::operator_type assignment_operation) const
Definition exprtk.hpp:23977
settings_store & enable_logic_operation(const settings_logic_opr logic)
Definition exprtk.hpp:24127
settings_store & disable_base_function(const settings_base_funcs bf)
Definition exprtk.hpp:24013
disabled_entity_set_t disabled_inequality_set_
Definition exprtk.hpp:24326
bool logic_enabled(const std::string &logic_operation) const
Definition exprtk.hpp:23918
std::string arith_opr_to_string(details::operator_type opr) const
Definition exprtk.hpp:24262
settings_store & disable_logic_operation(const settings_logic_opr logic)
Definition exprtk.hpp:24039
std::size_t max_stack_depth() const
Definition exprtk.hpp:24214
settings_store & disable_all_assignment_ops()
Definition exprtk.hpp:23852
static const std::size_t default_compile_all_opts
Definition exprtk.hpp:23745
bool control_struct_enabled(const std::string &control_struct) const
Definition exprtk.hpp:23910
settings_store & disable_local_vardef()
Definition exprtk.hpp:23870
void set_max_node_depth(const std::size_t max_node_depth)
Definition exprtk.hpp:24204
bool commutative_check_enabled() const
Definition exprtk.hpp:23889
void set_max_local_vector_size(const std::size_t max_local_vector_size)
Definition exprtk.hpp:24209
disabled_entity_set_t disabled_logic_set_
Definition exprtk.hpp:24323
std::size_t max_node_depth() const
Definition exprtk.hpp:24219
settings_store & enable_all_logic_ops()
Definition exprtk.hpp:23774
bool inequality_enabled(const details::operator_type &inequality) const
Definition exprtk.hpp:23944
settings_store & disable_inequality_operation(const settings_inequality_opr inequality)
Definition exprtk.hpp:24078
bool inequality_disabled(const details::operator_type &inequality) const
Definition exprtk.hpp:24004
disabled_entity_set_t disabled_ctrl_set_
Definition exprtk.hpp:24322
settings_store & enable_commutative_check()
Definition exprtk.hpp:23804
std::string assign_opr_to_string(details::operator_type opr) const
Definition exprtk.hpp:24248
settings_store(const std::size_t compile_options=default_compile_all_opts)
Definition exprtk.hpp:23754
settings_store & enable_local_vardef()
Definition exprtk.hpp:23798
settings_store & disable_control_structure(const settings_control_structs ctrl_struct)
Definition exprtk.hpp:24026
settings_store & enable_inequality_operation(const settings_inequality_opr inequality)
Definition exprtk.hpp:24181
disabled_entity_set_t disabled_func_set_
Definition exprtk.hpp:24321
bool logic_disabled(const std::string &logic_operation) const
Definition exprtk.hpp:23969
bool collect_assignments_enabled() const
Definition exprtk.hpp:23897
settings_store & enable_all_base_functions()
Definition exprtk.hpp:23762
bool arithmetic_enabled(const details::operator_type &arithmetic_operation) const
Definition exprtk.hpp:23926
void load_compile_options(const std::size_t compile_options)
Definition exprtk.hpp:24231
settings_store & disable_all_control_structures()
Definition exprtk.hpp:23825
bool strength_reduction_enabled() const
Definition exprtk.hpp:23894
bool arithmetic_disabled(const details::operator_type arithmetic_operation) const
Definition exprtk.hpp:23995
bool function_enabled(const std::string &function_name) const
Definition exprtk.hpp:23902
bool logic_disabled(const details::operator_type logic_operation) const
Definition exprtk.hpp:23986
std::string logic_opr_to_string(details::operator_type opr) const
Definition exprtk.hpp:24292
settings_store & enable_all_assignment_ops()
Definition exprtk.hpp:23786
void set_max_stack_depth(const std::size_t max_stack_depth)
Definition exprtk.hpp:24199
stack_limit_handler & operator=(const stack_limit_handler &)
stack_limit_handler(const stack_limit_handler &)
std::size_t paramseq_count() const
Definition exprtk.hpp:28311
std::vector< function_prototype_t > function_definition_list_t
Definition exprtk.hpp:28237
const return_type_t default_return_type_
Definition exprtk.hpp:28476
return_type_t return_type(const std::size_t &index) const
Definition exprtk.hpp:28321
bool is_valid_token(std::string param_seq, function_prototype_t &funcproto) const
Definition exprtk.hpp:28373
bool allow_zero_parameters() const
Definition exprtk.hpp:28331
type_checker(const type_checker &)
bool verify(const std::string &param_seq, std::size_t &pseq_index)
Definition exprtk.hpp:28251
function_definition_list_t function_definition_list_
Definition exprtk.hpp:28477
std::string paramseq(const std::size_t &index) const
Definition exprtk.hpp:28316
type_checker(parser_t &p, const std::string &func_name, const std::string &func_prototypes, const return_type_t default_return_type)
Definition exprtk.hpp:28239
type_checker & operator=(const type_checker &)
void parse_function_prototypes(const std::string &func_prototypes)
Definition exprtk.hpp:28422
std::vector< std::string > split_param_seq(const std::string &param_seq, const details::char_t delimiter='|') const
Definition exprtk.hpp:28347
expression_node_ptr parse_string_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition exprtk.hpp:28669
std::set< std::string, details::ilesscompare > disabled_func_set_t
Definition exprtk.hpp:22277
ifunction< T > F
Definition exprtk.hpp:22188
sf4_map_t sf4_map_
Definition exprtk.hpp:41631
expression_node_ptr parse_swap_statement()
Definition exprtk.hpp:29995
lexer::helper::bracket_checker bracket_checker_
Definition exprtk.hpp:41645
expression_node_ptr parse_for_loop()
Definition exprtk.hpp:26694
details::assignment_node< T > assignment_node_t
Definition exprtk.hpp:22241
void enable_unknown_symbol_resolver(unknown_symbol_resolver &usr)
Definition exprtk.hpp:24772
void clear_assert_check()
Definition exprtk.hpp:24818
expression_node_ptr parse_function_invocation(ifunction< T > *function, const std::string &function_name)
Definition exprtk.hpp:25592
interval_container_t< const void * > immutable_memory_map_t
Definition exprtk.hpp:30616
settings_store settings_
Definition exprtk.hpp:41614
bool is_invalid_inequality_operation(const details::operator_type operation) const
Definition exprtk.hpp:24881
details::vector_node< T > vector_node_t
Definition exprtk.hpp:22226
expression_node_ptr parse_special_function()
Definition exprtk.hpp:28859
expression_node_ptr parse_expression(precedence_level precedence=e_level00)
Definition exprtk.hpp:25065
void init_precompilation()
Definition exprtk.hpp:24379
void clear_vector_access_runtime_check()
Definition exprtk.hpp:24808
std::multimap< std::string, details::base_operation_t, details::ilesscompare > base_ops_map_t
Definition exprtk.hpp:22276
details::assignment_vec_elem_node< T > assignment_vec_elem_node_t
Definition exprtk.hpp:22242
bool is_invalid_assignment_operation(const details::operator_type operation) const
Definition exprtk.hpp:24876
std::map< std::string, std::pair< quaternary_functor_t, operator_t> > sf4_map_t
Definition exprtk.hpp:22273
details::trinary_node< T > trinary_node_t
Definition exprtk.hpp:22198
std::set< std::string > assert_ids_
Definition exprtk.hpp:41654
details::conditional_string_node< T > conditional_string_node_t
Definition exprtk.hpp:22238
parser< T > & operator=(const parser< T > &)
bool parse_range(range_t &rp, const bool skip_lsqr=false)
Definition exprtk.hpp:27621
binary_op_map_t binary_op_map_
Definition exprtk.hpp:41628
details::rebasevector_celem_node< T > rebasevector_celem_node_t
Definition exprtk.hpp:22223
details::T0oT1oT2oT3_define< T, cref_t, cref_t, const_t, cref_t > vovocov_t
Definition exprtk.hpp:22293
details::vector_size_node< T > vector_size_node_t
Definition exprtk.hpp:22227
expression_t compile(const std::string &expression_string, symbol_table_t &symtab)
Definition exprtk.hpp:24555
details::unary_node< T > unary_node_t
Definition exprtk.hpp:22196
bool compile(const std::string &expression_string, expression< T > &expr)
Definition exprtk.hpp:24443
bool valid_vararg_operation(const std::string &symbol) const
Definition exprtk.hpp:24839
expression_node_t * expression_node_ptr
Definition exprtk.hpp:22253
bool parse_igeneric_function_params(std::string &param_type_list, std::vector< expression_node_ptr > &arg_list, const std::string &function_name, igeneric_function< T > *function, const type_checker &tc)
Definition exprtk.hpp:28604
expression_node_ptr parse_vector()
Definition exprtk.hpp:28020
details::assignment_vec_elem_rtc_node< T > assignment_vec_elem_rtc_node_t
Definition exprtk.hpp:22243
std::map< std::string, std::pair< trinary_functor_t,operator_t> > sf3_map_t
Definition exprtk.hpp:22272
void register_compilation_timeout_check(compilation_check &compchk)
Definition exprtk.hpp:24793
interval_container_t< constvoid * >::interval_t interval_t
Definition exprtk.hpp:30615
details::T0oT1oT2oT3_define< T, cref_t, cref_t, cref_t, cref_t > vovovov_t
Definition exprtk.hpp:22291
void load_unary_operations_map(unary_op_map_t &m)
Definition exprtk.hpp:41419
void clear_compilation_timeout_check()
Definition exprtk.hpp:24813
expression_node_ptr parse_multi_switch_statement()
Definition exprtk.hpp:27106
details::switch_node< T > switch_node_t
Definition exprtk.hpp:22216
details::T0oT1oT2oT3_define< T, cref_t, const_t, cref_t, cref_t > vocovov_t
Definition exprtk.hpp:22294
details::assignment_vecvec_node< T > assignment_vecvec_node_t
Definition exprtk.hpp:22248
inv_binary_op_map_t inv_binary_op_map_
Definition exprtk.hpp:41629
expression_node_ptr parse_base_operation()
Definition exprtk.hpp:25832
std::size_t parse_base_function_call(expression_node_ptr(&param_list)[MaxNumberofParameters], const std::string &function_name="")
Definition exprtk.hpp:25760
details::for_loop_rtc_node< T > for_loop_rtc_node_t
Definition exprtk.hpp:22207
bool valid_base_operation(const std::string &symbol) const
Definition exprtk.hpp:24825
expression_node_ptr parse_continue_statement()
Definition exprtk.hpp:28986
details::for_loop_bc_node< T > for_loop_bc_node_t
Definition exprtk.hpp:22211
igeneric_function< T > igeneric_function_t
Definition exprtk.hpp:22193
vector_holder_t * vector_holder_ptr
Definition exprtk.hpp:22258
expression< T >::symtab_list_t symbol_table_list_t
Definition exprtk.hpp:22256
unknown_symbol_resolver default_usr_
Definition exprtk.hpp:41625
void load_sf3_map(sf3_map_t &sf3_map)
Definition exprtk.hpp:41522
std::map< operator_t, unary_functor_t > unary_op_map_t
Definition exprtk.hpp:22268
details::while_loop_bc_rtc_node< T > while_loop_bc_rtc_node_t
Definition exprtk.hpp:22212
void lodge_symbol(const std::string &symbol, const symbol_type st)
Definition exprtk.hpp:27805
parser(const settings_t &settings=settings_t())
Definition exprtk.hpp:24337
details::assignment_vec_node< T > assignment_vec_node_t
Definition exprtk.hpp:22247
details::range_pack< T > range_t
Definition exprtk.hpp:22228
bool is_invalid_logic_operation(const details::operator_type operation) const
Definition exprtk.hpp:24866
expression_node_ptr parse_conditional_statement_01(expression_node_ptr condition)
Definition exprtk.hpp:25899
expression_node_ptr simplify(Sequence< expression_node_ptr, Allocator1 > &expression_list, Sequence< bool, Allocator2 > &side_effect_list, const bool specialise_on_final_type=false)
Definition exprtk.hpp:27459
details::string_concat_node< T > string_concat_node_t
Definition exprtk.hpp:22235
expression_node_ptr parse_generic_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition exprtk.hpp:28480
details::stringvar_node< T > stringvar_node_t
Definition exprtk.hpp:22230
void return_cleanup()
Definition exprtk.hpp:41596
functor_t::qfunc_t quaternary_functor_t
Definition exprtk.hpp:22261
details::vector_elem_node< T > vector_elem_node_t
Definition exprtk.hpp:22218
bool is_invalid_arithmetic_operation(const details::operator_type operation) const
Definition exprtk.hpp:24871
interval_t make_memory_range(details::char_cptr begin, const std::size_t size)
Definition exprtk.hpp:30631
void pop_current_state()
Definition exprtk.hpp:25029
details::T0oT1oT2_define< T, const_t, const_t, cref_t > cocov_t
Definition exprtk.hpp:22288
loop_runtime_check_ptr loop_runtime_check_
Definition exprtk.hpp:41650
details::while_loop_bc_node< T > while_loop_bc_node_t
Definition exprtk.hpp:22209
details::T0oT1_define< T, cref_t, cref_t > vov_t
Definition exprtk.hpp:22279
details::expression_node< T > expression_node_t
Definition exprtk.hpp:22194
details::vector_celem_rtc_node< T > vector_celem_rtc_node_t
Definition exprtk.hpp:22221
dependent_entity_collector dec_
Definition exprtk.hpp:41618
std::vector< state_t > current_state_stack_
Definition exprtk.hpp:41634
ifunction< T > ifunction_t
Definition exprtk.hpp:22191
expression_node_ptr parse_corpus()
Definition exprtk.hpp:24904
std::deque< parser_error::type > error_list_
Definition exprtk.hpp:41619
lexer::helper::operator_joiner operator_joiner_3_
Definition exprtk.hpp:41643
unknown_symbol_resolver * unknown_symbol_resolver_
Definition exprtk.hpp:41624
details::while_loop_rtc_node< T > while_loop_rtc_node_t
Definition exprtk.hpp:22205
expression_node_ptr parse_vararg_function_call(ivararg_function< T > *vararg_function, const std::string &vararg_function_name)
Definition exprtk.hpp:28122
expression_node_ptr parse_switch_statement()
Definition exprtk.hpp:26933
details::T0oT1oT2_define< T, const_t, cref_t, cref_t > covov_t
Definition exprtk.hpp:22286
details::T0oT1oT2_define< T, cref_t, cref_t, cref_t > vovov_t
Definition exprtk.hpp:22283
details::assignment_rebasevec_elem_rtc_node< T > assignment_rebasevec_elem_rtc_node_t
Definition exprtk.hpp:22245
details::T0oT1oT2_define< T, cref_t, const_t, cref_t > vocov_t
Definition exprtk.hpp:22285
const T const_t
Definition exprtk.hpp:22187
parser_helper prsrhlpr_t
Definition exprtk.hpp:22304
details::cons_conditional_str_node< T > cons_conditional_str_node_t
Definition exprtk.hpp:22239
ivararg_function< T > VAF
Definition exprtk.hpp:22189
expression_node_ptr parse_const_string()
Definition exprtk.hpp:27918
void register_local_vars(expression< T > &e)
Definition exprtk.hpp:41351
vector_access_runtime_check_ptr vector_access_runtime_check_
Definition exprtk.hpp:41651
void parse_pending_vector_index_operator(expression_node_ptr &expression)
Definition exprtk.hpp:27403
settings_store settings_t
Definition exprtk.hpp:24335
expression_node_ptr parse_function_call(ifunction< T > *function, const std::string &function_name)
Definition exprtk.hpp:25645
void set_synthesis_error(const std::string &synthesis_error_message)
Definition exprtk.hpp:41343
details::conditional_node< T > conditional_node_t
Definition exprtk.hpp:22200
expression_node_ptr parse_overload_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition exprtk.hpp:28720
details::T0oT1oT2oT3_define< T, cref_t, const_t, const_t, cref_t > vococov_t
Definition exprtk.hpp:22300
lexer::helper::operator_joiner operator_joiner_2_
Definition exprtk.hpp:41642
expression_node_ptr parse_function_call_0(ifunction< T > *function, const std::string &function_name)
Definition exprtk.hpp:25732
functor_t::tfunc_t trinary_functor_t
Definition exprtk.hpp:22262
details::T0oT1_define< T, const_t, cref_t > cov_t
Definition exprtk.hpp:22280
details::for_loop_node< T > for_loop_node_t
Definition exprtk.hpp:22204
functor_t::bfunc_t binary_functor_t
Definition exprtk.hpp:22263
void process_lexer_errors()
Definition exprtk.hpp:24563
bool post_variable_process(const std::string &symbol)
Definition exprtk.hpp:30538
igeneric_function< T > GF
Definition exprtk.hpp:22190
details::assignment_string_node< T > assignment_string_node_t
Definition exprtk.hpp:22236
lexer::helper::symbol_replacer symbol_replacer_
Definition exprtk.hpp:41644
void enable_unknown_symbol_resolver(unknown_symbol_resolver *usr=reinterpret_cast< unknown_symbol_resolver * >(0))
Definition exprtk.hpp:24762
ivararg_function< T > ivararg_function_t
Definition exprtk.hpp:22192
details::T0oT1oT2oT3_define< T, const_t, cref_t, cref_t, const_t > covovoc_t
Definition exprtk.hpp:22299
expression_node_ptr parse_while_loop()
Definition exprtk.hpp:26437
expression_node_ptr parse_string()
Definition exprtk.hpp:27812
details::scand_node< T > scand_node_t
Definition exprtk.hpp:22250
std::map< binary_functor_t, operator_t> inv_binary_op_map_t
Definition exprtk.hpp:22275
expression_node_ptr parse_define_var_statement()
Definition exprtk.hpp:29558
void push_current_state(const state_t current_state)
Definition exprtk.hpp:25024
details::binary_node< T > binary_node_t
Definition exprtk.hpp:22197
dependent_entity_collector & dec()
Definition exprtk.hpp:24737
bool remove_replace_symbol(const std::string &symbol)
Definition exprtk.hpp:24752
expression_node_ptr parse_conditional_statement()
Definition exprtk.hpp:26232
results_context_t * results_context_
Definition exprtk.hpp:41623
details::literal_node< T > literal_node_t
Definition exprtk.hpp:22195
immutable_symtok_map_t immutable_symtok_map_
Definition exprtk.hpp:41637
symtab_store symtab_store_
Definition exprtk.hpp:41617
compilation_check_ptr compilation_check_ptr_
Definition exprtk.hpp:41652
sf3_map_t sf3_map_
Definition exprtk.hpp:41630
details::repeat_until_loop_node< T > repeat_until_loop_node_t
Definition exprtk.hpp:22203
static const precedence_level default_precedence
Definition exprtk.hpp:24996
details::repeat_until_loop_bc_node< T > repeat_until_loop_bc_node_t
Definition exprtk.hpp:22210
details::assignment_rebasevec_elem_node< T > assignment_rebasevec_elem_node_t
Definition exprtk.hpp:22244
std::map< operator_t, trinary_functor_t > trinary_op_map_t
Definition exprtk.hpp:22270
expression_node_ptr parse_vararg_function()
Definition exprtk.hpp:27222
void lodge_immutable_symbol(const lexer::token &token, const interval_t interval)
Definition exprtk.hpp:30636
details::variable_node< T > variable_node_t
Definition exprtk.hpp:22217
details::T0oT1oT2oT3_define< T, cref_t, const_t, cref_t, const_t > vocovoc_t
Definition exprtk.hpp:22298
details::T0oT1_define< T, cref_t, const_t > voc_t
Definition exprtk.hpp:22281
expression_generator< T > expression_generator_
Definition exprtk.hpp:41615
expression_node_ptr parse_multi_sequence(const std::string &source="", const bool enforce_crlbrackets=false)
Definition exprtk.hpp:27538
expression_node_ptr parse_branch(precedence_level precedence=e_level00)
Definition exprtk.hpp:31099
assert_check_ptr assert_check_
Definition exprtk.hpp:41653
expression_node_ptr parse_break_statement()
Definition exprtk.hpp:28911
void load_inv_binary_operations_map(inv_binary_op_map_t &m)
Definition exprtk.hpp:41494
details::T0oT1oT2oT3_define< T, const_t, cref_t, cref_t, cref_t > covovov_t
Definition exprtk.hpp:22295
lexer::helper::sequence_validator sequence_validator_
Definition exprtk.hpp:41647
lexer::helper::commutative_inserter commutative_inserter_
Definition exprtk.hpp:41641
interval_t make_memory_range(const T &t)
Definition exprtk.hpp:30619
expression< T > expression_t
Definition exprtk.hpp:22254
void handle_brkcnt_scope_exit()
Definition exprtk.hpp:26431
expression_node_ptr parse_conditional_statement_02(expression_node_ptr condition)
Definition exprtk.hpp:26035
details::T0oT1oT2oT3_define< T, cref_t, cref_t, cref_t, const_t > vovovoc_t
Definition exprtk.hpp:22292
expression_node_ptr parse_not_statement()
Definition exprtk.hpp:26415
details::operator_type operator_t
Definition exprtk.hpp:22266
bool run_assemblies()
Definition exprtk.hpp:24600
details::functor_t< T > functor_t
Definition exprtk.hpp:22260
const T & cref_t
Definition exprtk.hpp:22186
void register_loop_runtime_check(loop_runtime_check &lrtchk)
Definition exprtk.hpp:24783
details::vector_elem_rtc_node< T > vector_elem_rtc_node_t
Definition exprtk.hpp:22220
parser_state state_
Definition exprtk.hpp:41621
details::for_loop_bc_rtc_node< T > for_loop_bc_rtc_node_t
Definition exprtk.hpp:22214
details::conditional_vector_node< T > conditional_vector_node_t
Definition exprtk.hpp:22249
details::repeat_until_loop_bc_rtc_node< T > repeat_until_loop_bc_rtc_node_t
Definition exprtk.hpp:22213
parser(const parser< T > &)
lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_
Definition exprtk.hpp:41648
expression_node_ptr parse_assert_statement()
Definition exprtk.hpp:30350
void set_error(const parser_error::type &error_type)
Definition exprtk.hpp:41330
expression_node_ptr parse_null_statement()
Definition exprtk.hpp:28904
details::T0oT1oT2_define< T, cref_t, cref_t, const_t > vovoc_t
Definition exprtk.hpp:22284
expression_node_ptr synthesize_vector_element(const std::string &vector_name, vector_holder_ptr vec, expression_node_ptr vec_node, expression_node_ptr index_expr)
Definition exprtk.hpp:28092
lexer::helper::numeric_checker< T > numeric_checker_
Definition exprtk.hpp:41646
details::rebasevector_elem_rtc_node< T > rebasevector_elem_rtc_node_t
Definition exprtk.hpp:22224
parser_error::type get_error(const std::size_t &index) const
Definition exprtk.hpp:24712
void load_binary_operations_map(binary_op_map_t &m)
Definition exprtk.hpp:41466
bool post_bracket_process(const typename token_t::token_type &token, expression_node_ptr &branch)
Definition exprtk.hpp:30563
bool simplify_unary_negation_branch(expression_node_ptr &node)
Definition exprtk.hpp:25350
details::rebasevector_celem_rtc_node< T > rebasevector_celem_rtc_node_t
Definition exprtk.hpp:22225
std::string error() const
Definition exprtk.hpp:24722
details::node_allocator node_allocator_
Definition exprtk.hpp:41616
details::generic_string_range_node< T > generic_string_range_node_t
Definition exprtk.hpp:22234
details::T0oT1oT2oT3_define< T, const_t, cref_t, const_t, cref_t > covocov_t
Definition exprtk.hpp:22297
details::cons_conditional_node< T > cons_conditional_node_t
Definition exprtk.hpp:22201
void register_vector_access_runtime_check(vector_access_runtime_check &vartchk)
Definition exprtk.hpp:24788
void remove_last_error()
Definition exprtk.hpp:41335
results_context_t & results_ctx()
Definition exprtk.hpp:41586
unary_op_map_t unary_op_map_
Definition exprtk.hpp:41627
expression_node_ptr parse_define_vector_statement(const std::string &vec_name)
Definition exprtk.hpp:29010
expression_node_ptr parse_vector_index(const std::string &vector_name="")
Definition exprtk.hpp:27990
scope_element_manager sem_
Definition exprtk.hpp:41633
details::assignment_rebasevec_celem_node< T > assignment_rebasevec_celem_node_t
Definition exprtk.hpp:22246
expression_node_ptr parse_ternary_conditional_statement(expression_node_ptr condition)
Definition exprtk.hpp:26295
functor_t::ufunc_t unary_functor_t
Definition exprtk.hpp:22264
expression_node_ptr parse_symbol()
Definition exprtk.hpp:30973
bool replace_symbol(const std::string &old_symbol, const std::string &new_symbol)
Definition exprtk.hpp:24742
lexer::token token_t
Definition exprtk.hpp:22252
details::assignment_string_range_node< T > assignment_string_range_node_t
Definition exprtk.hpp:22237
details::scor_node< T > scor_node_t
Definition exprtk.hpp:22251
std::map< operator_t, binary_functor_t > binary_op_map_t
Definition exprtk.hpp:22269
results_context< T > results_context_t
Definition exprtk.hpp:22302
std::string synthesis_error_
Definition exprtk.hpp:41632
expression_node_ptr parse_string_range_statement(expression_node_ptr &expression)
Definition exprtk.hpp:27315
void register_return_results(expression< T > &e)
Definition exprtk.hpp:41413
details::T0oT1oT2_define< T, const_t, cref_t, const_t > covoc_t
Definition exprtk.hpp:22287
details::vector_holder< T > vector_holder_t
Definition exprtk.hpp:22257
interval_t make_memory_range(const T *begin, const std::size_t size)
Definition exprtk.hpp:30626
std::size_t error_count() const
Definition exprtk.hpp:24732
expression_node_ptr parse_define_string_statement(const std::string &str_name, expression_node_ptr initialisation_expression)
Definition exprtk.hpp:29474
details::string_range_node< T > string_range_node_t
Definition exprtk.hpp:22232
base_ops_map_t base_ops_map_
Definition exprtk.hpp:41626
details::quaternary_node< T > quaternary_node_t
Definition exprtk.hpp:22199
std::deque< bool > brkcnt_list_
Definition exprtk.hpp:41620
void clear_loop_runtime_check()
Definition exprtk.hpp:24803
void disable_unknown_symbol_resolver()
Definition exprtk.hpp:24777
immutable_memory_map_t immutable_memory_map_
Definition exprtk.hpp:41636
expression_node_ptr parse_return_statement()
Definition exprtk.hpp:30229
details::vector_celem_node< T > vector_celem_node_t
Definition exprtk.hpp:22219
state_t current_state() const
Definition exprtk.hpp:25037
void load_sf4_map(sf4_map_t &sf4_map)
Definition exprtk.hpp:41546
details::string_literal_node< T > string_literal_node_t
Definition exprtk.hpp:22231
settings_store & settings()
Definition exprtk.hpp:24707
expression_node_ptr parse_symtab_symbol()
Definition exprtk.hpp:30642
std::string construct_subexpr(lexer::token &begin_token, lexer::token &end_token, const bool cleanup_whitespace=true)
Definition exprtk.hpp:24980
details::T0oT1oT2_define< T, cref_t, const_t, const_t > vococ_t
Definition exprtk.hpp:22289
details::while_loop_node< T > while_loop_node_t
Definition exprtk.hpp:22202
expression_node_ptr parse_uninitialised_var_statement(const std::string &var_name)
Definition exprtk.hpp:29909
std::map< interval_t, token_t > immutable_symtok_map_t
Definition exprtk.hpp:30617
bool local_variable_is_shadowed(const std::string &symbol)
Definition exprtk.hpp:29552
void register_assert_check(assert_check &assrt_chck)
Definition exprtk.hpp:24798
bool resolve_unknown_symbol_
Definition exprtk.hpp:41622
lexer::helper::helper_assembly helper_assembly_
Definition exprtk.hpp:41639
symbol_table< T > symbol_table_t
Definition exprtk.hpp:22255
details::repeat_until_loop_rtc_node< T > repeat_until_loop_rtc_node_t
Definition exprtk.hpp:22206
details::rebasevector_elem_node< T > rebasevector_elem_node_t
Definition exprtk.hpp:22222
static expression_node_ptr error_node()
Definition exprtk.hpp:25405
bool parse_pending_string_rangesize(expression_node_ptr &expression)
Definition exprtk.hpp:27381
expression_node_ptr parse_repeat_until_loop()
Definition exprtk.hpp:26534
bool halt_compilation_check()
Definition exprtk.hpp:25044
expression_node_ptr parse_define_constvar_statement()
Definition exprtk.hpp:29741
details::const_string_range_node< T > const_string_range_node_t
Definition exprtk.hpp:22233
virtual T operator()()
Definition exprtk.hpp:42416
virtual ~polynomial()
Definition exprtk.hpp:42335
type_store_t::parameter_list parameter_list_t
Definition exprtk.hpp:4977
type_store_t::scalar_view scalar_t
Definition exprtk.hpp:4888
type_store_t::vector_view vector_t
Definition exprtk.hpp:4889
bool get_string(const std::size_t &index, std::string &out) const
Definition exprtk.hpp:4954
const type_store_t & operator[](const std::size_t &index) const
Definition exprtk.hpp:4909
std::size_t count() const
Definition exprtk.hpp:4896
void assign(const parameter_list_t &pl)
Definition exprtk.hpp:4979
type_store_t::string_view string_t
Definition exprtk.hpp:4890
type_store_t & operator[](const std::size_t &index)
Definition exprtk.hpp:4904
bool get_vector(const std::size_t &index, std::vector< T > &out) const
Definition exprtk.hpp:4949
bool get_scalar(const std::size_t &index, T &out) const
Definition exprtk.hpp:4914
bool get_vector(const std::size_t &index, OutputIterator out_itr) const
Definition exprtk.hpp:4930
std::vector< type_store_t > ts_list_t
Definition exprtk.hpp:4976
type_store< T > type_store_t
Definition exprtk.hpp:4887
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44132
igfun_t::generic_type generic_type
Definition exprtk.hpp:44130
T operator()(std::string &result, parameter_list_t parameters)
Definition exprtk.hpp:44140
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44128
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44129
generic_type::string_view string_t
Definition exprtk.hpp:44131
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:43949
generic_type::string_view string_t
Definition exprtk.hpp:43941
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:43938
igfun_t::generic_type generic_type
Definition exprtk.hpp:43940
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:43939
igfun_t::generic_type generic_type
Definition exprtk.hpp:44073
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44084
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44071
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44075
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44072
generic_type::vector_view vector_t
Definition exprtk.hpp:44076
generic_type::string_view string_t
Definition exprtk.hpp:44074
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44014
generic_type::vector_view vector_t
Definition exprtk.hpp:44019
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44027
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44018
igfun_t::generic_type generic_type
Definition exprtk.hpp:44016
generic_type::string_view string_t
Definition exprtk.hpp:44017
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44015
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44353
igfun_t::generic_type generic_type
Definition exprtk.hpp:44337
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44335
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44338
generic_type::vector_view vector_t
Definition exprtk.hpp:44339
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44336
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44273
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44272
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44275
generic_type::vector_view vector_t
Definition exprtk.hpp:44276
igfun_t::generic_type generic_type
Definition exprtk.hpp:44274
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44290
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44479
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44461
igfun_t::generic_type generic_type
Definition exprtk.hpp:44463
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44462
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44464
generic_type::vector_view vector_t
Definition exprtk.hpp:44465
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44399
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44401
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44416
generic_type::vector_view vector_t
Definition exprtk.hpp:44402
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44398
igfun_t::generic_type generic_type
Definition exprtk.hpp:44400
generic_type::vector_view vector_t
Definition exprtk.hpp:45011
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45025
igfun_t::generic_type generic_type
Definition exprtk.hpp:45009
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45007
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45008
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45010
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45368
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45386
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45369
generic_type::vector_view vector_t
Definition exprtk.hpp:45372
igfun_t::generic_type generic_type
Definition exprtk.hpp:45370
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45371
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45419
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45436
generic_type::vector_view vector_t
Definition exprtk.hpp:45422
igfun_t::generic_type generic_type
Definition exprtk.hpp:45420
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45421
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45418
generic_type::vector_view vector_t
Definition exprtk.hpp:45223
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45222
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45219
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45220
igfun_t::generic_type generic_type
Definition exprtk.hpp:45221
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45237
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45317
generic_type::vector_view vector_t
Definition exprtk.hpp:45321
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45335
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45320
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45318
igfun_t::generic_type generic_type
Definition exprtk.hpp:45319
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45471
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45472
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45474
igfun_t::generic_type generic_type
Definition exprtk.hpp:45473
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45489
generic_type::vector_view vector_t
Definition exprtk.hpp:45475
igfun_t::generic_type generic_type
Definition exprtk.hpp:45174
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45175
generic_type::vector_view vector_t
Definition exprtk.hpp:45176
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45173
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45190
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45172
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45285
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45268
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45270
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45267
generic_type::vector_view vector_t
Definition exprtk.hpp:45271
igfun_t::generic_type generic_type
Definition exprtk.hpp:45269
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44583
generic_type::vector_view vector_t
Definition exprtk.hpp:44587
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44600
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44586
igfun_t::generic_type generic_type
Definition exprtk.hpp:44585
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44584
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44527
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44525
generic_type::vector_view vector_t
Definition exprtk.hpp:44528
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44542
igfun_t::generic_type generic_type
Definition exprtk.hpp:44526
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44524
igfun_t::generic_type generic_type
Definition exprtk.hpp:45521
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45520
generic_type::vector_view vector_t
Definition exprtk.hpp:45523
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45537
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45522
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45519
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45584
generic_type::vector_view vector_t
Definition exprtk.hpp:45571
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45568
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45567
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45570
igfun_t::generic_type generic_type
Definition exprtk.hpp:45569
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45613
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45616
igfun_t::generic_type generic_type
Definition exprtk.hpp:45615
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45630
generic_type::vector_view vector_t
Definition exprtk.hpp:45617
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45614
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45062
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45082
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45060
igfun_t::generic_type generic_type
Definition exprtk.hpp:45061
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45059
generic_type::vector_view vector_t
Definition exprtk.hpp:45063
igfun_t::generic_type generic_type
Definition exprtk.hpp:44962
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44963
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44961
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44960
generic_type::vector_view vector_t
Definition exprtk.hpp:44964
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44977
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44755
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44739
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44741
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44738
generic_type::vector_view vector_t
Definition exprtk.hpp:44742
igfun_t::generic_type generic_type
Definition exprtk.hpp:44740
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44637
generic_type::vector_view vector_t
Definition exprtk.hpp:44640
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44639
igfun_t::generic_type generic_type
Definition exprtk.hpp:44638
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44636
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44653
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44690
generic_type::vector_view vector_t
Definition exprtk.hpp:44691
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44688
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44687
igfun_t::generic_type generic_type
Definition exprtk.hpp:44689
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44704
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44796
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44779
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44780
igfun_t::generic_type generic_type
Definition exprtk.hpp:44781
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44782
generic_type::vector_view vector_t
Definition exprtk.hpp:44783
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44838
igfun_t::generic_type generic_type
Definition exprtk.hpp:44839
generic_type::vector_view vector_t
Definition exprtk.hpp:44841
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44854
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44837
generic_type::scalar_view scalar_t
Definition exprtk.hpp:44840
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:44916
igfun_t::generic_type generic_type
Definition exprtk.hpp:44899
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44897
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:44898
generic_type::vector_view vector_t
Definition exprtk.hpp:44901
generic_type::string_view string_t
Definition exprtk.hpp:44900
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45119
generic_type::vector_view vector_t
Definition exprtk.hpp:45123
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45122
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45120
igfun_t::generic_type generic_type
Definition exprtk.hpp:45121
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45137
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45720
generic_type::vector_view vector_t
Definition exprtk.hpp:45723
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45722
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45740
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45719
igfun_t::generic_type generic_type
Definition exprtk.hpp:45721
generic_type::scalar_view scalar_t
Definition exprtk.hpp:45663
igfun_t::generic_type generic_type
Definition exprtk.hpp:45662
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition exprtk.hpp:45681
generic_type::vector_view vector_t
Definition exprtk.hpp:45664
igfun_t::parameter_list_t parameter_list_t
Definition exprtk.hpp:45661
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:45660
details::stringvar_node< T > stringvar_node_t
Definition exprtk.hpp:19709
std::string name() const
Definition exprtk.hpp:19721
stringvar_base(const std::string &name, stringvar_node_t *svn)
Definition exprtk.hpp:19711
void rebase(std::string &s)
Definition exprtk.hpp:19727
stringvar_node_t * string_varnode_
Definition exprtk.hpp:19736
bool add_package(Package &package)
Definition exprtk.hpp:21098
T(* ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19770
symbol_table(const symtab_mutability_type mutability=e_mutable)
Definition exprtk.hpp:20466
symtab_mutability_type mutability() const
Definition exprtk.hpp:20503
bool remove_vararg_function(const std::string &vararg_function_name)
Definition exprtk.hpp:21055
bool add_constant(const std::string &constant_name, const T &value)
Definition exprtk.hpp:20782
control_block * control_block_
Definition exprtk.hpp:21477
T(* ff10_functor)(T, T, T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19765
variable_ptr get_variable(const T &var_ref) const
Definition exprtk.hpp:20589
std::size_t function_count() const
Definition exprtk.hpp:20563
generic_function_ptr get_string_function(const std::string &function_name) const
Definition exprtk.hpp:20658
const local_data_t & local_data() const
Definition exprtk.hpp:21472
std::size_t get_function_list(Sequence< std::string, Allocator > &function_list) const
Definition exprtk.hpp:21157
variable_t * variable_ptr
Definition exprtk.hpp:20336
bool is_vararg_function(const std::string &vararg_function_name) const
Definition exprtk.hpp:21257
bool remove_variable(const std::string &variable_name, const bool delete_node=true)
Definition exprtk.hpp:21029
T(* ff05_functor)(T, T, T, T, T)
Definition exprtk.hpp:19760
void clear_variables(const bool delete_node=true)
Definition exprtk.hpp:20508
T(* ff03_functor)(T, T, T)
Definition exprtk.hpp:19758
std::string & stringvar_ref(const std::string &symbol_name)
Definition exprtk.hpp:20702
control_block::st_data local_data_t
Definition exprtk.hpp:21465
bool add_vector(const std::string &vector_name, std::vector< T, Allocator > &v)
Definition exprtk.hpp:21001
bool is_function(const std::string &function_name) const
Definition exprtk.hpp:21249
std::string get_variable_name(const expression_ptr &ptr) const
Definition exprtk.hpp:21273
bool add_function(const std::string &vararg_function_name, vararg_function_t &vararg_function)
Definition exprtk.hpp:20823
bool add_function(const std::string &function_name, function_t &function)
Definition exprtk.hpp:20811
bool is_stringvar(const std::string &stringvar_name) const
Definition exprtk.hpp:21225
details::vector_holder< T > vector_holder_t
Definition exprtk.hpp:20335
bool remove_vector(const std::string &vector_name)
Definition exprtk.hpp:21063
bool is_constant_node(const std::string &symbol_name) const
Definition exprtk.hpp:20714
stringvar_t * stringvar_ptr
Definition exprtk.hpp:20339
std::size_t get_variable_list(Sequence< std::string, Allocator > &vlist) const
Definition exprtk.hpp:21115
bool is_vector(const std::string &vector_name) const
Definition exprtk.hpp:21265
std::string get_stringvar_name(const expression_ptr &ptr) const
Definition exprtk.hpp:21284
void load_vectors_from(const symbol_table< T > &st)
Definition exprtk.hpp:21395
ivararg_function< T > vararg_function_t
Definition exprtk.hpp:20342
vararg_function_t * vararg_function_ptr
Definition exprtk.hpp:20345
bool valid_symbol(const std::string &symbol, const bool check_reserved_symb=true) const
Definition exprtk.hpp:21413
bool add_reserved_function(const std::string &vararg_function_name, vararg_function_t &vararg_function)
Definition exprtk.hpp:20904
T(* ff02_functor)(T, T)
Definition exprtk.hpp:19757
vector_holder_t * vector_holder_ptr
Definition exprtk.hpp:20678
local_data_t & local_data()
Definition exprtk.hpp:21467
function_ptr get_function(const std::string &function_name) const
Definition exprtk.hpp:20628
T(* ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19769
void load_from(const symbol_table< T > &st)
Definition exprtk.hpp:21301
details::expression_node< T > * expression_ptr
Definition exprtk.hpp:20333
T(* ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19767
igeneric_function< T > generic_function_t
Definition exprtk.hpp:20343
std::size_t get_variable_list(Sequence< std::pair< std::string, T >, Allocator > &vlist) const
Definition exprtk.hpp:21105
stringvar_ptr get_stringvar(const std::string &string_name) const
Definition exprtk.hpp:20599
std::string get_conststr_stringvar_name(const expression_ptr &ptr) const
Definition exprtk.hpp:21289
bool valid_function(const std::string &symbol) const
Definition exprtk.hpp:21439
bool add_vector(const std::string &vector_name, T *v, const std::size_t &v_size)
Definition exprtk.hpp:20986
T(* ff04_functor)(T, T, T, T)
Definition exprtk.hpp:19759
generic_function_t * generic_function_ptr
Definition exprtk.hpp:20346
std::size_t variable_count() const
Definition exprtk.hpp:20545
bool create_stringvar(const std::string &stringvar_name, const std::string &value=std::string(""))
Definition exprtk.hpp:20754
bool remove_stringvar(const std::string &string_name)
Definition exprtk.hpp:21038
std::string get_vector_name(const vector_holder_ptr &ptr) const
Definition exprtk.hpp:21278
variable_ptr get_variable(const std::string &variable_name) const
Definition exprtk.hpp:20579
symbol_table(const symbol_table< T > &st)
Definition exprtk.hpp:20479
bool add_function(const std::string &function_name, generic_function_t &function)
Definition exprtk.hpp:20835
generic_function_ptr get_generic_function(const std::string &function_name) const
Definition exprtk.hpp:20648
bool create_variable(const std::string &variable_name, const T &value=T(0))
Definition exprtk.hpp:20738
T(* ff11_functor)(T, T, T, T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19766
generic_function_ptr get_overload_function(const std::string &function_name) const
Definition exprtk.hpp:20668
std::size_t vector_count() const
Definition exprtk.hpp:20571
bool operator==(const symbol_table< T > &st) const
Definition exprtk.hpp:20498
bool is_conststr_stringvar(const std::string &symbol_name) const
Definition exprtk.hpp:21233
T(* ff06_functor)(T, T, T, T, T, T)
Definition exprtk.hpp:19761
bool add_variable(const std::string &variable_name, T &t, const bool is_constant=false)
Definition exprtk.hpp:20770
bool add_vector(const std::string &vector_name, exprtk::vector_view< T > &v)
Definition exprtk.hpp:21015
bool is_constant_string(const std::string &symbol_name) const
Definition exprtk.hpp:20725
void load_variables_from(const symbol_table< T > &st)
Definition exprtk.hpp:21379
bool valid() const
Definition exprtk.hpp:21295
symbol_table< T > & operator=(const symbol_table< T > &st)
Definition exprtk.hpp:20485
T(* ff08_functor)(T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19763
bool symbol_exists(const std::string &symbol_name, const bool check_reserved_symb=true) const
Definition exprtk.hpp:21191
bool add_reserved_function(const std::string &function_name, generic_function_t &function)
Definition exprtk.hpp:20916
details::stringvar_node< T > stringvar_t
Definition exprtk.hpp:20338
static const std::size_t lut_size
Definition exprtk.hpp:20348
std::size_t get_stringvar_list(Sequence< std::string, Allocator > &svlist) const
Definition exprtk.hpp:21136
bool add_vector(const std::string &vector_name, T(&v)[N])
Definition exprtk.hpp:20974
T & variable_ref(const std::string &symbol_name)
Definition exprtk.hpp:20690
bool add_stringvar(const std::string &stringvar_name, std::string &s, const bool is_constant=false)
Definition exprtk.hpp:20798
T(* ff09_functor)(T, T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19764
function_t * function_ptr
Definition exprtk.hpp:20344
ifunction< T > function_t
Definition exprtk.hpp:20341
std::size_t get_stringvar_list(Sequence< std::pair< std::string, std::string >, Allocator > &svlist) const
Definition exprtk.hpp:21126
std::vector< std::string > get_function_list() const
Definition exprtk.hpp:21184
std::size_t stringvar_count() const
Definition exprtk.hpp:20554
stringvar_base< T > get_stringvar_base(const std::string &string_name) const
Definition exprtk.hpp:20609
details::variable_node< T > variable_t
Definition exprtk.hpp:20334
std::size_t get_vector_list(Sequence< std::string, Allocator > &vec_list) const
Definition exprtk.hpp:21147
vector_holder_ptr get_vector(const std::string &vector_name) const
Definition exprtk.hpp:20680
vararg_function_ptr get_vararg_function(const std::string &vararg_function_name) const
Definition exprtk.hpp:20638
bool remove_function(const std::string &function_name)
Definition exprtk.hpp:21047
T(* ff07_functor)(T, T, T, T, T, T, T)
Definition exprtk.hpp:19762
bool add_reserved_function(const std::string &function_name, function_t &function)
Definition exprtk.hpp:20892
T(* ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T)
Definition exprtk.hpp:19768
bool is_variable(const std::string &variable_name) const
Definition exprtk.hpp:21216
double time() const
Definition exprtk.hpp:43502
struct timeval stop_time_
Definition exprtk.hpp:43524
struct timeval start_time_
Definition exprtk.hpp:43523
unsigned long long int usec_time() const
Definition exprtk.hpp:43486
bool in_use() const
Definition exprtk.hpp:43509
type_store & operator[](const std::size_t &index)
Definition exprtk.hpp:4719
parameter_list(std::vector< type_store > &pl)
Definition exprtk.hpp:4705
const type_store & front() const
Definition exprtk.hpp:4734
const type_store & back() const
Definition exprtk.hpp:4744
const type_store & operator[](const std::size_t &index) const
Definition exprtk.hpp:4724
std::vector< type_store > & parameter_list_
Definition exprtk.hpp:4751
const std::size_t base_size_
Definition exprtk.hpp:4653
std::size_t size() const
Definition exprtk.hpp:4599
std::vector< data_ptr_t * > data_ref_
Definition exprtk.hpp:4656
vector_view(data_ptr_t data, const std::size_t &size)
Definition exprtk.hpp:4558
const T & operator[](const std::size_t index) const
Definition exprtk.hpp:4604
void rebase(data_ptr_t data)
Definition exprtk.hpp:4576
T & operator[](const std::size_t index)
Definition exprtk.hpp:4610
std::size_t base_size() const
Definition exprtk.hpp:4594
std::size_t size_
Definition exprtk.hpp:4654
void remove_ref(data_ptr_t *data_ref)
Definition exprtk.hpp:4624
data_ptr_t data() const
Definition exprtk.hpp:4589
void set_ref(data_ptr_t *data_ref)
Definition exprtk.hpp:4616
vector_view(const vector_view< T > &vv)
Definition exprtk.hpp:4567
bool set_size(const std::size_t new_size)
Definition exprtk.hpp:4634
#define register_sf4(Op)
#define basic_opr_switch_statements
Definition exprtk.hpp:34691
#define register_binary_op(Op, BinaryFunctor)
#define define_sfop4(NN, OP0, OP1)
Definition exprtk.hpp:11857
#define exprtk_final
Definition exprtk.hpp:76
#define case_stmt(N)
Definition exprtk.hpp:32731
#define base_opr_case(N)
#define exprtk_register_function(FunctionName, FunctionType)
#define case_stmt1(op)
#define exprtk_process_digit
#define register_unary_op(Op, UnaryFunctor)
#define exprtk_define_unary_function(FunctionName)
Definition exprtk.hpp:1667
#define register_synthezier(S)
#define exprtk_define_process(Type)
Definition exprtk.hpp:19978
#define exprtk_register_real_type_tag(T)
Definition exprtk.hpp:837
#define empty_method_body(N)
Definition exprtk.hpp:19552
#define exprtk_crtype(Type)
Definition exprtk.hpp:16997
#define exprtk_define_erfc(TT, impl)
Definition exprtk.hpp:1289
#define case_stmt0(op)
#define parse_digit_1(d)
#define exprtk_define_unary_op(OpName)
Definition exprtk.hpp:15412
#define exprtk_define_erf(TT, impl)
Definition exprtk.hpp:1244
#define poly_rtrn(NN)
Definition exprtk.hpp:42338
#define parse_digit_2(d)
#define define_sfop3(NN, OP0, OP1)
Definition exprtk.hpp:11793
#define igeneric_function_empty_body(N)
Definition exprtk.hpp:19675
#define register_sf4ext(Op)
#define vector_ops
#define exprtk_register_int_type_tag(T)
Definition exprtk.hpp:841
#define def_fp_retval(N)
Definition exprtk.hpp:43011
#define pod_set_zero_value(T)
Definition exprtk.hpp:769
#define extended_opr_switch_statements
Definition exprtk.hpp:34699
#define exprtk_override
Definition exprtk.hpp:75
#define exprtk_debug(params)
Definition exprtk.hpp:64
#define synthesis_node_type_define(T0_, T1_, v_)
Definition exprtk.hpp:17161
#define exprtk_define_reserved_function(NN)
Definition exprtk.hpp:20945
#define exprtk_error_location
Definition exprtk.hpp:67
#define string_opr_switch_statements
Definition exprtk.hpp:40604
#define register_op(Symbol, Type, Args)
#define exprtk_assign(Index)
Definition exprtk.hpp:42603
#define exprtk_define_freefunction(NN)
Definition exprtk.hpp:20864
#define unary_opr_switch_statements
Definition exprtk.hpp:32907
#define register_sf3_extid(Id, Op)
#define exprtk_fallthrough
Definition exprtk.hpp:86
#define token_inserter_empty_body
Definition exprtk.hpp:3320
#define register_sf3(Op)
#define exprtk_define_epsilon_type(Type, Epsilon)
Definition exprtk.hpp:862
#define exprtk_loop(N)
#define batch_eqineq_logic_case
#define exprtk_delete
Definition exprtk.hpp:77
static const std::string expression_list[]
const unsigned int global_loop_batch_size
Definition exprtk.hpp:5115
static const double _180_pi
Definition exprtk.hpp:819
float erf_impl(const float v)
Definition exprtk.hpp:1247
bool is_nan_impl(const T v, real_type_tag)
Definition exprtk.hpp:879
T floor_impl(const T v, real_type_tag)
Definition exprtk.hpp:1386
T ceil_impl(const T v, real_type_tag)
Definition exprtk.hpp:1382
T shr_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1120
T tanh_impl(const T v, real_type_tag)
Definition exprtk.hpp:1396
T acosh_impl(const T v, real_type_tag)
Definition exprtk.hpp:1361
T nor_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1196
bool is_integer_impl(const T &v, real_type_tag)
Definition exprtk.hpp:1443
T sinc_impl(const T v, real_type_tag)
Definition exprtk.hpp:1327
T asin_impl(const T v, real_type_tag)
Definition exprtk.hpp:1380
T log10_impl(const T v, real_type_tag)
Definition exprtk.hpp:1388
T r2d_impl(const T v, real_type_tag)
Definition exprtk.hpp:1400
T shl_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1132
T logn_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1013
T sqrt_impl(const T v, real_type_tag)
Definition exprtk.hpp:1394
T xnor_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1220
T asinh_impl(const T v, real_type_tag)
Definition exprtk.hpp:1367
float erfc_impl(const float v)
Definition exprtk.hpp:1292
T d2r_impl(const T v, real_type_tag)
Definition exprtk.hpp:1401
T neg_impl(const T v, real_type_tag)
Definition exprtk.hpp:1390
T process_impl(const operator_type operation, const T arg)
Definition exprtk.hpp:5374
T root_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1052
T and_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1160
T pos_impl(const T v, real_type_tag)
Definition exprtk.hpp:1391
T log_impl(const T v, real_type_tag)
Definition exprtk.hpp:1387
_uint64_t to_uint64_impl(const T v, real_type_tag)
Definition exprtk.hpp:897
T ncdf_impl(const T v, real_type_tag)
Definition exprtk.hpp:1315
T csc_impl(const T v, real_type_tag)
Definition exprtk.hpp:1399
_int64_t to_int64_impl(const T v, real_type_tag)
Definition exprtk.hpp:891
T log2_impl(const T v, real_type_tag)
Definition exprtk.hpp:1389
T cot_impl(const T v, real_type_tag)
Definition exprtk.hpp:1397
T or_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1184
T cos_impl(const T v, real_type_tag)
Definition exprtk.hpp:1383
T sinh_impl(const T v, real_type_tag)
Definition exprtk.hpp:1393
T roundn_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1078
T sec_impl(const T v, real_type_tag)
Definition exprtk.hpp:1398
T atan2_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1108
T pow_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1001
T modulus_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:989
T log1p_impl(const T v, real_type_tag)
Definition exprtk.hpp:1025
T trunc_impl(const T v, real_type_tag)
Definition exprtk.hpp:1406
T frac_impl(const T v, real_type_tag)
Definition exprtk.hpp:1405
T hypot_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1096
T nand_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1172
T min_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:921
T equal_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:933
T nequal_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:968
T g2d_impl(const T v, real_type_tag)
Definition exprtk.hpp:1403
T max_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:927
T exp_impl(const T v, real_type_tag)
Definition exprtk.hpp:1385
T sin_impl(const T v, real_type_tag)
Definition exprtk.hpp:1392
T round_impl(const T v, real_type_tag)
Definition exprtk.hpp:1072
T abs_impl(const T v, real_type_tag)
Definition exprtk.hpp:915
T sgn_impl(const T v, real_type_tag)
Definition exprtk.hpp:1144
T d2g_impl(const T v, real_type_tag)
Definition exprtk.hpp:1402
T acos_impl(const T v, real_type_tag)
Definition exprtk.hpp:1379
T tan_impl(const T v, real_type_tag)
Definition exprtk.hpp:1395
T xor_impl(const T v0, const T v1, real_type_tag)
Definition exprtk.hpp:1208
T expm1_impl(const T v, real_type_tag)
Definition exprtk.hpp:952
int to_int32_impl(const T v, real_type_tag)
Definition exprtk.hpp:885
T atanh_impl(const T v, real_type_tag)
Definition exprtk.hpp:1373
T atan_impl(const T v, real_type_tag)
Definition exprtk.hpp:1381
T notl_impl(const T v, real_type_tag)
Definition exprtk.hpp:1404
T cosh_impl(const T v, real_type_tag)
Definition exprtk.hpp:1384
T logn(const T v0, const T v1)
Definition exprtk.hpp:1534
int to_int32(const T v)
Definition exprtk.hpp:1464
T process(const operator_type operation, const T arg)
Definition exprtk.hpp:5504
T xor_opr(const T v0, const T v1)
Definition exprtk.hpp:1611
T hypot(const T v0, const T v1)
Definition exprtk.hpp:1555
T pow(const T v0, const T v1)
Definition exprtk.hpp:1527
_uint64_t to_uint64(const T v)
Definition exprtk.hpp:1478
T nor_opr(const T v0, const T v1)
Definition exprtk.hpp:1604
bool is_nan(const T v)
Definition exprtk.hpp:1485
T root(const T v0, const T v1)
Definition exprtk.hpp:1541
bool is_integer(const T v)
Definition exprtk.hpp:1625
T nand_opr(const T v0, const T v1)
Definition exprtk.hpp:1590
T min(const T v0, const T v1)
Definition exprtk.hpp:1492
T nequal(const T v0, const T v1)
Definition exprtk.hpp:1513
T or_opr(const T v0, const T v1)
Definition exprtk.hpp:1597
T roundn(const T v0, const T v1)
Definition exprtk.hpp:1548
T atan2(const T v0, const T v1)
Definition exprtk.hpp:1562
T equal(const T v0, const T v1)
Definition exprtk.hpp:1506
T shl(const T v0, const T v1)
Definition exprtk.hpp:1576
T and_opr(const T v0, const T v1)
Definition exprtk.hpp:1583
T xnor_opr(const T v0, const T v1)
Definition exprtk.hpp:1618
_int64_t to_int64(const T v)
Definition exprtk.hpp:1471
T modulus(const T v0, const T v1)
Definition exprtk.hpp:1520
T max(const T v0, const T v1)
Definition exprtk.hpp:1499
T shr(const T v0, const T v1)
Definition exprtk.hpp:1569
bool is_string_ccondition_node(const expression_node< T > *node)
Definition exprtk.hpp:18967
bool is_left_bracket(const char_t c)
Definition exprtk.hpp:142
static bool parse_nan(Iterator &itr, const Iterator end, T &t)
Definition exprtk.hpp:1858
bool is_true(const double v)
Definition exprtk.hpp:5615
static const double pow10[]
Definition exprtk.hpp:797
bool is_voc_node(const expression_node< T > *node)
Definition exprtk.hpp:18883
bool is_vector_elem_rtc_node(const expression_node< T > *node)
Definition exprtk.hpp:5714
bool string_to_real(Iterator &itr_external, const Iterator end, T &t, numeric::details::real_type_tag)
Definition exprtk.hpp:1932
bool all_nodes_variables(expression_node< T > *const (&b)[N])
Definition exprtk.hpp:5884
bool is_ivector_node(const expression_node< T > *node)
Definition exprtk.hpp:5756
static const std::string assignment_ops_list[]
Definition exprtk.hpp:499
bool all_nodes_valid(expression_node< T > *const (&b)[N])
Definition exprtk.hpp:5860
bool is_sign(const char_t c)
Definition exprtk.hpp:157
T compute_pow10(T d, const int exponent)
Definition exprtk.hpp:1719
bool is_hex_digit(const uchar_t digit)
Definition exprtk.hpp:306
bool is_whitespace(const char_t c)
Definition exprtk.hpp:103
bool is_ivariable_node(const expression_node< T > *node)
Definition exprtk.hpp:5685
bool imatch(const char_t c1, const char_t c2)
Definition exprtk.hpp:190
bool is_unary_node(const expression_node< T > *node)
Definition exprtk.hpp:5661
bool is_invalid(const char_t c)
Definition exprtk.hpp:162
bool is_false(const expression_node< T > *node)
Definition exprtk.hpp:5643
bool is_rebasevector_elem_node(const expression_node< T > *node)
Definition exprtk.hpp:5726
bool is_base_function(const std::string &function_name)
Definition exprtk.hpp:542
bool is_function(const expression_node< T > *node)
Definition exprtk.hpp:5815
bool is_t0ot1ot2ot3_node(const expression_node< T > *node)
Definition exprtk.hpp:18907
long long int _int64_t
Definition exprtk.hpp:101
void construct_branch_pair(std::pair< expression_node< T > *, bool >(&branch)[N], expression_node< T > *b, const std::size_t &index)
Definition exprtk.hpp:6611
bool is_reserved_symbol(const std::string &symbol)
Definition exprtk.hpp:529
static const std::size_t arithmetic_ops_list_size
Definition exprtk.hpp:497
bool is_operator_char(const char_t c)
Definition exprtk.hpp:111
bool is_vector_celem_node(const expression_node< T > *node)
Definition exprtk.hpp:5708
bool is_control_struct(const std::string &cntrl_strct)
Definition exprtk.hpp:555
bool is_bracket(const char_t c)
Definition exprtk.hpp:152
static const std::size_t base_function_list_size
Definition exprtk.hpp:476
bool is_literal_node(const expression_node< T > *node)
Definition exprtk.hpp:5655
bool is_string_assignment_node(const expression_node< T > *node)
Definition exprtk.hpp:18943
void case_normalise(std::string &s)
Definition exprtk.hpp:182
bool is_sf4ext_node(const expression_node< T > *n)
Definition exprtk.hpp:17834
bool is_string_vararg_node(const expression_node< T > *node)
Definition exprtk.hpp:18973
bool string_to_type_converter_impl_ref(Iterator &itr, const Iterator end, T &result)
Definition exprtk.hpp:1781
bool match_impl(const Iterator pattern_begin, const Iterator pattern_end, const Iterator data_begin, const Iterator data_end, const typename std::iterator_traits< Iterator >::value_type &zero_or_more, const typename std::iterator_traits< Iterator >::value_type &exactly_one)
Definition exprtk.hpp:598
static const std::size_t assignment_ops_list_size
Definition exprtk.hpp:505
static const std::string arithmetic_ops_list[]
Definition exprtk.hpp:492
bool is_vov_node(const expression_node< T > *node)
Definition exprtk.hpp:18871
static const std::string reserved_symbols[]
Definition exprtk.hpp:444
bool branch_deletable(const expression_node< T > *node)
Definition exprtk.hpp:5852
bool is_uv_node(const expression_node< T > *node)
Definition exprtk.hpp:18913
bool is_rebasevector_celem_rtc_node(const expression_node< T > *node)
Definition exprtk.hpp:5738
bool is_vector_celem_rtc_node(const expression_node< T > *node)
Definition exprtk.hpp:5720
memory_context_t< T > make_memory_context(vector_holder< T > &vec_holder, vec_data_store< T > &vds)
Definition exprtk.hpp:13470
const char_t & back(const std::string &s)
Definition exprtk.hpp:272
bool is_constant_node(const expression_node< T > *node)
Definition exprtk.hpp:5781
void dump_vector(const std::string &, const T *, const std::size_t)
Definition exprtk.hpp:5167
static const std::string logic_ops_list[]
Definition exprtk.hpp:478
bool is_valid_sf_symbol(const std::string &symbol)
Definition exprtk.hpp:257
bool is_binary_node(const expression_node< T > *node)
Definition exprtk.hpp:5673
bool is_string_node(const expression_node< T > *node)
Definition exprtk.hpp:18919
void dump_ptr(const std::string &, const void *)
Definition exprtk.hpp:5164
bool is_valid_string_char(const char_t c)
Definition exprtk.hpp:175
T value(details::expression_node< T > *n)
Definition exprtk.hpp:15749
bool wc_match(const std::string &wild_card, const std::string &str)
Definition exprtk.hpp:660
static bool parse_inf(Iterator &itr, const Iterator end, T &t, const bool negative)
Definition exprtk.hpp:1891
bool is_const_string_range_node(const expression_node< T > *node)
Definition exprtk.hpp:18937
void load_operations_map(std::multimap< std::string, details::base_operation_t, details::ilesscompare > &m)
Definition exprtk.hpp:19395
static const std::string reserved_words[]
Definition exprtk.hpp:433
bool is_boc_node(const expression_node< T > *node)
Definition exprtk.hpp:18895
bool is_string_condition_node(const expression_node< T > *node)
Definition exprtk.hpp:18961
bool valid_exponent(const int exponent, numeric::details::real_type_tag)
Definition exprtk.hpp:1925
bool is_assert_node(const expression_node< T > *node)
Definition exprtk.hpp:5846
void disable_type_checking(Parser &p)
Definition exprtk.hpp:22168
static const std::string inequality_ops_list[]
Definition exprtk.hpp:507
static const std::size_t cntrl_struct_list_size
Definition exprtk.hpp:490
bool is_string_function_node(const expression_node< T > *node)
Definition exprtk.hpp:18955
bool is_letter_or_digit(const char_t c)
Definition exprtk.hpp:137
bool is_cov_node(const expression_node< T > *node)
Definition exprtk.hpp:18877
bool is_const_string_node(const expression_node< T > *node)
Definition exprtk.hpp:18931
bool is_genricstring_range_node(const expression_node< T > *node)
Definition exprtk.hpp:18979
uchar_t const * uchar_cptr
Definition exprtk.hpp:99
bool is_null_node(const expression_node< T > *node)
Definition exprtk.hpp:5791
T axn(const T a, const T x)
Definition exprtk.hpp:11769
T axnb(const T a, const T x, const T b)
Definition exprtk.hpp:11776
bool sequence_match(const std::string &pattern, const std::string &str, std::size_t &diff_index, char_t &diff_value)
Definition exprtk.hpp:686
static const std::size_t inequality_ops_list_size
Definition exprtk.hpp:514
std::string to_str(int i)
Definition exprtk.hpp:277
unsigned long long int _uint64_t
Definition exprtk.hpp:100
bool is_variable_node(const expression_node< T > *node)
Definition exprtk.hpp:5679
bool is_vector_node(const expression_node< T > *node)
Definition exprtk.hpp:5750
bool is_negate_node(const expression_node< T > *node)
Definition exprtk.hpp:5835
bool is_swap_node(const expression_node< T > *node)
Definition exprtk.hpp:5809
void destroy_node(expression_node< T > *&node)
Definition exprtk.hpp:6019
bool is_string_concat_node(const expression_node< T > *node)
Definition exprtk.hpp:18949
bool is_reserved_word(const std::string &symbol)
Definition exprtk.hpp:516
bool is_letter(const char_t c)
Definition exprtk.hpp:126
bool is_vector_elem_node(const expression_node< T > *node)
Definition exprtk.hpp:5702
bool wc_imatch(const std::string &wild_card, const std::string &str)
Definition exprtk.hpp:673
bool is_return_node(const expression_node< T > *node)
Definition exprtk.hpp:5827
static const std::size_t reserved_words_size
Definition exprtk.hpp:442
static const std::string cntrl_struct_list[]
Definition exprtk.hpp:485
bool is_cob_node(const expression_node< T > *node)
Definition exprtk.hpp:18889
unsigned char uchar_t
Definition exprtk.hpp:97
bool is_generally_string_node(const expression_node< T > *node)
Definition exprtk.hpp:18985
static const std::string base_function_list[]
Definition exprtk.hpp:463
uchar_t hex_to_bin(uchar_t h)
Definition exprtk.hpp:313
bool is_digit(const char_t c)
Definition exprtk.hpp:132
uchar_t * uchar_ptr
Definition exprtk.hpp:98
bool is_rebasevector_celem_node(const expression_node< T > *node)
Definition exprtk.hpp:5744
static const std::size_t reserved_symbols_size
Definition exprtk.hpp:461
bool is_string_range_node(const expression_node< T > *node)
Definition exprtk.hpp:18925
void free_node(NodeAllocator &, expression_node< T > *&node)
Definition exprtk.hpp:6007
bool is_continue_node(const expression_node< T > *node)
Definition exprtk.hpp:5803
bool is_logic_opr(const std::string &lgc_opr)
Definition exprtk.hpp:568
char_t const * char_cptr
Definition exprtk.hpp:96
bool parse_hex(Iterator &itr, Iterator end, char_t &result)
Definition exprtk.hpp:322
bool is_vararg_node(const expression_node< T > *node)
Definition exprtk.hpp:5821
void set_zero_value(T *data, const std::size_t size)
Definition exprtk.hpp:786
static const std::size_t pow10_size
Definition exprtk.hpp:806
const char_t & front(const std::string &s)
Definition exprtk.hpp:267
char_t * char_ptr
Definition exprtk.hpp:95
void free_all_nodes(NodeAllocator &node_allocator, expression_node< T > *(&b)[N])
Definition exprtk.hpp:5984
bool is_sf3ext_node(const expression_node< T > *n)
Definition exprtk.hpp:17656
bool is_rebasevector_elem_rtc_node(const expression_node< T > *node)
Definition exprtk.hpp:5732
bool cleanup_escapes(std::string &s)
Definition exprtk.hpp:345
static const std::size_t logic_ops_list_size
Definition exprtk.hpp:483
bool is_break_node(const expression_node< T > *node)
Definition exprtk.hpp:5797
bool is_right_bracket(const char_t c)
Definition exprtk.hpp:147
void init_branches(std::pair< expression_node< T > *, bool >(&branch)[N], expression_node< T > *b0, expression_node< T > *b1=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b2=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b3=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b4=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b5=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b6=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b7=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b8=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b9=reinterpret_cast< expression_node< T > * >(0))
Definition exprtk.hpp:6631
bool is_neg_unary_node(const expression_node< T > *node)
Definition exprtk.hpp:5667
bool is_t0ot1ot2_node(const expression_node< T > *node)
Definition exprtk.hpp:18901
static char_cptr date
Definition exprtk.hpp:45868
static char_cptr min_cpp
Definition exprtk.hpp:45869
static std::string data()
Definition exprtk.hpp:45871
static char_cptr version
Definition exprtk.hpp:45864
static char_cptr library
Definition exprtk.hpp:45863
void dump(const lexer::generator &generator)
Definition exprtk.hpp:3464
void dump_error(const type &error)
Definition exprtk.hpp:22156
bool update_error(type &error, const std::string &expression)
Definition exprtk.hpp:22114
type make_error(const error_mode mode, const std::string &diagnostic="", const std::string &src_location="")
Definition exprtk.hpp:22071
std::string to_str(error_mode mode)
Definition exprtk.hpp:22098
void print_type(const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
Definition exprtk.hpp:43547
file_descriptor * make_handle(T v)
Definition exprtk.hpp:43903
void kahan_sum(T &sum, T &error, const T v)
Definition exprtk.hpp:44257
bool invalid_range(const Vector &v, const std::size_t r0, const std::size_t r1)
Definition exprtk.hpp:44210
void enable_zero_parameters(FunctionType &func)
Definition exprtk.hpp:19497
bool collect_variables(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
Definition exprtk.hpp:41742
vector_access_runtime_check * vector_access_runtime_check_ptr
Definition exprtk.hpp:2192
void set_max_num_args(FunctionType &func, const std::size_t &num_args)
Definition exprtk.hpp:19535
bool is_valid(const expression< T > &expr)
Definition exprtk.hpp:22034
void disable_has_side_effects(FunctionType &func)
Definition exprtk.hpp:19520
compilation_check * compilation_check_ptr
Definition exprtk.hpp:2227
vector_view< T > make_vector_view(T *data, const std::size_t size, const std::size_t offset=0)
Definition exprtk.hpp:4660
void disable_zero_parameters(FunctionType &func)
Definition exprtk.hpp:19508
assert_check * assert_check_ptr
Definition exprtk.hpp:2212
T third_derivative(const expression< T > &e, T &x, const T &h=T(0.0001))
Definition exprtk.hpp:41958
bool collect_functions(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
Definition exprtk.hpp:41803
loop_runtime_check * loop_runtime_check_ptr
Definition exprtk.hpp:2168
bool compute(const std::string &expression_string, T &result)
Definition exprtk.hpp:42070
T derivative(const expression< T > &e, T &x, const T &h=T(0.00000001))
Definition exprtk.hpp:41915
T second_derivative(const expression< T > &e, T &x, const T &h=T(0.00001))
Definition exprtk.hpp:41936
std::string to_str(const StringView &view)
Definition exprtk.hpp:4869
void set_min_num_args(FunctionType &func, const std::size_t &num_args)
Definition exprtk.hpp:19526
void enable_has_side_effects(FunctionType &func)
Definition exprtk.hpp:19514
T integrate(const expression< T > &e, T &x, const T &r0, const T &r1, const std::size_t number_of_intervals=1000000)
Definition exprtk.hpp:41863
virtual ~assert_check()
Definition exprtk.hpp:2204
virtual void handle_assert(const assert_context &)
Definition exprtk.hpp:2207
virtual bool continue_compilation(compilation_context &)=0
details::T0oT1< T, T0, T1 > type0
Definition exprtk.hpp:17854
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition exprtk.hpp:17051
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition exprtk.hpp:17072
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition exprtk.hpp:17092
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition exprtk.hpp:17113
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition exprtk.hpp:17134
details::functor_t< T > functor_t
Definition exprtk.hpp:17046
details::T0oT1oT2< T, T0, T1, T2, typename T0oT1oT2process< T >::mode0 > type0
Definition exprtk.hpp:17860
details::T0oT1oT2_sf3< T, T0, T1, T2 > sf3_type
Definition exprtk.hpp:17862
details::T0oT1oT2< T, T0, T1, T2, typename T0oT1oT2process< T >::mode1 > type1
Definition exprtk.hpp:17861
details::sf3ext_type_node< T, T0, T1, T2 > sf3_type_node
Definition exprtk.hpp:17863
details::T0oT1oT2oT3_sf4< T, T0, T1, T2, T3 > sf4_type
Definition exprtk.hpp:17874
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode2 > type2
Definition exprtk.hpp:17871
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode0 > type0
Definition exprtk.hpp:17869
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode1 > type1
Definition exprtk.hpp:17870
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode4 > type4
Definition exprtk.hpp:17873
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode3 > type3
Definition exprtk.hpp:17872
static T process(const T &t0, const T &t1, const T &t2, const bfunc_t bf0, const bfunc_t bf1)
Definition exprtk.hpp:17008
static T process(const T &t0, const T &t1, const T &t2, const bfunc_t bf0, const bfunc_t bf1)
Definition exprtk.hpp:17026
details::functor_t< T > functor_t
Definition exprtk.hpp:17003
static T process(Type t1, Type t2)
Definition exprtk.hpp:15495
static T process(Type t1, Type t2, Type t3)
Definition exprtk.hpp:15496
static details::operator_type operation()
Definition exprtk.hpp:15499
static void assign(RefType t1, Type t2)
Definition exprtk.hpp:15497
opr_base< T >::Type Type
Definition exprtk.hpp:15492
opr_base< T >::RefType RefType
Definition exprtk.hpp:15493
static expression_node< T >::node_type type()
Definition exprtk.hpp:15498
static expression_node< T >::node_type type()
Definition exprtk.hpp:15647
static T process(Type t1, Type t2)
Definition exprtk.hpp:15646
static details::operator_type operation()
Definition exprtk.hpp:15648
opr_base< T >::Type Type
Definition exprtk.hpp:15644
static void execute(std::string &s, char_cptr data, const std::size_t size)
Definition exprtk.hpp:10972
static void execute(std::string &s, char_cptr data, const std::size_t size)
Definition exprtk.hpp:10966
base_operation_t(const operator_type t, const unsigned int &np)
Definition exprtk.hpp:5104
static bool cmp(const char_t c0, const char_t c1)
Definition exprtk.hpp:591
virtual bool process(const std::string &unknown_symbol, symbol_table_t &symbol_table, std::string &)
Definition exprtk.hpp:41681
static bool collection_pass(const std::string &expression_string, std::set< std::string > &symbol_set, const bool collect_variables, const bool collect_functions, const bool vector_pass, symbol_table_t &ext_symbol_table)
Definition exprtk.hpp:41691
parser_t::dependent_entity_collector::symbol_t symbol_t
Definition exprtk.hpp:41668
exprtk::symbol_table< T > symbol_table_t
Definition exprtk.hpp:41665
parser_t::unknown_symbol_resolver usr_t
Definition exprtk.hpp:41669
exprtk::expression< T > expression_t
Definition exprtk.hpp:41666
static bool cmp(const char_t c0, const char_t c1)
Definition exprtk.hpp:583
static T process(Type t1, Type t2)
Definition exprtk.hpp:15534
static details::operator_type operation()
Definition exprtk.hpp:15538
static void assign(RefType t1, Type t2)
Definition exprtk.hpp:15536
opr_base< T >::RefType RefType
Definition exprtk.hpp:15532
static expression_node< T >::node_type type()
Definition exprtk.hpp:15537
static T process(Type t1, Type t2, Type t3)
Definition exprtk.hpp:15535
opr_base< T >::Type Type
Definition exprtk.hpp:15531
opr_base< T >::Type Type
Definition exprtk.hpp:15612
static T process(Type t1, Type t2)
Definition exprtk.hpp:15613
static expression_node< T >::node_type type()
Definition exprtk.hpp:15615
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15614
static details::operator_type operation()
Definition exprtk.hpp:15616
static expression_node< T >::node_type type()
Definition exprtk.hpp:15626
static details::operator_type operation()
Definition exprtk.hpp:15627
static T process(Type t1, Type t2)
Definition exprtk.hpp:15624
opr_base< T >::Type Type
Definition exprtk.hpp:15622
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15625
static void execute(T_(&v)[1], const branch_t(&b)[1])
Definition exprtk.hpp:14589
static void execute(T_(&v)[2], const branch_t(&b)[2])
Definition exprtk.hpp:14579
static void execute(T_(&v)[3], const branch_t(&b)[3])
Definition exprtk.hpp:14568
static void execute(T_(&v)[4], const branch_t(&b)[4])
Definition exprtk.hpp:14556
static void execute(T_(&v)[5], const branch_t(&b)[5])
Definition exprtk.hpp:14543
static void execute(T_(&v)[6], const branch_t(&b)[6])
Definition exprtk.hpp:14529
static void execute(T_(&v)[BranchCount], const branch_t(&b)[BranchCount])
Definition exprtk.hpp:14517
static T_ execute(ifunction &f, T_(&v)[10])
Definition exprtk.hpp:14671
static T_ execute(ifunction &f, T_(&v)[11])
Definition exprtk.hpp:14664
static T_ execute(ifunction &f, T_(&v)[12])
Definition exprtk.hpp:14657
static T_ execute(ifunction &f, T_(&v)[13])
Definition exprtk.hpp:14650
static T_ execute(ifunction &f, T_(&v)[14])
Definition exprtk.hpp:14643
static T_ execute(ifunction &f, T_(&v)[15])
Definition exprtk.hpp:14636
static T_ execute(ifunction &f, T_(&v)[16])
Definition exprtk.hpp:14629
static T_ execute(ifunction &f, T_(&v)[17])
Definition exprtk.hpp:14622
static T_ execute(ifunction &f, T_(&v)[18])
Definition exprtk.hpp:14615
static T_ execute(ifunction &f, T_(&v)[19])
Definition exprtk.hpp:14608
static T_ execute(ifunction &f, T_(&v)[1])
Definition exprtk.hpp:14734
static T_ execute(ifunction &f, T_(&v)[20])
Definition exprtk.hpp:14601
static T_ execute(ifunction &f, T_(&v)[2])
Definition exprtk.hpp:14727
static T_ execute(ifunction &f, T_(&v)[3])
Definition exprtk.hpp:14720
static T_ execute(ifunction &f, T_(&v)[4])
Definition exprtk.hpp:14713
static T_ execute(ifunction &f, T_(&v)[5])
Definition exprtk.hpp:14706
static T_ execute(ifunction &f, T_(&v)[6])
Definition exprtk.hpp:14699
static T_ execute(ifunction &f, T_(&v)[7])
Definition exprtk.hpp:14692
static T_ execute(ifunction &f, T_(&v)[8])
Definition exprtk.hpp:14685
static T_ execute(ifunction &f, T_(&v)[9])
Definition exprtk.hpp:14678
static T execute(ifunction &, branch_t(&)[ParamCount])
Definition exprtk.hpp:14596
T(* bfunc_t)(Type t0, Type t1)
Definition exprtk.hpp:2114
T(* qfunc_t)(Type t0, Type t1, Type t2, Type t3)
Definition exprtk.hpp:2112
T(* tfunc_t)(Type t0, Type t1, Type t2)
Definition exprtk.hpp:2113
static expression_node< T >::node_type type()
Definition exprtk.hpp:15594
static T process(Type t1, Type t2)
Definition exprtk.hpp:15592
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15593
opr_base< T >::Type Type
Definition exprtk.hpp:15590
static details::operator_type operation()
Definition exprtk.hpp:15595
static T process(Type t1, Type t2)
Definition exprtk.hpp:15603
static expression_node< T >::node_type type()
Definition exprtk.hpp:15605
static details::operator_type operation()
Definition exprtk.hpp:15606
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15604
opr_base< T >::Type Type
Definition exprtk.hpp:15601
bool operator()(const std::string &s1, const std::string &s2) const
Definition exprtk.hpp:215
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15729
static details::operator_type operation()
Definition exprtk.hpp:15731
static T process(const T &, const T &)
Definition exprtk.hpp:15728
opr_base< T >::Type Type
Definition exprtk.hpp:15726
static expression_node< T >::node_type type()
Definition exprtk.hpp:15730
opr_base< T >::Type Type
Definition exprtk.hpp:15704
static T process(const T &, const T &)
Definition exprtk.hpp:15706
static expression_node< T >::node_type type()
Definition exprtk.hpp:15708
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15707
static details::operator_type operation()
Definition exprtk.hpp:15709
opr_base< T >::Type Type
Definition exprtk.hpp:15737
static expression_node< T >::node_type type()
Definition exprtk.hpp:15744
static details::operator_type operation()
Definition exprtk.hpp:15745
static T process(const T &t0, const T &t1, const T &t2)
Definition exprtk.hpp:15739
static T process(const std::string &t0, const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15740
static details::operator_type operation()
Definition exprtk.hpp:15720
static T process(const T &, const T &)
Definition exprtk.hpp:15717
static expression_node< T >::node_type type()
Definition exprtk.hpp:15719
opr_base< T >::Type Type
Definition exprtk.hpp:15715
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15718
const details::_uint64_t & max_loop_iterations_
Definition exprtk.hpp:7401
void reset(const _uint64_t initial_value=0) const
Definition exprtk.hpp:7368
loop_runtime_checker(loop_runtime_check_ptr loop_runtime_check, loop_runtime_check::loop_types lp_typ=loop_runtime_check::e_invalid)
Definition exprtk.hpp:7358
loop_runtime_check::loop_types loop_type_
Definition exprtk.hpp:7402
loop_runtime_check_ptr loop_runtime_check_
Definition exprtk.hpp:7400
details(const std::size_t &vsize, const unsigned int loop_batch_size=global_loop_batch_size)
Definition exprtk.hpp:5124
static T process(Type t1, Type t2)
Definition exprtk.hpp:15570
static expression_node< T >::node_type type()
Definition exprtk.hpp:15572
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15571
static details::operator_type operation()
Definition exprtk.hpp:15573
opr_base< T >::Type Type
Definition exprtk.hpp:15568
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15582
static details::operator_type operation()
Definition exprtk.hpp:15584
opr_base< T >::Type Type
Definition exprtk.hpp:15579
static T process(Type t1, Type t2)
Definition exprtk.hpp:15581
static expression_node< T >::node_type type()
Definition exprtk.hpp:15583
vector_holder_t * vector_holder_ptr
Definition exprtk.hpp:13452
vector_node< T > * vector_node_ptr
Definition exprtk.hpp:13450
vector_holder< T > vector_holder_t
Definition exprtk.hpp:13451
opr_base< T >::Type Type
Definition exprtk.hpp:15544
static T process(Type t1, Type t2)
Definition exprtk.hpp:15547
opr_base< T >::RefType RefType
Definition exprtk.hpp:15545
static expression_node< T >::node_type type()
Definition exprtk.hpp:15549
static details::operator_type operation()
Definition exprtk.hpp:15550
static void assign(RefType t1, Type t2)
Definition exprtk.hpp:15548
opr_base< T >::Type Type
Definition exprtk.hpp:15505
opr_base< T >::RefType RefType
Definition exprtk.hpp:15506
static expression_node< T >::node_type type()
Definition exprtk.hpp:15511
static details::operator_type operation()
Definition exprtk.hpp:15512
static void assign(RefType t1, Type t2)
Definition exprtk.hpp:15510
static T process(Type t1, Type t2, Type t3)
Definition exprtk.hpp:15509
static T process(Type t1, Type t2)
Definition exprtk.hpp:15508
static T process(Type t1, Type t2)
Definition exprtk.hpp:15656
static details::operator_type operation()
Definition exprtk.hpp:15658
opr_base< T >::Type Type
Definition exprtk.hpp:15654
static expression_node< T >::node_type type()
Definition exprtk.hpp:15657
static expression_node< T >::node_type type()
Definition exprtk.hpp:15637
static T process(Type t1, Type t2)
Definition exprtk.hpp:15635
opr_base< T >::Type Type
Definition exprtk.hpp:15633
static details::operator_type operation()
Definition exprtk.hpp:15638
static T process(const std::string &t1, const std::string &t2)
Definition exprtk.hpp:15636
virtual void collect_nodes(noderef_list_t &)
Definition exprtk.hpp:5526
std::vector< node_pp_t > noderef_list_t
Definition exprtk.hpp:5521
std::size_t compute_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2) const
Definition exprtk.hpp:6123
std::pair< node_ptr_t, bool > nb_pair_t
Definition exprtk.hpp:6032
std::size_t max_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2, const BranchType &n3) const
Definition exprtk.hpp:6102
virtual std::size_t node_depth() const
Definition exprtk.hpp:6042
std::size_t max_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2) const
Definition exprtk.hpp:6095
std::size_t compute_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2, const BranchType &n3) const
Definition exprtk.hpp:6136
std::size_t compute_node_depth(const nb_pair_t(&branch)[N]) const
Definition exprtk.hpp:6067
void collect(Node *&node, NodeSequence &delete_node_list) const
Definition exprtk.hpp:6210
std::size_t compute_node_depth(const Node *const &node) const
Definition exprtk.hpp:6044
std::size_t compute_node_depth(const Sequence< nb_pair_t, Allocator > &branch_list) const
Definition exprtk.hpp:6170
void collect(const nb_pair_t &branch, NodeSequence &delete_node_list) const
Definition exprtk.hpp:6203
std::size_t compute_node_depth(const BranchType &n0, const BranchType &n1) const
Definition exprtk.hpp:6111
void collect(const nb_pair_t(&branch)[N], NodeSequence &delete_node_list) const
Definition exprtk.hpp:6217
void collect(const Sequence< nb_pair_t, Allocator > &branch, NodeSequence &delete_node_list) const
Definition exprtk.hpp:6229
std::size_t compute_node_depth(const Sequence< node_ptr_t, Allocator > &branch_list) const
Definition exprtk.hpp:6150
void collect(node_ptr_t const &node, const bool deletable, NodeSequence &delete_node_list) const
Definition exprtk.hpp:6192
std::size_t max_node_depth(const BranchType &n0, const BranchType &n1) const
Definition exprtk.hpp:6089
std::size_t compute_node_depth(const nb_pair_t &branch) const
Definition exprtk.hpp:6055
void collect(const Sequence< node_ptr_t, Allocator > &branch_list, NodeSequence &delete_node_list) const
Definition exprtk.hpp:6241
void collect(const Sequence< node_ptr_t, AllocatorT > &branch_list, const Sequence< Boolean, AllocatorB > &branch_deletable_list, NodeSequence &delete_node_list) const
Definition exprtk.hpp:6255
static const expression_node< T >::node_type result
Definition exprtk.hpp:17157
static const expression_node< T >::node_type result
Definition exprtk.hpp:17179
static const expression_node< T >::node_type result
Definition exprtk.hpp:17201
opr_base< T >::Type Type
Definition exprtk.hpp:15674
static details::operator_type operation()
Definition exprtk.hpp:15678
static T process(Type t1, Type t2)
Definition exprtk.hpp:15676
static expression_node< T >::node_type type()
Definition exprtk.hpp:15677
functor_t::ufunc_t unary_functor_t
Definition exprtk.hpp:15486
functor_t::tfunc_t trinary_functor_t
Definition exprtk.hpp:15484
details::functor_t< T >::RefType RefType
Definition exprtk.hpp:15481
details::functor_t< T >::Type Type
Definition exprtk.hpp:15480
functor_t::bfunc_t binary_functor_t
Definition exprtk.hpp:15485
details::functor_t< T > functor_t
Definition exprtk.hpp:15482
functor_t::qfunc_t quaternary_functor_t
Definition exprtk.hpp:15483
static details::operator_type operation()
Definition exprtk.hpp:15668
opr_base< T >::Type Type
Definition exprtk.hpp:15664
static expression_node< T >::node_type type()
Definition exprtk.hpp:15667
static T process(Type t1, Type t2)
Definition exprtk.hpp:15666
static std::string result()
Definition exprtk.hpp:16992
static expression_node< T >::node_type type()
Definition exprtk.hpp:15561
opr_base< T >::RefType RefType
Definition exprtk.hpp:15557
opr_base< T >::Type Type
Definition exprtk.hpp:15556
static details::operator_type operation()
Definition exprtk.hpp:15562
static void assign(RefType t1, Type t2)
Definition exprtk.hpp:15560
static T process(Type t1, Type t2)
Definition exprtk.hpp:15559
string_base_node< T > * strbase_ptr_t
Definition exprtk.hpp:8449
std::size_t const_size() const
Definition exprtk.hpp:8400
std::size_t cache_size() const
Definition exprtk.hpp:8405
std::pair< bool, expression_node_ptr > n1_e
Definition exprtk.hpp:8411
expression_node< T > * expression_node_ptr
Definition exprtk.hpp:8300
std::pair< std::size_t, std::size_t > cached_range_t
Definition exprtk.hpp:8301
std::pair< bool, std::size_t > n0_c
Definition exprtk.hpp:8412
std::pair< bool, std::size_t > n1_c
Definition exprtk.hpp:8413
bool operator()(std::size_t &r0, std::size_t &r1, const std::size_t &size=std::numeric_limits< std::size_t >::max()) const
Definition exprtk.hpp:8361
std::pair< bool, expression_node_ptr > n0_e
Definition exprtk.hpp:8410
static void process(T *base_ptr, const std::size_t size)
Definition exprtk.hpp:759
details::functor_t< T >::Type Type
Definition exprtk.hpp:11785
functor_t::tfunc_t trinary_functor_t
Definition exprtk.hpp:11788
functor_t::ufunc_t unary_functor_t
Definition exprtk.hpp:11790
details::functor_t< T > functor_t
Definition exprtk.hpp:11786
functor_t::bfunc_t binary_functor_t
Definition exprtk.hpp:11789
functor_t::qfunc_t quaternary_functor_t
Definition exprtk.hpp:11787
static void assign(RefType t1, Type t2)
Definition exprtk.hpp:15523
static T process(Type t1, Type t2, Type t3)
Definition exprtk.hpp:15522
static T process(Type t1, Type t2)
Definition exprtk.hpp:15521
static expression_node< T >::node_type type()
Definition exprtk.hpp:15524
opr_base< T >::RefType RefType
Definition exprtk.hpp:15519
static details::operator_type operation()
Definition exprtk.hpp:15525
opr_base< T >::Type Type
Definition exprtk.hpp:15518
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:15831
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:15805
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:15817
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:15811
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:15824
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:15780
opr_base< T >::Type Type
Definition exprtk.hpp:15775
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:15954
opr_base< T >::Type Type
Definition exprtk.hpp:15909
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:15929
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:15935
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:15941
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:15947
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:15914
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:16172
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:16142
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:16112
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:16161
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:16151
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:16135
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:16069
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:16087
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:16081
opr_base< T >::Type Type
Definition exprtk.hpp:16036
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:16041
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:16095
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:16075
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:16016
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:16010
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:15998
opr_base< T >::Type Type
Definition exprtk.hpp:15965
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:16024
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:16004
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:15970
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:16241
opr_base< T >::Type Type
Definition exprtk.hpp:16187
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:16222
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:16252
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:16231
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:16192
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:16215
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:15847
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:15898
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:15872
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:15891
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:15878
opr_base< T >::Type Type
Definition exprtk.hpp:15842
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:15884
static T process_4(const Sequence &arg_list)
Definition exprtk.hpp:16318
static T process_2(const Sequence &arg_list)
Definition exprtk.hpp:16303
static T process_1(const Sequence &arg_list)
Definition exprtk.hpp:16297
static T process_7(const Sequence &arg_list)
Definition exprtk.hpp:16348
static T process_5(const Sequence &arg_list)
Definition exprtk.hpp:16327
static T process_8(const Sequence &arg_list)
Definition exprtk.hpp:16360
static T process(const Sequence< Type, Allocator > &arg_list)
Definition exprtk.hpp:16272
static T process_3(const Sequence &arg_list)
Definition exprtk.hpp:16310
static T process_6(const Sequence &arg_list)
Definition exprtk.hpp:16337
vector_interface< T > * ivector_ptr
Definition exprtk.hpp:16376
static T process(const ivector_ptr v)
Definition exprtk.hpp:16378
static T process(const ivector_ptr v)
Definition exprtk.hpp:16577
vector_interface< T > * ivector_ptr
Definition exprtk.hpp:16575
static control_block * create(const std::size_t &dsize, data_t data_ptr=data_t(0), bool dstrct=false)
Definition exprtk.hpp:5213
static void destroy(control_block *&cntrl_blck)
Definition exprtk.hpp:5226
control_block & operator=(const control_block &)
control_block(const std::size_t &dsize, data_t dptr, bool dstrct=false)
Definition exprtk.hpp:5196
vector_interface< T > * ivector_ptr
Definition exprtk.hpp:16611
static T process(const ivector_ptr v)
Definition exprtk.hpp:16613
vector_interface< T > * ivector_ptr
Definition exprtk.hpp:16587
static T process(const ivector_ptr v)
Definition exprtk.hpp:16589
vector_interface< T > * ivector_ptr
Definition exprtk.hpp:16476
static T process(const ivector_ptr v)
Definition exprtk.hpp:16478
static details::operator_type operation()
Definition exprtk.hpp:15698
static expression_node< T >::node_type type()
Definition exprtk.hpp:15697
opr_base< T >::Type Type
Definition exprtk.hpp:15694
static T process(Type t1, Type t2)
Definition exprtk.hpp:15696
static expression_node< T >::node_type type()
Definition exprtk.hpp:15687
static details::operator_type operation()
Definition exprtk.hpp:15688
opr_base< T >::Type Type
Definition exprtk.hpp:15684
static T process(Type t1, Type t2)
Definition exprtk.hpp:15686
data_pack(void *ptr, const data_type dt, const std::size_t sz=0)
Definition exprtk.hpp:21529
std::vector< data_pack > local_data_list_t
Definition exprtk.hpp:21540
static cntrl_blck_ptr_t create(expression_ptr e)
Definition exprtk.hpp:21599
static std::string to_str(data_type dt)
Definition exprtk.hpp:21506
static void destroy(cntrl_blck_ptr_t &cntrl_blck)
Definition exprtk.hpp:21604
results_context< T > results_context_t
Definition exprtk.hpp:21541
local_data_list_t local_data_list
Definition exprtk.hpp:21622
function_t & setup(expression_t &expr)
Definition exprtk.hpp:42646
void copy(const varref_t &src_v, var_t &dest_v)
Definition exprtk.hpp:42770
void copy(const str_t &src_str, lstr_vec_t &dest_str)
Definition exprtk.hpp:42835
virtual T value(expression_t &e)
Definition exprtk.hpp:42853
std::vector< std::string * > lstr_vec_t
Definition exprtk.hpp:42588
base_func(const std::size_t &pc=0)
Definition exprtk.hpp:42592
exprtk::ifunction< T > function_t
Definition exprtk.hpp:42582
void copy(const var_t &src_v, lvr_vec_t &dest_v)
Definition exprtk.hpp:42813
void copy(const lvr_vec_t &src_v, var_t &dest_v)
Definition exprtk.hpp:42794
void update(const T &v0, const T &v1, const T &v2, const T &v3)
Definition exprtk.hpp:42622
void update(const T &v0, const T &v1, const T &v2)
Definition exprtk.hpp:42616
void update(const T &v0, const T &v1)
Definition exprtk.hpp:42611
std::vector< lvarref_t > lvr_vec_t
Definition exprtk.hpp:42587
void update(const T &v0, const T &v1, const T &v2, const T &v3, const T &v4, const T &v5)
Definition exprtk.hpp:42635
std::vector< std::string > str_t
Definition exprtk.hpp:42585
void copy(const var_t &src_v, varref_t &dest_v)
Definition exprtk.hpp:42786
void copy(const lstr_vec_t &src_v, str_t &dest_v)
Definition exprtk.hpp:42778
void update(const T &v0, const T &v1, const T &v2, const T &v3, const T &v4)
Definition exprtk.hpp:42628
std::pair< T *, std::size_t > lvarref_t
Definition exprtk.hpp:42586
function(const std::string &name, const std::string &expression, const std::string &v0, const std::string &v1, const std::string &v2, const std::string &v3, const std::string &v4)
Definition exprtk.hpp:42497
function & vars(const std::string &v0, const std::string &v1, const std::string &v2)
Definition exprtk.hpp:42536
function & vars(const std::string &v0, const std::string &v1)
Definition exprtk.hpp:42528
function & vars(const std::string &v0, const std::string &v1, const std::string &v2, const std::string &v3)
Definition exprtk.hpp:42546
function & name(const std::string &n)
Definition exprtk.hpp:42510
function & vars(const std::string &v0, const std::string &v1, const std::string &v2, const std::string &v3, const std::string &v4)
Definition exprtk.hpp:42558
function(const std::string &name, const std::string &expression, const std::string &v0, const std::string &v1, const std::string &v2)
Definition exprtk.hpp:42475
function & expression(const std::string &e)
Definition exprtk.hpp:42516
function(const std::string &name, const std::string &expression, const std::string &v0, const std::string &v1)
Definition exprtk.hpp:42466
std::deque< std::string > v_
Definition exprtk.hpp:42574
function & var(const std::string &v)
Definition exprtk.hpp:42522
function(const std::string &name, const std::string &expression, const std::string &v0)
Definition exprtk.hpp:42457
function(const std::string &name, const std::string &expression)
Definition exprtk.hpp:42451
function(const std::string &name, const std::string &expression, const std::string &v0, const std::string &v1, const std::string &v2, const std::string &v3)
Definition exprtk.hpp:42486
scoped_bft & operator=(const scoped_bft &)
std::vector< lexer::token_inserter * > token_inserter_list
Definition exprtk.hpp:4337
bool register_inserter(lexer::token_inserter *inserter)
Definition exprtk.hpp:4232
lexer::token_joiner * error_token_joiner
Definition exprtk.hpp:4341
std::vector< lexer::token_joiner * > token_joiner_list
Definition exprtk.hpp:4336
bool run_inserters(lexer::generator &g)
Definition exprtk.hpp:4290
bool register_scanner(lexer::token_scanner *scanner)
Definition exprtk.hpp:4190
bool run_joiners(lexer::generator &g)
Definition exprtk.hpp:4268
std::vector< lexer::token_modifier * > token_modifier_list
Definition exprtk.hpp:4335
bool register_joiner(lexer::token_joiner *joiner)
Definition exprtk.hpp:4218
bool register_modifier(lexer::token_modifier *modifier)
Definition exprtk.hpp:4204
lexer::token_modifier * error_token_modifier
Definition exprtk.hpp:4340
std::vector< lexer::token_scanner * > token_scanner_list
Definition exprtk.hpp:4334
bool run_scanners(lexer::generator &g)
Definition exprtk.hpp:4312
lexer::token_scanner * error_token_scanner
Definition exprtk.hpp:4339
bool run_modifiers(lexer::generator &g)
Definition exprtk.hpp:4246
lexer::token_inserter * error_token_inserter
Definition exprtk.hpp:4342
std::size_t position
Definition exprtk.hpp:2400
bool is_error() const
Definition exprtk.hpp:2387
std::string value
Definition exprtk.hpp:2399
token & set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition exprtk.hpp:2287
token & set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition exprtk.hpp:2277
token & set_string(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition exprtk.hpp:2297
token & set_operator(const token_type tt, const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition exprtk.hpp:2265
token & set_string(const std::string &s, const std::size_t p)
Definition exprtk.hpp:2306
token & set_error(const token_type et, const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition exprtk.hpp:2315
static std::string to_str(token_type t)
Definition exprtk.hpp:2340
virtual void handle_runtime_violation(const violation_context &)
Definition exprtk.hpp:2159
details::_uint64_t max_loop_iterations
Definition exprtk.hpp:2145
static bool is_greater(const T_ &v, const T_ &end)
Definition exprtk.hpp:22694
static bool is_less(const T_ &v, const T_ &begin)
Definition exprtk.hpp:22689
static bool is_within(const T_ &v, const T_ &begin, const T_ &end)
Definition exprtk.hpp:22683
std::vector< std::pair< expression_node_ptr, bool > > arg_list_t
Definition exprtk.hpp:32729
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34807
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35256
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35032
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35118
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35580
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35375
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition exprtk.hpp:36863
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36877
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36980
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35784
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36627
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36730
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36746
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36849
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:37791
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:37619
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38784
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38745
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39287
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39326
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39791
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39829
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40333
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40371
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36545
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36496
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36561
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36611
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38057
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38229
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38904
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38865
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39447
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39408
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39912
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39951
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40454
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40493
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:37597
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:37530
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38723
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38684
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39265
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39226
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39769
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39731
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40311
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40273
static bool compile(expression_generator< Type > &expr_gen, const std::string &id, T0 t0, T1 t1, T2 t2, expression_node_ptr &result)
Definition exprtk.hpp:35888
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &sf3opr, T0 t0, T1 t1, T2 t2)
Definition exprtk.hpp:35864
static bool compile_left(expression_generator< Type > &expr_gen, ExternalType t, const details::operator_type &operation, expression_node_ptr &sf3node, expression_node_ptr &result)
Definition exprtk.hpp:36014
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &sf4opr, T0 t0, T1 t1, T2 t2, T3 t3)
Definition exprtk.hpp:35907
static bool compile_left_impl(expression_generator< Type > &expr_gen, const std::string &id, ExternalType t, expression_node_ptr &node, expression_node_ptr &result)
Definition exprtk.hpp:36078
static bool compile_right(expression_generator< Type > &expr_gen, ExternalType t, const details::operator_type &operation, expression_node_ptr &sf3node, expression_node_ptr &result)
Definition exprtk.hpp:35972
static bool compile_right_impl(expression_generator< Type > &expr_gen, const std::string &id, ExternalType t, expression_node_ptr &node, expression_node_ptr &result)
Definition exprtk.hpp:36056
static bool compile(expression_generator< Type > &expr_gen, const std::string &id, T0 t0, T1 t1, T2 t2, T3 t3, expression_node_ptr &result)
Definition exprtk.hpp:35955
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:34957
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35819
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:37107
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36996
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition exprtk.hpp:37122
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38251
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38422
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38964
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38926
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition exprtk.hpp:39463
static std::string id(expression_generator< Type > &, const details::operator_type, const details::operator_type, const details::operator_type)
Definition exprtk.hpp:39472
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40011
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39973
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition exprtk.hpp:40509
static std::string id(expression_generator< Type > &, const details::operator_type, const details::operator_type, const details::operator_type)
Definition exprtk.hpp:40518
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36415
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36366
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36480
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36431
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:37813
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38035
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38806
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38844
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39348
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39386
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39851
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39890
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40432
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40393
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:37441
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:37508
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38624
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38662
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39166
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39204
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39709
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39671
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40214
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40251
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:35760
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36285
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36235
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36350
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36301
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:37352
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:37419
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38564
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38602
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39106
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39144
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39611
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39649
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40192
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40154
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36154
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36105
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition exprtk.hpp:36219
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:36170
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:37263
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:37330
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38504
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38542
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39046
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39084
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39589
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39550
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40093
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40132
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:37241
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:37141
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:38482
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38444
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39024
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:38986
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:39490
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:39528
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition exprtk.hpp:40071
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition exprtk.hpp:40033
static bool is_less(const T_ &v, const T_ &begin)
Definition exprtk.hpp:22664
static bool is_within(const T_ &v, const T_ &begin, const T_ &end)
Definition exprtk.hpp:22658
static bool is_greater(const T_ &v, const T_ &end)
Definition exprtk.hpp:22669
static expression_node_ptr process(parser< Type > &p, const details::operator_type opt_type, const std::string &sf_name)
Definition exprtk.hpp:28795
void activate_side_effect(const std::string &)
Definition exprtk.hpp:23400
std::size_t parsing_loop_stmt_count
Definition exprtk.hpp:23421
stringvar_node_ptr str_node
Definition exprtk.hpp:22392
bool operator<(const scope_element &se) const
Definition exprtk.hpp:22344
variable_node_t * variable_node_ptr
Definition exprtk.hpp:22320
details::vector_holder< T > vector_holder_t
Definition exprtk.hpp:22318
stringvar_node_t * stringvar_node_ptr
Definition exprtk.hpp:22324
vector_holder_ptr vec_node
Definition exprtk.hpp:22390
expression_node_ptr var_node
Definition exprtk.hpp:22389
literal_node_t * literal_node_ptr
Definition exprtk.hpp:22319
expression_node_t * expression_node_ptr
Definition exprtk.hpp:22322
vector_holder_t * vector_holder_ptr
Definition exprtk.hpp:22321
scoped_delete(const scoped_delete< Type, N > &)
scoped_delete< Type, N > & operator=(const scoped_delete< Type, N > &)
scoped_delete(parser< T > &pr, ptr_t(&p)[N])
Definition exprtk.hpp:25447
scoped_delete(parser< T > &pr, ptr_t &p)
Definition exprtk.hpp:25441
std::deque< ptr_t > & deq_
Definition exprtk.hpp:25501
scoped_deq_delete(parser< T > &pr, std::deque< ptr_t > &deq)
Definition exprtk.hpp:25479
scoped_deq_delete(const scoped_deq_delete< Type > &)
scoped_deq_delete< Type > & operator=(const scoped_deq_delete< Type > &)
scoped_expression_delete & operator=(const scoped_expression_delete &)
scoped_expression_delete(parser< T > &pr, expression_node_ptr &expression)
Definition exprtk.hpp:25412
scoped_expression_delete(const scoped_expression_delete &)
scoped_vec_delete(parser< T > &pr, std::vector< ptr_t > &vec)
Definition exprtk.hpp:25514
scoped_vec_delete(const scoped_vec_delete< Type > &)
std::vector< ptr_t > & vec_
Definition exprtk.hpp:25541
scoped_vec_delete< Type > & operator=(const scoped_vec_delete< Type > &)
ptr_t operator[](const std::size_t index)
Definition exprtk.hpp:25534
precedence_level right
Definition exprtk.hpp:25019
void set(const precedence_level &l, const precedence_level &r, const details::operator_type &o, const token_t tkn=token_t())
Definition exprtk.hpp:25000
precedence_level left
Definition exprtk.hpp:25018
details::operator_type operation
Definition exprtk.hpp:25020
stringvar_ptr get_stringvar(const std::string &string_name) const
Definition exprtk.hpp:23001
std::string get_vector_name(const vector_holder_ptr &ptr) const
Definition exprtk.hpp:23346
symbol_table_t::function_ptr function_ptr
Definition exprtk.hpp:22826
symbol_table_t::variable_ptr variable_ptr
Definition exprtk.hpp:22825
function_ptr get_function(const std::string &function_name) const
Definition exprtk.hpp:23023
bool is_stringvar(const std::string &stringvar_name) const
Definition exprtk.hpp:23254
symbol_table_list_t symtab_list_
Definition exprtk.hpp:22822
std::string get_stringvar_name(const expression_node_ptr &ptr) const
Definition exprtk.hpp:23352
generic_function_ptr get_generic_function(const std::string &function_name) const
Definition exprtk.hpp:23065
vector_holder_ptr get_vector(const std::string &vector_name) const
Definition exprtk.hpp:23153
local_data_t & local_data(const std::size_t &index=0)
Definition exprtk.hpp:23363
symbol_table_t::vararg_function_ptr vararg_function_ptr
Definition exprtk.hpp:22831
symbol_table_t::vector_holder_ptr vector_holder_ptr
Definition exprtk.hpp:22830
bool is_conststr_stringvar(const std::string &symbol_name) const
Definition exprtk.hpp:23270
symbol_table_t::local_data_t local_data_t
Definition exprtk.hpp:22824
bool is_constant_node(const std::string &symbol_name) const
Definition exprtk.hpp:23178
variable_context get_variable_context(const std::string &variable_name) const
Definition exprtk.hpp:22909
variable_ptr get_variable(const T &var_ref) const
Definition exprtk.hpp:22956
string_context get_string_context(const std::string &string_name) const
Definition exprtk.hpp:22975
bool symbol_exists(const std::string &symbol) const
Definition exprtk.hpp:23219
bool is_constant_string(const std::string &symbol_name) const
Definition exprtk.hpp:23200
bool is_variable(const std::string &variable_name) const
Definition exprtk.hpp:23237
symbol_table_t::stringvar_ptr stringvar_ptr
Definition exprtk.hpp:22828
symbol_table_t & get_symbol_table(const std::size_t &index=0)
Definition exprtk.hpp:23373
vector_context get_vector_context(const std::string &vector_name) const
Definition exprtk.hpp:23128
vararg_function_ptr get_vararg_function(const std::string &vararg_function_name) const
Definition exprtk.hpp:23044
bool is_vararg_function(const std::string &vararg_function_name) const
Definition exprtk.hpp:23309
const local_data_t & local_data(const std::size_t &index=0) const
Definition exprtk.hpp:23368
bool valid_function_name(const std::string &symbol) const
Definition exprtk.hpp:22901
generic_function_ptr get_overload_function(const std::string &function_name) const
Definition exprtk.hpp:23107
bool is_vector(const std::string &vector_name) const
Definition exprtk.hpp:23325
std::string get_variable_name(const expression_node_ptr &ptr) const
Definition exprtk.hpp:23341
generic_function_ptr get_string_function(const std::string &function_name) const
Definition exprtk.hpp:23086
bool valid_symbol(const std::string &symbol) const
Definition exprtk.hpp:22893
symbol_table_t::generic_function_ptr generic_function_ptr
Definition exprtk.hpp:22832
variable_ptr get_variable(const std::string &variable_name) const
Definition exprtk.hpp:22935
bool is_function(const std::string &function_name) const
Definition exprtk.hpp:23293
std::string get_conststr_stringvar_name(const expression_node_ptr &ptr) const
Definition exprtk.hpp:23357
unknown_symbol_resolver(const usr_mode m=e_usrmode_default)
Definition exprtk.hpp:23444
virtual bool process(const std::string &, symbol_table_t &, std::string &)
Definition exprtk.hpp:23466
virtual bool process(const std::string &, usr_symbol_type &st, T &default_value, std::string &error_message)
Definition exprtk.hpp:23451
static T evaluate(const Type x, const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42215
static T evaluate(const Type x, const Type c11, const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42202
static T evaluate(const Type x, const Type c12, const Type c11, const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42189
static T evaluate(const Type x, const Type c1, const Type c0)
Definition exprtk.hpp:42318
static T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42308
static T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42298
static T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42288
static T evaluate(const Type x, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42276
static T evaluate(const Type x, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42264
static T evaluate(const Type x, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42252
static T evaluate(const Type x, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42240
static T evaluate(const Type x, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition exprtk.hpp:42228
generic_type::string_view string_t
Definition exprtk.hpp:43577
igeneric_function< T >::generic_type generic_type
Definition exprtk.hpp:43573
static void print(const string_t &s)
Definition exprtk.hpp:43618
igeneric_function< T >::parameter_list_t parameter_list_t
Definition exprtk.hpp:43574
static void print(const std::string &scalar_format, const scalar_t &s)
Definition exprtk.hpp:43602
generic_type::scalar_view scalar_t
Definition exprtk.hpp:43575
exprtk::details::numeric::details::number_type< T >::type num_type
Definition exprtk.hpp:43578
static void print(const std::string &scalar_format, const vector_t &v)
Definition exprtk.hpp:43607
static void process(const std::string &scalar_format, parameter_list_t parameters)
Definition exprtk.hpp:43580
generic_type::vector_view vector_t
Definition exprtk.hpp:43576
file_descriptor(const std::string &fname, const std::string &access)
Definition exprtk.hpp:43720
bool write(const View &view, const std::size_t amount, const std::size_t offset=0)
Definition exprtk.hpp:43813
bool read(View &view, const std::size_t amount, const std::size_t offset=0)
Definition exprtk.hpp:43832
file_mode get_file_mode(const std::string &access) const
Definition exprtk.hpp:43871
bool register_package(exprtk::symbol_table< T > &symtab)
Definition exprtk.hpp:44173
bool register_package(exprtk::symbol_table< T > &symtab)
Definition exprtk.hpp:43677
T operator()(parameter_list_t parameters)
Definition exprtk.hpp:43639
igeneric_function< T >::parameter_list_t parameter_list_t
Definition exprtk.hpp:43629
std::string scalar_format_
Definition exprtk.hpp:43645
print(const std::string &scalar_format="%10.5f")
Definition exprtk.hpp:43633
T operator()(parameter_list_t parameters)
Definition exprtk.hpp:43661
println(const std::string &scalar_format="%10.5f")
Definition exprtk.hpp:43655
igeneric_function< T >::parameter_list_t parameter_list_t
Definition exprtk.hpp:43651
exprtk::igeneric_function< T > igfun_t
Definition exprtk.hpp:44225
static bool process(parameter_list_t &parameters, std::size_t &r0, std::size_t &r1, const std::size_t &r0_prmidx, const std::size_t &r1_prmidx, const std::size_t vec_idx=0)
Definition exprtk.hpp:44231
threshold_below< T > tb
Definition exprtk.hpp:45803
bool register_package(exprtk::symbol_table< T > &symtab)
Definition exprtk.hpp:45805
threshold_above< T > ta
Definition exprtk.hpp:45802
type_store< vector_holder_t, vector_holder_t > vector_store
Definition exprtk.hpp:20361
type_store< function_t, function_t > function_store
Definition exprtk.hpp:20356
std::list< std::string > local_stringvar_list_
Definition exprtk.hpp:20404
std::set< std::string > reserved_symbol_table_
Definition exprtk.hpp:20405
bool is_reserved_symbol(const std::string &symbol) const
Definition exprtk.hpp:20387
type_store< vararg_function_t, vararg_function_t > vararg_function_store
Definition exprtk.hpp:20357
type_store< generic_function_t, generic_function_t > string_function_store
Definition exprtk.hpp:20359
std::vector< ifunction< T > * > free_function_list_
Definition exprtk.hpp:20406
type_store< generic_function_t, generic_function_t > overload_function_store
Definition exprtk.hpp:20360
type_store< generic_function_t, generic_function_t > generic_function_store
Definition exprtk.hpp:20358
type_store< stringvar_t, std::string > stringvar_store
Definition exprtk.hpp:20363
type_store< variable_t, T > variable_store
Definition exprtk.hpp:20355
symtab_mutability_type mutability_
Definition exprtk.hpp:20461
static void destroy(control_block *&cntrl_blck, SymTab *sym_tab)
Definition exprtk.hpp:20435
static control_block * create()
Definition exprtk.hpp:20429
void set_mutability(const symtab_mutability_type mutability)
Definition exprtk.hpp:20454
static void process(std::pair< bool, variable_node_t * > &n)
Definition exprtk.hpp:19984
static void process(std::pair< bool, DeleteType * > &)
Definition exprtk.hpp:19993
static bool test(const variable_node_t *p, const void *ptr)
Definition exprtk.hpp:20200
static bool test(const PtrType, const void *)
Definition exprtk.hpp:20191
static std::pair< bool, vector_t * > make(std::pair< T *, std::size_t > v, const bool is_const=false)
Definition exprtk.hpp:20070
static std::pair< bool, vector_t * > make(std::deque< T, Allocator > &v, const bool is_const=false)
Definition exprtk.hpp:20096
static std::pair< bool, vector_t * > make(std::vector< T, Allocator > &v, const bool is_const=false)
Definition exprtk.hpp:20079
static std::pair< bool, vector_t * > make(exprtk::vector_view< T > &v, const bool is_const=false)
Definition exprtk.hpp:20087
details::stringvar_node< T > stringvar_node_t
Definition exprtk.hpp:19957
bool remove(const std::string &symbol_name, const bool delete_node=true)
Definition exprtk.hpp:20226
type_map_t::iterator tm_itr_t
Definition exprtk.hpp:19964
igeneric_function< T > igeneric_function_t
Definition exprtk.hpp:19954
std::map< std::string, type_pair_t, details::ilesscompare > type_map_t
Definition exprtk.hpp:19963
details::variable_node< T > variable_node_t
Definition exprtk.hpp:19951
std::size_t get_list(Sequence< std::string, Allocator > &vlist) const
Definition exprtk.hpp:20312
bool add_impl(const std::string &symbol_name, RType t, const bool is_const)
Definition exprtk.hpp:20044
type_map_t::const_iterator tm_const_itr_t
Definition exprtk.hpp:19965
type_ptr get(const std::string &symbol_name) const
Definition exprtk.hpp:20178
std::string entity_name(const PtrType &ptr) const
Definition exprtk.hpp:20008
std::pair< bool, type_ptr > type_pair_t
Definition exprtk.hpp:19962
bool add(const std::string &symbol_name, std::vector< T, Allocator > &v, const bool is_const=false)
Definition exprtk.hpp:20116
bool is_constant(const std::string &symbol_name) const
Definition exprtk.hpp:20028
bool add(const std::string &symbol_name, RawType &t_, const bool is_const=false)
Definition exprtk.hpp:20135
bool symbol_exists(const std::string &symbol_name) const
Definition exprtk.hpp:19997
bool add(const std::string &symbol_name, T(&v)[v_size], const bool is_const=false)
Definition exprtk.hpp:20103
ivararg_function< T > ivararg_function_t
Definition exprtk.hpp:19953
type_ptr get_from_varptr(const void *ptr) const
Definition exprtk.hpp:20207
bool add(const std::string &symbol_name, std::deque< T, Allocator > &v, const bool is_const=false)
Definition exprtk.hpp:20129
bool add(const std::string &symbol_name, exprtk::vector_view< T > &v, const bool is_const=false)
Definition exprtk.hpp:20122
void clear(const bool delete_node=true)
Definition exprtk.hpp:20266
details::expression_node< T > * expression_ptr
Definition exprtk.hpp:19950
RawType & type_ref(const std::string &symbol_name)
Definition exprtk.hpp:20246
details::vector_holder< T > vector_t
Definition exprtk.hpp:19955
std::size_t get_list(Sequence< std::pair< std::string, RawType >, Allocator > &list) const
Definition exprtk.hpp:20290
bool add(const std::string &symbol_name, T *v, const std::size_t v_size, const bool is_const=false)
Definition exprtk.hpp:20109
symbol_table< T > symbol_table_t
Definition exprtk.hpp:43531
expression< T > expression_t
Definition exprtk.hpp:43532
function_compositor< T > compositor_t
Definition exprtk.hpp:43535
compositor_t::function function_t
Definition exprtk.hpp:43536
parser_error::type error_t
Definition exprtk.hpp:43534
parser< T > parser_t
Definition exprtk.hpp:43533
bool to_uint(UIntType &u) const
Definition exprtk.hpp:4852
scalar_view(type_store_t &ts)
Definition exprtk.hpp:4812
scalar_view(const type_store_t &ts)
Definition exprtk.hpp:4816
bool to_int(IntType &i) const
Definition exprtk.hpp:4841
type_view(type_store_t &ts)
Definition exprtk.hpp:4762
value_t & operator[](const std::size_t &i)
Definition exprtk.hpp:4777
type_view(const type_store_t &ts)
Definition exprtk.hpp:4767
std::size_t size() const
Definition exprtk.hpp:4772
const value_t & operator[](const std::size_t &i) const
Definition exprtk.hpp:4782
const value_t * end() const
Definition exprtk.hpp:4790
const value_t * begin() const
Definition exprtk.hpp:4787
type_store< T > type_store_t
Definition exprtk.hpp:4759
type_view< T > vector_view
Definition exprtk.hpp:4804
std::size_t size
Definition exprtk.hpp:4698
type_view< char > string_view
Definition exprtk.hpp:4805
store_type type
Definition exprtk.hpp:4699
virtual bool handle_runtime_violation(violation_context &)
Definition exprtk.hpp:2183