GranOO  3.0
A robust and versatile workbench to build 3D dynamic simulations based on the Discrete Element Method
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 
59 namespace exprtk
60 {
61  #define exprtk_disable_caseinsensitivity // DA : to use 't' and 'T' variables
62 
63  #ifdef exprtk_enable_debugging
64  #define exprtk_debug(params) printf params
65  #else
66  #define exprtk_debug(params) (void)0
67  #endif
68 
69  #define exprtk_error_location \
70  "exprtk.hpp:" + details::to_str(__LINE__) \
71 
72  #if __cplusplus >= 201103L
73  #define exprtk_override override
74  #define exprtk_final final
75  #define exprtk_delete = delete
76  #else
77  #define exprtk_override
78  #define exprtk_final
79  #define exprtk_delete
80  #endif
81 
82  #if __cplusplus >= 201603L
83  #define exprtk_fallthrough [[fallthrough]];
84  #else
85  #define exprtk_fallthrough
86  #endif
87 
88  namespace details
89  {
90  typedef char char_t;
91  typedef char_t* char_ptr;
92  typedef char_t const* char_cptr;
93  typedef unsigned char uchar_t;
94  typedef uchar_t* uchar_ptr;
95  typedef uchar_t const* uchar_cptr;
96  typedef unsigned long long int _uint64_t;
97  typedef long long int _int64_t;
98 
99  inline bool is_whitespace(const char_t c)
100  {
101  return (' ' == c) || ('\n' == c) ||
102  ('\r' == c) || ('\t' == c) ||
103  ('\b' == c) || ('\v' == c) ||
104  ('\f' == c) ;
105  }
106 
107  inline bool is_operator_char(const char_t c)
108  {
109  return ('+' == c) || ('-' == c) ||
110  ('*' == c) || ('/' == c) ||
111  ('^' == c) || ('<' == c) ||
112  ('>' == c) || ('=' == c) ||
113  (',' == c) || ('!' == c) ||
114  ('(' == c) || (')' == c) ||
115  ('[' == c) || (']' == c) ||
116  ('{' == c) || ('}' == c) ||
117  ('%' == c) || (':' == c) ||
118  ('?' == c) || ('&' == c) ||
119  ('|' == c) || (';' == c) ;
120  }
121 
122  inline bool is_letter(const char_t c)
123  {
124  return (('a' <= c) && (c <= 'z')) ||
125  (('A' <= c) && (c <= 'Z')) ;
126  }
127 
128  inline bool is_digit(const char_t c)
129  {
130  return ('0' <= c) && (c <= '9');
131  }
132 
133  inline bool is_letter_or_digit(const char_t c)
134  {
135  return is_letter(c) || is_digit(c);
136  }
137 
138  inline bool is_left_bracket(const char_t c)
139  {
140  return ('(' == c) || ('[' == c) || ('{' == c);
141  }
142 
143  inline bool is_right_bracket(const char_t c)
144  {
145  return (')' == c) || (']' == c) || ('}' == c);
146  }
147 
148  inline bool is_bracket(const char_t c)
149  {
150  return is_left_bracket(c) || is_right_bracket(c);
151  }
152 
153  inline bool is_sign(const char_t c)
154  {
155  return ('+' == c) || ('-' == c);
156  }
157 
158  inline bool is_invalid(const char_t c)
159  {
160  return !is_whitespace (c) &&
161  !is_operator_char(c) &&
162  !is_letter (c) &&
163  !is_digit (c) &&
164  ('.' != c) &&
165  ('_' != c) &&
166  ('$' != c) &&
167  ('~' != c) &&
168  ('\'' != c);
169  }
170 
171  inline bool is_valid_string_char(const char_t c)
172  {
173  return std::isprint(static_cast<uchar_t>(c)) ||
174  is_whitespace(c);
175  }
176 
177  #ifndef exprtk_disable_caseinsensitivity
178  inline void case_normalise(std::string& s)
179  {
180  for (std::size_t i = 0; i < s.size(); ++i)
181  {
182  s[i] = static_cast<std::string::value_type>(std::tolower(s[i]));
183  }
184  }
185 
186  inline bool imatch(const char_t c1, const char_t c2)
187  {
188  return std::tolower(c1) == std::tolower(c2);
189  }
190 
191  inline bool imatch(const std::string& s1, const std::string& s2)
192  {
193  if (s1.size() == s2.size())
194  {
195  for (std::size_t i = 0; i < s1.size(); ++i)
196  {
197  if (std::tolower(s1[i]) != std::tolower(s2[i]))
198  {
199  return false;
200  }
201  }
202 
203  return true;
204  }
205 
206  return false;
207  }
208 
209  struct ilesscompare
210  {
211  inline bool operator() (const std::string& s1, const std::string& s2) const
212  {
213  const std::size_t length = std::min(s1.size(),s2.size());
214 
215  for (std::size_t i = 0; i < length; ++i)
216  {
217  const char_t c1 = static_cast<char_t>(std::tolower(s1[i]));
218  const char_t c2 = static_cast<char_t>(std::tolower(s2[i]));
219 
220  if (c1 < c2)
221  return true;
222  else if (c2 < c1)
223  return false;
224  }
225 
226  return s1.size() < s2.size();
227  }
228  };
229 
230  #else
231  inline void case_normalise(std::string&)
232  {}
233 
234  inline bool imatch(const char_t c1, const char_t c2)
235  {
236  return c1 == c2;
237  }
238 
239  inline bool imatch(const std::string& s1, const std::string& s2)
240  {
241  return s1 == s2;
242  }
243 
245  {
246  inline bool operator() (const std::string& s1, const std::string& s2) const
247  {
248  return s1 < s2;
249  }
250  };
251  #endif
252 
253  inline bool is_valid_sf_symbol(const std::string& symbol)
254  {
255  // Special function: $f12 or $F34
256  return (4 == symbol.size()) &&
257  ('$' == symbol[0]) &&
258  imatch('f',symbol[1]) &&
259  is_digit(symbol[2]) &&
260  is_digit(symbol[3]);
261  }
262 
263  inline const char_t& front(const std::string& s)
264  {
265  return s[0];
266  }
267 
268  inline const char_t& back(const std::string& s)
269  {
270  return s[s.size() - 1];
271  }
272 
273  inline std::string to_str(int i)
274  {
275  if (0 == i)
276  return std::string("0");
277 
278  std::string result;
279 
280  const int sign = (i < 0) ? -1 : 1;
281 
282  for ( ; i; i /= 10)
283  {
284  result += '0' + static_cast<char_t>(sign * (i % 10));
285  }
286 
287  if (sign < 0)
288  {
289  result += '-';
290  }
291 
292  std::reverse(result.begin(), result.end());
293 
294  return result;
295  }
296 
297  inline std::string to_str(std::size_t i)
298  {
299  return to_str(static_cast<int>(i));
300  }
301 
302  inline bool is_hex_digit(const uchar_t digit)
303  {
304  return (('0' <= digit) && (digit <= '9')) ||
305  (('A' <= digit) && (digit <= 'F')) ||
306  (('a' <= digit) && (digit <= 'f')) ;
307  }
308 
310  {
311  if (('0' <= h) && (h <= '9'))
312  return (h - '0');
313  else
314  return static_cast<uchar_t>(std::toupper(h) - 'A');
315  }
316 
317  template <typename Iterator>
318  inline bool parse_hex(Iterator& itr, Iterator end,
319  char_t& result)
320  {
321  if (
322  (end == (itr )) ||
323  (end == (itr + 1)) ||
324  (end == (itr + 2)) ||
325  (end == (itr + 3)) ||
326  ('0' != *(itr )) ||
327  ('X' != std::toupper(*(itr + 1))) ||
328  (!is_hex_digit(*(itr + 2))) ||
329  (!is_hex_digit(*(itr + 3)))
330  )
331  {
332  return false;
333  }
334 
335  result = hex_to_bin(static_cast<uchar_t>(*(itr + 2))) << 4 |
336  hex_to_bin(static_cast<uchar_t>(*(itr + 3))) ;
337 
338  return true;
339  }
340 
341  inline bool cleanup_escapes(std::string& s)
342  {
343  typedef std::string::iterator str_itr_t;
344 
345  str_itr_t itr1 = s.begin();
346  str_itr_t itr2 = s.begin();
347  str_itr_t end = s.end ();
348 
349  std::size_t removal_count = 0;
350 
351  while (end != itr1)
352  {
353  if ('\\' == (*itr1))
354  {
355  if (end == ++itr1)
356  {
357  return false;
358  }
359  else if (parse_hex(itr1, end, *itr2))
360  {
361  itr1 += 4;
362  itr2 += 1;
363  removal_count += 4;
364  }
365  else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; }
366  else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; }
367  else if ('f' == (*itr1)) { (*itr2++) = '\f'; ++itr1; ++removal_count; }
368  else if ('n' == (*itr1)) { (*itr2++) = '\n'; ++itr1; ++removal_count; }
369  else if ('r' == (*itr1)) { (*itr2++) = '\r'; ++itr1; ++removal_count; }
370  else if ('t' == (*itr1)) { (*itr2++) = '\t'; ++itr1; ++removal_count; }
371  else if ('v' == (*itr1)) { (*itr2++) = '\v'; ++itr1; ++removal_count; }
372  else if ('0' == (*itr1)) { (*itr2++) = '\0'; ++itr1; ++removal_count; }
373  else
374  {
375  (*itr2++) = (*itr1++);
376  ++removal_count;
377  }
378 
379  continue;
380  }
381  else
382  (*itr2++) = (*itr1++);
383  }
384 
385  if ((removal_count > s.size()) || (0 == removal_count))
386  return false;
387 
388  s.resize(s.size() - removal_count);
389 
390  return true;
391  }
392 
394  {
395  public:
396 
397  explicit build_string(const std::size_t& initial_size = 64)
398  {
399  data_.reserve(initial_size);
400  }
401 
402  inline build_string& operator << (const std::string& s)
403  {
404  data_ += s;
405  return (*this);
406  }
407 
409  {
410  data_ += std::string(s);
411  return (*this);
412  }
413 
414  inline operator std::string () const
415  {
416  return data_;
417  }
418 
419  inline std::string as_string() const
420  {
421  return data_;
422  }
423 
424  private:
425 
426  std::string data_;
427  };
428 
429  static const std::string reserved_words[] =
430  {
431  "break", "case", "continue", "default", "false", "for",
432  "if", "else", "ilike", "in", "like", "and", "nand", "nor",
433  "not", "null", "or", "repeat", "return", "shl", "shr",
434  "swap", "switch", "true", "until", "var", "while", "xnor",
435  "xor", "&", "|"
436  };
437 
438  static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
439 
440  static const std::string reserved_symbols[] =
441  {
442  "abs", "acos", "acosh", "and", "asin", "asinh", "atan",
443  "atanh", "atan2", "avg", "break", "case", "ceil", "clamp",
444  "continue", "cos", "cosh", "cot", "csc", "default",
445  "deg2grad", "deg2rad", "equal", "erf", "erfc", "exp",
446  "expm1", "false", "floor", "for", "frac", "grad2deg",
447  "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
448  "like", "log", "log10", "log2", "logn", "log1p", "mand",
449  "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor",
450  "not", "not_equal", "null", "or", "pow", "rad2deg",
451  "repeat", "return", "root", "round", "roundn", "sec", "sgn",
452  "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap",
453  "switch", "tan", "tanh", "true", "trunc", "until", "var",
454  "while", "xnor", "xor", "&", "|"
455  };
456 
457  static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
458 
459  static const std::string base_function_list[] =
460  {
461  "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh",
462  "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot",
463  "csc", "equal", "erf", "erfc", "exp", "expm1", "floor",
464  "frac", "hypot", "iclamp", "like", "log", "log10", "log2",
465  "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul",
466  "ncdf", "pow", "root", "round", "roundn", "sec", "sgn",
467  "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
468  "trunc", "not_equal", "inrange", "deg2grad", "deg2rad",
469  "rad2deg", "grad2deg"
470  };
471 
472  static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
473 
474  static const std::string logic_ops_list[] =
475  {
476  "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|"
477  };
478 
479  static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
480 
481  static const std::string cntrl_struct_list[] =
482  {
483  "if", "switch", "for", "while", "repeat", "return"
484  };
485 
486  static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
487 
488  static const std::string arithmetic_ops_list[] =
489  {
490  "+", "-", "*", "/", "%", "^"
491  };
492 
493  static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
494 
495  static const std::string assignment_ops_list[] =
496  {
497  ":=", "+=", "-=",
498  "*=", "/=", "%="
499  };
500 
501  static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
502 
503  static const std::string inequality_ops_list[] =
504  {
505  "<", "<=", "==",
506  "=", "!=", "<>",
507  ">=", ">"
508  };
509 
510  static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string);
511 
512  inline bool is_reserved_word(const std::string& symbol)
513  {
514  for (std::size_t i = 0; i < reserved_words_size; ++i)
515  {
516  if (imatch(symbol, reserved_words[i]))
517  {
518  return true;
519  }
520  }
521 
522  return false;
523  }
524 
525  inline bool is_reserved_symbol(const std::string& symbol)
526  {
527  for (std::size_t i = 0; i < reserved_symbols_size; ++i)
528  {
529  if (imatch(symbol, reserved_symbols[i]))
530  {
531  return true;
532  }
533  }
534 
535  return false;
536  }
537 
538  inline bool is_base_function(const std::string& function_name)
539  {
540  for (std::size_t i = 0; i < base_function_list_size; ++i)
541  {
542  if (imatch(function_name, base_function_list[i]))
543  {
544  return true;
545  }
546  }
547 
548  return false;
549  }
550 
551  inline bool is_control_struct(const std::string& cntrl_strct)
552  {
553  for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
554  {
555  if (imatch(cntrl_strct, cntrl_struct_list[i]))
556  {
557  return true;
558  }
559  }
560 
561  return false;
562  }
563 
564  inline bool is_logic_opr(const std::string& lgc_opr)
565  {
566  for (std::size_t i = 0; i < logic_ops_list_size; ++i)
567  {
568  if (imatch(lgc_opr, logic_ops_list[i]))
569  {
570  return true;
571  }
572  }
573 
574  return false;
575  }
576 
577  struct cs_match
578  {
579  static inline bool cmp(const char_t c0, const char_t c1)
580  {
581  return (c0 == c1);
582  }
583  };
584 
585  struct cis_match
586  {
587  static inline bool cmp(const char_t c0, const char_t c1)
588  {
589  return (std::tolower(c0) == std::tolower(c1));
590  }
591  };
592 
593  template <typename Iterator, typename Compare>
594  inline bool match_impl(const Iterator pattern_begin,
595  const Iterator pattern_end ,
596  const Iterator data_begin ,
597  const Iterator data_end ,
598  const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
599  const typename std::iterator_traits<Iterator>::value_type& exactly_one )
600  {
601  typedef typename std::iterator_traits<Iterator>::value_type type;
602 
603  const Iterator null_itr(0);
604 
605  Iterator p_itr = pattern_begin;
606  Iterator d_itr = data_begin;
607  Iterator np_itr = null_itr;
608  Iterator nd_itr = null_itr;
609 
610  for ( ; ; )
611  {
612  if (p_itr != pattern_end)
613  {
614  const type c = *(p_itr);
615 
616  if ((data_end != d_itr) && (Compare::cmp(c,*(d_itr)) || (exactly_one == c)))
617  {
618  ++d_itr;
619  ++p_itr;
620  continue;
621  }
622  else if (zero_or_more == c)
623  {
624  while ((pattern_end != p_itr) && (zero_or_more == *(p_itr)))
625  {
626  ++p_itr;
627  }
628 
629  const type d = *(p_itr);
630 
631  while ((data_end != d_itr) && !(Compare::cmp(d,*(d_itr)) || (exactly_one == d)))
632  {
633  ++d_itr;
634  }
635 
636  // set backtrack iterators
637  np_itr = p_itr - 1;
638  nd_itr = d_itr + 1;
639 
640  continue;
641  }
642  }
643  else if (data_end == d_itr)
644  break;
645 
646  if ((data_end == d_itr) || (null_itr == nd_itr))
647  return false;
648 
649  p_itr = np_itr;
650  d_itr = nd_itr;
651  }
652 
653  return true;
654  }
655 
656  inline bool wc_match(const std::string& wild_card,
657  const std::string& str)
658  {
659  return match_impl<char_cptr,cs_match>
660  (
661  wild_card.data(),
662  wild_card.data() + wild_card.size(),
663  str.data(),
664  str.data() + str.size(),
665  '*', '?'
666  );
667  }
668 
669  inline bool wc_imatch(const std::string& wild_card,
670  const std::string& str)
671  {
672  return match_impl<char_cptr,cis_match>
673  (
674  wild_card.data(),
675  wild_card.data() + wild_card.size(),
676  str.data(),
677  str.data() + str.size(),
678  '*', '?'
679  );
680  }
681 
682  inline bool sequence_match(const std::string& pattern,
683  const std::string& str,
684  std::size_t& diff_index,
685  char_t& diff_value)
686  {
687  if (str.empty())
688  {
689  return ("Z" == pattern);
690  }
691  else if ('*' == pattern[0])
692  return false;
693 
694  typedef std::string::const_iterator itr_t;
695 
696  itr_t p_itr = pattern.begin();
697  itr_t s_itr = str .begin();
698 
699  const itr_t p_end = pattern.end();
700  const itr_t s_end = str .end();
701 
702  while ((s_end != s_itr) && (p_end != p_itr))
703  {
704  if ('*' == (*p_itr))
705  {
706  const char_t target = static_cast<char_t>(std::toupper(*(p_itr - 1)));
707 
708  if ('*' == target)
709  {
710  diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
711  diff_value = static_cast<char_t>(std::toupper(*p_itr));
712 
713  return false;
714  }
715  else
716  ++p_itr;
717 
718  while (s_itr != s_end)
719  {
720  if (target != std::toupper(*s_itr))
721  break;
722  else
723  ++s_itr;
724  }
725 
726  continue;
727  }
728  else if (
729  ('?' != *p_itr) &&
730  std::toupper(*p_itr) != std::toupper(*s_itr)
731  )
732  {
733  diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
734  diff_value = static_cast<char_t>(std::toupper(*p_itr));
735 
736  return false;
737  }
738 
739  ++p_itr;
740  ++s_itr;
741  }
742 
743  return (
744  (s_end == s_itr) &&
745  (
746  (p_end == p_itr) ||
747  ('*' == *p_itr)
748  )
749  );
750  }
751 
752  template<typename T>
754  {
755  static inline void process(T* base_ptr, const std::size_t size)
756  {
757  const T zero = T(0);
758  for (std::size_t i = 0; i < size; ++i)
759  {
760  base_ptr[i] = zero;
761  }
762  }
763  };
764 
765  #define pod_set_zero_value(T) \
766  template <> \
767  struct set_zero_value_impl<T> \
768  { \
769  static inline void process(T* base_ptr, const std::size_t size) \
770  { std::memset(base_ptr, 0x00, size * sizeof(T)); } \
771  }; \
772 
774  pod_set_zero_value(double )
775  pod_set_zero_value(long double)
776 
777  #ifdef pod_set_zero_value
778  #undef pod_set_zero_value
779  #endif
780 
781  template<typename T>
782  inline void set_zero_value(T* data, const std::size_t size)
783  {
785  }
786 
787  template<typename T>
788  inline void set_zero_value(std::vector<T>& v)
789  {
790  set_zero_value(v.data(),v.size());
791  }
792 
793  static const double pow10[] =
794  {
795  1.0,
796  1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
797  1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
798  1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
799  1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
800  };
801 
802  static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
803 
804  namespace numeric
805  {
806  namespace constant
807  {
808  static const double e = 2.71828182845904523536028747135266249775724709369996;
809  static const double pi = 3.14159265358979323846264338327950288419716939937510;
810  static const double pi_2 = 1.57079632679489661923132169163975144209858469968755;
811  static const double pi_4 = 0.78539816339744830961566084581987572104929234984378;
812  static const double pi_180 = 0.01745329251994329576923690768488612713442871888542;
813  static const double _1_pi = 0.31830988618379067153776752674502872406891929148091;
814  static const double _2_pi = 0.63661977236758134307553505349005744813783858296183;
815  static const double _180_pi = 57.29577951308232087679815481410517033240547246656443;
816  static const double log2 = 0.69314718055994530941723212145817656807550013436026;
817  static const double sqrt2 = 1.41421356237309504880168872420969807856967187537695;
818  }
819 
820  namespace details
821  {
823  struct real_type_tag { real_type_tag () {} };
824  struct int_type_tag { int_type_tag () {} };
825 
826  template <typename T>
827  struct number_type
828  {
831  };
832 
833  #define exprtk_register_real_type_tag(T) \
834  template <> struct number_type<T> \
835  { typedef real_type_tag type; number_type() {} }; \
836 
837  #define exprtk_register_int_type_tag(T) \
838  template <> struct number_type<T> \
839  { typedef int_type_tag type; number_type() {} }; \
840 
843  exprtk_register_real_type_tag(long double)
844 
848  exprtk_register_int_type_tag(unsigned short)
849  exprtk_register_int_type_tag(unsigned int )
851 
852  #undef exprtk_register_real_type_tag
853  #undef exprtk_register_int_type_tag
854 
855  template <typename T>
856  struct epsilon_type {};
857 
858  #define exprtk_define_epsilon_type(Type, Epsilon) \
859  template <> struct epsilon_type<Type> \
860  { \
861  static inline Type value() \
862  { \
863  const Type epsilon = static_cast<Type>(Epsilon); \
864  return epsilon; \
865  } \
866  }; \
867 
868  exprtk_define_epsilon_type(float , 0.00000100000f)
869  exprtk_define_epsilon_type(double , 0.000000000100)
870  exprtk_define_epsilon_type(long double, 0.000000000001)
871 
872  #undef exprtk_define_epsilon_type
873 
874  template <typename T>
875  inline bool is_nan_impl(const T v, real_type_tag)
876  {
877  return std::not_equal_to<T>()(v,v);
878  }
879 
880  template <typename T>
881  inline int to_int32_impl(const T v, real_type_tag)
882  {
883  return static_cast<int>(v);
884  }
885 
886  template <typename T>
888  {
889  return static_cast<_int64_t>(v);
890  }
891 
892  template <typename T>
894  {
895  return static_cast<_uint64_t>(v);
896  }
897 
898  template <typename T>
899  inline bool is_true_impl(const T v)
900  {
901  return std::not_equal_to<T>()(T(0),v);
902  }
903 
904  template <typename T>
905  inline bool is_false_impl(const T v)
906  {
907  return std::equal_to<T>()(T(0),v);
908  }
909 
910  template <typename T>
911  inline T abs_impl(const T v, real_type_tag)
912  {
913  return ((v < T(0)) ? -v : v);
914  }
915 
916  template <typename T>
917  inline T min_impl(const T v0, const T v1, real_type_tag)
918  {
919  return std::min<T>(v0,v1);
920  }
921 
922  template <typename T>
923  inline T max_impl(const T v0, const T v1, real_type_tag)
924  {
925  return std::max<T>(v0,v1);
926  }
927 
928  template <typename T>
929  inline T equal_impl(const T v0, const T v1, real_type_tag)
930  {
931  const T epsilon = epsilon_type<T>::value();
932  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);
933  }
934 
935  inline float equal_impl(const float v0, const float v1, real_type_tag)
936  {
937  const float epsilon = epsilon_type<float>::value();
938  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;
939  }
940 
941  template <typename T>
942  inline T equal_impl(const T v0, const T v1, int_type_tag)
943  {
944  return (v0 == v1) ? 1 : 0;
945  }
946 
947  template <typename T>
948  inline T expm1_impl(const T v, real_type_tag)
949  {
950  // return std::expm1<T>(v);
951  if (abs_impl(v,real_type_tag()) < T(0.00001))
952  return v + (T(0.5) * v * v);
953  else
954  return std::exp(v) - T(1);
955  }
956 
957  template <typename T>
958  inline T expm1_impl(const T v, int_type_tag)
959  {
960  return T(std::exp<double>(v)) - T(1);
961  }
962 
963  template <typename T>
964  inline T nequal_impl(const T v0, const T v1, real_type_tag)
965  {
966  typedef real_type_tag rtg;
967  const T epsilon = epsilon_type<T>::value();
968  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);
969  }
970 
971  inline float nequal_impl(const float v0, const float v1, real_type_tag)
972  {
973  typedef real_type_tag rtg;
974  const float epsilon = epsilon_type<float>::value();
975  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;
976  }
977 
978  template <typename T>
979  inline T nequal_impl(const T v0, const T v1, int_type_tag)
980  {
981  return (v0 != v1) ? 1 : 0;
982  }
983 
984  template <typename T>
985  inline T modulus_impl(const T v0, const T v1, real_type_tag)
986  {
987  return std::fmod(v0,v1);
988  }
989 
990  template <typename T>
991  inline T modulus_impl(const T v0, const T v1, int_type_tag)
992  {
993  return v0 % v1;
994  }
995 
996  template <typename T>
997  inline T pow_impl(const T v0, const T v1, real_type_tag)
998  {
999  return std::pow(v0,v1);
1000  }
1001 
1002  template <typename T>
1003  inline T pow_impl(const T v0, const T v1, int_type_tag)
1004  {
1005  return std::pow(static_cast<double>(v0),static_cast<double>(v1));
1006  }
1007 
1008  template <typename T>
1009  inline T logn_impl(const T v0, const T v1, real_type_tag)
1010  {
1011  return std::log(v0) / std::log(v1);
1012  }
1013 
1014  template <typename T>
1015  inline T logn_impl(const T v0, const T v1, int_type_tag)
1016  {
1017  return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
1018  }
1019 
1020  template <typename T>
1021  inline T log1p_impl(const T v, real_type_tag)
1022  {
1023  if (v > T(-1))
1024  {
1025  if (abs_impl(v,real_type_tag()) > T(0.0001))
1026  {
1027  return std::log(T(1) + v);
1028  }
1029  else
1030  return (T(-0.5) * v + T(1)) * v;
1031  }
1032 
1033  return std::numeric_limits<T>::quiet_NaN();
1034  }
1035 
1036  template <typename T>
1037  inline T log1p_impl(const T v, int_type_tag)
1038  {
1039  if (v > T(-1))
1040  {
1041  return std::log(T(1) + v);
1042  }
1043 
1044  return std::numeric_limits<T>::quiet_NaN();
1045  }
1046 
1047  template <typename T>
1048  inline T root_impl(const T v0, const T v1, real_type_tag)
1049  {
1050  if (v1 < T(0))
1051  return std::numeric_limits<T>::quiet_NaN();
1052 
1053  const std::size_t n = static_cast<std::size_t>(v1);
1054 
1055  if ((v0 < T(0)) && (0 == (n % 2)))
1056  return std::numeric_limits<T>::quiet_NaN();
1057 
1058  return std::pow(v0, T(1) / n);
1059  }
1060 
1061  template <typename T>
1062  inline T root_impl(const T v0, const T v1, int_type_tag)
1063  {
1064  return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
1065  }
1066 
1067  template <typename T>
1068  inline T round_impl(const T v, real_type_tag)
1069  {
1070  return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5)));
1071  }
1072 
1073  template <typename T>
1074  inline T roundn_impl(const T v0, const T v1, real_type_tag)
1075  {
1076  const int index = std::max<int>(0, std::min<int>(pow10_size - 1, static_cast<int>(std::floor(v1))));
1077  const T p10 = T(pow10[index]);
1078 
1079  if (v0 < T(0))
1080  return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
1081  else
1082  return T(std::floor((v0 * p10) + T(0.5)) / p10);
1083  }
1084 
1085  template <typename T>
1086  inline T roundn_impl(const T v0, const T, int_type_tag)
1087  {
1088  return v0;
1089  }
1090 
1091  template <typename T>
1092  inline T hypot_impl(const T v0, const T v1, real_type_tag)
1093  {
1094  return std::sqrt((v0 * v0) + (v1 * v1));
1095  }
1096 
1097  template <typename T>
1098  inline T hypot_impl(const T v0, const T v1, int_type_tag)
1099  {
1100  return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
1101  }
1102 
1103  template <typename T>
1104  inline T atan2_impl(const T v0, const T v1, real_type_tag)
1105  {
1106  return std::atan2(v0,v1);
1107  }
1108 
1109  template <typename T>
1110  inline T atan2_impl(const T, const T, int_type_tag)
1111  {
1112  return 0;
1113  }
1114 
1115  template <typename T>
1116  inline T shr_impl(const T v0, const T v1, real_type_tag)
1117  {
1118  return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
1119  }
1120 
1121  template <typename T>
1122  inline T shr_impl(const T v0, const T v1, int_type_tag)
1123  {
1124  return v0 >> v1;
1125  }
1126 
1127  template <typename T>
1128  inline T shl_impl(const T v0, const T v1, real_type_tag)
1129  {
1130  return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
1131  }
1132 
1133  template <typename T>
1134  inline T shl_impl(const T v0, const T v1, int_type_tag)
1135  {
1136  return v0 << v1;
1137  }
1138 
1139  template <typename T>
1140  inline T sgn_impl(const T v, real_type_tag)
1141  {
1142  if (v > T(0)) return T(+1);
1143  else if (v < T(0)) return T(-1);
1144  else return T( 0);
1145  }
1146 
1147  template <typename T>
1148  inline T sgn_impl(const T v, int_type_tag)
1149  {
1150  if (v > T(0)) return T(+1);
1151  else if (v < T(0)) return T(-1);
1152  else return T( 0);
1153  }
1154 
1155  template <typename T>
1156  inline T and_impl(const T v0, const T v1, real_type_tag)
1157  {
1158  return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0);
1159  }
1160 
1161  template <typename T>
1162  inline T and_impl(const T v0, const T v1, int_type_tag)
1163  {
1164  return v0 && v1;
1165  }
1166 
1167  template <typename T>
1168  inline T nand_impl(const T v0, const T v1, real_type_tag)
1169  {
1170  return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0);
1171  }
1172 
1173  template <typename T>
1174  inline T nand_impl(const T v0, const T v1, int_type_tag)
1175  {
1176  return !(v0 && v1);
1177  }
1178 
1179  template <typename T>
1180  inline T or_impl(const T v0, const T v1, real_type_tag)
1181  {
1182  return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0);
1183  }
1184 
1185  template <typename T>
1186  inline T or_impl(const T v0, const T v1, int_type_tag)
1187  {
1188  return (v0 || v1);
1189  }
1190 
1191  template <typename T>
1192  inline T nor_impl(const T v0, const T v1, real_type_tag)
1193  {
1194  return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0);
1195  }
1196 
1197  template <typename T>
1198  inline T nor_impl(const T v0, const T v1, int_type_tag)
1199  {
1200  return !(v0 || v1);
1201  }
1202 
1203  template <typename T>
1204  inline T xor_impl(const T v0, const T v1, real_type_tag)
1205  {
1206  return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0);
1207  }
1208 
1209  template <typename T>
1210  inline T xor_impl(const T v0, const T v1, int_type_tag)
1211  {
1212  return v0 ^ v1;
1213  }
1214 
1215  template <typename T>
1216  inline T xnor_impl(const T v0, const T v1, real_type_tag)
1217  {
1218  const bool v0_true = is_true_impl(v0);
1219  const bool v1_true = is_true_impl(v1);
1220 
1221  if ((v0_true && v1_true) || (!v0_true && !v1_true))
1222  return T(1);
1223  else
1224  return T(0);
1225  }
1226 
1227  template <typename T>
1228  inline T xnor_impl(const T v0, const T v1, int_type_tag)
1229  {
1230  const bool v0_true = is_true_impl(v0);
1231  const bool v1_true = is_true_impl(v1);
1232 
1233  if ((v0_true && v1_true) || (!v0_true && !v1_true))
1234  return T(1);
1235  else
1236  return T(0);
1237  }
1238 
1239  #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1240  #define exprtk_define_erf(TT, impl) \
1241  inline TT erf_impl(const TT v) { return impl(v); } \
1242 
1243  exprtk_define_erf(float , ::erff)
1244  exprtk_define_erf(double , ::erf )
1245  exprtk_define_erf(long double, ::erfl)
1246  #undef exprtk_define_erf
1247  #endif
1248 
1249  template <typename T>
1250  inline T erf_impl(const T v, real_type_tag)
1251  {
1252  #if defined(_MSC_VER) && (_MSC_VER < 1900)
1253  // Credits: Abramowitz & Stegun Equations 7.1.25-28
1254  static const T c[] =
1255  {
1256  T( 1.26551223), T(1.00002368),
1257  T( 0.37409196), T(0.09678418),
1258  T(-0.18628806), T(0.27886807),
1259  T(-1.13520398), T(1.48851587),
1260  T(-0.82215223), T(0.17087277)
1261  };
1262 
1263  const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
1264 
1265  const T result = T(1) - t * std::exp((-v * v) -
1266  c[0] + t * (c[1] + t *
1267  (c[2] + t * (c[3] + t *
1268  (c[4] + t * (c[5] + t *
1269  (c[6] + t * (c[7] + t *
1270  (c[8] + t * (c[9]))))))))));
1271 
1272  return (v >= T(0)) ? result : -result;
1273  #else
1274  return erf_impl(v);
1275  #endif
1276  }
1277 
1278  template <typename T>
1279  inline T erf_impl(const T v, int_type_tag)
1280  {
1281  return erf_impl(static_cast<double>(v),real_type_tag());
1282  }
1283 
1284  #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1285  #define exprtk_define_erfc(TT, impl) \
1286  inline TT erfc_impl(const TT v) { return impl(v); } \
1287 
1288  exprtk_define_erfc(float ,::erfcf)
1289  exprtk_define_erfc(double ,::erfc )
1290  exprtk_define_erfc(long double,::erfcl)
1291  #undef exprtk_define_erfc
1292  #endif
1293 
1294  template <typename T>
1295  inline T erfc_impl(const T v, real_type_tag)
1296  {
1297  #if defined(_MSC_VER) && (_MSC_VER < 1900)
1298  return T(1) - erf_impl(v,real_type_tag());
1299  #else
1300  return erfc_impl(v);
1301  #endif
1302  }
1303 
1304  template <typename T>
1305  inline T erfc_impl(const T v, int_type_tag)
1306  {
1307  return erfc_impl(static_cast<double>(v),real_type_tag());
1308  }
1309 
1310  template <typename T>
1311  inline T ncdf_impl(const T v, real_type_tag)
1312  {
1313  const T cnd = T(0.5) * (T(1) +
1316  return (v < T(0)) ? (T(1) - cnd) : cnd;
1317  }
1318 
1319  template <typename T>
1320  inline T ncdf_impl(const T v, int_type_tag)
1321  {
1322  return ncdf_impl(static_cast<double>(v),real_type_tag());
1323  }
1324 
1325  template <typename T>
1326  inline T sinc_impl(const T v, real_type_tag)
1327  {
1328  if (std::abs(v) >= std::numeric_limits<T>::epsilon())
1329  return(std::sin(v) / v);
1330  else
1331  return T(1);
1332  }
1333 
1334  template <typename T>
1335  inline T sinc_impl(const T v, int_type_tag)
1336  {
1337  return sinc_impl(static_cast<double>(v),real_type_tag());
1338  }
1339 
1340  template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
1341  template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
1342  template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
1343  template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
1344  template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
1345  template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); }
1346  template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
1347  template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
1348  template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
1349  template <typename T> inline T exp_impl(const T v, real_type_tag) { return std::exp (v); }
1350  template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
1351  template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
1352  template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
1353  template <typename T> inline T log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1354  template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
1355  template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
1356  template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
1357  template <typename T> inline T sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
1358  template <typename T> inline T sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
1359  template <typename T> inline T tan_impl(const T v, real_type_tag) { return std::tan (v); }
1360  template <typename T> inline T tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
1361  template <typename T> inline T cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
1362  template <typename T> inline T sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
1363  template <typename T> inline T csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
1364  template <typename T> inline T r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
1365  template <typename T> inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
1366  template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(10.0/9.0)); }
1367  template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/10.0)); }
1368  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)); }
1369  template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
1370  template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); }
1371 
1372  template <typename T> inline T const_pi_impl(real_type_tag) { return T(numeric::constant::pi); }
1373  template <typename T> inline T const_e_impl(real_type_tag) { return T(numeric::constant::e); }
1374  template <typename T> inline T const_qnan_impl(real_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1375 
1376  template <typename T> inline T abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
1377  template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
1378  template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
1379  template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
1380  template <typename T> inline T log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1381  template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
1382  template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
1383  template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
1384  template <typename T> inline T floor_impl(const T v, int_type_tag) { return v; }
1385  template <typename T> inline T round_impl(const T v, int_type_tag) { return v; }
1386  template <typename T> inline T notl_impl(const T v, int_type_tag) { return !v; }
1387  template <typename T> inline T sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
1388  template <typename T> inline T frac_impl(const T , int_type_tag) { return T(0); }
1389  template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v; }
1390  template <typename T> inline T acos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1391  template <typename T> inline T acosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1392  template <typename T> inline T asin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1393  template <typename T> inline T asinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1394  template <typename T> inline T atan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1395  template <typename T> inline T atanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1396  template <typename T> inline T cos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1397  template <typename T> inline T cosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1398  template <typename T> inline T sin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1399  template <typename T> inline T sinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1400  template <typename T> inline T tan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1401  template <typename T> inline T tanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1402  template <typename T> inline T cot_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1403  template <typename T> inline T sec_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1404  template <typename T> inline T csc_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1405 
1406  template <typename T>
1407  inline bool is_integer_impl(const T& v, real_type_tag)
1408  {
1409  return std::equal_to<T>()(T(0),std::fmod(v,T(1)));
1410  }
1411 
1412  template <typename T>
1413  inline bool is_integer_impl(const T&, int_type_tag)
1414  {
1415  return true;
1416  }
1417  }
1418 
1419  template <typename Type>
1420  struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
1421 
1422  template <> struct numeric_info<int > { enum { length = 10, size = 16, bound_length = 9 }; };
1423  template <> struct numeric_info<float > { enum { min_exp = -38, max_exp = +38 }; };
1424  template <> struct numeric_info<double > { enum { min_exp = -308, max_exp = +308 }; };
1425  template <> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308 }; };
1426 
1427  template <typename T>
1428  inline int to_int32(const T v)
1429  {
1430  const typename details::number_type<T>::type num_type;
1431  return to_int32_impl(v, num_type);
1432  }
1433 
1434  template <typename T>
1435  inline _int64_t to_int64(const T v)
1436  {
1437  const typename details::number_type<T>::type num_type;
1438  return to_int64_impl(v, num_type);
1439  }
1440 
1441  template <typename T>
1442  inline _uint64_t to_uint64(const T v)
1443  {
1444  const typename details::number_type<T>::type num_type;
1445  return to_uint64_impl(v, num_type);
1446  }
1447 
1448  template <typename T>
1449  inline bool is_nan(const T v)
1450  {
1451  const typename details::number_type<T>::type num_type;
1452  return is_nan_impl(v, num_type);
1453  }
1454 
1455  template <typename T>
1456  inline T min(const T v0, const T v1)
1457  {
1458  const typename details::number_type<T>::type num_type;
1459  return min_impl(v0, v1, num_type);
1460  }
1461 
1462  template <typename T>
1463  inline T max(const T v0, const T v1)
1464  {
1465  const typename details::number_type<T>::type num_type;
1466  return max_impl(v0, v1, num_type);
1467  }
1468 
1469  template <typename T>
1470  inline T equal(const T v0, const T v1)
1471  {
1472  const typename details::number_type<T>::type num_type;
1473  return equal_impl(v0, v1, num_type);
1474  }
1475 
1476  template <typename T>
1477  inline T nequal(const T v0, const T v1)
1478  {
1479  const typename details::number_type<T>::type num_type;
1480  return nequal_impl(v0, v1, num_type);
1481  }
1482 
1483  template <typename T>
1484  inline T modulus(const T v0, const T v1)
1485  {
1486  const typename details::number_type<T>::type num_type;
1487  return modulus_impl(v0, v1, num_type);
1488  }
1489 
1490  template <typename T>
1491  inline T pow(const T v0, const T v1)
1492  {
1493  const typename details::number_type<T>::type num_type;
1494  return pow_impl(v0, v1, num_type);
1495  }
1496 
1497  template <typename T>
1498  inline T logn(const T v0, const T v1)
1499  {
1500  const typename details::number_type<T>::type num_type;
1501  return logn_impl(v0, v1, num_type);
1502  }
1503 
1504  template <typename T>
1505  inline T root(const T v0, const T v1)
1506  {
1507  const typename details::number_type<T>::type num_type;
1508  return root_impl(v0, v1, num_type);
1509  }
1510 
1511  template <typename T>
1512  inline T roundn(const T v0, const T v1)
1513  {
1514  const typename details::number_type<T>::type num_type;
1515  return roundn_impl(v0, v1, num_type);
1516  }
1517 
1518  template <typename T>
1519  inline T hypot(const T v0, const T v1)
1520  {
1521  const typename details::number_type<T>::type num_type;
1522  return hypot_impl(v0, v1, num_type);
1523  }
1524 
1525  template <typename T>
1526  inline T atan2(const T v0, const T v1)
1527  {
1528  const typename details::number_type<T>::type num_type;
1529  return atan2_impl(v0, v1, num_type);
1530  }
1531 
1532  template <typename T>
1533  inline T shr(const T v0, const T v1)
1534  {
1535  const typename details::number_type<T>::type num_type;
1536  return shr_impl(v0, v1, num_type);
1537  }
1538 
1539  template <typename T>
1540  inline T shl(const T v0, const T v1)
1541  {
1542  const typename details::number_type<T>::type num_type;
1543  return shl_impl(v0, v1, num_type);
1544  }
1545 
1546  template <typename T>
1547  inline T and_opr(const T v0, const T v1)
1548  {
1549  const typename details::number_type<T>::type num_type;
1550  return and_impl(v0, v1, num_type);
1551  }
1552 
1553  template <typename T>
1554  inline T nand_opr(const T v0, const T v1)
1555  {
1556  const typename details::number_type<T>::type num_type;
1557  return nand_impl(v0, v1, num_type);
1558  }
1559 
1560  template <typename T>
1561  inline T or_opr(const T v0, const T v1)
1562  {
1563  const typename details::number_type<T>::type num_type;
1564  return or_impl(v0, v1, num_type);
1565  }
1566 
1567  template <typename T>
1568  inline T nor_opr(const T v0, const T v1)
1569  {
1570  const typename details::number_type<T>::type num_type;
1571  return nor_impl(v0, v1, num_type);
1572  }
1573 
1574  template <typename T>
1575  inline T xor_opr(const T v0, const T v1)
1576  {
1577  const typename details::number_type<T>::type num_type;
1578  return xor_impl(v0, v1, num_type);
1579  }
1580 
1581  template <typename T>
1582  inline T xnor_opr(const T v0, const T v1)
1583  {
1584  const typename details::number_type<T>::type num_type;
1585  return xnor_impl(v0, v1, num_type);
1586  }
1587 
1588  template <typename T>
1589  inline bool is_integer(const T v)
1590  {
1591  const typename details::number_type<T>::type num_type;
1592  return is_integer_impl(v, num_type);
1593  }
1594 
1595  template <typename T, unsigned int N>
1596  struct fast_exp
1597  {
1598  static inline T result(T v)
1599  {
1600  unsigned int k = N;
1601  T l = T(1);
1602 
1603  while (k)
1604  {
1605  if (1 == (k % 2))
1606  {
1607  l *= v;
1608  --k;
1609  }
1610 
1611  v *= v;
1612  k /= 2;
1613  }
1614 
1615  return l;
1616  }
1617  };
1618 
1619  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; } };
1620  template <typename T> struct fast_exp<T, 9> { static inline T result(const T v) { return fast_exp<T,8>::result(v) * v; } };
1621  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; } };
1622  template <typename T> struct fast_exp<T, 7> { static inline T result(const T v) { return fast_exp<T,6>::result(v) * v; } };
1623  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; } };
1624  template <typename T> struct fast_exp<T, 5> { static inline T result(const T v) { return fast_exp<T,4>::result(v) * v; } };
1625  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; } };
1626  template <typename T> struct fast_exp<T, 3> { static inline T result(const T v) { return v * v * v; } };
1627  template <typename T> struct fast_exp<T, 2> { static inline T result(const T v) { return v * v; } };
1628  template <typename T> struct fast_exp<T, 1> { static inline T result(const T v) { return v; } };
1629  template <typename T> struct fast_exp<T, 0> { static inline T result(const T ) { return T(1); } };
1630 
1631  #define exprtk_define_unary_function(FunctionName) \
1632  template <typename T> \
1633  inline T FunctionName (const T v) \
1634  { \
1635  const typename details::number_type<T>::type num_type; \
1636  return FunctionName##_impl(v,num_type); \
1637  } \
1638 
1679  #undef exprtk_define_unary_function
1680  }
1681 
1682  template <typename T>
1683  inline T compute_pow10(T d, const int exponent)
1684  {
1685  static const double fract10[] =
1686  {
1687  0.0,
1688  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,
1689  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,
1690  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,
1691  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,
1692  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,
1693  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,
1694  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,
1695  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,
1696  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,
1697  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,
1698  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,
1699  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,
1700  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,
1701  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,
1702  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,
1703  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,
1704  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,
1705  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,
1706  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,
1707  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,
1708  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,
1709  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,
1710  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,
1711  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,
1712  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,
1713  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,
1714  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,
1715  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,
1716  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,
1717  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,
1718  1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
1719  };
1720 
1721  static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
1722 
1723  const int e = std::abs(exponent);
1724 
1725  if (exponent >= std::numeric_limits<T>::min_exponent10)
1726  {
1727  if (e < fract10_size)
1728  {
1729  if (exponent > 0)
1730  return T(d * fract10[e]);
1731  else
1732  return T(d / fract10[e]);
1733  }
1734  else
1735  return T(d * std::pow(10.0, 10.0 * exponent));
1736  }
1737  else
1738  {
1739  d /= T(fract10[ -std::numeric_limits<T>::min_exponent10]);
1740  return T(d / fract10[-exponent + std::numeric_limits<T>::min_exponent10]);
1741  }
1742  }
1743 
1744  template <typename Iterator, typename T>
1745  inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result)
1746  {
1747  if (itr == end)
1748  return false;
1749 
1750  const bool negative = ('-' == (*itr));
1751 
1752  if (negative || ('+' == (*itr)))
1753  {
1754  if (end == ++itr)
1755  return false;
1756  }
1757 
1758  static const uchar_t zero = static_cast<uchar_t>('0');
1759 
1760  while ((end != itr) && (zero == (*itr))) ++itr;
1761 
1762  bool return_result = true;
1763  unsigned int digit = 0;
1764  const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
1765 
1766  if (length <= 4)
1767  {
1768  switch (length)
1769  {
1770  #ifdef exprtk_use_lut
1771 
1772  #define exprtk_process_digit \
1773  if ((digit = details::digit_table[(int)*itr++]) < 10) \
1774  result = result * 10 + (digit); \
1775  else \
1776  { \
1777  return_result = false; \
1778  break; \
1779  } \
1780  exprtk_fallthrough \
1781 
1782  #else
1783 
1784  #define exprtk_process_digit \
1785  if ((digit = (*itr++ - zero)) < 10) \
1786  result = result * T(10) + digit; \
1787  else \
1788  { \
1789  return_result = false; \
1790  break; \
1791  } \
1792  exprtk_fallthrough \
1793 
1794  #endif
1795 
1796  case 4 : exprtk_process_digit
1797  case 3 : exprtk_process_digit
1798  case 2 : exprtk_process_digit
1799  case 1 : if ((digit = (*itr - zero))>= 10)
1800  {
1801  digit = 0;
1802  return_result = false;
1803  }
1804 
1805  #undef exprtk_process_digit
1806  }
1807  }
1808  else
1809  return_result = false;
1810 
1811  if (length && return_result)
1812  {
1813  result = result * 10 + static_cast<T>(digit);
1814  ++itr;
1815  }
1816 
1817  result = negative ? -result : result;
1818  return return_result;
1819  }
1820 
1821  template <typename Iterator, typename T>
1822  static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
1823  {
1824  typedef typename std::iterator_traits<Iterator>::value_type type;
1825 
1826  static const std::size_t nan_length = 3;
1827 
1828  if (std::distance(itr,end) != static_cast<int>(nan_length))
1829  return false;
1830 
1831  if (static_cast<type>('n') == (*itr))
1832  {
1833  if (
1834  (static_cast<type>('a') != *(itr + 1)) ||
1835  (static_cast<type>('n') != *(itr + 2))
1836  )
1837  {
1838  return false;
1839  }
1840  }
1841  else if (
1842  (static_cast<type>('A') != *(itr + 1)) ||
1843  (static_cast<type>('N') != *(itr + 2))
1844  )
1845  {
1846  return false;
1847  }
1848 
1849  t = std::numeric_limits<T>::quiet_NaN();
1850 
1851  return true;
1852  }
1853 
1854  template <typename Iterator, typename T>
1855  static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, const bool negative)
1856  {
1857  static const char_t inf_uc[] = "INFINITY";
1858  static const char_t inf_lc[] = "infinity";
1859  static const std::size_t inf_length = 8;
1860 
1861  const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
1862 
1863  if ((3 != length) && (inf_length != length))
1864  return false;
1865 
1866  char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
1867 
1868  while (end != itr)
1869  {
1870  if (*inf_itr == static_cast<char_t>(*itr))
1871  {
1872  ++itr;
1873  ++inf_itr;
1874  continue;
1875  }
1876  else
1877  return false;
1878  }
1879 
1880  if (negative)
1881  t = -std::numeric_limits<T>::infinity();
1882  else
1883  t = std::numeric_limits<T>::infinity();
1884 
1885  return true;
1886  }
1887 
1888  template <typename T>
1889  inline bool valid_exponent(const int exponent, numeric::details::real_type_tag)
1890  {
1891  using namespace details::numeric;
1892  return (numeric_info<T>::min_exp <= exponent) && (exponent <= numeric_info<T>::max_exp);
1893  }
1894 
1895  template <typename Iterator, typename T>
1896  inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t, numeric::details::real_type_tag)
1897  {
1898  if (end == itr_external) return false;
1899 
1900  Iterator itr = itr_external;
1901 
1902  T d = T(0);
1903 
1904  const bool negative = ('-' == (*itr));
1905 
1906  if (negative || '+' == (*itr))
1907  {
1908  if (end == ++itr)
1909  return false;
1910  }
1911 
1912  bool instate = false;
1913 
1914  static const char_t zero = static_cast<uchar_t>('0');
1915 
1916  #define parse_digit_1(d) \
1917  if ((digit = (*itr - zero)) < 10) \
1918  { d = d * T(10) + digit; } \
1919  else \
1920  { break; } \
1921  if (end == ++itr) break; \
1922 
1923  #define parse_digit_2(d) \
1924  if ((digit = (*itr - zero)) < 10) \
1925  { d = d * T(10) + digit; } \
1926  else \
1927  { break; } \
1928  ++itr; \
1929 
1930  if ('.' != (*itr))
1931  {
1932  const Iterator curr = itr;
1933 
1934  while ((end != itr) && (zero == (*itr))) ++itr;
1935 
1936  while (end != itr)
1937  {
1938  unsigned int digit;
1939  parse_digit_1(d)
1940  parse_digit_1(d)
1941  parse_digit_2(d)
1942  }
1943 
1944  if (curr != itr) instate = true;
1945  }
1946 
1947  int exponent = 0;
1948 
1949  if (end != itr)
1950  {
1951  if ('.' == (*itr))
1952  {
1953  const Iterator curr = ++itr;
1954  T tmp_d = T(0);
1955 
1956  while (end != itr)
1957  {
1958  unsigned int digit;
1959  parse_digit_1(tmp_d)
1960  parse_digit_1(tmp_d)
1961  parse_digit_2(tmp_d)
1962  }
1963 
1964  if (curr != itr)
1965  {
1966  instate = true;
1967 
1968  const int frac_exponent = static_cast<int>(-std::distance(curr, itr));
1969 
1970  if (!valid_exponent<T>(frac_exponent, numeric::details::real_type_tag()))
1971  return false;
1972 
1973  d += compute_pow10(tmp_d, frac_exponent);
1974  }
1975 
1976  #undef parse_digit_1
1977  #undef parse_digit_2
1978  }
1979 
1980  if (end != itr)
1981  {
1982  typename std::iterator_traits<Iterator>::value_type c = (*itr);
1983 
1984  if (('e' == c) || ('E' == c))
1985  {
1986  int exp = 0;
1987 
1988  if (!details::string_to_type_converter_impl_ref(++itr, end, exp))
1989  {
1990  if (end == itr)
1991  return false;
1992  else
1993  c = (*itr);
1994  }
1995 
1996  exponent += exp;
1997  }
1998 
1999  if (end != itr)
2000  {
2001  if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
2002  ++itr;
2003  else if ('#' == c)
2004  {
2005  if (end == ++itr)
2006  return false;
2007  else if (('I' <= (*itr)) && ((*itr) <= 'n'))
2008  {
2009  if (('i' == (*itr)) || ('I' == (*itr)))
2010  {
2011  return parse_inf(itr, end, t, negative);
2012  }
2013  else if (('n' == (*itr)) || ('N' == (*itr)))
2014  {
2015  return parse_nan(itr, end, t);
2016  }
2017  else
2018  return false;
2019  }
2020  else
2021  return false;
2022  }
2023  else if (('I' <= (*itr)) && ((*itr) <= 'n'))
2024  {
2025  if (('i' == (*itr)) || ('I' == (*itr)))
2026  {
2027  return parse_inf(itr, end, t, negative);
2028  }
2029  else if (('n' == (*itr)) || ('N' == (*itr)))
2030  {
2031  return parse_nan(itr, end, t);
2032  }
2033  else
2034  return false;
2035  }
2036  else
2037  return false;
2038  }
2039  }
2040  }
2041 
2042  if ((end != itr) || (!instate))
2043  return false;
2044  else if (!valid_exponent<T>(exponent, numeric::details::real_type_tag()))
2045  return false;
2046  else if (exponent)
2047  d = compute_pow10(d,exponent);
2048 
2049  t = static_cast<T>((negative) ? -d : d);
2050  return true;
2051  }
2052 
2053  template <typename T>
2054  inline bool string_to_real(const std::string& s, T& t)
2055  {
2056  const typename numeric::details::number_type<T>::type num_type;
2057 
2058  char_cptr begin = s.data();
2059  char_cptr end = s.data() + s.size();
2060 
2061  return string_to_real(begin, end, t, num_type);
2062  }
2063 
2064  template <typename T>
2065  struct functor_t
2066  {
2067  /*
2068  Note: The following definitions for Type, may require tweaking
2069  based on the compiler and target architecture. The benchmark
2070  should provide enough information to make the right choice.
2071  */
2072  //typedef T Type;
2073  //typedef const T Type;
2074  typedef const T& Type;
2075  typedef T& RefType;
2076  typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3);
2077  typedef T (*tfunc_t)(Type t0, Type t1, Type t2);
2078  typedef T (*bfunc_t)(Type t0, Type t1);
2079  typedef T (*ufunc_t)(Type t0);
2080  };
2081 
2082  } // namespace details
2083 
2085  {
2087  {
2088  e_invalid = 0,
2089  e_for_loop = 1,
2090  e_while_loop = 2,
2091  e_repeat_until_loop = 4,
2092  e_all_loops = 7
2093  };
2094 
2096  {
2098  e_iteration_count = 1,
2099  e_timeout = 2
2100  };
2101 
2103 
2105  : loop_set(e_invalid)
2106  , max_loop_iterations(0)
2107  {}
2108 
2110 
2112  {
2116  };
2117 
2118  virtual bool check()
2119  {
2120  return true;
2121  }
2122 
2124  {
2125  throw std::runtime_error("ExprTk Loop runtime violation.");
2126  }
2127 
2129  {}
2130  };
2131 
2133 
2135  {
2137  {
2138  void* base_ptr;
2139  void* end_ptr;
2140  void* access_ptr;
2141  std::size_t type_size;
2142  };
2143 
2145  {}
2146 
2147  virtual bool handle_runtime_violation(violation_context& /*context*/)
2148  {
2149  throw std::runtime_error("ExprTk runtime vector access violation.");
2150  #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
2151  return false;
2152  #endif
2153  }
2154  };
2155 
2157 
2159  {
2161  {
2162  std::string error_message;
2163  };
2164 
2165  virtual bool continue_compilation(compilation_context& /*context*/) = 0;
2166 
2168  {}
2169  };
2170 
2172 
2173  namespace lexer
2174  {
2175  struct token
2176  {
2178  {
2179  e_none = 0, e_error = 1, e_err_symbol = 2,
2180  e_err_number = 3, e_err_string = 4, e_err_sfunc = 5,
2181  e_eof = 6, e_number = 7, e_symbol = 8,
2182  e_string = 9, e_assign = 10, e_addass = 11,
2183  e_subass = 12, e_mulass = 13, e_divass = 14,
2184  e_modass = 15, e_shr = 16, e_shl = 17,
2185  e_lte = 18, e_ne = 19, e_gte = 20,
2186  e_swap = 21, e_lt = '<', e_gt = '>',
2187  e_eq = '=', e_rbracket = ')', e_lbracket = '(',
2188  e_rsqrbracket = ']', e_lsqrbracket = '[', e_rcrlbracket = '}',
2189  e_lcrlbracket = '{', e_comma = ',', e_add = '+',
2190  e_sub = '-', e_div = '/', e_mul = '*',
2191  e_mod = '%', e_pow = '^', e_colon = ':',
2192  e_ternary = '?'
2193  };
2194 
2196  : type(e_none)
2197  , value("")
2198  , position(std::numeric_limits<std::size_t>::max())
2199  {}
2200 
2201  void clear()
2202  {
2203  type = e_none;
2204  value = "";
2206  }
2207 
2208  template <typename Iterator>
2209  inline token& set_operator(const token_type tt,
2210  const Iterator begin, const Iterator end,
2211  const Iterator base_begin = Iterator(0))
2212  {
2213  type = tt;
2214  value.assign(begin,end);
2215  if (base_begin)
2216  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2217  return (*this);
2218  }
2219 
2220  template <typename Iterator>
2221  inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2222  {
2223  type = e_symbol;
2224  value.assign(begin,end);
2225  if (base_begin)
2226  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2227  return (*this);
2228  }
2229 
2230  template <typename Iterator>
2231  inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2232  {
2233  type = e_number;
2234  value.assign(begin,end);
2235  if (base_begin)
2236  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2237  return (*this);
2238  }
2239 
2240  template <typename Iterator>
2241  inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2242  {
2243  type = e_string;
2244  value.assign(begin,end);
2245  if (base_begin)
2246  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2247  return (*this);
2248  }
2249 
2250  inline token& set_string(const std::string& s, const std::size_t p)
2251  {
2252  type = e_string;
2253  value = s;
2254  position = p;
2255  return (*this);
2256  }
2257 
2258  template <typename Iterator>
2259  inline token& set_error(const token_type et,
2260  const Iterator begin, const Iterator end,
2261  const Iterator base_begin = Iterator(0))
2262  {
2263  if (
2264  (e_error == et) ||
2265  (e_err_symbol == et) ||
2266  (e_err_number == et) ||
2267  (e_err_string == et) ||
2268  (e_err_sfunc == et)
2269  )
2270  {
2271  type = et;
2272  }
2273  else
2274  type = e_error;
2275 
2276  value.assign(begin,end);
2277 
2278  if (base_begin)
2279  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2280 
2281  return (*this);
2282  }
2283 
2284  static inline std::string to_str(token_type t)
2285  {
2286  switch (t)
2287  {
2288  case e_none : return "NONE";
2289  case e_error : return "ERROR";
2290  case e_err_symbol : return "ERROR_SYMBOL";
2291  case e_err_number : return "ERROR_NUMBER";
2292  case e_err_string : return "ERROR_STRING";
2293  case e_eof : return "EOF";
2294  case e_number : return "NUMBER";
2295  case e_symbol : return "SYMBOL";
2296  case e_string : return "STRING";
2297  case e_assign : return ":=";
2298  case e_addass : return "+=";
2299  case e_subass : return "-=";
2300  case e_mulass : return "*=";
2301  case e_divass : return "/=";
2302  case e_modass : return "%=";
2303  case e_shr : return ">>";
2304  case e_shl : return "<<";
2305  case e_lte : return "<=";
2306  case e_ne : return "!=";
2307  case e_gte : return ">=";
2308  case e_lt : return "<";
2309  case e_gt : return ">";
2310  case e_eq : return "=";
2311  case e_rbracket : return ")";
2312  case e_lbracket : return "(";
2313  case e_rsqrbracket : return "]";
2314  case e_lsqrbracket : return "[";
2315  case e_rcrlbracket : return "}";
2316  case e_lcrlbracket : return "{";
2317  case e_comma : return ",";
2318  case e_add : return "+";
2319  case e_sub : return "-";
2320  case e_div : return "/";
2321  case e_mul : return "*";
2322  case e_mod : return "%";
2323  case e_pow : return "^";
2324  case e_colon : return ":";
2325  case e_ternary : return "?";
2326  case e_swap : return "<=>";
2327  default : return "UNKNOWN";
2328  }
2329  }
2330 
2331  inline bool is_error() const
2332  {
2333  return (
2334  (e_error == type) ||
2335  (e_err_symbol == type) ||
2336  (e_err_number == type) ||
2337  (e_err_string == type) ||
2338  (e_err_sfunc == type)
2339  );
2340  }
2341 
2343  std::string value;
2344  std::size_t position;
2345  };
2346 
2348  {
2349  public:
2350 
2351  typedef token token_t;
2352  typedef std::vector<token_t> token_list_t;
2353  typedef token_list_t::iterator token_list_itr_t;
2355 
2357  : base_itr_(0)
2358  , s_itr_ (0)
2359  , s_end_ (0)
2360  {
2361  clear();
2362  }
2363 
2364  inline void clear()
2365  {
2366  base_itr_ = 0;
2367  s_itr_ = 0;
2368  s_end_ = 0;
2369  token_list_.clear();
2370  token_itr_ = token_list_.end();
2371  store_token_itr_ = token_list_.end();
2372  }
2373 
2374  inline bool process(const std::string& str)
2375  {
2376  base_itr_ = str.data();
2377  s_itr_ = str.data();
2378  s_end_ = str.data() + str.size();
2379 
2380  eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_);
2381  token_list_.clear();
2382 
2383  while (!is_end(s_itr_))
2384  {
2385  scan_token();
2386 
2387  if (!token_list_.empty() && token_list_.back().is_error())
2388  return false;
2389  }
2390 
2391  return true;
2392  }
2393 
2394  inline bool empty() const
2395  {
2396  return token_list_.empty();
2397  }
2398 
2399  inline std::size_t size() const
2400  {
2401  return token_list_.size();
2402  }
2403 
2404  inline void begin()
2405  {
2406  token_itr_ = token_list_.begin();
2407  store_token_itr_ = token_list_.begin();
2408  }
2409 
2410  inline void store()
2411  {
2412  store_token_itr_ = token_itr_;
2413  }
2414 
2415  inline void restore()
2416  {
2417  token_itr_ = store_token_itr_;
2418  }
2419 
2421  {
2422  if (token_list_.end() != token_itr_)
2423  {
2424  return *token_itr_++;
2425  }
2426  else
2427  return eof_token_;
2428  }
2429 
2431  {
2432  if (token_list_.end() != token_itr_)
2433  {
2434  return *token_itr_;
2435  }
2436  else
2437  return eof_token_;
2438  }
2439 
2440  inline token_t& operator[](const std::size_t& index)
2441  {
2442  if (index < token_list_.size())
2443  return token_list_[index];
2444  else
2445  return eof_token_;
2446  }
2447 
2448  inline token_t operator[](const std::size_t& index) const
2449  {
2450  if (index < token_list_.size())
2451  return token_list_[index];
2452  else
2453  return eof_token_;
2454  }
2455 
2456  inline bool finished() const
2457  {
2458  return (token_list_.end() == token_itr_);
2459  }
2460 
2461  inline void insert_front(token_t::token_type tk_type)
2462  {
2463  if (
2464  !token_list_.empty() &&
2465  (token_list_.end() != token_itr_)
2466  )
2467  {
2468  token_t t = *token_itr_;
2469 
2470  t.type = tk_type;
2471  token_itr_ = token_list_.insert(token_itr_,t);
2472  }
2473  }
2474 
2475  inline std::string substr(const std::size_t& begin, const std::size_t& end) const
2476  {
2477  const details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
2478  const details::char_cptr end_itr = ((base_itr_ + end ) < s_end_) ? (base_itr_ + end ) : s_end_;
2479 
2480  return std::string(begin_itr,end_itr);
2481  }
2482 
2483  inline std::string remaining() const
2484  {
2485  if (finished())
2486  return "";
2487  else if (token_list_.begin() != token_itr_)
2488  return std::string(base_itr_ + (token_itr_ - 1)->position, s_end_);
2489  else
2490  return std::string(base_itr_ + token_itr_->position, s_end_);
2491  }
2492 
2493  private:
2494 
2495  inline bool is_end(details::char_cptr itr) const
2496  {
2497  return (s_end_ == itr);
2498  }
2499 
2500  #ifndef exprtk_disable_comments
2501  inline bool is_comment_start(details::char_cptr itr) const
2502  {
2503  const char_t c0 = *(itr + 0);
2504  const char_t c1 = *(itr + 1);
2505 
2506  if ('#' == c0)
2507  return true;
2508  else if (!is_end(itr + 1))
2509  {
2510  if (('/' == c0) && ('/' == c1)) return true;
2511  if (('/' == c0) && ('*' == c1)) return true;
2512  }
2513  return false;
2514  }
2515  #else
2516  inline bool is_comment_start(details::char_cptr) const
2517  {
2518  return false;
2519  }
2520  #endif
2521 
2522  inline void skip_whitespace()
2523  {
2524  while (!is_end(s_itr_) && details::is_whitespace(*s_itr_))
2525  {
2526  ++s_itr_;
2527  }
2528  }
2529 
2530  inline void skip_comments()
2531  {
2532  #ifndef exprtk_disable_comments
2533  // The following comment styles are supported:
2534  // 1. // .... \n
2535  // 2. # .... \n
2536  // 3. /* .... */
2537  struct test
2538  {
2539  static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr)
2540  {
2541  mode = 0;
2542  if ('#' == c0) { mode = 1; incr = 1; }
2543  else if ('/' == c0)
2544  {
2545  if ('/' == c1) { mode = 1; incr = 2; }
2546  else if ('*' == c1) { mode = 2; incr = 2; }
2547  }
2548  return (0 != mode);
2549  }
2550 
2551  static inline bool comment_end(const char_t c0, const char_t c1, int& mode)
2552  {
2553  if (
2554  ((1 == mode) && ('\n' == c0)) ||
2555  ((2 == mode) && ( '*' == c0) && ('/' == c1))
2556  )
2557  {
2558  mode = 0;
2559  return true;
2560  }
2561  else
2562  return false;
2563  }
2564  };
2565 
2566  int mode = 0;
2567  int increment = 0;
2568 
2569  if (is_end(s_itr_))
2570  return;
2571  else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment))
2572  return;
2573 
2574  details::char_cptr cmt_start = s_itr_;
2575 
2576  s_itr_ += increment;
2577 
2578  while (!is_end(s_itr_))
2579  {
2580  if ((1 == mode) && test::comment_end(*s_itr_, 0, mode))
2581  {
2582  ++s_itr_;
2583  return;
2584  }
2585 
2586  if ((2 == mode))
2587  {
2588  if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode))
2589  {
2590  s_itr_ += 2;
2591  return;
2592  }
2593  }
2594 
2595  ++s_itr_;
2596  }
2597 
2598  if (2 == mode)
2599  {
2600  token_t t;
2601  t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_);
2602  token_list_.push_back(t);
2603  }
2604  #endif
2605  }
2606 
2607  inline void scan_token()
2608  {
2609  const char_t c = *s_itr_;
2610 
2611  if (details::is_whitespace(c))
2612  {
2613  skip_whitespace();
2614  return;
2615  }
2616  else if (is_comment_start(s_itr_))
2617  {
2618  skip_comments();
2619  return;
2620  }
2621  else if (details::is_operator_char(c))
2622  {
2623  scan_operator();
2624  return;
2625  }
2626  else if (details::is_letter(c))
2627  {
2628  scan_symbol();
2629  return;
2630  }
2631  else if (details::is_digit(c) || ('.' == c))
2632  {
2633  scan_number();
2634  return;
2635  }
2636  else if ('$' == c)
2637  {
2638  scan_special_function();
2639  return;
2640  }
2641  #ifndef exprtk_disable_string_capabilities
2642  else if ('\'' == c)
2643  {
2644  scan_string();
2645  return;
2646  }
2647  #endif
2648  else if ('~' == c)
2649  {
2650  token_t t;
2651  t.set_symbol(s_itr_, s_itr_ + 1, base_itr_);
2652  token_list_.push_back(t);
2653  ++s_itr_;
2654  return;
2655  }
2656  else
2657  {
2658  token_t t;
2659  t.set_error(token::e_error, s_itr_, s_itr_ + 2, base_itr_);
2660  token_list_.push_back(t);
2661  ++s_itr_;
2662  }
2663  }
2664 
2665  inline void scan_operator()
2666  {
2667  token_t t;
2668 
2669  const char_t c0 = s_itr_[0];
2670 
2671  if (!is_end(s_itr_ + 1))
2672  {
2673  const char_t c1 = s_itr_[1];
2674 
2675  if (!is_end(s_itr_ + 2))
2676  {
2677  const char_t c2 = s_itr_[2];
2678 
2679  if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
2680  {
2681  t.set_operator(token_t::e_swap, s_itr_, s_itr_ + 3, base_itr_);
2682  token_list_.push_back(t);
2683  s_itr_ += 3;
2684  return;
2685  }
2686  }
2687 
2688  token_t::token_type ttype = token_t::e_none;
2689 
2690  if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
2691  else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
2692  else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
2693  else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
2694  else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq;
2695  else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign;
2696  else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl;
2697  else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr;
2698  else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass;
2699  else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass;
2700  else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass;
2701  else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass;
2702  else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass;
2703 
2704  if (token_t::e_none != ttype)
2705  {
2706  t.set_operator(ttype, s_itr_, s_itr_ + 2, base_itr_);
2707  token_list_.push_back(t);
2708  s_itr_ += 2;
2709  return;
2710  }
2711  }
2712 
2713  if ('<' == c0)
2714  t.set_operator(token_t::e_lt , s_itr_, s_itr_ + 1, base_itr_);
2715  else if ('>' == c0)
2716  t.set_operator(token_t::e_gt , s_itr_, s_itr_ + 1, base_itr_);
2717  else if (';' == c0)
2718  t.set_operator(token_t::e_eof, s_itr_, s_itr_ + 1, base_itr_);
2719  else if ('&' == c0)
2720  t.set_symbol(s_itr_, s_itr_ + 1, base_itr_);
2721  else if ('|' == c0)
2722  t.set_symbol(s_itr_, s_itr_ + 1, base_itr_);
2723  else
2724  t.set_operator(token_t::token_type(c0), s_itr_, s_itr_ + 1, base_itr_);
2725 
2726  token_list_.push_back(t);
2727  ++s_itr_;
2728  }
2729 
2730  inline void scan_symbol()
2731  {
2732  details::char_cptr initial_itr = s_itr_;
2733 
2734  while (!is_end(s_itr_))
2735  {
2736  if (!details::is_letter_or_digit(*s_itr_) && ('_' != (*s_itr_)))
2737  {
2738  if ('.' != (*s_itr_))
2739  break;
2740  /*
2741  Permit symbols that contain a 'dot'
2742  Allowed : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123
2743  Disallowed: .abc, abc.<white-space>, abc.<eof>, abc.<operator +,-,*,/...>
2744  */
2745  if (
2746  (s_itr_ != initial_itr) &&
2747  !is_end(s_itr_ + 1) &&
2748  !details::is_letter_or_digit(*(s_itr_ + 1)) &&
2749  ('_' != (*(s_itr_ + 1)))
2750  )
2751  break;
2752  }
2753 
2754  ++s_itr_;
2755  }
2756 
2757  token_t t;
2758  t.set_symbol(initial_itr, s_itr_, base_itr_);
2759  token_list_.push_back(t);
2760  }
2761 
2762  inline void scan_number()
2763  {
2764  /*
2765  Attempt to match a valid numeric value in one of the following formats:
2766  (01) 123456
2767  (02) 123456.
2768  (03) 123.456
2769  (04) 123.456e3
2770  (05) 123.456E3
2771  (06) 123.456e+3
2772  (07) 123.456E+3
2773  (08) 123.456e-3
2774  (09) 123.456E-3
2775  (00) .1234
2776  (11) .1234e3
2777  (12) .1234E+3
2778  (13) .1234e+3
2779  (14) .1234E-3
2780  (15) .1234e-3
2781  */
2782 
2783  details::char_cptr initial_itr = s_itr_;
2784  bool dot_found = false;
2785  bool e_found = false;
2786  bool post_e_sign_found = false;
2787  bool post_e_digit_found = false;
2788  token_t t;
2789 
2790  while (!is_end(s_itr_))
2791  {
2792  if ('.' == (*s_itr_))
2793  {
2794  if (dot_found)
2795  {
2796  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2797  token_list_.push_back(t);
2798 
2799  return;
2800  }
2801 
2802  dot_found = true;
2803  ++s_itr_;
2804 
2805  continue;
2806  }
2807  else if ('e' == std::tolower(*s_itr_))
2808  {
2809  const char_t& c = *(s_itr_ + 1);
2810 
2811  if (is_end(s_itr_ + 1))
2812  {
2813  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2814  token_list_.push_back(t);
2815 
2816  return;
2817  }
2818  else if (
2819  ('+' != c) &&
2820  ('-' != c) &&
2821  !details::is_digit(c)
2822  )
2823  {
2824  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2825  token_list_.push_back(t);
2826 
2827  return;
2828  }
2829 
2830  e_found = true;
2831  ++s_itr_;
2832 
2833  continue;
2834  }
2835  else if (e_found && details::is_sign(*s_itr_) && !post_e_digit_found)
2836  {
2837  if (post_e_sign_found)
2838  {
2839  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2840  token_list_.push_back(t);
2841 
2842  return;
2843  }
2844 
2845  post_e_sign_found = true;
2846  ++s_itr_;
2847 
2848  continue;
2849  }
2850  else if (e_found && details::is_digit(*s_itr_))
2851  {
2852  post_e_digit_found = true;
2853  ++s_itr_;
2854 
2855  continue;
2856  }
2857  else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_))
2858  break;
2859  else
2860  ++s_itr_;
2861  }
2862 
2863  t.set_numeric(initial_itr, s_itr_, base_itr_);
2864  token_list_.push_back(t);
2865 
2866  return;
2867  }
2868 
2870  {
2871  details::char_cptr initial_itr = s_itr_;
2872  token_t t;
2873 
2874  // $fdd(x,x,x) = at least 11 chars
2875  if (std::distance(s_itr_,s_end_) < 11)
2876  {
2877  t.set_error(
2878  token::e_err_sfunc,
2879  initial_itr, std::min(initial_itr + 11, s_end_),
2880  base_itr_);
2881  token_list_.push_back(t);
2882 
2883  return;
2884  }
2885 
2886  if (
2887  !(('$' == *s_itr_) &&
2888  (details::imatch ('f',*(s_itr_ + 1))) &&
2889  (details::is_digit(*(s_itr_ + 2))) &&
2890  (details::is_digit(*(s_itr_ + 3))))
2891  )
2892  {
2893  t.set_error(
2894  token::e_err_sfunc,
2895  initial_itr, std::min(initial_itr + 4, s_end_),
2896  base_itr_);
2897  token_list_.push_back(t);
2898 
2899  return;
2900  }
2901 
2902  s_itr_ += 4; // $fdd = 4chars
2903 
2904  t.set_symbol(initial_itr, s_itr_, base_itr_);
2905  token_list_.push_back(t);
2906 
2907  return;
2908  }
2909 
2910  #ifndef exprtk_disable_string_capabilities
2911  inline void scan_string()
2912  {
2913  details::char_cptr initial_itr = s_itr_ + 1;
2914  token_t t;
2915 
2916  if (std::distance(s_itr_,s_end_) < 2)
2917  {
2918  t.set_error(token::e_err_string, s_itr_, s_end_, base_itr_);
2919  token_list_.push_back(t);
2920 
2921  return;
2922  }
2923 
2924  ++s_itr_;
2925 
2926  bool escaped_found = false;
2927  bool escaped = false;
2928 
2929  while (!is_end(s_itr_))
2930  {
2931  if (!details::is_valid_string_char(*s_itr_))
2932  {
2933  t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
2934  token_list_.push_back(t);
2935 
2936  return;
2937  }
2938  else if (!escaped && ('\\' == *s_itr_))
2939  {
2940  escaped_found = true;
2941  escaped = true;
2942  ++s_itr_;
2943 
2944  continue;
2945  }
2946  else if (!escaped)
2947  {
2948  if ('\'' == *s_itr_)
2949  break;
2950  }
2951  else if (escaped)
2952  {
2953  if (
2954  !is_end(s_itr_) && ('0' == *(s_itr_)) &&
2955  ((s_itr_ + 4) <= s_end_)
2956  )
2957  {
2958  const bool x_separator = ('X' == std::toupper(*(s_itr_ + 1)));
2959 
2960  const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) &&
2961  details::is_hex_digit(*(s_itr_ + 3)) ;
2962 
2963  if (!(x_separator && both_digits))
2964  {
2965  t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
2966  token_list_.push_back(t);
2967 
2968  return;
2969  }
2970  else
2971  s_itr_ += 3;
2972  }
2973 
2974  escaped = false;
2975  }
2976 
2977  ++s_itr_;
2978  }
2979 
2980  if (is_end(s_itr_))
2981  {
2982  t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
2983  token_list_.push_back(t);
2984 
2985  return;
2986  }
2987 
2988  if (!escaped_found)
2989  t.set_string(initial_itr, s_itr_, base_itr_);
2990  else
2991  {
2992  std::string parsed_string(initial_itr,s_itr_);
2993 
2994  if (!details::cleanup_escapes(parsed_string))
2995  {
2996  t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
2997  token_list_.push_back(t);
2998 
2999  return;
3000  }
3001 
3002  t.set_string(
3003  parsed_string,
3004  static_cast<std::size_t>(std::distance(base_itr_,initial_itr)));
3005  }
3006 
3007  token_list_.push_back(t);
3008  ++s_itr_;
3009 
3010  return;
3011  }
3012  #endif
3013 
3014  private:
3015 
3023 
3024  friend class token_scanner;
3025  friend class token_modifier;
3026  friend class token_inserter;
3027  friend class token_joiner;
3028  }; // class generator
3029 
3031  {
3032  public:
3033 
3034  virtual void init() { }
3035  virtual void reset() { }
3036  virtual bool result() { return true; }
3037  virtual std::size_t process(generator&) { return 0; }
3038  virtual ~helper_interface() { }
3039  };
3040 
3042  {
3043  public:
3044 
3045  virtual ~token_scanner()
3046  {}
3047 
3048  explicit token_scanner(const std::size_t& stride)
3049  : stride_(stride)
3050  {
3051  if (stride > 4)
3052  {
3053  throw std::invalid_argument("token_scanner() - Invalid stride value");
3054  }
3055  }
3056 
3057  inline std::size_t process(generator& g) exprtk_override
3058  {
3059  if (g.token_list_.size() >= stride_)
3060  {
3061  for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
3062  {
3063  token t;
3064 
3065  switch (stride_)
3066  {
3067  case 1 :
3068  {
3069  const token& t0 = g.token_list_[i];
3070 
3071  if (!operator()(t0))
3072  {
3073  return i;
3074  }
3075  }
3076  break;
3077 
3078  case 2 :
3079  {
3080  const token& t0 = g.token_list_[i ];
3081  const token& t1 = g.token_list_[i + 1];
3082 
3083  if (!operator()(t0, t1))
3084  {
3085  return i;
3086  }
3087  }
3088  break;
3089 
3090  case 3 :
3091  {
3092  const token& t0 = g.token_list_[i ];
3093  const token& t1 = g.token_list_[i + 1];
3094  const token& t2 = g.token_list_[i + 2];
3095 
3096  if (!operator()(t0, t1, t2))
3097  {
3098  return i;
3099  }
3100  }
3101  break;
3102 
3103  case 4 :
3104  {
3105  const token& t0 = g.token_list_[i ];
3106  const token& t1 = g.token_list_[i + 1];
3107  const token& t2 = g.token_list_[i + 2];
3108  const token& t3 = g.token_list_[i + 3];
3109 
3110  if (!operator()(t0, t1, t2, t3))
3111  {
3112  return i;
3113  }
3114  }
3115  break;
3116  }
3117  }
3118  }
3119 
3120  return (g.token_list_.size() - stride_ + 1);
3121  }
3122 
3123  virtual bool operator() (const token&)
3124  {
3125  return false;
3126  }
3127 
3128  virtual bool operator() (const token&, const token&)
3129  {
3130  return false;
3131  }
3132 
3133  virtual bool operator() (const token&, const token&, const token&)
3134  {
3135  return false;
3136  }
3137 
3138  virtual bool operator() (const token&, const token&, const token&, const token&)
3139  {
3140  return false;
3141  }
3142 
3143  private:
3144 
3145  const std::size_t stride_;
3146  }; // class token_scanner
3147 
3149  {
3150  public:
3151 
3152  inline std::size_t process(generator& g) exprtk_override
3153  {
3154  std::size_t changes = 0;
3155 
3156  for (std::size_t i = 0; i < g.token_list_.size(); ++i)
3157  {
3158  if (modify(g.token_list_[i])) changes++;
3159  }
3160 
3161  return changes;
3162  }
3163 
3164  virtual bool modify(token& t) = 0;
3165  };
3166 
3168  {
3169  public:
3170 
3171  explicit token_inserter(const std::size_t& stride)
3172  : stride_(stride)
3173  {
3174  if (stride > 5)
3175  {
3176  throw std::invalid_argument("token_inserter() - Invalid stride value");
3177  }
3178  }
3179 
3180  inline std::size_t process(generator& g) exprtk_override
3181  {
3182  if (g.token_list_.empty())
3183  return 0;
3184  else if (g.token_list_.size() < stride_)
3185  return 0;
3186 
3187  std::size_t changes = 0;
3188 
3189  typedef std::pair<std::size_t, token> insert_t;
3190  std::vector<insert_t> insert_list;
3191  insert_list.reserve(10000);
3192 
3193  for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
3194  {
3195  int insert_index = -1;
3196  token t;
3197 
3198  switch (stride_)
3199  {
3200  case 1 : insert_index = insert(g.token_list_[i],t);
3201  break;
3202 
3203  case 2 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], t);
3204  break;
3205 
3206  case 3 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], g.token_list_[i + 2], t);
3207  break;
3208 
3209  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);
3210  break;
3211 
3212  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);
3213  break;
3214  }
3215 
3216  if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1)))
3217  {
3218  insert_list.push_back(insert_t(i, t));
3219  changes++;
3220  }
3221  }
3222 
3223  if (!insert_list.empty())
3224  {
3225  generator::token_list_t token_list;
3226 
3227  std::size_t insert_index = 0;
3228 
3229  for (std::size_t i = 0; i < g.token_list_.size(); ++i)
3230  {
3231  token_list.push_back(g.token_list_[i]);
3232 
3233  if (
3234  (insert_index < insert_list.size()) &&
3235  (insert_list[insert_index].first == i)
3236  )
3237  {
3238  token_list.push_back(insert_list[insert_index].second);
3239  insert_index++;
3240  }
3241  }
3242 
3243  std::swap(g.token_list_,token_list);
3244  }
3245 
3246  return changes;
3247  }
3248 
3249  #define token_inserter_empty_body \
3250  { \
3251  return -1; \
3252  } \
3253 
3254  inline virtual int insert(const token&, token&)
3256 
3257  inline virtual int insert(const token&, const token&, token&)
3259 
3260  inline virtual int insert(const token&, const token&, const token&, token&)
3262 
3263  inline virtual int insert(const token&, const token&, const token&, const token&, token&)
3265 
3266  inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&)
3268 
3269  #undef token_inserter_empty_body
3270 
3271  private:
3272 
3273  const std::size_t stride_;
3274  };
3275 
3277  {
3278  public:
3279 
3280  explicit token_joiner(const std::size_t& stride)
3281  : stride_(stride)
3282  {}
3283 
3284  inline std::size_t process(generator& g) exprtk_override
3285  {
3286  if (g.token_list_.empty())
3287  return 0;
3288 
3289  switch (stride_)
3290  {
3291  case 2 : return process_stride_2(g);
3292  case 3 : return process_stride_3(g);
3293  default : return 0;
3294  }
3295  }
3296 
3297  virtual bool join(const token&, const token&, token&) { return false; }
3298  virtual bool join(const token&, const token&, const token&, token&) { return false; }
3299 
3300  private:
3301 
3302  inline std::size_t process_stride_2(generator& g)
3303  {
3304  if (g.token_list_.size() < 2)
3305  return 0;
3306 
3307  std::size_t changes = 0;
3308 
3309  generator::token_list_t token_list;
3310  token_list.reserve(10000);
3311 
3312  for (int i = 0; i < static_cast<int>(g.token_list_.size() - 1); ++i)
3313  {
3314  token t;
3315 
3316  for ( ; ; )
3317  {
3318  if (!join(g[i], g[i + 1], t))
3319  {
3320  token_list.push_back(g[i]);
3321  break;
3322  }
3323 
3324  token_list.push_back(t);
3325 
3326  ++changes;
3327 
3328  i += 2;
3329 
3330  if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1))
3331  break;
3332  }
3333  }
3334 
3335  token_list.push_back(g.token_list_.back());
3336 
3337  assert(token_list.size() <= g.token_list_.size());
3338 
3339  std::swap(token_list, g.token_list_);
3340 
3341  return changes;
3342  }
3343 
3344  inline std::size_t process_stride_3(generator& g)
3345  {
3346  if (g.token_list_.size() < 3)
3347  return 0;
3348 
3349  std::size_t changes = 0;
3350 
3351  generator::token_list_t token_list;
3352  token_list.reserve(10000);
3353 
3354  for (int i = 0; i < static_cast<int>(g.token_list_.size() - 2); ++i)
3355  {
3356  token t;
3357 
3358  for ( ; ; )
3359  {
3360  if (!join(g[i], g[i + 1], g[i + 2], t))
3361  {
3362  token_list.push_back(g[i]);
3363  break;
3364  }
3365 
3366  token_list.push_back(t);
3367 
3368  ++changes;
3369 
3370  i += 3;
3371 
3372  if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2))
3373  break;
3374  }
3375  }
3376 
3377  token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 2));
3378  token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 1));
3379 
3380  assert(token_list.size() <= g.token_list_.size());
3381 
3382  std::swap(token_list, g.token_list_);
3383 
3384  return changes;
3385  }
3386 
3387  const std::size_t stride_;
3388  };
3389 
3390  namespace helper
3391  {
3392 
3393  inline void dump(const lexer::generator& generator)
3394  {
3395  for (std::size_t i = 0; i < generator.size(); ++i)
3396  {
3397  const lexer::token& t = generator[i];
3398  printf("Token[%02d] @ %03d %6s --> '%s'\n",
3399  static_cast<int>(i),
3400  static_cast<int>(t.position),
3401  t.to_str(t.type).c_str(),
3402  t.value.c_str());
3403  }
3404  }
3405 
3407  {
3408  public:
3409 
3411 
3413  : lexer::token_inserter(2)
3414  {}
3415 
3416  inline void ignore_symbol(const std::string& symbol)
3417  {
3418  ignore_set_.insert(symbol);
3419  }
3420 
3421  inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) exprtk_override
3422  {
3423  bool match = false;
3424  new_token.type = lexer::token::e_mul;
3425  new_token.value = "*";
3426  new_token.position = t1.position;
3427 
3428  if (t0.type == lexer::token::e_symbol)
3429  {
3430  if (ignore_set_.end() != ignore_set_.find(t0.value))
3431  {
3432  return -1;
3433  }
3434  else if (!t0.value.empty() && ('$' == t0.value[0]))
3435  {
3436  return -1;
3437  }
3438  }
3439 
3440  if (t1.type == lexer::token::e_symbol)
3441  {
3442  if (ignore_set_.end() != ignore_set_.find(t1.value))
3443  {
3444  return -1;
3445  }
3446  }
3447  if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
3448  else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lbracket )) match = true;
3449  else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
3450  else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
3451  else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_number )) match = true;
3452  else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_number )) match = true;
3453  else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number )) match = true;
3454  else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number )) match = true;
3455  else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_symbol )) match = true;
3456  else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol )) match = true;
3457  else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol )) match = true;
3458  else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_symbol )) match = true;
3459 
3460  return (match) ? 1 : -1;
3461  }
3462 
3463  private:
3464 
3465  std::set<std::string,details::ilesscompare> ignore_set_;
3466  };
3467 
3468  class operator_joiner exprtk_final : public token_joiner
3469  {
3470  public:
3471 
3472  explicit operator_joiner(const std::size_t& stride)
3473  : token_joiner(stride)
3474  {}
3475 
3476  inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) exprtk_override
3477  {
3478  // ': =' --> ':='
3479  if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
3480  {
3481  t.type = lexer::token::e_assign;
3482  t.value = ":=";
3483  t.position = t0.position;
3484 
3485  return true;
3486  }
3487  // '+ =' --> '+='
3488  else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq))
3489  {
3490  t.type = lexer::token::e_addass;
3491  t.value = "+=";
3492  t.position = t0.position;
3493 
3494  return true;
3495  }
3496  // '- =' --> '-='
3497  else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq))
3498  {
3499  t.type = lexer::token::e_subass;
3500  t.value = "-=";
3501  t.position = t0.position;
3502 
3503  return true;
3504  }
3505  // '* =' --> '*='
3506  else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq))
3507  {
3508  t.type = lexer::token::e_mulass;
3509  t.value = "*=";
3510  t.position = t0.position;
3511 
3512  return true;
3513  }
3514  // '/ =' --> '/='
3515  else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq))
3516  {
3517  t.type = lexer::token::e_divass;
3518  t.value = "/=";
3519  t.position = t0.position;
3520 
3521  return true;
3522  }
3523  // '% =' --> '%='
3524  else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq))
3525  {
3526  t.type = lexer::token::e_modass;
3527  t.value = "%=";
3528  t.position = t0.position;
3529 
3530  return true;
3531  }
3532  // '> =' --> '>='
3533  else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq))
3534  {
3535  t.type = lexer::token::e_gte;
3536  t.value = ">=";
3537  t.position = t0.position;
3538 
3539  return true;
3540  }
3541  // '< =' --> '<='
3542  else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq))
3543  {
3544  t.type = lexer::token::e_lte;
3545  t.value = "<=";
3546  t.position = t0.position;
3547 
3548  return true;
3549  }
3550  // '= =' --> '=='
3551  else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq))
3552  {
3553  t.type = lexer::token::e_eq;
3554  t.value = "==";
3555  t.position = t0.position;
3556 
3557  return true;
3558  }
3559  // '! =' --> '!='
3560  else if ((static_cast<details::char_t>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
3561  {
3562  t.type = lexer::token::e_ne;
3563  t.value = "!=";
3564  t.position = t0.position;
3565 
3566  return true;
3567  }
3568  // '< >' --> '<>'
3569  else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt))
3570  {
3571  t.type = lexer::token::e_ne;
3572  t.value = "<>";
3573  t.position = t0.position;
3574 
3575  return true;
3576  }
3577  // '<= >' --> '<=>'
3578  else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt))
3579  {
3580  t.type = lexer::token::e_swap;
3581  t.value = "<=>";
3582  t.position = t0.position;
3583 
3584  return true;
3585  }
3586  // '+ -' --> '-'
3587  else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_sub))
3588  {
3589  t.type = lexer::token::e_sub;
3590  t.value = "-";
3591  t.position = t0.position;
3592 
3593  return true;
3594  }
3595  // '- +' --> '-'
3596  else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_add))
3597  {
3598  t.type = lexer::token::e_sub;
3599  t.value = "-";
3600  t.position = t0.position;
3601 
3602  return true;
3603  }
3604  // '- -' --> '+'
3605  else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub))
3606  {
3607  /*
3608  Note: May need to reconsider this when wanting to implement
3609  pre/postfix decrement operator
3610  */
3611  t.type = lexer::token::e_add;
3612  t.value = "+";
3613  t.position = t0.position;
3614 
3615  return true;
3616  }
3617  else
3618  return false;
3619  }
3620 
3621  inline bool join(const lexer::token& t0,
3622  const lexer::token& t1,
3623  const lexer::token& t2,
3625  {
3626  // '[ * ]' --> '[*]'
3627  if (
3628  (t0.type == lexer::token::e_lsqrbracket) &&
3629  (t1.type == lexer::token::e_mul ) &&
3630  (t2.type == lexer::token::e_rsqrbracket)
3631  )
3632  {
3633  t.type = lexer::token::e_symbol;
3634  t.value = "[*]";
3635  t.position = t0.position;
3636 
3637  return true;
3638  }
3639  else
3640  return false;
3641  }
3642  };
3643 
3644  class bracket_checker exprtk_final : public lexer::token_scanner
3645  {
3646  public:
3647 
3648  using lexer::token_scanner::operator();
3649 
3651  : token_scanner(1)
3652  , state_(true)
3653  {}
3654 
3656  {
3657  if (!stack_.empty())
3658  {
3659  lexer::token t;
3660  t.value = stack_.top().first;
3661  t.position = stack_.top().second;
3662  error_token_ = t;
3663  state_ = false;
3664 
3665  return false;
3666  }
3667  else
3668  return state_;
3669  }
3670 
3672  {
3673  return error_token_;
3674  }
3675 
3677  {
3678  // Why? because msvc doesn't support swap properly.
3679  stack_ = std::stack<std::pair<char,std::size_t> >();
3680  state_ = true;
3681  error_token_.clear();
3682  }
3683 
3684  bool operator() (const lexer::token& t) exprtk_override
3685  {
3686  if (
3687  !t.value.empty() &&
3688  (lexer::token::e_string != t.type) &&
3689  (lexer::token::e_symbol != t.type) &&
3690  exprtk::details::is_bracket(t.value[0])
3691  )
3692  {
3693  details::char_t c = t.value[0];
3694 
3695  if (t.type == lexer::token::e_lbracket ) stack_.push(std::make_pair(')',t.position));
3696  else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
3697  else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position));
3699  {
3700  if (stack_.empty())
3701  {
3702  state_ = false;
3703  error_token_ = t;
3704 
3705  return false;
3706  }
3707  else if (c != stack_.top().first)
3708  {
3709  state_ = false;
3710  error_token_ = t;
3711 
3712  return false;
3713  }
3714  else
3715  stack_.pop();
3716  }
3717  }
3718 
3719  return true;
3720  }
3721 
3722  private:
3723 
3724  bool state_;
3725  std::stack<std::pair<char,std::size_t> > stack_;
3727  };
3728 
3729  template <typename T>
3730  class numeric_checker exprtk_final : public lexer::token_scanner
3731  {
3732  public:
3733 
3734  using lexer::token_scanner::operator();
3735 
3737  : token_scanner (1)
3738  , current_index_(0)
3739  {}
3740 
3742  {
3743  return error_list_.empty();
3744  }
3745 
3747  {
3748  error_list_.clear();
3749  current_index_ = 0;
3750  }
3751 
3752  bool operator() (const lexer::token& t) exprtk_override
3753  {
3754  if (token::e_number == t.type)
3755  {
3756  T v;
3757 
3758  if (!exprtk::details::string_to_real(t.value,v))
3759  {
3760  error_list_.push_back(current_index_);
3761  }
3762  }
3763 
3764  ++current_index_;
3765 
3766  return true;
3767  }
3768 
3769  std::size_t error_count() const
3770  {
3771  return error_list_.size();
3772  }
3773 
3774  std::size_t error_index(const std::size_t& i)
3775  {
3776  if (i < error_list_.size())
3777  return error_list_[i];
3778  else
3780  }
3781 
3783  {
3784  error_list_.clear();
3785  }
3786 
3787  private:
3788 
3789  std::size_t current_index_;
3790  std::vector<std::size_t> error_list_;
3791  };
3792 
3793  class symbol_replacer exprtk_final : public lexer::token_modifier
3794  {
3795  private:
3796 
3797  typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t;
3798 
3799  public:
3800 
3801  bool remove(const std::string& target_symbol)
3802  {
3803  const replace_map_t::iterator itr = replace_map_.find(target_symbol);
3804 
3805  if (replace_map_.end() == itr)
3806  return false;
3807 
3808  replace_map_.erase(itr);
3809 
3810  return true;
3811  }
3812 
3813  bool add_replace(const std::string& target_symbol,
3814  const std::string& replace_symbol,
3816  {
3817  const replace_map_t::iterator itr = replace_map_.find(target_symbol);
3818 
3819  if (replace_map_.end() != itr)
3820  {
3821  return false;
3822  }
3823 
3824  replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type);
3825 
3826  return true;
3827  }
3828 
3829  void clear()
3830  {
3831  replace_map_.clear();
3832  }
3833 
3834  private:
3835 
3837  {
3838  if (lexer::token::e_symbol == t.type)
3839  {
3840  if (replace_map_.empty())
3841  return false;
3842 
3843  const replace_map_t::iterator itr = replace_map_.find(t.value);
3844 
3845  if (replace_map_.end() != itr)
3846  {
3847  t.value = itr->second.first;
3848  t.type = itr->second.second;
3849 
3850  return true;
3851  }
3852  }
3853 
3854  return false;
3855  }
3856 
3858  };
3859 
3860  class sequence_validator exprtk_final : public lexer::token_scanner
3861  {
3862  private:
3863 
3864  typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t;
3865  typedef std::set<token_pair_t> set_t;
3866 
3867  public:
3868 
3869  using lexer::token_scanner::operator();
3870 
3872  : lexer::token_scanner(2)
3873  {
3878 
3879  add_invalid_set1(lexer::token::e_assign );
3880  add_invalid_set1(lexer::token::e_shr );
3881  add_invalid_set1(lexer::token::e_shl );
3882  add_invalid_set1(lexer::token::e_lte );
3883  add_invalid_set1(lexer::token::e_ne );
3884  add_invalid_set1(lexer::token::e_gte );
3885  add_invalid_set1(lexer::token::e_lt );
3886  add_invalid_set1(lexer::token::e_gt );
3887  add_invalid_set1(lexer::token::e_eq );
3888  add_invalid_set1(lexer::token::e_comma );
3889  add_invalid_set1(lexer::token::e_add );
3890  add_invalid_set1(lexer::token::e_sub );
3891  add_invalid_set1(lexer::token::e_div );
3892  add_invalid_set1(lexer::token::e_mul );
3893  add_invalid_set1(lexer::token::e_mod );
3894  add_invalid_set1(lexer::token::e_pow );
3895  add_invalid_set1(lexer::token::e_colon );
3896  add_invalid_set1(lexer::token::e_ternary);
3897  }
3898 
3900  {
3901  return error_list_.empty();
3902  }
3903 
3904  bool operator() (const lexer::token& t0, const lexer::token& t1) exprtk_override
3905  {
3906  const set_t::value_type p = std::make_pair(t0.type,t1.type);
3907 
3908  if (invalid_bracket_check(t0.type,t1.type))
3909  {
3910  error_list_.push_back(std::make_pair(t0,t1));
3911  }
3912  else if (invalid_comb_.find(p) != invalid_comb_.end())
3913  {
3914  error_list_.push_back(std::make_pair(t0,t1));
3915  }
3916 
3917  return true;
3918  }
3919 
3920  std::size_t error_count() const
3921  {
3922  return error_list_.size();
3923  }
3924 
3925  std::pair<lexer::token,lexer::token> error(const std::size_t index)
3926  {
3927  if (index < error_list_.size())
3928  {
3929  return error_list_[index];
3930  }
3931  else
3932  {
3933  static const lexer::token error_token;
3934  return std::make_pair(error_token,error_token);
3935  }
3936  }
3937 
3939  {
3940  error_list_.clear();
3941  }
3942 
3943  private:
3944 
3946  {
3947  invalid_comb_.insert(std::make_pair(base,t));
3948  }
3949 
3951  {
3952  add_invalid(t, lexer::token::e_assign);
3953  add_invalid(t, lexer::token::e_shr );
3954  add_invalid(t, lexer::token::e_shl );
3955  add_invalid(t, lexer::token::e_lte );
3956  add_invalid(t, lexer::token::e_ne );
3957  add_invalid(t, lexer::token::e_gte );
3958  add_invalid(t, lexer::token::e_lt );
3959  add_invalid(t, lexer::token::e_gt );
3960  add_invalid(t, lexer::token::e_eq );
3961  add_invalid(t, lexer::token::e_comma );
3962  add_invalid(t, lexer::token::e_div );
3963  add_invalid(t, lexer::token::e_mul );
3964  add_invalid(t, lexer::token::e_mod );
3965  add_invalid(t, lexer::token::e_pow );
3966  add_invalid(t, lexer::token::e_colon );
3967  }
3968 
3970  {
3971  if (details::is_right_bracket(static_cast<details::char_t>(base)))
3972  {
3973  switch (t)
3974  {
3975  case lexer::token::e_assign : return (']' != base);
3976  case lexer::token::e_string : return (')' != base);
3977  default : return false;
3978  }
3979  }
3980  else if (details::is_left_bracket(static_cast<details::char_t>(base)))
3981  {
3982  if (details::is_right_bracket(static_cast<details::char_t>(t)))
3983  return false;
3984  else if (details::is_left_bracket(static_cast<details::char_t>(t)))
3985  return false;
3986  else
3987  {
3988  switch (t)
3989  {
3990  case lexer::token::e_number : return false;
3991  case lexer::token::e_symbol : return false;
3992  case lexer::token::e_string : return false;
3993  case lexer::token::e_add : return false;
3994  case lexer::token::e_sub : return false;
3995  case lexer::token::e_colon : return false;
3996  case lexer::token::e_ternary : return false;
3997  default : return true ;
3998  }
3999  }
4000  }
4001  else if (details::is_right_bracket(static_cast<details::char_t>(t)))
4002  {
4003  switch (base)
4004  {
4005  case lexer::token::e_number : return false;
4006  case lexer::token::e_symbol : return false;
4007  case lexer::token::e_string : return false;
4008  case lexer::token::e_eof : return false;
4009  case lexer::token::e_colon : return false;
4010  case lexer::token::e_ternary : return false;
4011  default : return true ;
4012  }
4013  }
4014  else if (details::is_left_bracket(static_cast<details::char_t>(t)))
4015  {
4016  switch (base)
4017  {
4018  case lexer::token::e_rbracket : return true;
4019  case lexer::token::e_rsqrbracket : return true;
4020  case lexer::token::e_rcrlbracket : return true;
4021  default : return false;
4022  }
4023  }
4024 
4025  return false;
4026  }
4027 
4029  std::vector<std::pair<lexer::token,lexer::token> > error_list_;
4030  };
4031 
4032  class sequence_validator_3tokens exprtk_final : public lexer::token_scanner
4033  {
4034  private:
4035 
4037  typedef std::pair<token_t,std::pair<token_t,token_t> > token_triplet_t;
4038  typedef std::set<token_triplet_t> set_t;
4039 
4040  public:
4041 
4042  using lexer::token_scanner::operator();
4043 
4045  : lexer::token_scanner(3)
4046  {
4050 
4057 
4064  }
4065 
4067  {
4068  return error_list_.empty();
4069  }
4070 
4071  bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2) exprtk_override
4072  {
4073  const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type));
4074 
4075  if (invalid_comb_.find(p) != invalid_comb_.end())
4076  {
4077  error_list_.push_back(std::make_pair(t0,t1));
4078  }
4079 
4080  return true;
4081  }
4082 
4083  std::size_t error_count() const
4084  {
4085  return error_list_.size();
4086  }
4087 
4088  std::pair<lexer::token,lexer::token> error(const std::size_t index)
4089  {
4090  if (index < error_list_.size())
4091  {
4092  return error_list_[index];
4093  }
4094  else
4095  {
4096  static const lexer::token error_token;
4097  return std::make_pair(error_token,error_token);
4098  }
4099  }
4100 
4102  {
4103  error_list_.clear();
4104  }
4105 
4106  private:
4107 
4108  void add_invalid(const token_t t0, const token_t t1, const token_t t2)
4109  {
4110  invalid_comb_.insert(std::make_pair(t0,std::make_pair(t1,t2)));
4111  }
4112 
4113  set_t invalid_comb_;
4114  std::vector<std::pair<lexer::token,lexer::token> > error_list_;
4115  };
4116 
4118  {
4120  {
4121  if (token_scanner_list.end() != std::find(token_scanner_list.begin(),
4122  token_scanner_list.end (),
4123  scanner))
4124  {
4125  return false;
4126  }
4127 
4128  token_scanner_list.push_back(scanner);
4129 
4130  return true;
4131  }
4132 
4134  {
4135  if (token_modifier_list.end() != std::find(token_modifier_list.begin(),
4136  token_modifier_list.end (),
4137  modifier))
4138  {
4139  return false;
4140  }
4141 
4142  token_modifier_list.push_back(modifier);
4143 
4144  return true;
4145  }
4146 
4148  {
4149  if (token_joiner_list.end() != std::find(token_joiner_list.begin(),
4150  token_joiner_list.end (),
4151  joiner))
4152  {
4153  return false;
4154  }
4155 
4156  token_joiner_list.push_back(joiner);
4157 
4158  return true;
4159  }
4160 
4162  {
4163  if (token_inserter_list.end() != std::find(token_inserter_list.begin(),
4164  token_inserter_list.end (),
4165  inserter))
4166  {
4167  return false;
4168  }
4169 
4170  token_inserter_list.push_back(inserter);
4171 
4172  return true;
4173  }
4174 
4176  {
4177  error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0);
4178 
4179  for (std::size_t i = 0; i < token_modifier_list.size(); ++i)
4180  {
4181  lexer::token_modifier& modifier = (*token_modifier_list[i]);
4182 
4183  modifier.reset();
4184  modifier.process(g);
4185 
4186  if (!modifier.result())
4187  {
4188  error_token_modifier = token_modifier_list[i];
4189 
4190  return false;
4191  }
4192  }
4193 
4194  return true;
4195  }
4196 
4198  {
4199  error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
4200 
4201  for (std::size_t i = 0; i < token_joiner_list.size(); ++i)
4202  {
4203  lexer::token_joiner& joiner = (*token_joiner_list[i]);
4204 
4205  joiner.reset();
4206  joiner.process(g);
4207 
4208  if (!joiner.result())
4209  {
4210  error_token_joiner = token_joiner_list[i];
4211 
4212  return false;
4213  }
4214  }
4215 
4216  return true;
4217  }
4218 
4220  {
4221  error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
4222 
4223  for (std::size_t i = 0; i < token_inserter_list.size(); ++i)
4224  {
4225  lexer::token_inserter& inserter = (*token_inserter_list[i]);
4226 
4227  inserter.reset();
4228  inserter.process(g);
4229 
4230  if (!inserter.result())
4231  {
4232  error_token_inserter = token_inserter_list[i];
4233 
4234  return false;
4235  }
4236  }
4237 
4238  return true;
4239  }
4240 
4242  {
4243  error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
4244 
4245  for (std::size_t i = 0; i < token_scanner_list.size(); ++i)
4246  {
4247  lexer::token_scanner& scanner = (*token_scanner_list[i]);
4248 
4249  scanner.reset();
4250  scanner.process(g);
4251 
4252  if (!scanner.result())
4253  {
4254  error_token_scanner = token_scanner_list[i];
4255 
4256  return false;
4257  }
4258  }
4259 
4260  return true;
4261  }
4262 
4263  std::vector<lexer::token_scanner*> token_scanner_list;
4264  std::vector<lexer::token_modifier*> token_modifier_list;
4265  std::vector<lexer::token_joiner*> token_joiner_list;
4266  std::vector<lexer::token_inserter*> token_inserter_list;
4267 
4272  };
4273  }
4274 
4276  {
4277  public:
4278 
4279  typedef token token_t;
4281 
4282  inline bool init(const std::string& str)
4283  {
4284  if (!lexer_.process(str))
4285  {
4286  return false;
4287  }
4288 
4289  lexer_.begin();
4290 
4291  next_token();
4292 
4293  return true;
4294  }
4295 
4296  inline generator_t& lexer()
4297  {
4298  return lexer_;
4299  }
4300 
4301  inline const generator_t& lexer() const
4302  {
4303  return lexer_;
4304  }
4305 
4306  inline void store_token()
4307  {
4308  lexer_.store();
4309  store_current_token_ = current_token_;
4310  }
4311 
4312  inline void restore_token()
4313  {
4314  lexer_.restore();
4315  current_token_ = store_current_token_;
4316  }
4317 
4318  inline void next_token()
4319  {
4320  current_token_ = lexer_.next_token();
4321  }
4322 
4323  inline const token_t& current_token() const
4324  {
4325  return current_token_;
4326  }
4327 
4328  inline const token_t& peek_next_token()
4329  {
4330  return lexer_.peek_next_token();
4331  }
4332 
4334  {
4335  e_hold = 0,
4336  e_advance = 1
4337  };
4338 
4339  inline void advance_token(const token_advance_mode mode)
4340  {
4341  if (e_advance == mode)
4342  {
4343  next_token();
4344  }
4345  }
4346 
4347  inline bool token_is(const token_t::token_type& ttype, const token_advance_mode mode = e_advance)
4348  {
4349  if (current_token().type != ttype)
4350  {
4351  return false;
4352  }
4353 
4354  advance_token(mode);
4355 
4356  return true;
4357  }
4358 
4359  inline bool token_is(const token_t::token_type& ttype,
4360  const std::string& value,
4361  const token_advance_mode mode = e_advance)
4362  {
4363  if (
4364  (current_token().type != ttype) ||
4365  !exprtk::details::imatch(value,current_token().value)
4366  )
4367  {
4368  return false;
4369  }
4370 
4371  advance_token(mode);
4372 
4373  return true;
4374  }
4375 
4376  inline bool token_is(const std::string& value,
4377  const token_advance_mode mode = e_advance)
4378  {
4379  if (!exprtk::details::imatch(value,current_token().value))
4380  {
4381  return false;
4382  }
4383 
4384  advance_token(mode);
4385 
4386  return true;
4387  }
4388 
4389  inline bool token_is_arithmetic_opr(const token_advance_mode mode = e_advance)
4390  {
4391  switch (current_token().type)
4392  {
4393  case token_t::e_add :
4394  case token_t::e_sub :
4395  case token_t::e_div :
4396  case token_t::e_mul :
4397  case token_t::e_mod :
4398  case token_t::e_pow : break;
4399  default : return false;
4400  }
4401 
4402  advance_token(mode);
4403 
4404  return true;
4405  }
4406 
4407  inline bool token_is_ineq_opr(const token_advance_mode mode = e_advance)
4408  {
4409  switch (current_token().type)
4410  {
4411  case token_t::e_eq :
4412  case token_t::e_lte :
4413  case token_t::e_ne :
4414  case token_t::e_gte :
4415  case token_t::e_lt :
4416  case token_t::e_gt : break;
4417  default : return false;
4418  }
4419 
4420  advance_token(mode);
4421 
4422  return true;
4423  }
4424 
4425  inline bool token_is_left_bracket(const token_advance_mode mode = e_advance)
4426  {
4427  switch (current_token().type)
4428  {
4429  case token_t::e_lbracket :
4430  case token_t::e_lcrlbracket :
4431  case token_t::e_lsqrbracket : break;
4432  default : return false;
4433  }
4434 
4435  advance_token(mode);
4436 
4437  return true;
4438  }
4439 
4440  inline bool token_is_right_bracket(const token_advance_mode mode = e_advance)
4441  {
4442  switch (current_token().type)
4443  {
4444  case token_t::e_rbracket :
4445  case token_t::e_rcrlbracket :
4446  case token_t::e_rsqrbracket : break;
4447  default : return false;
4448  }
4449 
4450  advance_token(mode);
4451 
4452  return true;
4453  }
4454 
4455  inline bool token_is_loop(const token_advance_mode mode = e_advance)
4456  {
4457  return token_is("for" , mode) ||
4458  token_is("while" , mode) ||
4459  token_is("repeat", mode) ;
4460  }
4461 
4462  inline bool peek_token_is(const token_t::token_type& ttype)
4463  {
4464  return (lexer_.peek_next_token().type == ttype);
4465  }
4466 
4467  inline bool peek_token_is(const std::string& s)
4468  {
4469  return (exprtk::details::imatch(lexer_.peek_next_token().value,s));
4470  }
4471 
4472  private:
4473 
4477  };
4478  }
4479 
4480  template <typename T>
4482  {
4483  public:
4484 
4485  typedef T* data_ptr_t;
4486 
4487  vector_view(data_ptr_t data, const std::size_t& size)
4488  : base_size_(size)
4489  , size_(size)
4490  , data_(data)
4491  , data_ref_(0)
4492  {
4493  assert(size_ > 0);
4494  }
4495 
4497  : base_size_(vv.base_size_)
4498  , size_(vv.size_)
4499  , data_(vv.data_)
4500  , data_ref_(0)
4501  {
4502  assert(size_ > 0);
4503  }
4504 
4505  inline void rebase(data_ptr_t data)
4506  {
4507  data_ = data;
4508 
4509  if (!data_ref_.empty())
4510  {
4511  for (std::size_t i = 0; i < data_ref_.size(); ++i)
4512  {
4513  (*data_ref_[i]) = data;
4514  }
4515  }
4516  }
4517 
4518  inline data_ptr_t data() const
4519  {
4520  return data_;
4521  }
4522 
4523  inline std::size_t base_size() const
4524  {
4525  return base_size_;
4526  }
4527 
4528  inline std::size_t size() const
4529  {
4530  return size_;
4531  }
4532 
4533  inline const T& operator[](const std::size_t index) const
4534  {
4535  assert(index < size_);
4536  return data_[index];
4537  }
4538 
4539  inline T& operator[](const std::size_t index)
4540  {
4541  assert(index < size_);
4542  return data_[index];
4543  }
4544 
4545  void set_ref(data_ptr_t* data_ref)
4546  {
4547  data_ref_.push_back(data_ref);
4548  exprtk_debug(("vector_view::set_ref() - data_ref: %p data_ref_.size(): %lu\n",
4549  reinterpret_cast<void*>(data_ref),
4550  data_ref_.size()));
4551  }
4552 
4553  void remove_ref(data_ptr_t* data_ref)
4554  {
4555  data_ref_.erase(
4556  std::remove(data_ref_.begin(), data_ref_.end(), data_ref),
4557  data_ref_.end());
4558  exprtk_debug(("vector_view::remove_ref() - data_ref: %p data_ref_.size(): %lu\n",
4559  reinterpret_cast<void*>(data_ref),
4560  data_ref_.size()));
4561  }
4562 
4563  bool set_size(const std::size_t new_size)
4564  {
4565  if ((new_size > 0) && (new_size <= base_size_))
4566  {
4567  size_ = new_size;
4568  exprtk_debug(("vector_view::set_size() - data_: %p size: %lu\n",
4569  reinterpret_cast<void*>(data_),
4570  size_));
4571  return true;
4572  }
4573 
4574  exprtk_debug(("vector_view::set_size() - error invalid new_size: %lu base_size: %lu\n",
4575  new_size,
4576  base_size_));
4577  return false;
4578  }
4579 
4580  private:
4581 
4582  const std::size_t base_size_;
4583  std::size_t size_;
4585  std::vector<data_ptr_t*> data_ref_;
4586  };
4587 
4588  template <typename T>
4590  const std::size_t size, const std::size_t offset = 0)
4591  {
4592  return vector_view<T>(data + offset, size);
4593  }
4594 
4595  template <typename T>
4596  inline vector_view<T> make_vector_view(std::vector<T>& v,
4597  const std::size_t size, const std::size_t offset = 0)
4598  {
4599  return vector_view<T>(v.data() + offset, size);
4600  }
4601 
4602  template <typename T> class results_context;
4603 
4604  template <typename T>
4605  struct type_store
4606  {
4608  {
4612  e_string
4613  };
4614 
4616  : data(0)
4617  , size(0)
4618  , type(e_unknown)
4619  {}
4620 
4621  union
4622  {
4623  void* data;
4625  };
4626 
4627  std::size_t size;
4629 
4631  {
4632  public:
4633 
4634  explicit parameter_list(std::vector<type_store>& pl)
4635  : parameter_list_(pl)
4636  {}
4637 
4638  inline bool empty() const
4639  {
4640  return parameter_list_.empty();
4641  }
4642 
4643  inline std::size_t size() const
4644  {
4645  return parameter_list_.size();
4646  }
4647 
4648  inline type_store& operator[](const std::size_t& index)
4649  {
4650  return parameter_list_[index];
4651  }
4652 
4653  inline const type_store& operator[](const std::size_t& index) const
4654  {
4655  return parameter_list_[index];
4656  }
4657 
4658  inline type_store& front()
4659  {
4660  return parameter_list_[0];
4661  }
4662 
4663  inline const type_store& front() const
4664  {
4665  return parameter_list_[0];
4666  }
4667 
4668  inline type_store& back()
4669  {
4670  return parameter_list_.back();
4671  }
4672 
4673  inline const type_store& back() const
4674  {
4675  return parameter_list_.back();
4676  }
4677 
4678  private:
4679 
4680  std::vector<type_store>& parameter_list_;
4681 
4682  friend class results_context<T>;
4683  };
4684 
4685  template <typename ViewType>
4686  struct type_view
4687  {
4689  typedef ViewType value_t;
4690 
4691  explicit type_view(type_store_t& ts)
4692  : ts_(ts)
4693  , data_(reinterpret_cast<value_t*>(ts_.data))
4694  {}
4695 
4696  explicit type_view(const type_store_t& ts)
4697  : ts_(const_cast<type_store_t&>(ts))
4698  , data_(reinterpret_cast<value_t*>(ts_.data))
4699  {}
4700 
4701  inline std::size_t size() const
4702  {
4703  return ts_.size;
4704  }
4705 
4706  inline value_t& operator[](const std::size_t& i)
4707  {
4708  return data_[i];
4709  }
4710 
4711  inline const value_t& operator[](const std::size_t& i) const
4712  {
4713  return data_[i];
4714  }
4715 
4716  inline const value_t* begin() const { return data_; }
4717  inline value_t* begin() { return data_; }
4718 
4719  inline const value_t* end() const
4720  {
4721  return static_cast<value_t*>(data_ + ts_.size);
4722  }
4723 
4724  inline value_t* end()
4725  {
4726  return static_cast<value_t*>(data_ + ts_.size);
4727  }
4728 
4731  };
4732 
4735 
4737  {
4739  typedef T value_t;
4740 
4742  : v_(*reinterpret_cast<value_t*>(ts.data))
4743  {}
4744 
4745  explicit scalar_view(const type_store_t& ts)
4746  : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
4747  {}
4748 
4749  inline value_t& operator() ()
4750  {
4751  return v_;
4752  }
4753 
4754  inline const value_t& operator() () const
4755  {
4756  return v_;
4757  }
4758 
4759  inline operator value_t() const
4760  {
4761  return v_;
4762  }
4763 
4764  inline operator value_t()
4765  {
4766  return v_;
4767  }
4768 
4769  template <typename IntType>
4770  inline bool to_int(IntType& i) const
4771  {
4773  return false;
4774 
4775  i = static_cast<IntType>(v_);
4776 
4777  return true;
4778  }
4779 
4780  template <typename UIntType>
4781  inline bool to_uint(UIntType& u) const
4782  {
4783  if (v_ < T(0))
4784  return false;
4786  return false;
4787 
4788  u = static_cast<UIntType>(v_);
4789 
4790  return true;
4791  }
4792 
4793  T& v_;
4794  };
4795  };
4796 
4797  template <typename StringView>
4798  inline std::string to_str(const StringView& view)
4799  {
4800  return std::string(view.begin(),view.size());
4801  }
4802 
4803  #ifndef exprtk_disable_return_statement
4804  namespace details
4805  {
4806  template <typename T> class return_node;
4807  template <typename T> class return_envelope_node;
4808  }
4809  #endif
4810 
4811  template <typename T>
4813  {
4814  public:
4815 
4820 
4822  : results_available_(false)
4823  {}
4824 
4825  inline std::size_t count() const
4826  {
4827  if (results_available_)
4828  return parameter_list_.size();
4829  else
4830  return 0;
4831  }
4832 
4833  inline type_store_t& operator[](const std::size_t& index)
4834  {
4835  return parameter_list_[index];
4836  }
4837 
4838  inline const type_store_t& operator[](const std::size_t& index) const
4839  {
4840  return parameter_list_[index];
4841  }
4842 
4843  inline bool get_scalar(const std::size_t& index, T& out) const
4844  {
4845  if (
4846  (index < parameter_list_.size()) &&
4847  (parameter_list_[index].type == type_store_t::e_scalar)
4848  )
4849  {
4850  const scalar_t scalar(parameter_list_[index]);
4851  out = scalar();
4852  return true;
4853  }
4854 
4855  return false;
4856  }
4857 
4858  template <typename OutputIterator>
4859  inline bool get_vector(const std::size_t& index, OutputIterator out_itr) const
4860  {
4861  if (
4862  (index < parameter_list_.size()) &&
4863  (parameter_list_[index].type == type_store_t::e_vector)
4864  )
4865  {
4866  const vector_t vector(parameter_list_[index]);
4867  for (std::size_t i = 0; i < vector.size(); ++i)
4868  {
4869  *(out_itr++) = vector[i];
4870  }
4871 
4872  return true;
4873  }
4874 
4875  return false;
4876  }
4877 
4878  inline bool get_vector(const std::size_t& index, std::vector<T>& out) const
4879  {
4880  return get_vector(index,std::back_inserter(out));
4881  }
4882 
4883  inline bool get_string(const std::size_t& index, std::string& out) const
4884  {
4885  if (
4886  (index < parameter_list_.size()) &&
4887  (parameter_list_[index].type == type_store_t::e_string)
4888  )
4889  {
4890  const string_t str(parameter_list_[index]);
4891  out.assign(str.begin(),str.size());
4892  return true;
4893  }
4894 
4895  return false;
4896  }
4897 
4898  private:
4899 
4900  inline void clear()
4901  {
4902  results_available_ = false;
4903  }
4904 
4905  typedef std::vector<type_store_t> ts_list_t;
4907 
4908  inline void assign(const parameter_list_t& pl)
4909  {
4910  parameter_list_ = pl.parameter_list_;
4911  results_available_ = true;
4912  }
4913 
4915  ts_list_t parameter_list_;
4916 
4917  #ifndef exprtk_disable_return_statement
4918  friend class details::return_node<T>;
4919  friend class details::return_envelope_node<T>;
4920  #endif
4921  };
4922 
4923  namespace details
4924  {
4926  {
4951 
4952  // Do not add new functions/operators after this point.
4953  e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
4954  e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007,
4955  e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011,
4956  e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015,
4957  e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019,
4958  e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023,
4959  e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027,
4960  e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031,
4961  e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035,
4962  e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039,
4963  e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043,
4964  e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047,
4965  e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051,
4966  e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055,
4967  e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059,
4968  e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063,
4969  e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067,
4970  e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071,
4971  e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075,
4972  e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079,
4973  e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083,
4974  e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087,
4975  e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091,
4976  e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095,
4977  e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099,
4978  e_sffinal = 1100,
4979  e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003,
4980  e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007,
4981  e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011,
4982  e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015,
4983  e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019,
4984  e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023,
4985  e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027,
4986  e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031,
4987  e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035,
4988  e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039,
4989  e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043,
4990  e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047,
4991  e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051,
4992  e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055,
4993  e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059,
4994  e_sf4ext60 = 2060, e_sf4ext61 = 2061
4995  };
4996 
4997  inline std::string to_str(const operator_type opr)
4998  {
4999  switch (opr)
5000  {
5001  case e_add : return "+" ;
5002  case e_sub : return "-" ;
5003  case e_mul : return "*" ;
5004  case e_div : return "/" ;
5005  case e_mod : return "%" ;
5006  case e_pow : return "^" ;
5007  case e_assign : return ":=" ;
5008  case e_addass : return "+=" ;
5009  case e_subass : return "-=" ;
5010  case e_mulass : return "*=" ;
5011  case e_divass : return "/=" ;
5012  case e_modass : return "%=" ;
5013  case e_lt : return "<" ;
5014  case e_lte : return "<=" ;
5015  case e_eq : return "==" ;
5016  case e_equal : return "=" ;
5017  case e_ne : return "!=" ;
5018  case e_nequal : return "<>" ;
5019  case e_gte : return ">=" ;
5020  case e_gt : return ">" ;
5021  case e_and : return "and" ;
5022  case e_or : return "or" ;
5023  case e_xor : return "xor" ;
5024  case e_nand : return "nand";
5025  case e_nor : return "nor" ;
5026  case e_xnor : return "xnor";
5027  default : return "N/A" ;
5028  }
5029  }
5030 
5032  {
5033  base_operation_t(const operator_type t, const unsigned int& np)
5034  : type(t)
5035  , num_params(np)
5036  {}
5037 
5039  unsigned int num_params;
5040  };
5041 
5042  namespace loop_unroll
5043  {
5044  const unsigned int global_loop_batch_size =
5045  #ifndef exprtk_disable_superscalar_unroll
5046  16;
5047  #else
5048  4;
5049  #endif
5050 
5051  struct details
5052  {
5053  explicit details(const std::size_t& vsize,
5054  const unsigned int loop_batch_size = global_loop_batch_size)
5055  : batch_size(loop_batch_size )
5056  , remainder (vsize % batch_size)
5057  , upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0)))
5058  {}
5059 
5060  unsigned int batch_size;
5063  };
5064  }
5065 
5066  #ifdef exprtk_enable_debugging
5067  inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0)
5068  {
5069  if (size)
5070  exprtk_debug(("%s - addr: %p size: %d\n",
5071  s.c_str(),
5072  ptr,
5073  static_cast<unsigned int>(size)));
5074  else
5075  exprtk_debug(("%s - addr: %p\n", s.c_str(), ptr));
5076  }
5077 
5078  template <typename T>
5079  inline void dump_vector(const std::string& vec_name, const T* data, const std::size_t size)
5080  {
5081  printf("----- %s (%p) -----\n",
5082  vec_name.c_str(),
5083  static_cast<const void*>(data));
5084  printf("[ ");
5085  for (std::size_t i = 0; i < size; ++i)
5086  {
5087  printf("%8.3f\t", data[i]);
5088  }
5089  printf(" ]\n");
5090  printf("---------------------\n");
5091  }
5092  #else
5093  inline void dump_ptr(const std::string&, const void*) {}
5094  inline void dump_ptr(const std::string&, const void*, const std::size_t) {}
5095  template <typename T>
5096  inline void dump_vector(const std::string&, const T*, const std::size_t) {}
5097  #endif
5098 
5099  template <typename T>
5101  {
5102  public:
5103 
5105  typedef T* data_t;
5106 
5107  private:
5108 
5110  {
5112  : ref_count(1)
5113  , size (0)
5114  , data (0)
5115  , destruct (true)
5116  {}
5117 
5118  explicit control_block(const std::size_t& dsize)
5119  : ref_count(1 )
5120  , size (dsize)
5121  , data (0 )
5122  , destruct (true )
5123  { create_data(); }
5124 
5125  control_block(const std::size_t& dsize, data_t dptr, bool dstrct = false)
5126  : ref_count(1 )
5127  , size (dsize )
5128  , data (dptr )
5129  , destruct (dstrct)
5130  {}
5131 
5133  {
5134  if (data && destruct && (0 == ref_count))
5135  {
5136  dump_ptr("~vec_data_store::control_block() data",data);
5137  delete[] data;
5138  data = reinterpret_cast<data_t>(0);
5139  }
5140  }
5141 
5142  static inline control_block* create(const std::size_t& dsize, data_t data_ptr = data_t(0), bool dstrct = false)
5143  {
5144  if (dsize)
5145  {
5146  if (0 == data_ptr)
5147  return (new control_block(dsize));
5148  else
5149  return (new control_block(dsize, data_ptr, dstrct));
5150  }
5151  else
5152  return (new control_block);
5153  }
5154 
5155  static inline void destroy(control_block*& cntrl_blck)
5156  {
5157  if (cntrl_blck)
5158  {
5159  if (
5160  (0 != cntrl_blck->ref_count) &&
5161  (0 == --cntrl_blck->ref_count)
5162  )
5163  {
5164  delete cntrl_blck;
5165  }
5166 
5167  cntrl_blck = 0;
5168  }
5169  }
5170 
5171  std::size_t ref_count;
5172  std::size_t size;
5174  bool destruct;
5175 
5176  private:
5177 
5180 
5181  inline void create_data()
5182  {
5183  destruct = true;
5184  data = new T[size];
5185  std::fill_n(data, size, T(0));
5186  dump_ptr("control_block::create_data() - data", data, size);
5187  }
5188  };
5189 
5190  public:
5191 
5193  : control_block_(control_block::create(0))
5194  {}
5195 
5196  explicit vec_data_store(const std::size_t& size)
5197  : control_block_(control_block::create(size,reinterpret_cast<data_t>(0),true))
5198  {}
5199 
5200  vec_data_store(const std::size_t& size, data_t data, bool dstrct = false)
5201  : control_block_(control_block::create(size, data, dstrct))
5202  {}
5203 
5204  vec_data_store(const type& vds)
5205  {
5206  control_block_ = vds.control_block_;
5207  control_block_->ref_count++;
5208  }
5209 
5211  {
5212  control_block::destroy(control_block_);
5213  }
5214 
5215  type& operator=(const type& vds)
5216  {
5217  if (this != &vds)
5218  {
5219  const std::size_t final_size = min_size(control_block_, vds.control_block_);
5220 
5221  vds.control_block_->size = final_size;
5222  control_block_->size = final_size;
5223 
5224  if (control_block_->destruct || (0 == control_block_->data))
5225  {
5226  control_block::destroy(control_block_);
5227 
5228  control_block_ = vds.control_block_;
5229  control_block_->ref_count++;
5230  }
5231  }
5232 
5233  return (*this);
5234  }
5235 
5236  inline data_t data()
5237  {
5238  return control_block_->data;
5239  }
5240 
5241  inline data_t data() const
5242  {
5243  return control_block_->data;
5244  }
5245 
5246  inline std::size_t size() const
5247  {
5248  return control_block_->size;
5249  }
5250 
5251  inline data_t& ref()
5252  {
5253  return control_block_->data;
5254  }
5255 
5256  inline void dump() const
5257  {
5258  #ifdef exprtk_enable_debugging
5259  exprtk_debug(("size: %d\taddress:%p\tdestruct:%c\n",
5260  size(),
5261  data(),
5262  (control_block_->destruct ? 'T' : 'F')));
5263 
5264  for (std::size_t i = 0; i < size(); ++i)
5265  {
5266  if (5 == i)
5267  exprtk_debug(("\n"));
5268 
5269  exprtk_debug(("%15.10f ", data()[i]));
5270  }
5271  exprtk_debug(("\n"));
5272  #endif
5273  }
5274 
5275  static inline void match_sizes(type& vds0, type& vds1)
5276  {
5277  const std::size_t size = min_size(vds0.control_block_,vds1.control_block_);
5278  vds0.control_block_->size = size;
5279  vds1.control_block_->size = size;
5280  }
5281 
5282  private:
5283 
5284  static inline std::size_t min_size(const control_block* cb0, const control_block* cb1)
5285  {
5286  const std::size_t size0 = cb0->size;
5287  const std::size_t size1 = cb1->size;
5288 
5289  if (size0 && size1)
5290  return std::min(size0,size1);
5291  else
5292  return (size0) ? size0 : size1;
5293  }
5294 
5296  };
5297 
5298  namespace numeric
5299  {
5300  namespace details
5301  {
5302  template <typename T>
5303  inline T process_impl(const operator_type operation, const T arg)
5304  {
5305  switch (operation)
5306  {
5307  case e_abs : return numeric::abs (arg);
5308  case e_acos : return numeric::acos (arg);
5309  case e_acosh : return numeric::acosh(arg);
5310  case e_asin : return numeric::asin (arg);
5311  case e_asinh : return numeric::asinh(arg);
5312  case e_atan : return numeric::atan (arg);
5313  case e_atanh : return numeric::atanh(arg);
5314  case e_ceil : return numeric::ceil (arg);
5315  case e_cos : return numeric::cos (arg);
5316  case e_cosh : return numeric::cosh (arg);
5317  case e_exp : return numeric::exp (arg);
5318  case e_expm1 : return numeric::expm1(arg);
5319  case e_floor : return numeric::floor(arg);
5320  case e_log : return numeric::log (arg);
5321  case e_log10 : return numeric::log10(arg);
5322  case e_log2 : return numeric::log2 (arg);
5323  case e_log1p : return numeric::log1p(arg);
5324  case e_neg : return numeric::neg (arg);
5325  case e_pos : return numeric::pos (arg);
5326  case e_round : return numeric::round(arg);
5327  case e_sin : return numeric::sin (arg);
5328  case e_sinc : return numeric::sinc (arg);
5329  case e_sinh : return numeric::sinh (arg);
5330  case e_sqrt : return numeric::sqrt (arg);
5331  case e_tan : return numeric::tan (arg);
5332  case e_tanh : return numeric::tanh (arg);
5333  case e_cot : return numeric::cot (arg);
5334  case e_sec : return numeric::sec (arg);
5335  case e_csc : return numeric::csc (arg);
5336  case e_r2d : return numeric::r2d (arg);
5337  case e_d2r : return numeric::d2r (arg);
5338  case e_d2g : return numeric::d2g (arg);
5339  case e_g2d : return numeric::g2d (arg);
5340  case e_notl : return numeric::notl (arg);
5341  case e_sgn : return numeric::sgn (arg);
5342  case e_erf : return numeric::erf (arg);
5343  case e_erfc : return numeric::erfc (arg);
5344  case e_ncdf : return numeric::ncdf (arg);
5345  case e_frac : return numeric::frac (arg);
5346  case e_trunc : return numeric::trunc(arg);
5347 
5348  default : exprtk_debug(("numeric::details::process_impl<T> - Invalid unary operation.\n"));
5349  return std::numeric_limits<T>::quiet_NaN();
5350  }
5351  }
5352 
5353  template <typename T>
5354  inline T process_impl(const operator_type operation, const T arg0, const T arg1)
5355  {
5356  switch (operation)
5357  {
5358  case e_add : return (arg0 + arg1);
5359  case e_sub : return (arg0 - arg1);
5360  case e_mul : return (arg0 * arg1);
5361  case e_div : return (arg0 / arg1);
5362  case e_mod : return modulus<T>(arg0,arg1);
5363  case e_pow : return pow<T>(arg0,arg1);
5364  case e_atan2 : return atan2<T>(arg0,arg1);
5365  case e_min : return std::min<T>(arg0,arg1);
5366  case e_max : return std::max<T>(arg0,arg1);
5367  case e_logn : return logn<T>(arg0,arg1);
5368  case e_lt : return (arg0 < arg1) ? T(1) : T(0);
5369  case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
5370  case e_eq : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0);
5371  case e_ne : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0);
5372  case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
5373  case e_gt : return (arg0 > arg1) ? T(1) : T(0);
5374  case e_and : return and_opr <T>(arg0,arg1);
5375  case e_nand : return nand_opr<T>(arg0,arg1);
5376  case e_or : return or_opr <T>(arg0,arg1);
5377  case e_nor : return nor_opr <T>(arg0,arg1);
5378  case e_xor : return xor_opr <T>(arg0,arg1);
5379  case e_xnor : return xnor_opr<T>(arg0,arg1);
5380  case e_root : return root <T>(arg0,arg1);
5381  case e_roundn : return roundn <T>(arg0,arg1);
5382  case e_equal : return equal <T>(arg0,arg1);
5383  case e_nequal : return nequal <T>(arg0,arg1);
5384  case e_hypot : return hypot <T>(arg0,arg1);
5385  case e_shr : return shr <T>(arg0,arg1);
5386  case e_shl : return shl <T>(arg0,arg1);
5387 
5388  default : exprtk_debug(("numeric::details::process_impl<T> - Invalid binary operation.\n"));
5389  return std::numeric_limits<T>::quiet_NaN();
5390  }
5391  }
5392 
5393  template <typename T>
5394  inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag)
5395  {
5396  switch (operation)
5397  {
5398  case e_add : return (arg0 + arg1);
5399  case e_sub : return (arg0 - arg1);
5400  case e_mul : return (arg0 * arg1);
5401  case e_div : return (arg0 / arg1);
5402  case e_mod : return arg0 % arg1;
5403  case e_pow : return pow<T>(arg0,arg1);
5404  case e_min : return std::min<T>(arg0,arg1);
5405  case e_max : return std::max<T>(arg0,arg1);
5406  case e_logn : return logn<T>(arg0,arg1);
5407  case e_lt : return (arg0 < arg1) ? T(1) : T(0);
5408  case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
5409  case e_eq : return (arg0 == arg1) ? T(1) : T(0);
5410  case e_ne : return (arg0 != arg1) ? T(1) : T(0);
5411  case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
5412  case e_gt : return (arg0 > arg1) ? T(1) : T(0);
5413  case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
5414  case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
5415  case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
5416  case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
5417  case e_xor : return arg0 ^ arg1;
5418  case e_xnor : return !(arg0 ^ arg1);
5419  case e_root : return root<T>(arg0,arg1);
5420  case e_equal : return arg0 == arg1;
5421  case e_nequal : return arg0 != arg1;
5422  case e_hypot : return hypot<T>(arg0,arg1);
5423  case e_shr : return arg0 >> arg1;
5424  case e_shl : return arg0 << arg1;
5425 
5426  default : exprtk_debug(("numeric::details::process_impl<IntType> - Invalid binary operation.\n"));
5427  return std::numeric_limits<T>::quiet_NaN();
5428  }
5429  }
5430  }
5431 
5432  template <typename T>
5433  inline T process(const operator_type operation, const T arg)
5434  {
5436  }
5437 
5438  template <typename T>
5439  inline T process(const operator_type operation, const T arg0, const T arg1)
5440  {
5441  return exprtk::details::numeric::details::process_impl(operation, arg0, arg1);
5442  }
5443  }
5444 
5445  template <typename Node>
5447  {
5448  typedef Node* node_ptr_t;
5449  typedef Node** node_pp_t;
5450  typedef std::vector<node_pp_t> noderef_list_t;
5451 
5453  {}
5454 
5456  {}
5457  };
5458 
5459  template <typename Node>
5460  struct node_depth_base;
5461 
5462  template <typename T>
5463  class expression_node : public node_collector_interface<expression_node<T> >
5464  , public node_depth_base<expression_node<T> >
5465  {
5466  public:
5467 
5469  {
5470  e_none , e_null , e_constant , e_unary ,
5471  e_binary , e_binary_ext , e_trinary , e_quaternary ,
5472  e_vararg , e_conditional , e_while , e_repeat ,
5473  e_for , e_switch , e_mswitch , e_return ,
5474  e_retenv , e_variable , e_stringvar , e_stringconst ,
5475  e_stringvarrng , e_cstringvarrng , e_strgenrange , e_strconcat ,
5476  e_stringvarsize , e_strswap , e_stringsize , e_stringvararg ,
5477  e_function , e_vafunction , e_genfunction , e_strfunction ,
5478  e_strcondition , e_strccondition , e_add , e_sub ,
5483  e_in , e_like , e_ilike , e_inranges ,
5484  e_ipow , e_ipowinv , e_abs , e_acos ,
5494  e_frac , e_trunc , e_uvouv , e_vov ,
5495  e_cov , e_voc , e_vob , e_bov ,
5496  e_cob , e_boc , e_vovov , e_vovoc ,
5497  e_vocov , e_covov , e_covoc , e_vovovov ,
5498  e_vovovoc , e_vovocov , e_vocovov , e_covovov ,
5499  e_covocov , e_vocovoc , e_covovoc , e_vococov ,
5500  e_sf3ext , e_sf4ext , e_nulleq , e_strass ,
5501  e_vector , e_vecsize , e_vecelem , e_veccelem ,
5502  e_vecelemrtc , e_veccelemrtc , e_rbvecelem , e_rbvecelemrtc ,
5503  e_rbveccelem , e_rbveccelemrtc , e_vecdefass , e_vecvalass ,
5504  e_vecvecass , e_vecopvalass , e_vecopvecass , e_vecfunc ,
5505  e_vecvecswap , e_vecvecineq , e_vecvalineq , e_valvecineq ,
5506  e_vecvecarith , e_vecvalarith , e_valvecarith , e_vecunaryop ,
5507  e_vecondition , e_break , e_continue , e_swap
5508  };
5509 
5510  typedef T value_type;
5515 
5517  {}
5518 
5519  inline virtual T value() const
5520  {
5521  return std::numeric_limits<T>::quiet_NaN();
5522  }
5523 
5524  inline virtual expression_node<T>* branch(const std::size_t& index = 0) const
5525  {
5526  return reinterpret_cast<expression_ptr>(index * 0);
5527  }
5528 
5529  inline virtual node_type type() const
5530  {
5531  return e_none;
5532  }
5533 
5534  inline virtual bool valid() const
5535  {
5536  return true;
5537  }
5538  }; // class expression_node
5539 
5540  template <typename T>
5541  inline bool is_generally_string_node(const expression_node<T>* node);
5542 
5543  inline bool is_true(const double v)
5544  {
5545  return std::not_equal_to<double>()(0.0,v);
5546  }
5547 
5548  inline bool is_true(const long double v)
5549  {
5550  return std::not_equal_to<long double>()(0.0L,v);
5551  }
5552 
5553  inline bool is_true(const float v)
5554  {
5555  return std::not_equal_to<float>()(0.0f,v);
5556  }
5557 
5558  template <typename T>
5559  inline bool is_true(const expression_node<T>* node)
5560  {
5561  return std::not_equal_to<T>()(T(0),node->value());
5562  }
5563 
5564  template <typename T>
5565  inline bool is_true(const std::pair<expression_node<T>*,bool>& node)
5566  {
5567  return std::not_equal_to<T>()(T(0),node.first->value());
5568  }
5569 
5570  template <typename T>
5571  inline bool is_false(const expression_node<T>* node)
5572  {
5573  return std::equal_to<T>()(T(0),node->value());
5574  }
5575 
5576  template <typename T>
5577  inline bool is_false(const std::pair<expression_node<T>*,bool>& node)
5578  {
5579  return std::equal_to<T>()(T(0),node.first->value());
5580  }
5581 
5582  template <typename T>
5583  inline bool is_literal_node(const expression_node<T>* node)
5584  {
5585  return node && (details::expression_node<T>::e_constant == node->type());
5586  }
5587 
5588  template <typename T>
5589  inline bool is_unary_node(const expression_node<T>* node)
5590  {
5591  return node && (details::expression_node<T>::e_unary == node->type());
5592  }
5593 
5594  template <typename T>
5595  inline bool is_neg_unary_node(const expression_node<T>* node)
5596  {
5597  return node && (details::expression_node<T>::e_neg == node->type());
5598  }
5599 
5600  template <typename T>
5601  inline bool is_binary_node(const expression_node<T>* node)
5602  {
5603  return node && (details::expression_node<T>::e_binary == node->type());
5604  }
5605 
5606  template <typename T>
5607  inline bool is_variable_node(const expression_node<T>* node)
5608  {
5609  return node && (details::expression_node<T>::e_variable == node->type());
5610  }
5611 
5612  template <typename T>
5613  inline bool is_ivariable_node(const expression_node<T>* node)
5614  {
5615  return node &&
5616  (
5626  );
5627  }
5628 
5629  template <typename T>
5630  inline bool is_vector_elem_node(const expression_node<T>* node)
5631  {
5632  return node && (details::expression_node<T>::e_vecelem == node->type());
5633  }
5634 
5635  template <typename T>
5636  inline bool is_vector_celem_node(const expression_node<T>* node)
5637  {
5638  return node && (details::expression_node<T>::e_veccelem == node->type());
5639  }
5640 
5641  template <typename T>
5643  {
5644  return node && (details::expression_node<T>::e_vecelemrtc == node->type());
5645  }
5646 
5647  template <typename T>
5649  {
5650  return node && (details::expression_node<T>::e_veccelemrtc == node->type());
5651  }
5652 
5653  template <typename T>
5655  {
5656  return node && (details::expression_node<T>::e_rbvecelem == node->type());
5657  }
5658 
5659  template <typename T>
5661  {
5662  return node && (details::expression_node<T>::e_rbvecelemrtc == node->type());
5663  }
5664 
5665  template <typename T>
5667  {
5668  return node && (details::expression_node<T>::e_rbveccelemrtc == node->type());
5669  }
5670 
5671  template <typename T>
5673  {
5674  return node && (details::expression_node<T>::e_rbveccelem == node->type());
5675  }
5676 
5677  template <typename T>
5678  inline bool is_vector_node(const expression_node<T>* node)
5679  {
5680  return node && (details::expression_node<T>::e_vector == node->type());
5681  }
5682 
5683  template <typename T>
5684  inline bool is_ivector_node(const expression_node<T>* node)
5685  {
5686  if (node)
5687  {
5688  switch (node->type())
5689  {
5700  case details::expression_node<T>::e_vecondition : return true;
5701  default : return false;
5702  }
5703  }
5704  else
5705  return false;
5706  }
5707 
5708  template <typename T>
5709  inline bool is_constant_node(const expression_node<T>* node)
5710  {
5711  return node &&
5712  (
5715  );
5716  }
5717 
5718  template <typename T>
5719  inline bool is_null_node(const expression_node<T>* node)
5720  {
5721  return node && (details::expression_node<T>::e_null == node->type());
5722  }
5723 
5724  template <typename T>
5725  inline bool is_break_node(const expression_node<T>* node)
5726  {
5727  return node && (details::expression_node<T>::e_break == node->type());
5728  }
5729 
5730  template <typename T>
5731  inline bool is_continue_node(const expression_node<T>* node)
5732  {
5733  return node && (details::expression_node<T>::e_continue == node->type());
5734  }
5735 
5736  template <typename T>
5737  inline bool is_swap_node(const expression_node<T>* node)
5738  {
5739  return node && (details::expression_node<T>::e_swap == node->type());
5740  }
5741 
5742  template <typename T>
5743  inline bool is_function(const expression_node<T>* node)
5744  {
5745  return node && (details::expression_node<T>::e_function == node->type());
5746  }
5747 
5748  template <typename T>
5749  inline bool is_return_node(const expression_node<T>* node)
5750  {
5751  return node && (details::expression_node<T>::e_return == node->type());
5752  }
5753 
5754  template <typename T> class unary_node;
5755 
5756  template <typename T>
5757  inline bool is_negate_node(const expression_node<T>* node)
5758  {
5759  if (node && is_unary_node(node))
5760  {
5761  return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation());
5762  }
5763  else
5764  return false;
5765  }
5766 
5767  template <typename T>
5768  inline bool branch_deletable(const expression_node<T>* node)
5769  {
5770  return (0 != node) &&
5771  !is_variable_node(node) &&
5772  !is_string_node (node) ;
5773  }
5774 
5775  template <std::size_t N, typename T>
5776  inline bool all_nodes_valid(expression_node<T>* const (&b)[N])
5777  {
5778  for (std::size_t i = 0; i < N; ++i)
5779  {
5780  if (0 == b[i]) return false;
5781  }
5782 
5783  return true;
5784  }
5785 
5786  template <typename T,
5787  typename Allocator,
5788  template <typename, typename> class Sequence>
5789  inline bool all_nodes_valid(const Sequence<expression_node<T>*,Allocator>& b)
5790  {
5791  for (std::size_t i = 0; i < b.size(); ++i)
5792  {
5793  if (0 == b[i]) return false;
5794  }
5795 
5796  return true;
5797  }
5798 
5799  template <std::size_t N, typename T>
5800  inline bool all_nodes_variables(expression_node<T>* const (&b)[N])
5801  {
5802  for (std::size_t i = 0; i < N; ++i)
5803  {
5804  if (0 == b[i])
5805  return false;
5806  else if (!is_variable_node(b[i]))
5807  return false;
5808  }
5809 
5810  return true;
5811  }
5812 
5813  template <typename T,
5814  typename Allocator,
5815  template <typename, typename> class Sequence>
5816  inline bool all_nodes_variables(const Sequence<expression_node<T>*,Allocator>& b)
5817  {
5818  for (std::size_t i = 0; i < b.size(); ++i)
5819  {
5820  if (0 == b[i])
5821  return false;
5822  else if (!is_variable_node(b[i]))
5823  return false;
5824  }
5825 
5826  return true;
5827  }
5828 
5829  template <typename Node>
5831  {
5832  public:
5833 
5835 
5836  typedef typename nci_t::node_ptr_t node_ptr_t;
5837  typedef typename nci_t::node_pp_t node_pp_t;
5839 
5841  {
5842  std::vector<node_pp_t> node_delete_list;
5843  node_delete_list.reserve(1000);
5844 
5845  collect_nodes(root, node_delete_list);
5846 
5847  for (std::size_t i = 0; i < node_delete_list.size(); ++i)
5848  {
5849  node_ptr_t& node = *node_delete_list[i];
5850  exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", reinterpret_cast<void*>(node)));
5851  delete node;
5852  node = reinterpret_cast<node_ptr_t>(0);
5853  }
5854  }
5855 
5856  private:
5857 
5858  static void collect_nodes(node_ptr_t& root, noderef_list_t& node_delete_list)
5859  {
5860  std::deque<node_ptr_t> node_list;
5861  node_list.push_back(root);
5862  node_delete_list.push_back(&root);
5863 
5864  noderef_list_t child_node_delete_list;
5865  child_node_delete_list.reserve(1000);
5866 
5867  while (!node_list.empty())
5868  {
5869  node_list.front()->collect_nodes(child_node_delete_list);
5870 
5871  if (!child_node_delete_list.empty())
5872  {
5873  for (std::size_t i = 0; i < child_node_delete_list.size(); ++i)
5874  {
5875  node_pp_t& node = child_node_delete_list[i];
5876 
5877  if (0 == (*node))
5878  {
5879  exprtk_debug(("ncd::collect_nodes() - null node encountered.\n"));
5880  }
5881 
5882  node_list.push_back(*node);
5883  }
5884 
5885  node_delete_list.insert(
5886  node_delete_list.end(),
5887  child_node_delete_list.begin(), child_node_delete_list.end());
5888 
5889  child_node_delete_list.clear();
5890  }
5891 
5892  node_list.pop_front();
5893  }
5894 
5895  std::reverse(node_delete_list.begin(), node_delete_list.end());
5896  }
5897  };
5898 
5899  template <typename NodeAllocator, typename T, std::size_t N>
5900  inline void free_all_nodes(NodeAllocator& node_allocator, expression_node<T>* (&b)[N])
5901  {
5902  for (std::size_t i = 0; i < N; ++i)
5903  {
5904  free_node(node_allocator,b[i]);
5905  }
5906  }
5907 
5908  template <typename NodeAllocator,
5909  typename T,
5910  typename Allocator,
5911  template <typename, typename> class Sequence>
5912  inline void free_all_nodes(NodeAllocator& node_allocator, Sequence<expression_node<T>*,Allocator>& b)
5913  {
5914  for (std::size_t i = 0; i < b.size(); ++i)
5915  {
5916  free_node(node_allocator,b[i]);
5917  }
5918 
5919  b.clear();
5920  }
5921 
5922  template <typename NodeAllocator, typename T>
5923  inline void free_node(NodeAllocator&, expression_node<T>*& node)
5924  {
5925  if ((0 == node) || is_variable_node(node) || is_string_node(node))
5926  {
5927  return;
5928  }
5929 
5931  ::delete_nodes(node);
5932  }
5933 
5934  template <typename T>
5935  inline void destroy_node(expression_node<T>*& node)
5936  {
5937  if (0 != node)
5938  {
5940  ::delete_nodes(node);
5941  }
5942  }
5943 
5944  template <typename Node>
5946  {
5947  typedef Node* node_ptr_t;
5948  typedef std::pair<node_ptr_t,bool> nb_pair_t;
5949 
5951  : depth_set(false)
5952  , depth(0)
5953  {}
5954 
5956  {}
5957 
5958  virtual std::size_t node_depth() const { return 1; }
5959 
5960  std::size_t compute_node_depth(const Node* const& node) const
5961  {
5962  if (!depth_set)
5963  {
5964  depth = 1 + (node ? node->node_depth() : 0);
5965  depth_set = true;
5966  }
5967 
5968  return depth;
5969  }
5970 
5971  std::size_t compute_node_depth(const nb_pair_t& branch) const
5972  {
5973  if (!depth_set)
5974  {
5975  depth = 1 + (branch.first ? branch.first->node_depth() : 0);
5976  depth_set = true;
5977  }
5978 
5979  return depth;
5980  }
5981 
5982  template <std::size_t N>
5983  std::size_t compute_node_depth(const nb_pair_t (&branch)[N]) const
5984  {
5985  if (!depth_set)
5986  {
5987  depth = 0;
5988 
5989  for (std::size_t i = 0; i < N; ++i)
5990  {
5991  if (branch[i].first)
5992  {
5993  depth = std::max(depth,branch[i].first->node_depth());
5994  }
5995  }
5996 
5997  depth += 1;
5998  depth_set = true;
5999  }
6000 
6001  return depth;
6002  }
6003 
6004  template <typename BranchType>
6005  std::size_t max_node_depth(const BranchType& n0, const BranchType& n1) const
6006  {
6007  return std::max(compute_node_depth(n0), compute_node_depth(n1));
6008  }
6009 
6010  template <typename BranchType>
6011  std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, const BranchType& n2) const
6012  {
6013  return std::max(compute_node_depth(n0),
6014  std::max(compute_node_depth(n1), compute_node_depth(n2)));
6015  }
6016 
6017  template <typename BranchType>
6018  std::size_t max_node_depth(const BranchType& n0, const BranchType& n1,
6019  const BranchType& n2, const BranchType& n3) const
6020  {
6021  return std::max(
6022  std::max(compute_node_depth(n0), compute_node_depth(n1)),
6023  std::max(compute_node_depth(n2), compute_node_depth(n3)));
6024  }
6025 
6026  template <typename BranchType>
6027  std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1) const
6028  {
6029  if (!depth_set)
6030  {
6031  depth = 1 + max_node_depth(n0, n1);
6032  depth_set = true;
6033  }
6034 
6035  return depth;
6036  }
6037 
6038  template <typename BranchType>
6039  std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1,
6040  const BranchType& n2) const
6041  {
6042  if (!depth_set)
6043  {
6044  depth = 1 + max_node_depth(n0, n1, n2);
6045  depth_set = true;
6046  }
6047 
6048  return depth;
6049  }
6050 
6051  template <typename BranchType>
6052  std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1,
6053  const BranchType& n2, const BranchType& n3) const
6054  {
6055  if (!depth_set)
6056  {
6057  depth = 1 + max_node_depth(n0, n1, n2, n3);
6058  depth_set = true;
6059  }
6060 
6061  return depth;
6062  }
6063 
6064  template <typename Allocator,
6065  template <typename, typename> class Sequence>
6066  std::size_t compute_node_depth(const Sequence<node_ptr_t, Allocator>& branch_list) const
6067  {
6068  if (!depth_set)
6069  {
6070  for (std::size_t i = 0; i < branch_list.size(); ++i)
6071  {
6072  if (branch_list[i])
6073  {
6074  depth = std::max(depth, compute_node_depth(branch_list[i]));
6075  }
6076  }
6077  depth_set = true;
6078  }
6079 
6080  return depth;
6081  }
6082 
6083  template <typename Allocator,
6084  template <typename, typename> class Sequence>
6085  std::size_t compute_node_depth(const Sequence<nb_pair_t,Allocator>& branch_list) const
6086  {
6087  if (!depth_set)
6088  {
6089  for (std::size_t i = 0; i < branch_list.size(); ++i)
6090  {
6091  if (branch_list[i].first)
6092  {
6093  depth = std::max(depth, compute_node_depth(branch_list[i].first));
6094  }
6095  }
6096 
6097  depth_set = true;
6098  }
6099 
6100  return depth;
6101  }
6102 
6103  mutable bool depth_set;
6104  mutable std::size_t depth;
6105 
6106  template <typename NodeSequence>
6107  void collect(node_ptr_t const& node,
6108  const bool deletable,
6109  NodeSequence& delete_node_list) const
6110  {
6111  if ((0 != node) && deletable)
6112  {
6113  delete_node_list.push_back(const_cast<node_ptr_t*>(&node));
6114  }
6115  }
6116 
6117  template <typename NodeSequence>
6118  void collect(const nb_pair_t& branch,
6119  NodeSequence& delete_node_list) const
6120  {
6121  collect(branch.first, branch.second, delete_node_list);
6122  }
6123 
6124  template <typename NodeSequence>
6125  void collect(Node*& node,
6126  NodeSequence& delete_node_list) const
6127  {
6128  collect(node, branch_deletable(node), delete_node_list);
6129  }
6130 
6131  template <std::size_t N, typename NodeSequence>
6132  void collect(const nb_pair_t(&branch)[N],
6133  NodeSequence& delete_node_list) const
6134  {
6135  for (std::size_t i = 0; i < N; ++i)
6136  {
6137  collect(branch[i].first, branch[i].second, delete_node_list);
6138  }
6139  }
6140 
6141  template <typename Allocator,
6142  template <typename, typename> class Sequence,
6143  typename NodeSequence>
6144  void collect(const Sequence<nb_pair_t, Allocator>& branch,
6145  NodeSequence& delete_node_list) const
6146  {
6147  for (std::size_t i = 0; i < branch.size(); ++i)
6148  {
6149  collect(branch[i].first, branch[i].second, delete_node_list);
6150  }
6151  }
6152 
6153  template <typename Allocator,
6154  template <typename, typename> class Sequence,
6155  typename NodeSequence>
6156  void collect(const Sequence<node_ptr_t, Allocator>& branch_list,
6157  NodeSequence& delete_node_list) const
6158  {
6159  for (std::size_t i = 0; i < branch_list.size(); ++i)
6160  {
6161  collect(branch_list[i], branch_deletable(branch_list[i]), delete_node_list);
6162  }
6163  }
6164 
6165  template <typename Boolean,
6166  typename AllocatorT,
6167  typename AllocatorB,
6168  template <typename, typename> class Sequence,
6169  typename NodeSequence>
6170  void collect(const Sequence<node_ptr_t, AllocatorT>& branch_list,
6171  const Sequence<Boolean, AllocatorB>& branch_deletable_list,
6172  NodeSequence& delete_node_list) const
6173  {
6174  for (std::size_t i = 0; i < branch_list.size(); ++i)
6175  {
6176  collect(branch_list[i], branch_deletable_list[i], delete_node_list);
6177  }
6178  }
6179  };
6180 
6181  template <typename Type>
6183  {
6184  private:
6185 
6186  typedef Type value_type;
6190 
6192  {
6193  public:
6194 
6196  {}
6197 
6198  inline value_ptr operator[](const std::size_t& index) const
6199  {
6200  return value_at(index);
6201  }
6202 
6203  inline std::size_t size() const
6204  {
6205  return vector_size();
6206  }
6207 
6208  inline std::size_t base_size() const
6209  {
6210  return vector_base_size();
6211  }
6212 
6213  inline value_ptr data() const
6214  {
6215  return value_at(0);
6216  }
6217 
6218  virtual inline bool rebaseable() const
6219  {
6220  return false;
6221  }
6222 
6223  virtual void set_ref(value_ptr*)
6224  {}
6225 
6226  virtual void remove_ref(value_ptr*)
6227  {}
6228 
6230  {
6231  return reinterpret_cast<vector_view<Type>*>(0);
6232  }
6233 
6234  protected:
6235 
6236  virtual value_ptr value_at(const std::size_t&) const = 0;
6237  virtual std::size_t vector_size() const = 0;
6238  virtual std::size_t vector_base_size() const = 0;
6239  };
6240 
6241  class array_vector_impl exprtk_final : public vector_holder_base
6242  {
6243  public:
6244 
6245  array_vector_impl(const Type* vec, const std::size_t& vec_size)
6246  : vec_(vec)
6247  , size_(vec_size)
6248  {}
6249 
6250  protected:
6251 
6252  value_ptr value_at(const std::size_t& index) const exprtk_override
6253  {
6254  assert(index < size_);
6255  return const_cast<const_value_ptr>(vec_ + index);
6256  }
6257 
6259  {
6260  return size_;
6261  }
6262 
6264  {
6265  return vector_size();
6266  }
6267 
6268  private:
6269 
6270  array_vector_impl(const array_vector_impl&) exprtk_delete;
6271  array_vector_impl& operator=(const array_vector_impl&) exprtk_delete;
6272 
6273  const Type* vec_;
6274  const std::size_t size_;
6275  };
6276 
6277  template <typename Allocator,
6278  template <typename, typename> class Sequence>
6279  class sequence_vector_impl exprtk_final : public vector_holder_base
6280  {
6281  public:
6282 
6283  typedef Sequence<Type,Allocator> sequence_t;
6284 
6286  : sequence_(seq)
6287  {}
6288 
6289  protected:
6290 
6291  value_ptr value_at(const std::size_t& index) const exprtk_override
6292  {
6293  assert(index < sequence_.size());
6294  return (&sequence_[index]);
6295  }
6296 
6298  {
6299  return sequence_.size();
6300  }
6301 
6303  {
6304  return vector_size();
6305  }
6306 
6307  private:
6308 
6309  sequence_vector_impl(const sequence_vector_impl&) exprtk_delete;
6310  sequence_vector_impl& operator=(const sequence_vector_impl&) exprtk_delete;
6311 
6313  };
6314 
6315  class vector_view_impl exprtk_final : public vector_holder_base
6316  {
6317  public:
6318 
6320 
6322  : vec_view_(vec_view)
6323  {
6324  assert(vec_view_.size() > 0);
6325  }
6326 
6328  {
6329  vec_view_.set_ref(ref);
6330  }
6331 
6333  {
6334  vec_view_.remove_ref(ref);
6335  }
6336 
6338  {
6339  return true;
6340  }
6341 
6343  {
6344  return &vec_view_;
6345  }
6346 
6347  protected:
6348 
6349  value_ptr value_at(const std::size_t& index) const exprtk_override
6350  {
6351  assert(index < vec_view_.size());
6352  return (&vec_view_[index]);
6353  }
6354 
6356  {
6357  return vec_view_.size();
6358  }
6359 
6361  {
6362  return vec_view_.base_size();
6363  }
6364 
6365  private:
6366 
6367  vector_view_impl(const vector_view_impl&) exprtk_delete;
6368  vector_view_impl& operator=(const vector_view_impl&) exprtk_delete;
6369 
6371  };
6372 
6373  class resizable_vector_impl exprtk_final : public vector_holder_base
6374  {
6375  public:
6376 
6378  const Type* vec,
6379  const std::size_t& vec_size)
6380  : vec_(vec)
6381  , size_(vec_size)
6382  , vec_view_holder_(*vec_view_holder.rebaseable_instance())
6383  {
6384  assert(vec_view_holder.rebaseable_instance());
6385  assert(size_ <= vector_base_size());
6386  }
6387 
6389  {}
6390 
6391  protected:
6392 
6393  value_ptr value_at(const std::size_t& index) const exprtk_override
6394  {
6395  assert(index < vector_size());
6396  return const_cast<const_value_ptr>(vec_ + index);
6397  }
6398 
6400  {
6401  return vec_view_holder_.size();
6402  }
6403 
6405  {
6406  return vec_view_holder_.base_size();
6407  }
6408 
6410  {
6411  return true;
6412  }
6413 
6415  {
6416  return &vec_view_holder_;
6417  }
6418 
6419  private:
6420 
6421  resizable_vector_impl(const resizable_vector_impl&) exprtk_delete;
6422  resizable_vector_impl& operator=(const resizable_vector_impl&) exprtk_delete;
6423 
6424  const Type* vec_;
6425  const std::size_t size_;
6427  };
6428 
6429  public:
6430 
6432 
6433  vector_holder(Type* vec, const std::size_t& vec_size)
6434  : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
6435  {}
6436 
6437  explicit vector_holder(const vds_t& vds)
6438  : vector_holder_base_(new(buffer)array_vector_impl(vds.data(),vds.size()))
6439  {}
6440 
6441  template <typename Allocator>
6442  explicit vector_holder(std::vector<Type,Allocator>& vec)
6443  : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
6444  {}
6445 
6447  : vector_holder_base_(new(buffer)vector_view_impl(vec))
6448  {}
6449 
6450  explicit vector_holder(vector_holder_t& vec_holder, const vds_t& vds)
6451  : vector_holder_base_(new(buffer)resizable_vector_impl(vec_holder, vds.data(), vds.size()))
6452  {}
6453 
6454  inline value_ptr operator[](const std::size_t& index) const
6455  {
6456  return (*vector_holder_base_)[index];
6457  }
6458 
6459  inline std::size_t size() const
6460  {
6461  return vector_holder_base_->size();
6462  }
6463 
6464  inline std::size_t base_size() const
6465  {
6466  return vector_holder_base_->base_size();
6467  }
6468 
6469  inline value_ptr data() const
6470  {
6471  return vector_holder_base_->data();
6472  }
6473 
6474  void set_ref(value_ptr* ref)
6475  {
6476  if (rebaseable())
6477  {
6478  vector_holder_base_->set_ref(ref);
6479  }
6480  }
6481 
6483  {
6484  if (rebaseable())
6485  {
6486  vector_holder_base_->remove_ref(ref);
6487  }
6488  }
6489 
6490  bool rebaseable() const
6491  {
6492  return vector_holder_base_->rebaseable();
6493  }
6494 
6496  {
6497  return vector_holder_base_->rebaseable_instance();
6498  }
6499 
6500  private:
6501 
6504 
6506  uchar_t buffer[64];
6507  };
6508 
6509  template <typename T>
6510  class null_node exprtk_final : public expression_node<T>
6511  {
6512  public:
6513 
6515  {
6516  return std::numeric_limits<T>::quiet_NaN();
6517  }
6518 
6520  {
6522  }
6523  };
6524 
6525  template <typename T, std::size_t N>
6526  inline void construct_branch_pair(std::pair<expression_node<T>*,bool> (&branch)[N],
6527  expression_node<T>* b,
6528  const std::size_t& index)
6529  {
6530  if (b && (index < N))
6531  {
6532  branch[index] = std::make_pair(b,branch_deletable(b));
6533  }
6534  }
6535 
6536  template <typename T>
6537  inline void construct_branch_pair(std::pair<expression_node<T>*,bool>& branch, expression_node<T>* b)
6538  {
6539  if (b)
6540  {
6541  branch = std::make_pair(b,branch_deletable(b));
6542  }
6543  }
6544 
6545  template <std::size_t N, typename T>
6546  inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N],
6547  expression_node<T>* b0,
6548  expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0),
6549  expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0),
6550  expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0),
6551  expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0),
6552  expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0),
6553  expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0),
6554  expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0),
6555  expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0),
6556  expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0))
6557  {
6558  construct_branch_pair(branch, b0, 0);
6559  construct_branch_pair(branch, b1, 1);
6560  construct_branch_pair(branch, b2, 2);
6561  construct_branch_pair(branch, b3, 3);
6562  construct_branch_pair(branch, b4, 4);
6563  construct_branch_pair(branch, b5, 5);
6564  construct_branch_pair(branch, b6, 6);
6565  construct_branch_pair(branch, b7, 7);
6566  construct_branch_pair(branch, b8, 8);
6567  construct_branch_pair(branch, b9, 9);
6568  }
6569 
6570  template <typename T>
6571  class null_eq_node exprtk_final : public expression_node<T>
6572  {
6573  public:
6574 
6576  typedef std::pair<expression_ptr,bool> branch_t;
6577 
6578  explicit null_eq_node(expression_ptr branch, const bool equality = true)
6579  : equality_(equality)
6580  {
6581  construct_branch_pair(branch_, branch);
6582  assert(valid());
6583  }
6584 
6586  {
6587  const T v = branch_.first->value();
6588  const bool result = details::numeric::is_nan(v);
6589 
6590  if (result)
6591  return equality_ ? T(1) : T(0);
6592  else
6593  return equality_ ? T(0) : T(1);
6594  }
6595 
6597  {
6599  }
6600 
6601  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6602  {
6603  return branch_.first;
6604  }
6605 
6607  {
6608  return branch_.first;
6609  }
6610 
6612  {
6613  expression_node<T>::ndb_t::collect(branch_, node_delete_list);
6614  }
6615 
6617  {
6619  }
6620 
6621  private:
6622 
6625  };
6626 
6627  template <typename T>
6628  class literal_node exprtk_final : public expression_node<T>
6629  {
6630  public:
6631 
6632  explicit literal_node(const T& v)
6633  : value_(v)
6634  {}
6635 
6637  {
6638  return value_;
6639  }
6640 
6642  {
6644  }
6645 
6646  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6647  {
6648  return reinterpret_cast<expression_node<T>*>(0);
6649  }
6650 
6651  private:
6652 
6653  literal_node(const literal_node<T>&) exprtk_delete;
6654  literal_node<T>& operator=(const literal_node<T>&) exprtk_delete;
6655 
6656  const T value_;
6657  };
6658 
6659  template <typename T>
6660  struct range_pack;
6661 
6662  template <typename T>
6663  struct range_data_type;
6664 
6665  template <typename T>
6667  {
6668  public:
6669 
6671 
6673  {}
6674 
6675  virtual range_t& range_ref() = 0;
6676 
6677  virtual const range_t& range_ref() const = 0;
6678  };
6679 
6680  #ifndef exprtk_disable_string_capabilities
6681  template <typename T>
6683  {
6684  public:
6685 
6687 
6689  {}
6690 
6691  virtual std::string str () const = 0;
6692 
6693  virtual char_cptr base() const = 0;
6694 
6695  virtual std::size_t size() const = 0;
6696  };
6697 
6698  template <typename T>
6699  class string_literal_node exprtk_final
6700  : public expression_node <T>
6701  , public string_base_node<T>
6702  , public range_interface <T>
6703  {
6704  public:
6705 
6707 
6708  explicit string_literal_node(const std::string& v)
6709  : value_(v)
6710  {
6711  rp_.n0_c = std::make_pair<bool,std::size_t>(true, 0);
6712  rp_.n1_c = std::make_pair<bool,std::size_t>(true, v.size());
6713  rp_.cache.first = rp_.n0_c.second;
6714  rp_.cache.second = rp_.n1_c.second;
6715  }
6716 
6718  {
6719  return std::numeric_limits<T>::quiet_NaN();
6720  }
6721 
6723  {
6725  }
6726 
6727  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6728  {
6729  return reinterpret_cast<expression_node<T>*>(0);
6730  }
6731 
6732  std::string str() const exprtk_override
6733  {
6734  return value_;
6735  }
6736 
6738  {
6739  return value_.data();
6740  }
6741 
6743  {
6744  return value_.size();
6745  }
6746 
6748  {
6749  return rp_;
6750  }
6751 
6753  {
6754  return rp_;
6755  }
6756 
6757  private:
6758 
6759  string_literal_node(const string_literal_node<T>&) exprtk_delete;
6760  string_literal_node<T>& operator=(const string_literal_node<T>&) exprtk_delete;
6761 
6762  const std::string value_;
6764  };
6765  #endif
6766 
6767  template <typename T>
6768  class unary_node : public expression_node<T>
6769  {
6770  public:
6771 
6773  typedef std::pair<expression_ptr,bool> branch_t;
6774 
6776  : operation_(opr)
6777  {
6778  construct_branch_pair(branch_,branch);
6779  assert(valid());
6780  }
6781 
6783  {
6784  return numeric::process<T>
6785  (operation_,branch_.first->value());
6786  }
6787 
6789  {
6791  }
6792 
6794  {
6795  return operation_;
6796  }
6797 
6798  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
6799  {
6800  return branch_.first;
6801  }
6802 
6804  {
6805  return branch_.first && branch_.first->valid();
6806  }
6807 
6808  inline void release()
6809  {
6810  branch_.second = false;
6811  }
6812 
6814  {
6815  expression_node<T>::ndb_t::collect(branch_, node_delete_list);
6816  }
6817 
6819  {
6821  }
6822 
6823  private:
6824 
6827  };
6828 
6829  template <typename T>
6830  class binary_node : public expression_node<T>
6831  {
6832  public:
6833 
6835  typedef std::pair<expression_ptr,bool> branch_t;
6836 
6838  expression_ptr branch0,
6839  expression_ptr branch1)
6840  : operation_(opr)
6841  {
6842  init_branches<2>(branch_, branch0, branch1);
6843  assert(valid());
6844  }
6845 
6847  {
6848  return numeric::process<T>
6849  (
6850  operation_,
6851  branch_[0].first->value(),
6852  branch_[1].first->value()
6853  );
6854  }
6855 
6857  {
6859  }
6860 
6862  {
6863  return operation_;
6864  }
6865 
6866  inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
6867  {
6868  assert(index < 2);
6869  return branch_[index].first;
6870  }
6871 
6873  {
6874  return
6875  branch_[0].first && branch_[0].first->valid() &&
6876  branch_[1].first && branch_[1].first->valid() ;
6877  }
6878 
6880  {
6881  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
6882  }
6883 
6885  {
6886  return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_);
6887  }
6888 
6889  private:
6890 
6892  branch_t branch_[2];
6893  };
6894 
6895  template <typename T, typename Operation>
6896  class binary_ext_node exprtk_final : public expression_node<T>
6897  {
6898  public:
6899 
6901  typedef std::pair<expression_ptr,bool> branch_t;
6902 
6904  {
6905  init_branches<2>(branch_, branch0, branch1);
6906  assert(valid());
6907  }
6908 
6910  {
6911  const T arg0 = branch_[0].first->value();
6912  const T arg1 = branch_[1].first->value();
6913  return Operation::process(arg0,arg1);
6914  }
6915 
6917  {
6919  }
6920 
6922  {
6923  return Operation::operation();
6924  }
6925 
6926  inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override
6927  {
6928  assert(index < 2);
6929  return branch_[index].first;
6930  }
6931 
6933  {
6934  return
6935  branch_[0].first && branch_[0].first->valid() &&
6936  branch_[1].first && branch_[1].first->valid() ;
6937  }
6938 
6940  {
6941  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
6942  }
6943 
6945  {
6946  return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_);
6947  }
6948 
6949  protected:
6950 
6951  branch_t branch_[2];
6952  };
6953 
6954  template <typename T>
6955  class trinary_node : public expression_node<T>
6956  {
6957  public:
6958 
6960  typedef std::pair<expression_ptr,bool> branch_t;
6961 
6963  expression_ptr branch0,
6964  expression_ptr branch1,
6965  expression_ptr branch2)
6966  : operation_(opr)
6967  {
6968  init_branches<3>(branch_, branch0, branch1, branch2);
6969  assert(valid());
6970  }
6971 
6973  {
6974  const T arg0 = branch_[0].first->value();
6975  const T arg1 = branch_[1].first->value();
6976  const T arg2 = branch_[2].first->value();
6977 
6978  switch (operation_)
6979  {
6980  case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1));
6981 
6982  case e_clamp : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1);
6983 
6984  case e_iclamp : if ((arg1 <= arg0) || (arg1 >= arg2))
6985  return arg1;
6986  else
6987  return ((T(2) * arg1 <= (arg2 + arg0)) ? arg0 : arg2);
6988 
6989  default : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n"));
6990  return std::numeric_limits<T>::quiet_NaN();
6991  }
6992  }
6993 
6995  {
6997  }
6998 
7000  {
7001  return
7002  branch_[0].first && branch_[0].first->valid() &&
7003  branch_[1].first && branch_[1].first->valid() &&
7004  branch_[2].first && branch_[2].first->valid() ;
7005  }
7006 
7008  {
7009  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
7010  }
7011 
7013  {
7014  return expression_node<T>::ndb_t::template compute_node_depth<3>(branch_);
7015  }
7016 
7017  protected:
7018 
7020  branch_t branch_[3];
7021  };
7022 
7023  template <typename T>
7025  {
7026  public:
7027 
7029  typedef std::pair<expression_ptr,bool> branch_t;
7030 
7032  expression_ptr branch0,
7033  expression_ptr branch1,
7034  expression_ptr branch2,
7035  expression_ptr branch3)
7036  : operation_(opr)
7037  {
7038  init_branches<4>(branch_, branch0, branch1, branch2, branch3);
7039  }
7040 
7042  {
7043  return std::numeric_limits<T>::quiet_NaN();
7044  }
7045 
7047  {
7049  }
7050 
7052  {
7053  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
7054  }
7055 
7057  {
7058  return expression_node<T>::ndb_t::template compute_node_depth<4>(branch_);
7059  }
7060 
7062  {
7063  return
7064  branch_[0].first && branch_[0].first->valid() &&
7065  branch_[1].first && branch_[1].first->valid() &&
7066  branch_[2].first && branch_[2].first->valid() &&
7067  branch_[3].first && branch_[3].first->valid() ;
7068  }
7069 
7070  protected:
7071 
7073  branch_t branch_[4];
7074  };
7075 
7076  template <typename T>
7077  class conditional_node exprtk_final : public expression_node<T>
7078  {
7079  public:
7080 
7082  typedef std::pair<expression_ptr,bool> branch_t;
7083 
7085  expression_ptr consequent,
7086  expression_ptr alternative)
7087  {
7088  construct_branch_pair(condition_ , condition );
7089  construct_branch_pair(consequent_ , consequent );
7090  construct_branch_pair(alternative_, alternative);
7091  assert(valid());
7092  }
7093 
7095  {
7096  if (is_true(condition_))
7097  return consequent_.first->value();
7098  else
7099  return alternative_.first->value();
7100  }
7101 
7103  {
7105  }
7106 
7108  {
7109  return
7110  condition_ .first && condition_ .first->valid() &&
7111  consequent_ .first && consequent_ .first->valid() &&
7112  alternative_.first && alternative_.first->valid() ;
7113  }
7114 
7116  {
7117  expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
7118  expression_node<T>::ndb_t::collect(consequent_ , node_delete_list);
7119  expression_node<T>::ndb_t::collect(alternative_ , node_delete_list);
7120  }
7121 
7123  {
7125  (condition_, consequent_, alternative_);
7126  }
7127 
7128  private:
7129 
7133  };
7134 
7135  template <typename T>
7136  class cons_conditional_node exprtk_final : public expression_node<T>
7137  {
7138  public:
7139 
7140  // Consequent only conditional statement node
7142  typedef std::pair<expression_ptr,bool> branch_t;
7143 
7145  expression_ptr consequent)
7146  {
7147  construct_branch_pair(condition_ , condition );
7148  construct_branch_pair(consequent_, consequent);
7149  assert(valid());
7150  }
7151 
7153  {
7154  if (is_true(condition_))
7155  return consequent_.first->value();
7156  else
7157  return std::numeric_limits<T>::quiet_NaN();
7158  }
7159 
7161  {
7163  }
7164 
7166  {
7167  return
7168  condition_ .first && condition_ .first->valid() &&
7169  consequent_.first && consequent_.first->valid() ;
7170  }
7171 
7173  {
7174  expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
7175  expression_node<T>::ndb_t::collect(consequent_ , node_delete_list);
7176  }
7177 
7179  {
7181  compute_node_depth(condition_, consequent_);
7182  }
7183 
7184  private:
7185 
7186  branch_t condition_;
7187  branch_t consequent_;
7188  };
7189 
7190  #ifndef exprtk_disable_break_continue
7191  template <typename T>
7193  {
7194  public:
7195 
7196  explicit break_exception(const T& v)
7197  : value(v)
7198  {}
7199 
7201  };
7202 
7204 
7205  template <typename T>
7206  class break_node exprtk_final : public expression_node<T>
7207  {
7208  public:
7209 
7211  typedef std::pair<expression_ptr,bool> branch_t;
7212 
7214  {
7215  construct_branch_pair(return_, ret);
7216  }
7217 
7219  {
7220  const T result = return_.first ?
7221  return_.first->value() :
7222  std::numeric_limits<T>::quiet_NaN();
7223 
7224  throw break_exception<T>(result);
7225 
7226  #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
7227  return std::numeric_limits<T>::quiet_NaN();
7228  #endif
7229  }
7230 
7232  {
7234  }
7235 
7237  {
7238  expression_node<T>::ndb_t::collect(return_, node_delete_list);
7239  }
7240 
7242  {
7244  }
7245 
7246  private:
7247 
7249  };
7250 
7251  template <typename T>
7252  class continue_node exprtk_final : public expression_node<T>
7253  {
7254  public:
7255 
7257  {
7258  throw continue_exception();
7259  #if !defined(_MSC_VER) && !defined(__NVCOMPILER)
7260  return std::numeric_limits<T>::quiet_NaN();
7261  #endif
7262  }
7263 
7265  {
7267  }
7268  };
7269  #endif
7270 
7272  {
7275  : iteration_count_(0)
7276  , loop_runtime_check_(loop_runtime_check)
7277  , max_loop_iterations_(loop_runtime_check_->max_loop_iterations)
7278  , loop_type_(lp_typ)
7279  {
7280  assert(loop_runtime_check_);
7281  }
7282 
7283  inline void reset(const _uint64_t initial_value = 0) const
7284  {
7285  iteration_count_ = initial_value;
7286  }
7287 
7288  inline bool check() const
7289  {
7290  if (
7291  (0 == loop_runtime_check_) ||
7292  ((++iteration_count_ <= max_loop_iterations_) && loop_runtime_check_->check())
7293  )
7294  {
7295  return true;
7296  }
7297 
7299  ctxt.loop = loop_type_;
7301 
7302  loop_runtime_check_->handle_runtime_violation(ctxt);
7303 
7304  return false;
7305  }
7306 
7311  };
7312 
7313  template <typename T>
7315  {
7316  public:
7317 
7319  typedef std::pair<expression_ptr,bool> branch_t;
7320 
7322  expression_ptr loop_body)
7323  {
7324  construct_branch_pair(condition_, condition);
7325  construct_branch_pair(loop_body_, loop_body);
7326  assert(valid());
7327  }
7328 
7330  {
7331  T result = T(0);
7332 
7333  while (is_true(condition_))
7334  {
7335  result = loop_body_.first->value();
7336  }
7337 
7338  return result;
7339  }
7340 
7342  {
7344  }
7345 
7347  {
7348  return
7349  condition_.first && condition_.first->valid() &&
7350  loop_body_.first && loop_body_.first->valid() ;
7351  }
7352 
7354  {
7355  expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
7356  expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list);
7357  }
7358 
7360  {
7361  return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_);
7362  }
7363 
7364  protected:
7365 
7368  };
7369 
7370  template <typename T>
7371  class while_loop_rtc_node exprtk_final
7372  : public while_loop_node<T>
7373  , public loop_runtime_checker
7374  {
7375  public:
7376 
7379 
7381  expression_ptr loop_body,
7382  loop_runtime_check_ptr loop_rt_chk)
7383  : parent_t(condition, loop_body)
7384  , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop)
7385  {
7386  assert(parent_t::valid());
7387  }
7388 
7390  {
7391 
7392  T result = T(0);
7393 
7395 
7396  while (is_true(parent_t::condition_) && loop_runtime_checker::check())
7397  {
7398  result = parent_t::loop_body_.first->value();
7399  }
7400 
7401  return result;
7402  }
7403  };
7404 
7405  template <typename T>
7407  {
7408  public:
7409 
7411  typedef std::pair<expression_ptr,bool> branch_t;
7412 
7414  expression_ptr loop_body)
7415  {
7416  construct_branch_pair(condition_, condition);
7417  construct_branch_pair(loop_body_, loop_body);
7418  assert(valid());
7419  }
7420 
7422  {
7423  T result = T(0);
7424 
7425  do
7426  {
7427  result = loop_body_.first->value();
7428  }
7429  while (is_false(condition_.first));
7430 
7431  return result;
7432  }
7433 
7435  {
7437  }
7438 
7440  {
7441  return
7442  condition_.first && condition_.first->valid() &&
7443  loop_body_.first && loop_body_.first->valid() ;
7444  }
7445 
7447  {
7448  expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
7449  expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list);
7450  }
7451 
7453  {
7454  return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_);
7455  }
7456 
7457  protected:
7458 
7461  };
7462 
7463  template <typename T>
7464  class repeat_until_loop_rtc_node exprtk_final
7465  : public repeat_until_loop_node<T>
7466  , public loop_runtime_checker
7467  {
7468  public:
7469 
7472 
7474  expression_ptr loop_body,
7475  loop_runtime_check_ptr loop_rt_chk)
7476  : parent_t(condition, loop_body)
7477  , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop)
7478  {
7479  assert(parent_t::valid());
7480  }
7481 
7483  {
7484  T result = T(0);
7485 
7487 
7488  do
7489  {
7490  result = parent_t::loop_body_.first->value();
7491  }
7492  while (is_false(parent_t::condition_.first) && loop_runtime_checker::check());
7493 
7494  return result;
7495  }
7496  };
7497 
7498  template <typename T>
7499  class for_loop_node : public expression_node<T>
7500  {
7501  public:
7502 
7504  typedef std::pair<expression_ptr,bool> branch_t;
7505 
7507  expression_ptr condition,
7508  expression_ptr incrementor,
7509  expression_ptr loop_body)
7510  {
7511  construct_branch_pair(initialiser_, initialiser);
7512  construct_branch_pair(condition_ , condition );
7513  construct_branch_pair(incrementor_, incrementor);
7514  construct_branch_pair(loop_body_ , loop_body );
7515  assert(valid());
7516  }
7517 
7519  {
7520  T result = T(0);
7521 
7522  if (initialiser_.first)
7523  initialiser_.first->value();
7524 
7525  if (incrementor_.first)
7526  {
7527  while (is_true(condition_))
7528  {
7529  result = loop_body_.first->value();
7530  incrementor_.first->value();
7531  }
7532  }
7533  else
7534  {
7535  while (is_true(condition_))
7536  {
7537  result = loop_body_.first->value();
7538  }
7539  }
7540 
7541  return result;
7542  }
7543 
7545  {
7547  }
7548 
7550  {
7551  return condition_.first && loop_body_.first;
7552  }
7553 
7555  {
7556  expression_node<T>::ndb_t::collect(initialiser_ , node_delete_list);
7557  expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
7558  expression_node<T>::ndb_t::collect(incrementor_ , node_delete_list);
7559  expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list);
7560  }
7561 
7563  {
7565  (initialiser_, condition_, incrementor_, loop_body_);
7566  }
7567 
7568  protected:
7569 
7574  };
7575 
7576  template <typename T>
7577  class for_loop_rtc_node exprtk_final
7578  : public for_loop_node<T>
7579  , public loop_runtime_checker
7580  {
7581  public:
7582 
7585 
7587  expression_ptr condition,
7588  expression_ptr incrementor,
7589  expression_ptr loop_body,
7590  loop_runtime_check_ptr loop_rt_chk)
7591  : parent_t(initialiser, condition, incrementor, loop_body)
7592  , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop)
7593  {
7594  assert(parent_t::valid());
7595  }
7596 
7598  {
7599  T result = T(0);
7600 
7602 
7603  if (parent_t::initialiser_.first)
7604  parent_t::initialiser_.first->value();
7605 
7606  if (parent_t::incrementor_.first)
7607  {
7608  while (is_true(parent_t::condition_) && loop_runtime_checker::check())
7609  {
7610  result = parent_t::loop_body_.first->value();
7611  parent_t::incrementor_.first->value();
7612  }
7613  }
7614  else
7615  {
7616  while (is_true(parent_t::condition_) && loop_runtime_checker::check())
7617  {
7618  result = parent_t::loop_body_.first->value();
7619  }
7620  }
7621 
7622  return result;
7623  }
7624  };
7625 
7626  #ifndef exprtk_disable_break_continue
7627  template <typename T>
7629  {
7630  public:
7631 
7634 
7636  expression_ptr loop_body)
7637  : parent_t(condition, loop_body)
7638  {
7639  assert(parent_t::valid());
7640  }
7641 
7643  {
7644  T result = T(0);
7645 
7646  while (is_true(parent_t::condition_))
7647  {
7648  try
7649  {
7650  result = parent_t::loop_body_.first->value();
7651  }
7652  catch(const break_exception<T>& e)
7653  {
7654  return e.value;
7655  }
7656  catch(const continue_exception&)
7657  {}
7658  }
7659 
7660  return result;
7661  }
7662  };
7663 
7664  template <typename T>
7665  class while_loop_bc_rtc_node exprtk_final
7666  : public while_loop_bc_node<T>
7667  , public loop_runtime_checker
7668  {
7669  public:
7670 
7673 
7675  expression_ptr loop_body,
7676  loop_runtime_check_ptr loop_rt_chk)
7677  : parent_t(condition, loop_body)
7678  , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop)
7679  {
7680  assert(parent_t::valid());
7681  }
7682 
7684  {
7685  T result = T(0);
7686 
7688 
7689  while (is_true(parent_t::condition_) && loop_runtime_checker::check())
7690  {
7691  try
7692  {
7693  result = parent_t::loop_body_.first->value();
7694  }
7695  catch(const break_exception<T>& e)
7696  {
7697  return e.value;
7698  }
7699  catch(const continue_exception&)
7700  {}
7701  }
7702 
7703  return result;
7704  }
7705  };
7706 
7707  template <typename T>
7709  {
7710  public:
7711 
7714 
7716  expression_ptr loop_body)
7717  : parent_t(condition, loop_body)
7718  {
7719  assert(parent_t::valid());
7720  }
7721 
7723  {
7724  T result = T(0);
7725 
7726  do
7727  {
7728  try
7729  {
7730  result = parent_t::loop_body_.first->value();
7731  }
7732  catch(const break_exception<T>& e)
7733  {
7734  return e.value;
7735  }
7736  catch(const continue_exception&)
7737  {}
7738  }
7739  while (is_false(parent_t::condition_.first));
7740 
7741  return result;
7742  }
7743  };
7744 
7745  template <typename T>
7746  class repeat_until_loop_bc_rtc_node exprtk_final
7747  : public repeat_until_loop_bc_node<T>
7748  , public loop_runtime_checker
7749  {
7750  public:
7751 
7754 
7756  expression_ptr loop_body,
7757  loop_runtime_check_ptr loop_rt_chk)
7758  : parent_t(condition, loop_body)
7759  , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop)
7760  {
7761  assert(parent_t::valid());
7762  }
7763 
7765  {
7766  T result = T(0);
7767 
7769 
7770  do
7771  {
7772  try
7773  {
7774  result = parent_t::loop_body_.first->value();
7775  }
7776  catch(const break_exception<T>& e)
7777  {
7778  return e.value;
7779  }
7780  catch(const continue_exception&)
7781  {}
7782  }
7783  while (is_false(parent_t::condition_.first) && loop_runtime_checker::check());
7784 
7785  return result;
7786  }
7787  };
7788 
7789  template <typename T>
7791  {
7792  public:
7793 
7796 
7798  expression_ptr condition,
7799  expression_ptr incrementor,
7800  expression_ptr loop_body)
7801  : parent_t(initialiser, condition, incrementor, loop_body)
7802  {
7803  assert(parent_t::valid());
7804  }
7805 
7807  {
7808  T result = T(0);
7809 
7810  if (parent_t::initialiser_.first)
7811  parent_t::initialiser_.first->value();
7812 
7813  if (parent_t::incrementor_.first)
7814  {
7815  while (is_true(parent_t::condition_))
7816  {
7817  try
7818  {
7819  result = parent_t::loop_body_.first->value();
7820  }
7821  catch(const break_exception<T>& e)
7822  {
7823  return e.value;
7824  }
7825  catch(const continue_exception&)
7826  {}
7827 
7828  parent_t::incrementor_.first->value();
7829  }
7830  }
7831  else
7832  {
7833  while (is_true(parent_t::condition_))
7834  {
7835  try
7836  {
7837  result = parent_t::loop_body_.first->value();
7838  }
7839  catch(const break_exception<T>& e)
7840  {
7841  return e.value;
7842  }
7843  catch(const continue_exception&)
7844  {}
7845  }
7846  }
7847 
7848  return result;
7849  }
7850  };
7851 
7852  template <typename T>
7853  class for_loop_bc_rtc_node exprtk_final
7854  : public for_loop_bc_node<T>
7855  , public loop_runtime_checker
7856  {
7857  public:
7858 
7861 
7863  expression_ptr condition,
7864  expression_ptr incrementor,
7865  expression_ptr loop_body,
7866  loop_runtime_check_ptr loop_rt_chk)
7867  : parent_t(initialiser, condition, incrementor, loop_body)
7868  , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop)
7869  {
7870  assert(parent_t::valid());
7871  }
7872 
7874  {
7875  T result = T(0);
7876 
7878 
7879  if (parent_t::initialiser_.first)
7880  parent_t::initialiser_.first->value();
7881 
7882  if (parent_t::incrementor_.first)
7883  {
7884  while (is_true(parent_t::condition_) && loop_runtime_checker::check())
7885  {
7886  try
7887  {
7888  result = parent_t::loop_body_.first->value();
7889  }
7890  catch(const break_exception<T>& e)
7891  {
7892  return e.value;
7893  }
7894  catch(const continue_exception&)
7895  {}
7896 
7897  parent_t::incrementor_.first->value();
7898  }
7899  }
7900  else
7901  {
7902  while (is_true(parent_t::condition_) && loop_runtime_checker::check())
7903  {
7904  try
7905  {
7906  result = parent_t::loop_body_.first->value();
7907  }
7908  catch(const break_exception<T>& e)
7909  {
7910  return e.value;
7911  }
7912  catch(const continue_exception&)
7913  {}
7914  }
7915  }
7916 
7917  return result;
7918  }
7919  };
7920  #endif
7921 
7922  template <typename T>
7923  class switch_node : public expression_node<T>
7924  {
7925  public:
7926 
7928  typedef std::pair<expression_ptr,bool> branch_t;
7929 
7930  template <typename Allocator,
7931  template <typename, typename> class Sequence>
7932  explicit switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
7933  {
7934  if (1 != (arg_list.size() & 1))
7935  return;
7936 
7937  arg_list_.resize(arg_list.size());
7938 
7939  for (std::size_t i = 0; i < arg_list.size(); ++i)
7940  {
7941  if (arg_list[i] && arg_list[i]->valid())
7942  {
7943  construct_branch_pair(arg_list_[i], arg_list[i]);
7944  }
7945  else
7946  {
7947  arg_list_.clear();
7948  return;
7949  }
7950  }
7951 
7952  assert(valid());
7953  }
7954 
7956  {
7957  const std::size_t upper_bound = (arg_list_.size() - 1);
7958 
7959  for (std::size_t i = 0; i < upper_bound; i += 2)
7960  {
7961  expression_ptr condition = arg_list_[i ].first;
7962  expression_ptr consequent = arg_list_[i + 1].first;
7963 
7964  if (is_true(condition))
7965  {
7966  return consequent->value();
7967  }
7968  }
7969 
7970  return arg_list_[upper_bound].first->value();
7971  }
7972 
7974  {
7976  }
7977 
7979  {
7980  return !arg_list_.empty();
7981  }
7982 
7984  {
7985  expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
7986  }
7987 
7989  {
7991  }
7992 
7993  protected:
7994 
7995  std::vector<branch_t> arg_list_;
7996  };
7997 
7998  template <typename T, typename Switch_N>
7999  class switch_n_node exprtk_final : public switch_node<T>
8000  {
8001  public:
8002 
8004 
8005  template <typename Allocator,
8006  template <typename, typename> class Sequence>
8007  explicit switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list)
8008  : switch_node<T>(arg_list)
8009  {}
8010 
8012  {
8014  }
8015  };
8016 
8017  template <typename T>
8018  class multi_switch_node exprtk_final : public expression_node<T>
8019  {
8020  public:
8021 
8023  typedef std::pair<expression_ptr,bool> branch_t;
8024 
8025  template <typename Allocator,
8026  template <typename, typename> class Sequence>
8027  explicit multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
8028  {
8029  if (0 != (arg_list.size() & 1))
8030  return;
8031 
8032  arg_list_.resize(arg_list.size());
8033 
8034  for (std::size_t i = 0; i < arg_list.size(); ++i)
8035  {
8036  if (arg_list[i] && arg_list[i]->valid())
8037  {
8038  construct_branch_pair(arg_list_[i], arg_list[i]);
8039  }
8040  else
8041  {
8042  arg_list_.clear();
8043  return;
8044  }
8045  }
8046 
8047  assert(valid());
8048  }
8049 
8051  {
8052  const std::size_t upper_bound = (arg_list_.size() - 1);
8053 
8054  T result = T(0);
8055 
8056  for (std::size_t i = 0; i < upper_bound; i += 2)
8057  {
8058  expression_ptr condition = arg_list_[i ].first;
8059  expression_ptr consequent = arg_list_[i + 1].first;
8060 
8061  if (is_true(condition))
8062  {
8063  result = consequent->value();
8064  }
8065  }
8066 
8067  return result;
8068  }
8069 
8071  {
8073  }
8074 
8076  {
8077  return !arg_list_.empty() && (0 == (arg_list_.size() % 2));
8078  }
8079 
8081  {
8082  expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
8083  }
8084 
8086  {
8088  }
8089 
8090  private:
8091 
8092  std::vector<branch_t> arg_list_;
8093  };
8094 
8095  template <typename T>
8097  {
8098  public:
8099 
8100  virtual ~ivariable()
8101  {}
8102 
8103  virtual T& ref() = 0;
8104  virtual const T& ref() const = 0;
8105  };
8106 
8107  template <typename T>
8108  class variable_node exprtk_final
8109  : public expression_node<T>
8110  , public ivariable <T>
8111  {
8112  public:
8113 
8114  static T null_value;
8115 
8116  explicit variable_node()
8117  : value_(&null_value)
8118  {}
8119 
8120  explicit variable_node(T& v)
8121  : value_(&v)
8122  {}
8123 
8124  inline bool operator <(const variable_node<T>& v) const
8125  {
8126  return this < (&v);
8127  }
8128 
8130  {
8131  return (*value_);
8132  }
8133 
8134  inline T& ref() exprtk_override
8135  {
8136  return (*value_);
8137  }
8138 
8139  inline const T& ref() const exprtk_override
8140  {
8141  return (*value_);
8142  }
8143 
8145  {
8147  }
8148 
8149  private:
8150 
8152  };
8153 
8154  template <typename T>
8155  T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN());
8156 
8157  template <typename T>
8158  struct range_pack
8159  {
8161  typedef std::pair<std::size_t,std::size_t> cached_range_t;
8162 
8164  : n0_e (std::make_pair(false,expression_node_ptr(0)))
8165  , n1_e (std::make_pair(false,expression_node_ptr(0)))
8166  , n0_c (std::make_pair(false,0))
8167  , n1_c (std::make_pair(false,0))
8168  , cache(std::make_pair(0,0))
8169  {}
8170 
8171  void clear()
8172  {
8173  n0_e = std::make_pair(false,expression_node_ptr(0));
8174  n1_e = std::make_pair(false,expression_node_ptr(0));
8175  n0_c = std::make_pair(false,0);
8176  n1_c = std::make_pair(false,0);
8177  cache = std::make_pair(0,0);
8178  }
8179 
8180  void free()
8181  {
8182  if (n0_e.first && n0_e.second)
8183  {
8184  n0_e.first = false;
8185 
8186  if (
8187  !is_variable_node(n0_e.second) &&
8188  !is_string_node (n0_e.second)
8189  )
8190  {
8191  destroy_node(n0_e.second);
8192  }
8193  }
8194 
8195  if (n1_e.first && n1_e.second)
8196  {
8197  n1_e.first = false;
8198 
8199  if (
8200  !is_variable_node(n1_e.second) &&
8201  !is_string_node (n1_e.second)
8202  )
8203  {
8204  destroy_node(n1_e.second);
8205  }
8206  }
8207  }
8208 
8209  bool const_range() const
8210  {
8211  return ( n0_c.first && n1_c.first) &&
8212  (!n0_e.first && !n1_e.first);
8213  }
8214 
8215  bool var_range() const
8216  {
8217  return ( n0_e.first && n1_e.first) &&
8218  (!n0_c.first && !n1_c.first);
8219  }
8220 
8221  bool operator() (std::size_t& r0, std::size_t& r1,
8222  const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
8223  {
8224  if (n0_c.first)
8225  r0 = n0_c.second;
8226  else if (n0_e.first)
8227  {
8228  r0 = static_cast<std::size_t>(details::numeric::to_int64(n0_e.second->value()));
8229  }
8230  else
8231  return false;
8232 
8233  if (n1_c.first)
8234  r1 = n1_c.second;
8235  else if (n1_e.first)
8236  {
8237  r1 = static_cast<std::size_t>(details::numeric::to_int64(n1_e.second->value()));
8238  }
8239  else
8240  return false;
8241 
8242  if (
8245  )
8246  {
8247  r1 = size;
8248  }
8249 
8250  cache.first = r0;
8251  cache.second = r1;
8252 
8253  #ifndef exprtk_enable_range_runtime_checks
8254  return (r0 <= r1);
8255  #else
8256  return range_runtime_check(r0, r1, size);
8257  #endif
8258  }
8259 
8260  inline std::size_t const_size() const
8261  {
8262  return (n1_c.second - n0_c.second);
8263  }
8264 
8265  inline std::size_t cache_size() const
8266  {
8267  return (cache.second - cache.first);
8268  }
8269 
8270  std::pair<bool,expression_node_ptr> n0_e;
8271  std::pair<bool,expression_node_ptr> n1_e;
8272  std::pair<bool,std::size_t > n0_c;
8273  std::pair<bool,std::size_t > n1_c;
8275 
8276  #ifdef exprtk_enable_range_runtime_checks
8277  bool range_runtime_check(const std::size_t r0,
8278  const std::size_t r1,
8279  const std::size_t size) const
8280  {
8281  if (r0 > size)
8282  {
8283  throw std::runtime_error("range error: (r0 < 0) || (r0 > size)");
8284  #ifndef _MSC_VER
8285  return false;
8286  #endif
8287  }
8288 
8289  if (r1 > size)
8290  {
8291  throw std::runtime_error("range error: (r1 < 0) || (r1 > size)");
8292  #ifndef _MSC_VER
8293  return false;
8294  #endif
8295  }
8296 
8297  return (r0 <= r1);
8298  }
8299  #endif
8300  };
8301 
8302  template <typename T>
8303  class string_base_node;
8304 
8305  template <typename T>
8307  {
8310 
8312  : range(0)
8313  , data (0)
8314  , size (0)
8315  , type_size(0)
8316  , str_node (0)
8317  {}
8318 
8320  void* data;
8321  std::size_t size;
8322  std::size_t type_size;
8324  };
8325 
8326  template <typename T> class vector_node;
8327 
8328  template <typename T>
8330  {
8331  public:
8332 
8335 
8337  {}
8338 
8339  virtual std::size_t size () const = 0;
8340 
8341  virtual std::size_t base_size() const = 0;
8342 
8343  virtual vector_node_ptr vec () const = 0;
8344 
8345  virtual vector_node_ptr vec () = 0;
8346 
8347  virtual vds_t& vds () = 0;
8348 
8349  virtual const vds_t& vds () const = 0;
8350 
8351  virtual bool side_effect () const { return false; }
8352  };
8353 
8354  template <typename T>
8355  class vector_node exprtk_final
8356  : public expression_node <T>
8357  , public vector_interface<T>
8358  {
8359  public:
8360 
8365 
8367  : vector_holder_(vh)
8368  , vds_((*vector_holder_).size(),(*vector_holder_)[0])
8369  {
8370  vector_holder_->set_ref(&vds_.ref());
8371  }
8372 
8374  : vector_holder_(vh)
8375  , vds_(vds)
8376  {}
8377 
8379  {
8380  assert(valid());
8381  vector_holder_->remove_ref(&vds_.ref());
8382  }
8383 
8385  {
8386  return vds().data()[0];
8387  }
8388 
8390  {
8391  return const_cast<vector_node_ptr>(this);
8392  }
8393 
8395  {
8396  return this;
8397  }
8398 
8400  {
8402  }
8403 
8405  {
8406  return vector_holder_;
8407  }
8408 
8410  {
8411  return vec_holder().size();
8412  }
8413 
8415  {
8416  return vec_holder().base_size();
8417  }
8418 
8420  {
8421  return vds_;
8422  }
8423 
8425  {
8426  return vds_;
8427  }
8428 
8430  {
8431  return (*vector_holder_);
8432  }
8433 
8434  inline vector_holder_t& vec_holder() const
8435  {
8436  return (*vector_holder_);
8437  }
8438 
8439  private:
8440 
8443  };
8444 
8445  template <typename T>
8446  class vector_size_node exprtk_final
8447  : public expression_node <T>
8448  {
8449  public:
8450 
8453 
8455  : vector_holder_(vh)
8456  {}
8457 
8459  {
8460  assert(valid());
8461  }
8462 
8464  {
8465  assert(vector_holder_);
8466  return static_cast<T>(vector_holder_->size());
8467  }
8468 
8470  {
8472  }
8473 
8475  {
8476  return vector_holder_ && vector_holder_->size();
8477  }
8478 
8480  {
8481  return vector_holder_;
8482  }
8483 
8484  private:
8485 
8486  vector_holder_t* vector_holder_;
8487  };
8488 
8489  template <typename T>
8490  class vector_elem_node exprtk_final
8491  : public expression_node<T>
8492  , public ivariable <T>
8493  {
8494  public:
8495 
8499  typedef std::pair<expression_ptr,bool> branch_t;
8500 
8502  expression_ptr index,
8503  vector_holder_ptr vec_holder)
8504  : vector_holder_(vec_holder)
8505  , vector_base_((*vec_holder)[0])
8506  {
8507  construct_branch_pair(vector_node_, vec_node);
8508  construct_branch_pair(index_ , index );
8509  assert(valid());
8510  }
8511 
8513  {
8514  return *access_vector();
8515  }
8516 
8517  inline T& ref() exprtk_override
8518  {
8519  return *access_vector();
8520  }
8521 
8522  inline const T& ref() const exprtk_override
8523  {
8524  return *access_vector();
8525  }
8526 
8528  {
8530  }
8531 
8533  {
8534  return
8535  vector_holder_ &&
8536  index_.first &&
8537  vector_node_.first &&
8538  index_.first->valid() &&
8539  vector_node_.first->valid();
8540  }
8541 
8543  {
8544  return (*vector_holder_);
8545  }
8546 
8548  {
8549  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
8550  expression_node<T>::ndb_t::collect(index_ , node_delete_list);
8551  }
8552 
8554  {
8556  (vector_node_, index_);
8557  }
8558 
8559  private:
8560 
8561  inline T* access_vector() const
8562  {
8563  vector_node_.first->value();
8564  return (vector_base_ + details::numeric::to_uint64(index_.first->value()));
8565  }
8566 
8571  };
8572 
8573  template <typename T>
8574  class vector_celem_node exprtk_final
8575  : public expression_node<T>
8576  , public ivariable <T>
8577  {
8578  public:
8579 
8583  typedef std::pair<expression_ptr,bool> branch_t;
8584 
8586  const std::size_t index,
8587  vector_holder_ptr vec_holder)
8588  : index_(index)
8589  , vector_holder_(vec_holder)
8590  , vector_base_((*vec_holder)[0])
8591  {
8592  construct_branch_pair(vector_node_, vec_node);
8593  assert(valid());
8594  }
8595 
8597  {
8598  return *access_vector();
8599  }
8600 
8601  inline T& ref() exprtk_override
8602  {
8603  return *access_vector();
8604  }
8605 
8606  inline const T& ref() const exprtk_override
8607  {
8608  return *access_vector();
8609  }
8610 
8612  {
8614  }
8615 
8617  {
8618  return
8619  vector_holder_ &&
8620  vector_node_.first &&
8621  vector_node_.first->valid();
8622  }
8623 
8625  {
8626  return (*vector_holder_);
8627  }
8628 
8630  {
8631  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
8632  }
8633 
8635  {
8636  return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
8637  }
8638 
8639  private:
8640 
8641  inline T* access_vector() const
8642  {
8643  vector_node_.first->value();
8644  return (vector_base_ + index_);
8645  }
8646 
8647  const std::size_t index_;
8648  vector_holder_ptr vector_holder_;
8649  T* vector_base_;
8650  branch_t vector_node_;
8651  };
8652 
8653  template <typename T>
8654  class vector_elem_rtc_node exprtk_final
8655  : public expression_node<T>
8656  , public ivariable <T>
8657  {
8658  public:
8659 
8663  typedef std::pair<expression_ptr,bool> branch_t;
8664 
8666  expression_ptr index,
8667  vector_holder_ptr vec_holder,
8669  : vector_holder_(vec_holder)
8670  , vector_base_((*vec_holder)[0])
8671  , vec_rt_chk_(vec_rt_chk)
8672  , max_vector_index_(vector_holder_->size() - 1)
8673  {
8674  construct_branch_pair(vector_node_, vec_node);
8675  construct_branch_pair(index_ , index );
8676  assert(valid());
8677  }
8678 
8680  {
8681  return *access_vector();
8682  }
8683 
8684  inline T& ref() exprtk_override
8685  {
8686  return *access_vector();
8687  }
8688 
8689  inline const T& ref() const exprtk_override
8690  {
8691  return *access_vector();
8692  }
8693 
8695  {
8697  }
8698 
8700  {
8701  return
8702  vector_holder_ &&
8703  index_.first &&
8704  vector_node_.first &&
8705  index_.first->valid() &&
8706  vector_node_.first->valid();
8707  }
8708 
8710  {
8711  return (*vector_holder_);
8712  }
8713 
8715  {
8716  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
8717  expression_node<T>::ndb_t::collect(index_, node_delete_list);
8718  }
8719 
8721  {
8723  (vector_node_, index_);
8724  }
8725 
8726  private:
8727 
8728  inline T* access_vector() const
8729  {
8730  const _uint64_t index = details::numeric::to_uint64(index_.first->value());
8731  vector_node_.first->value();
8732 
8733  if (index <= max_vector_index_)
8734  {
8735  return (vector_holder_->data() + index);
8736  }
8737 
8738  assert(vec_rt_chk_);
8739 
8741  context.base_ptr = reinterpret_cast<void*>(vector_base_);
8742  context.end_ptr = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
8743  context.access_ptr = reinterpret_cast<void*>(vector_base_ + index);
8744  context.type_size = sizeof(T);
8745 
8746  return vec_rt_chk_->handle_runtime_violation(context) ?
8747  reinterpret_cast<T*>(context.access_ptr) :
8748  vector_base_ ;
8749  }
8750 
8751  vector_holder_ptr vector_holder_;
8752  T* vector_base_;
8753  branch_t vector_node_;
8754  branch_t index_;
8756  const std::size_t max_vector_index_;
8757  };
8758 
8759  template <typename T>
8760  class vector_celem_rtc_node exprtk_final
8761  : public expression_node<T>
8762  , public ivariable <T>
8763  {
8764  public:
8765 
8769  typedef std::pair<expression_ptr,bool> branch_t;
8770 
8772  const std::size_t index,
8773  vector_holder_ptr vec_holder,
8775  : index_(index)
8776  , max_vector_index_(vec_holder->size() - 1)
8777  , vector_holder_(vec_holder)
8778  , vector_base_((*vec_holder)[0])
8779  , vec_rt_chk_(vec_rt_chk)
8780  {
8781  construct_branch_pair(vector_node_, vec_node);
8782  assert(valid());
8783  }
8784 
8786  {
8787  return *access_vector();
8788  }
8789 
8790  inline T& ref() exprtk_override
8791  {
8792  return *access_vector();
8793  }
8794 
8795  inline const T& ref() const exprtk_override
8796  {
8797  return *access_vector();
8798  }
8799 
8801  {
8803  }
8804 
8806  {
8807  return
8808  vector_holder_ &&
8809  vector_node_.first &&
8810  vector_node_.first->valid();
8811  }
8812 
8814  {
8815  return (*vector_holder_);
8816  }
8817 
8819  {
8820  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
8821  }
8822 
8824  {
8825  return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
8826  }
8827 
8828  private:
8829 
8830  inline T* access_vector() const
8831  {
8832  vector_node_.first->value();
8833 
8834  if (index_ <= max_vector_index_)
8835  {
8836  return (vector_holder_->data() + index_);
8837  }
8838 
8839  assert(vec_rt_chk_);
8840 
8842  context.base_ptr = reinterpret_cast<void*>(vector_base_);
8843  context.end_ptr = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
8844  context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_);
8845  context.type_size = sizeof(T);
8846 
8847  return vec_rt_chk_->handle_runtime_violation(context) ?
8848  reinterpret_cast<T*>(context.access_ptr) :
8849  vector_base_ ;
8850  }
8851 
8852  const std::size_t index_;
8853  const std::size_t max_vector_index_;
8854  vector_holder_ptr vector_holder_;
8855  T* vector_base_;
8856  branch_t vector_node_;
8857  vector_access_runtime_check_ptr vec_rt_chk_;
8858  };
8859 
8860  template <typename T>
8861  class rebasevector_elem_node exprtk_final
8862  : public expression_node<T>
8863  , public ivariable <T>
8864  {
8865  public:
8866 
8871  typedef std::pair<expression_ptr,bool> branch_t;
8872 
8874  expression_ptr index,
8875  vector_holder_ptr vec_holder)
8876  : vector_holder_(vec_holder)
8877  {
8878  construct_branch_pair(vector_node_, vec_node);
8879  construct_branch_pair(index_ , index );
8880  assert(valid());
8881  }
8882 
8884  {
8885  return *access_vector();
8886  }
8887 
8888  inline T& ref() exprtk_override
8889  {
8890  return *access_vector();
8891  }
8892 
8893  inline const T& ref() const exprtk_override
8894  {
8895  return *access_vector();
8896  }
8897 
8899  {
8901  }
8902 
8904  {
8905  return
8906  vector_holder_ &&
8907  index_.first &&
8908  vector_node_.first &&
8909  index_.first->valid() &&
8910  vector_node_.first->valid();
8911  }
8912 
8914  {
8915  return (*vector_holder_);
8916  }
8917 
8919  {
8920  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
8921  expression_node<T>::ndb_t::collect(index_, node_delete_list);
8922  }
8923 
8925  {
8927  (vector_node_, index_);
8928  }
8929 
8930  private:
8931 
8932  inline T* access_vector() const
8933  {
8934  vector_node_.first->value();
8935  return (vector_holder_->data() + details::numeric::to_uint64(index_.first->value()));
8936  }
8937 
8938  vector_holder_ptr vector_holder_;
8939  branch_t vector_node_;
8940  branch_t index_;
8941  };
8942 
8943  template <typename T>
8944  class rebasevector_celem_node exprtk_final
8945  : public expression_node<T>
8946  , public ivariable <T>
8947  {
8948  public:
8949 
8953  typedef std::pair<expression_ptr,bool> branch_t;
8954 
8956  const std::size_t index,
8957  vector_holder_ptr vec_holder)
8958  : index_(index)
8959  , vector_holder_(vec_holder)
8960  {
8961  construct_branch_pair(vector_node_, vec_node);
8962  assert(valid());
8963  }
8964 
8966  {
8967  vector_node_.first->value();
8968  return ref();;
8969  }
8970 
8971  inline T& ref() exprtk_override
8972  {
8973  return *(vector_holder_->data() + index_);
8974  }
8975 
8976  inline const T& ref() const exprtk_override
8977  {
8978  return *(vector_holder_->data() + index_);
8979  }
8980 
8982  {
8984  }
8985 
8987  {
8988  return
8989  vector_holder_ &&
8990  vector_node_.first &&
8991  vector_node_.first->valid();
8992  }
8993 
8995  {
8996  return (*vector_holder_);
8997  }
8998 
9000  {
9001  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
9002  }
9003 
9005  {
9006  return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
9007  }
9008 
9009  private:
9010 
9011  const std::size_t index_;
9012  vector_holder_ptr vector_holder_;
9013  branch_t vector_node_;
9014  };
9015 
9016  template <typename T>
9017  class rebasevector_elem_rtc_node exprtk_final
9018  : public expression_node<T>
9019  , public ivariable <T>
9020  {
9021  public:
9022 
9026  typedef std::pair<expression_ptr,bool> branch_t;
9027 
9029  expression_ptr index,
9030  vector_holder_ptr vec_holder,
9032  : vector_holder_(vec_holder)
9033  , vec_rt_chk_(vec_rt_chk)
9034  {
9035  construct_branch_pair(vector_node_, vec_node);
9036  construct_branch_pair(index_ , index );
9037  assert(valid());
9038  }
9039 
9041  {
9042  return *access_vector();
9043  }
9044 
9045  inline T& ref() exprtk_override
9046  {
9047  return *access_vector();
9048  }
9049 
9050  inline const T& ref() const exprtk_override
9051  {
9052  return *access_vector();
9053  }
9054 
9056  {
9058  }
9059 
9061  {
9062  return
9063  vector_holder_ &&
9064  index_.first &&
9065  vector_node_.first &&
9066  index_.first->valid() &&
9067  vector_node_.first->valid();
9068  }
9069 
9071  {
9072  return (*vector_holder_);
9073  }
9074 
9076  {
9077  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
9078  expression_node<T>::ndb_t::collect(index_ , node_delete_list);
9079  }
9080 
9082  {
9084  (vector_node_, index_);
9085  }
9086 
9087  private:
9088 
9089  inline T* access_vector() const
9090  {
9091  vector_node_.first->value();
9092  const _uint64_t index = details::numeric::to_uint64(index_.first->value());
9093 
9094  if (index <= (vector_holder_->size() - 1))
9095  {
9096  return (vector_holder_->data() + index);
9097  }
9098 
9099  assert(vec_rt_chk_);
9100 
9102  context.base_ptr = reinterpret_cast<void*>(vector_holder_->data());
9103  context.end_ptr = reinterpret_cast<void*>(vector_holder_->data() + vector_holder_->size());
9104  context.access_ptr = reinterpret_cast<void*>(vector_holder_->data() + index);
9105  context.type_size = sizeof(T);
9106 
9107  return vec_rt_chk_->handle_runtime_violation(context) ?
9108  reinterpret_cast<T*>(context.access_ptr) :
9109  vector_holder_->data() ;
9110  }
9111 
9112  vector_holder_ptr vector_holder_;
9113  branch_t vector_node_;
9114  branch_t index_;
9115  vector_access_runtime_check_ptr vec_rt_chk_;
9116  };
9117 
9118  template <typename T>
9119  class rebasevector_celem_rtc_node exprtk_final
9120  : public expression_node<T>
9121  , public ivariable <T>
9122  {
9123  public:
9124 
9128  typedef std::pair<expression_ptr,bool> branch_t;
9129 
9131  const std::size_t index,
9132  vector_holder_ptr vec_holder,
9134  : index_(index)
9135  , vector_holder_(vec_holder)
9136  , vector_base_((*vec_holder)[0])
9137  , vec_rt_chk_(vec_rt_chk)
9138  {
9139  construct_branch_pair(vector_node_, vec_node);
9140  assert(valid());
9141  }
9142 
9144  {
9145  return *access_vector();
9146  }
9147 
9148  inline T& ref() exprtk_override
9149  {
9150  return *access_vector();
9151  }
9152 
9153  inline const T& ref() const exprtk_override
9154  {
9155  return *access_vector();
9156  }
9157 
9159  {
9161  }
9162 
9164  {
9165  return
9166  vector_holder_ &&
9167  vector_node_.first &&
9168  vector_node_.first->valid();
9169  }
9170 
9172  {
9173  return (*vector_holder_);
9174  }
9175 
9177  {
9178  expression_node<T>::ndb_t::collect(vector_node_, node_delete_list);
9179  }
9180 
9182  {
9183  return expression_node<T>::ndb_t::compute_node_depth(vector_node_);
9184  }
9185 
9186  private:
9187 
9188  inline T* access_vector() const
9189  {
9190  vector_node_.first->value();
9191 
9192  if (index_ <= vector_holder_->size() - 1)
9193  {
9194  return (vector_holder_->data() + index_);
9195  }
9196 
9197  assert(vec_rt_chk_);
9198 
9200  context.base_ptr = reinterpret_cast<void*>(vector_base_);
9201  context.end_ptr = reinterpret_cast<void*>(vector_base_ + vector_holder_->size());
9202  context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_);
9203  context.type_size = sizeof(T);
9204 
9205  return vec_rt_chk_->handle_runtime_violation(context) ?
9206  reinterpret_cast<T*>(context.access_ptr) :
9207  vector_base_ ;
9208  }
9209 
9210  const std::size_t index_;
9211  vector_holder_ptr vector_holder_;
9212  T* vector_base_;
9213  branch_t vector_node_;
9214  vector_access_runtime_check_ptr vec_rt_chk_;
9215  };
9216 
9217  template <typename T>
9218  class vector_assignment_node exprtk_final : public expression_node<T>
9219  {
9220  public:
9221 
9223 
9224  vector_assignment_node(T* vector_base,
9225  const std::size_t& size,
9226  const std::vector<expression_ptr>& initialiser_list,
9227  const bool single_value_initialse)
9228  : vector_base_(vector_base)
9229  , initialiser_list_(initialiser_list)
9230  , size_(size)
9231  , single_value_initialse_(single_value_initialse)
9232  , zero_value_initialse_(false)
9233  , const_nonzero_literal_value_initialse_(false)
9234  , single_initialiser_value_(T(0))
9235  {
9236  if (single_value_initialse_)
9237  {
9238  if (initialiser_list_.empty())
9239  zero_value_initialse_ = true;
9240  else if (
9241  (initialiser_list_.size() == 1) &&
9242  details::is_constant_node(initialiser_list_[0]) &&
9243  (T(0) == initialiser_list_[0]->value())
9244  )
9245  {
9246  zero_value_initialse_ = true;
9247  }
9248  else
9249  {
9250  assert(initialiser_list_.size() == 1);
9251 
9252  if (details::is_constant_node(initialiser_list_[0]))
9253  {
9254  const_nonzero_literal_value_initialse_ = true;
9255  single_initialiser_value_ = initialiser_list_[0]->value();
9256  assert(T(0) != single_initialiser_value_);
9257  }
9258  }
9259  }
9260  }
9261 
9263  {
9264  if (single_value_initialse_)
9265  {
9266  if (zero_value_initialse_)
9267  {
9268  details::set_zero_value(vector_base_, size_);
9269  }
9270  else if (const_nonzero_literal_value_initialse_)
9271  {
9272  for (std::size_t i = 0; i < size_; ++i)
9273  {
9274  *(vector_base_ + i) = single_initialiser_value_;
9275  }
9276  }
9277  else
9278  {
9279  for (std::size_t i = 0; i < size_; ++i)
9280  {
9281  *(vector_base_ + i) = initialiser_list_[0]->value();
9282  }
9283  }
9284  }
9285  else
9286  {
9287  const std::size_t initialiser_list_size = initialiser_list_.size();
9288 
9289  for (std::size_t i = 0; i < initialiser_list_size; ++i)
9290  {
9291  *(vector_base_ + i) = initialiser_list_[i]->value();
9292  }
9293 
9294  if (initialiser_list_size < size_)
9295  {
9297  vector_base_ + initialiser_list_size,
9298  (size_ - initialiser_list_size));
9299  }
9300  }
9301 
9302  return *(vector_base_);
9303  }
9304 
9306  {
9308  }
9309 
9311  {
9312  return vector_base_;
9313  }
9314 
9316  {
9317  expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list);
9318  }
9319 
9321  {
9322  return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_);
9323  }
9324 
9325  private:
9326 
9327  vector_assignment_node(const vector_assignment_node<T>&) exprtk_delete;
9328  vector_assignment_node<T>& operator=(const vector_assignment_node<T>&) exprtk_delete;
9329 
9330  mutable T* vector_base_;
9331  std::vector<expression_ptr> initialiser_list_;
9332  const std::size_t size_;
9337  };
9338 
9339  template <typename T>
9340  class swap_node exprtk_final : public expression_node<T>
9341  {
9342  public:
9343 
9345  typedef variable_node<T>* variable_node_ptr;
9346 
9348  : var0_(var0)
9349  , var1_(var1)
9350  {}
9351 
9353  {
9354  std::swap(var0_->ref(),var1_->ref());
9355  return var1_->ref();
9356  }
9357 
9359  {
9361  }
9362 
9363  private:
9364 
9367  };
9368 
9369  template <typename T>
9370  class swap_generic_node exprtk_final : public binary_node<T>
9371  {
9372  public:
9373 
9376 
9378  : binary_node<T>(details::e_swap, var0, var1)
9379  , var0_(dynamic_cast<ivariable_ptr>(var0))
9380  , var1_(dynamic_cast<ivariable_ptr>(var1))
9381  {}
9382 
9384  {
9385  std::swap(var0_->ref(),var1_->ref());
9386  return var1_->ref();
9387  }
9388 
9390  {
9392  }
9393 
9394  private:
9395 
9398  };
9399 
9400  template <typename T>
9401  class swap_vecvec_node exprtk_final
9402  : public binary_node <T>
9403  , public vector_interface<T>
9404  {
9405  public:
9406 
9410 
9411  using binary_node<T>::branch;
9412 
9414  expression_ptr branch1)
9415  : binary_node<T>(details::e_swap, branch0, branch1)
9416  , vec0_node_ptr_(0)
9417  , vec1_node_ptr_(0)
9418  , initialised_ (false)
9419  {
9420  if (is_ivector_node(branch(0)))
9421  {
9422  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
9423 
9424  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
9425  {
9426  vec0_node_ptr_ = vi->vec();
9427  vds() = vi->vds();
9428  }
9429  }
9430 
9431  if (is_ivector_node(branch(1)))
9432  {
9433  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
9434 
9435  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
9436  {
9437  vec1_node_ptr_ = vi->vec();
9438  }
9439  }
9440 
9441  if (vec0_node_ptr_ && vec1_node_ptr_)
9442  {
9443  initialised_ = size() <= base_size();
9444  }
9445 
9446  assert(valid());
9447  }
9448 
9450  {
9451  binary_node<T>::branch(0)->value();
9452  binary_node<T>::branch(1)->value();
9453 
9454  T* vec0 = vec0_node_ptr_->vds().data();
9455  T* vec1 = vec1_node_ptr_->vds().data();
9456 
9457  assert(size() <= base_size());
9458  const std::size_t n = size();
9459 
9460  for (std::size_t i = 0; i < n; ++i)
9461  {
9462  std::swap(vec0[i],vec1[i]);
9463  }
9464 
9465  return vec1_node_ptr_->value();
9466  }
9467 
9469  {
9470  return vec0_node_ptr_;
9471  }
9472 
9474  {
9475  return vec0_node_ptr_;
9476  }
9477 
9479  {
9481  }
9482 
9484  {
9485  return initialised_ && binary_node<T>::valid();
9486  }
9487 
9489  {
9490  return std::min(
9491  vec0_node_ptr_->vec_holder().size(),
9492  vec1_node_ptr_->vec_holder().size());
9493  }
9494 
9496  {
9497  return std::min(
9498  vec0_node_ptr_->vec_holder().base_size(),
9499  vec1_node_ptr_->vec_holder().base_size());
9500  }
9501 
9503  {
9504  return vds_;
9505  }
9506 
9508  {
9509  return vds_;
9510  }
9511 
9512  private:
9513 
9517  vds_t vds_;
9518  };
9519 
9520  #ifndef exprtk_disable_string_capabilities
9521  template <typename T>
9522  class stringvar_node exprtk_final
9523  : public expression_node <T>
9524  , public string_base_node<T>
9525  , public range_interface <T>
9526  {
9527  public:
9528 
9530 
9531  static std::string null_value;
9532 
9533  explicit stringvar_node()
9534  : value_(&null_value)
9535  {}
9536 
9537  explicit stringvar_node(std::string& v)
9538  : value_(&v)
9539  {
9540  rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
9541  rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size());
9542  rp_.cache.first = rp_.n0_c.second;
9543  rp_.cache.second = rp_.n1_c.second;
9544  }
9545 
9546  inline bool operator <(const stringvar_node<T>& v) const
9547  {
9548  return this < (&v);
9549  }
9550 
9552  {
9553  rp_.n1_c.second = (*value_).size();
9554  rp_.cache.second = rp_.n1_c.second;
9555 
9556  return std::numeric_limits<T>::quiet_NaN();
9557  }
9558 
9559  std::string str() const exprtk_override
9560  {
9561  return ref();
9562  }
9563 
9565  {
9566  return &(*value_)[0];
9567  }
9568 
9570  {
9571  return ref().size();
9572  }
9573 
9574  std::string& ref()
9575  {
9576  return (*value_);
9577  }
9578 
9579  const std::string& ref() const
9580  {
9581  return (*value_);
9582  }
9583 
9585  {
9586  return rp_;
9587  }
9588 
9590  {
9591  return rp_;
9592  }
9593 
9595  {
9597  }
9598 
9599  void rebase(std::string& s)
9600  {
9601  value_ = &s;
9602  rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
9603  rp_.n1_c = std::make_pair<bool,std::size_t>(true,value_->size() - 1);
9604  rp_.cache.first = rp_.n0_c.second;
9605  rp_.cache.second = rp_.n1_c.second;
9606  }
9607 
9608  private:
9609 
9610  std::string* value_;
9611  mutable range_t rp_;
9612  };
9613 
9614  template <typename T>
9615  std::string stringvar_node<T>::null_value = std::string("");
9616 
9617  template <typename T>
9618  class string_range_node exprtk_final
9619  : public expression_node <T>
9620  , public string_base_node<T>
9621  , public range_interface <T>
9622  {
9623  public:
9624 
9626 
9627  static std::string null_value;
9628 
9629  explicit string_range_node(std::string& v, const range_t& rp)
9630  : value_(&v)
9631  , rp_(rp)
9632  {}
9633 
9635  {
9636  rp_.free();
9637  }
9638 
9639  inline bool operator <(const string_range_node<T>& v) const
9640  {
9641  return this < (&v);
9642  }
9643 
9645  {
9646  return std::numeric_limits<T>::quiet_NaN();
9647  }
9648 
9649  inline std::string str() const exprtk_override
9650  {
9651  return (*value_);
9652  }
9653 
9655  {
9656  return &(*value_)[0];
9657  }
9658 
9660  {
9661  return ref().size();
9662  }
9663 
9664  inline range_t range() const
9665  {
9666  return rp_;
9667  }
9668 
9669  inline virtual std::string& ref()
9670  {
9671  return (*value_);
9672  }
9673 
9674  inline virtual const std::string& ref() const
9675  {
9676  return (*value_);
9677  }
9678 
9680  {
9681  return rp_;
9682  }
9683 
9685  {
9686  return rp_;
9687  }
9688 
9690  {
9692  }
9693 
9694  private:
9695 
9696  std::string* value_;
9697  range_t rp_;
9698  };
9699 
9700  template <typename T>
9701  std::string string_range_node<T>::null_value = std::string("");
9702 
9703  template <typename T>
9704  class const_string_range_node exprtk_final
9705  : public expression_node <T>
9706  , public string_base_node<T>
9707  , public range_interface <T>
9708  {
9709  public:
9710 
9712 
9713  explicit const_string_range_node(const std::string& v, const range_t& rp)
9714  : value_(v)
9715  , rp_(rp)
9716  {}
9717 
9719  {
9720  rp_.free();
9721  }
9722 
9724  {
9725  return std::numeric_limits<T>::quiet_NaN();
9726  }
9727 
9728  std::string str() const exprtk_override
9729  {
9730  return value_;
9731  }
9732 
9734  {
9735  return value_.data();
9736  }
9737 
9739  {
9740  return value_.size();
9741  }
9742 
9743  range_t range() const
9744  {
9745  return rp_;
9746  }
9747 
9749  {
9750  return rp_;
9751  }
9752 
9754  {
9755  return rp_;
9756  }
9757 
9759  {
9761  }
9762 
9763  private:
9764 
9765  const_string_range_node(const const_string_range_node<T>&) exprtk_delete;
9766  const_string_range_node<T>& operator=(const const_string_range_node<T>&) exprtk_delete;
9767 
9768  const std::string value_;
9769  range_t rp_;
9770  };
9771 
9772  template <typename T>
9773  class generic_string_range_node exprtk_final
9774  : public expression_node <T>
9775  , public string_base_node<T>
9776  , public range_interface <T>
9777  {
9778  public:
9779 
9781  typedef stringvar_node <T>* strvar_node_ptr;
9784  typedef range_t* range_ptr;
9787  typedef std::pair<expression_ptr,bool> branch_t;
9788 
9790  : initialised_(false)
9791  , str_base_ptr_ (0)
9792  , str_range_ptr_(0)
9793  , base_range_(brange)
9794  {
9795  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
9796  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
9797  range_.cache.first = range_.n0_c.second;
9798  range_.cache.second = range_.n1_c.second;
9799 
9800  construct_branch_pair(branch_, str_branch);
9801 
9802  if (is_generally_string_node(branch_.first))
9803  {
9804  str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first);
9805 
9806  if (0 == str_base_ptr_)
9807  return;
9808 
9809  str_range_ptr_ = dynamic_cast<irange_ptr>(branch_.first);
9810 
9811  if (0 == str_range_ptr_)
9812  return;
9813  }
9814 
9815  initialised_ = (str_base_ptr_ && str_range_ptr_);
9816  assert(valid());
9817  }
9818 
9820  {
9821  base_range_.free();
9822  }
9823 
9825  {
9826  branch_.first->value();
9827 
9828  std::size_t str_r0 = 0;
9829  std::size_t str_r1 = 0;
9830 
9831  std::size_t r0 = 0;
9832  std::size_t r1 = 0;
9833 
9834  const range_t& range = str_range_ptr_->range_ref();
9835 
9836  const std::size_t base_str_size = str_base_ptr_->size();
9837 
9838  if (
9839  range (str_r0, str_r1, base_str_size ) &&
9840  base_range_(r0 , r1 , base_str_size - str_r0)
9841  )
9842  {
9843  const std::size_t size = r1 - r0;
9844 
9845  range_.n1_c.second = size;
9846  range_.cache.second = range_.n1_c.second;
9847 
9848  value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
9849  }
9850 
9851  return std::numeric_limits<T>::quiet_NaN();
9852  }
9853 
9854  std::string str() const exprtk_override
9855  {
9856  return value_;
9857  }
9858 
9860  {
9861  return &value_[0];
9862  }
9863 
9865  {
9866  return value_.size();
9867  }
9868 
9870  {
9871  return range_;
9872  }
9873 
9875  {
9876  return range_;
9877  }
9878 
9880  {
9882  }
9883 
9885  {
9886  return initialised_ && branch_.first;
9887  }
9888 
9890  {
9891  expression_node<T>::ndb_t::collect(branch_, node_delete_list);
9892  }
9893 
9895  {
9897  }
9898 
9899  private:
9900 
9901  bool initialised_;
9902  branch_t branch_;
9906  mutable range_t range_;
9907  mutable std::string value_;
9908  };
9909 
9910  template <typename T>
9911  class string_concat_node exprtk_final
9912  : public binary_node <T>
9913  , public string_base_node<T>
9914  , public range_interface <T>
9915  {
9916  public:
9917 
9921  typedef range_t* range_ptr;
9924 
9925  using binary_node<T>::branch;
9926 
9928  expression_ptr branch0,
9929  expression_ptr branch1)
9930  : binary_node<T>(opr, branch0, branch1)
9931  , initialised_(false)
9932  , str0_base_ptr_ (0)
9933  , str1_base_ptr_ (0)
9934  , str0_range_ptr_(0)
9935  , str1_range_ptr_(0)
9936  {
9937  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
9938  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
9939 
9940  range_.cache.first = range_.n0_c.second;
9941  range_.cache.second = range_.n1_c.second;
9942 
9943  if (is_generally_string_node(branch(0)))
9944  {
9945  str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
9946 
9947  if (0 == str0_base_ptr_)
9948  return;
9949 
9950  str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0));
9951 
9952  if (0 == str0_range_ptr_)
9953  return;
9954  }
9955 
9956  if (is_generally_string_node(branch(1)))
9957  {
9958  str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
9959 
9960  if (0 == str1_base_ptr_)
9961  return;
9962 
9963  str1_range_ptr_ = dynamic_cast<irange_ptr>(branch(1));
9964 
9965  if (0 == str1_range_ptr_)
9966  return;
9967  }
9968 
9969  initialised_ = str0_base_ptr_ &&
9970  str1_base_ptr_ &&
9971  str0_range_ptr_ &&
9972  str1_range_ptr_ ;
9973 
9974  assert(valid());
9975  }
9976 
9978  {
9979  branch(0)->value();
9980  branch(1)->value();
9981 
9982  std::size_t str0_r0 = 0;
9983  std::size_t str0_r1 = 0;
9984 
9985  std::size_t str1_r0 = 0;
9986  std::size_t str1_r1 = 0;
9987 
9988  const range_t& range0 = str0_range_ptr_->range_ref();
9989  const range_t& range1 = str1_range_ptr_->range_ref();
9990 
9991  if (
9992  range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
9993  range1(str1_r0, str1_r1, str1_base_ptr_->size())
9994  )
9995  {
9996  const std::size_t size0 = (str0_r1 - str0_r0);
9997  const std::size_t size1 = (str1_r1 - str1_r0);
9998 
9999  value_.assign(str0_base_ptr_->base() + str0_r0, size0);
10000  value_.append(str1_base_ptr_->base() + str1_r0, size1);
10001 
10002  range_.n1_c.second = value_.size();
10003  range_.cache.second = range_.n1_c.second;
10004  }
10005 
10006  return std::numeric_limits<T>::quiet_NaN();
10007  }
10008 
10009  std::string str() const exprtk_override
10010  {
10011  return value_;
10012  }
10013 
10015  {
10016  return &value_[0];
10017  }
10018 
10020  {
10021  return value_.size();
10022  }
10023 
10025  {
10026  return range_;
10027  }
10028 
10030  {
10031  return range_;
10032  }
10033 
10035  {
10037  }
10038 
10040  {
10041  return initialised_ && binary_node<T>::valid();
10042  }
10043 
10044  private:
10045 
10046  bool initialised_;
10051  mutable range_t range_;
10052  mutable std::string value_;
10053  };
10054 
10055  template <typename T>
10056  class swap_string_node exprtk_final
10057  : public binary_node <T>
10058  , public string_base_node<T>
10059  , public range_interface <T>
10060  {
10061  public:
10062 
10064  typedef range_t* range_ptr;
10068  typedef stringvar_node <T>* strvar_node_ptr;
10070 
10071  using binary_node<T>::branch;
10072 
10074  : binary_node<T>(details::e_swap, branch0, branch1)
10075  , initialised_(false)
10076  , str0_node_ptr_(0)
10077  , str1_node_ptr_(0)
10078  {
10079  if (is_string_node(branch(0)))
10080  {
10081  str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0));
10082  }
10083 
10084  if (is_string_node(branch(1)))
10085  {
10086  str1_node_ptr_ = static_cast<strvar_node_ptr>(branch(1));
10087  }
10088 
10089  initialised_ = (str0_node_ptr_ && str1_node_ptr_);
10090  assert(valid());
10091  }
10092 
10094  {
10095  branch(0)->value();
10096  branch(1)->value();
10097 
10098  std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref());
10099 
10100  return std::numeric_limits<T>::quiet_NaN();
10101  }
10102 
10103  std::string str() const exprtk_override
10104  {
10105  return str0_node_ptr_->str();
10106  }
10107 
10109  {
10110  return str0_node_ptr_->base();
10111  }
10112 
10114  {
10115  return str0_node_ptr_->size();
10116  }
10117 
10119  {
10120  return str0_node_ptr_->range_ref();
10121  }
10122 
10124  {
10125  return str0_node_ptr_->range_ref();
10126  }
10127 
10129  {
10131  }
10132 
10134  {
10135  return initialised_ && binary_node<T>::valid();
10136  }
10137 
10138  private:
10139 
10140  bool initialised_;
10143  };
10144 
10145  template <typename T>
10146  class swap_genstrings_node exprtk_final : public binary_node<T>
10147  {
10148  public:
10149 
10151  typedef range_t* range_ptr;
10156 
10157  using binary_node<T>::branch;
10158 
10160  expression_ptr branch1)
10161  : binary_node<T>(details::e_default, branch0, branch1)
10162  , str0_base_ptr_ (0)
10163  , str1_base_ptr_ (0)
10164  , str0_range_ptr_(0)
10165  , str1_range_ptr_(0)
10166  , initialised_(false)
10167  {
10168  if (is_generally_string_node(branch(0)))
10169  {
10170  str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
10171 
10172  if (0 == str0_base_ptr_)
10173  return;
10174 
10175  irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
10176 
10177  if (0 == range)
10178  return;
10179 
10180  str0_range_ptr_ = &(range->range_ref());
10181  }
10182 
10183  if (is_generally_string_node(branch(1)))
10184  {
10185  str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
10186 
10187  if (0 == str1_base_ptr_)
10188  return;
10189 
10190  irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
10191 
10192  if (0 == range)
10193  return;
10194 
10195  str1_range_ptr_ = &(range->range_ref());
10196  }
10197 
10198  initialised_ = str0_base_ptr_ &&
10199  str1_base_ptr_ &&
10200  str0_range_ptr_ &&
10201  str1_range_ptr_ ;
10202 
10203  assert(valid());
10204  }
10205 
10207  {
10208  branch(0)->value();
10209  branch(1)->value();
10210 
10211  std::size_t str0_r0 = 0;
10212  std::size_t str0_r1 = 0;
10213 
10214  std::size_t str1_r0 = 0;
10215  std::size_t str1_r1 = 0;
10216 
10217  const range_t& range0 = (*str0_range_ptr_);
10218  const range_t& range1 = (*str1_range_ptr_);
10219 
10220  if (
10221  range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
10222  range1(str1_r0, str1_r1, str1_base_ptr_->size())
10223  )
10224  {
10225  const std::size_t size0 = range0.cache_size();
10226  const std::size_t size1 = range1.cache_size();
10227  const std::size_t max_size = std::min(size0,size1);
10228 
10229  char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0);
10230  char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0);
10231 
10232  loop_unroll::details lud(max_size);
10233  char_cptr upper_bound = s0 + lud.upper_bound;
10234 
10235  while (s0 < upper_bound)
10236  {
10237  #define exprtk_loop(N) \
10238  std::swap(s0[N], s1[N]); \
10239 
10240  exprtk_loop( 0) exprtk_loop( 1)
10241  exprtk_loop( 2) exprtk_loop( 3)
10242  #ifndef exprtk_disable_superscalar_unroll
10243  exprtk_loop( 4) exprtk_loop( 5)
10244  exprtk_loop( 6) exprtk_loop( 7)
10245  exprtk_loop( 8) exprtk_loop( 9)
10246  exprtk_loop(10) exprtk_loop(11)
10247  exprtk_loop(12) exprtk_loop(13)
10248  exprtk_loop(14) exprtk_loop(15)
10249  #endif
10250 
10251  s0 += lud.batch_size;
10252  s1 += lud.batch_size;
10253  }
10254 
10255  int i = 0;
10256 
10257  switch (lud.remainder)
10258  {
10259  #define case_stmt(N) \
10260  case N : { std::swap(s0[i], s1[i]); ++i; } \
10261  exprtk_fallthrough \
10262 
10263  #ifndef exprtk_disable_superscalar_unroll
10264  case_stmt(15) case_stmt(14)
10265  case_stmt(13) case_stmt(12)
10266  case_stmt(11) case_stmt(10)
10267  case_stmt( 9) case_stmt( 8)
10268  case_stmt( 7) case_stmt( 6)
10269  case_stmt( 5) case_stmt( 4)
10270  #endif
10271  case_stmt( 3) case_stmt( 2)
10272  case_stmt( 1)
10273  default: break;
10274  }
10275 
10276  #undef exprtk_loop
10277  #undef case_stmt
10278  }
10279 
10280  return std::numeric_limits<T>::quiet_NaN();
10281  }
10282 
10284  {
10286  }
10287 
10289  {
10290  return initialised_ && binary_node<T>::valid();
10291  }
10292 
10293  private:
10294 
10295  swap_genstrings_node(const swap_genstrings_node<T>&) exprtk_delete;
10296  swap_genstrings_node<T>& operator=(const swap_genstrings_node<T>&) exprtk_delete;
10297 
10298  str_base_ptr str0_base_ptr_;
10299  str_base_ptr str1_base_ptr_;
10302  bool initialised_;
10303  };
10304 
10305  template <typename T>
10306  class stringvar_size_node exprtk_final : public expression_node<T>
10307  {
10308  public:
10309 
10310  static const std::string null_value;
10311 
10313  : value_(&null_value)
10314  {}
10315 
10316  explicit stringvar_size_node(std::string& v)
10317  : value_(&v)
10318  {}
10319 
10321  {
10322  return T((*value_).size());
10323  }
10324 
10326  {
10328  }
10329 
10330  private:
10331 
10332  const std::string* value_;
10333  };
10334 
10335  template <typename T>
10336  const std::string stringvar_size_node<T>::null_value = std::string("");
10337 
10338  template <typename T>
10339  class string_size_node exprtk_final : public expression_node<T>
10340  {
10341  public:
10342 
10345  typedef std::pair<expression_ptr,bool> branch_t;
10346 
10348  : str_base_ptr_(0)
10349  {
10350  construct_branch_pair(branch_, branch);
10351 
10352  if (is_generally_string_node(branch_.first))
10353  {
10354  str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first);
10355  }
10356 
10357  assert(valid());
10358  }
10359 
10361  {
10362  branch_.first->value();
10363  return T(str_base_ptr_->size());
10364  }
10365 
10367  {
10369  }
10370 
10372  {
10373  return str_base_ptr_;
10374  }
10375 
10377  {
10378  expression_node<T>::ndb_t::collect(branch_, node_delete_list);
10379  }
10380 
10382  {
10384  }
10385 
10386  private:
10387 
10388  branch_t branch_;
10389  str_base_ptr str_base_ptr_;
10390  };
10391 
10393  {
10394  static inline void execute(std::string& s, char_cptr data, const std::size_t size)
10395  { s.assign(data,size); }
10396  };
10397 
10399  {
10400  static inline void execute(std::string& s, char_cptr data, const std::size_t size)
10401  { s.append(data,size); }
10402  };
10403 
10404  template <typename T, typename AssignmentProcess = asn_assignment>
10405  class assignment_string_node exprtk_final
10406  : public binary_node <T>
10407  , public string_base_node<T>
10408  , public range_interface <T>
10409  {
10410  public:
10411 
10413  typedef range_t* range_ptr;
10417  typedef stringvar_node <T>* strvar_node_ptr;
10419 
10420  using binary_node<T>::branch;
10421 
10423  expression_ptr branch0,
10424  expression_ptr branch1)
10425  : binary_node<T>(opr, branch0, branch1)
10426  , initialised_(false)
10427  , str0_base_ptr_ (0)
10428  , str1_base_ptr_ (0)
10429  , str0_node_ptr_ (0)
10430  , str1_range_ptr_(0)
10431  {
10432  if (is_string_node(branch(0)))
10433  {
10434  str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0));
10435  str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
10436  }
10437 
10438  if (is_generally_string_node(branch(1)))
10439  {
10440  str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
10441 
10442  if (0 == str1_base_ptr_)
10443  return;
10444 
10445  irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
10446 
10447  if (0 == range)
10448  return;
10449 
10450  str1_range_ptr_ = &(range->range_ref());
10451  }
10452 
10453  initialised_ = str0_base_ptr_ &&
10454  str1_base_ptr_ &&
10455  str0_node_ptr_ &&
10456  str1_range_ptr_ ;
10457 
10458  assert(valid());
10459  }
10460 
10462  {
10463  branch(1)->value();
10464 
10465  std::size_t r0 = 0;
10466  std::size_t r1 = 0;
10467 
10468  const range_t& range = (*str1_range_ptr_);
10469 
10470  if (range(r0, r1, str1_base_ptr_->size()))
10471  {
10472  AssignmentProcess::execute(
10473  str0_node_ptr_->ref(),
10474  str1_base_ptr_->base() + r0, (r1 - r0));
10475 
10476  branch(0)->value();
10477  }
10478 
10479  return std::numeric_limits<T>::quiet_NaN();
10480  }
10481 
10482  std::string str() const exprtk_override
10483  {
10484  return str0_node_ptr_->str();
10485  }
10486 
10488  {
10489  return str0_node_ptr_->base();
10490  }
10491 
10493  {
10494  return str0_node_ptr_->size();
10495  }
10496 
10498  {
10499  return str0_node_ptr_->range_ref();
10500  }
10501 
10503  {
10504  return str0_node_ptr_->range_ref();
10505  }
10506 
10508  {
10510  }
10511 
10513  {
10514  return initialised_ && binary_node<T>::valid();
10515  }
10516 
10517  private:
10518 
10519  bool initialised_;
10520  str_base_ptr str0_base_ptr_;
10521  str_base_ptr str1_base_ptr_;
10522  strvar_node_ptr str0_node_ptr_;
10523  range_ptr str1_range_ptr_;
10524  };
10525 
10526  template <typename T, typename AssignmentProcess = asn_assignment>
10527  class assignment_string_range_node exprtk_final
10528  : public binary_node <T>
10529  , public string_base_node<T>
10530  , public range_interface <T>
10531  {
10532  public:
10533 
10535  typedef range_t* range_ptr;
10539  typedef stringvar_node <T>* strvar_node_ptr;
10540  typedef string_range_node<T>* str_rng_node_ptr;
10542 
10543  using binary_node<T>::branch;
10544 
10546  expression_ptr branch0,
10547  expression_ptr branch1)
10548  : binary_node<T>(opr, branch0, branch1)
10549  , initialised_(false)
10550  , str0_base_ptr_ (0)
10551  , str1_base_ptr_ (0)
10552  , str0_rng_node_ptr_(0)
10553  , str0_range_ptr_ (0)
10554  , str1_range_ptr_ (0)
10555  {
10556  if (is_string_range_node(branch(0)))
10557  {
10558  str0_rng_node_ptr_ = static_cast<str_rng_node_ptr>(branch(0));
10559  str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
10560  irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
10561 
10562  if (0 == range)
10563  return;
10564 
10565  str0_range_ptr_ = &(range->range_ref());
10566  }
10567 
10568  if (is_generally_string_node(branch(1)))
10569  {
10570  str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
10571 
10572  if (0 == str1_base_ptr_)
10573  return;
10574 
10575  irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
10576 
10577  if (0 == range)
10578  return;
10579 
10580  str1_range_ptr_ = &(range->range_ref());
10581  }
10582 
10583  initialised_ = str0_base_ptr_ &&
10584  str1_base_ptr_ &&
10585  str0_rng_node_ptr_ &&
10586  str0_range_ptr_ &&
10587  str1_range_ptr_ ;
10588 
10589  assert(valid());
10590  }
10591 
10593  {
10594  branch(0)->value();
10595  branch(1)->value();
10596 
10597  std::size_t s0_r0 = 0;
10598  std::size_t s0_r1 = 0;
10599 
10600  std::size_t s1_r0 = 0;
10601  std::size_t s1_r1 = 0;
10602 
10603  const range_t& range0 = (*str0_range_ptr_);
10604  const range_t& range1 = (*str1_range_ptr_);
10605 
10606  if (
10607  range0(s0_r0, s0_r1, str0_base_ptr_->size()) &&
10608  range1(s1_r0, s1_r1, str1_base_ptr_->size())
10609  )
10610  {
10611  const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0));
10612 
10613  std::copy(
10614  str1_base_ptr_->base() + s1_r0,
10615  str1_base_ptr_->base() + s1_r0 + size,
10616  const_cast<char_ptr>(base() + s0_r0));
10617  }
10618 
10619  return std::numeric_limits<T>::quiet_NaN();
10620  }
10621 
10622  std::string str() const exprtk_override
10623  {
10624  return str0_base_ptr_->str();
10625  }
10626 
10628  {
10629  return str0_base_ptr_->base();
10630  }
10631 
10633  {
10634  return str0_base_ptr_->size();
10635  }
10636 
10638  {
10639  return str0_rng_node_ptr_->range_ref();
10640  }
10641 
10643  {
10644  return str0_rng_node_ptr_->range_ref();
10645  }
10646 
10648  {
10650  }
10651 
10653  {
10654  return initialised_ && binary_node<T>::valid();
10655  }
10656 
10657  private:
10658 
10659  bool initialised_;
10660  str_base_ptr str0_base_ptr_;
10661  str_base_ptr str1_base_ptr_;
10663  range_ptr str0_range_ptr_;
10664  range_ptr str1_range_ptr_;
10665  };
10666 
10667  template <typename T>
10668  class conditional_string_node exprtk_final
10669  : public trinary_node <T>
10670  , public string_base_node<T>
10671  , public range_interface <T>
10672  {
10673  public:
10674 
10676  typedef range_t* range_ptr;
10681 
10683  expression_ptr consequent,
10684  expression_ptr alternative)
10685  : trinary_node<T>(details::e_default, consequent, alternative, condition)
10686  , initialised_(false)
10687  , str0_base_ptr_ (0)
10688  , str1_base_ptr_ (0)
10689  , str0_range_ptr_(0)
10690  , str1_range_ptr_(0)
10691  , condition_ (condition )
10692  , consequent_ (consequent )
10693  , alternative_(alternative)
10694  {
10695  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
10696  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
10697 
10698  range_.cache.first = range_.n0_c.second;
10699  range_.cache.second = range_.n1_c.second;
10700 
10702  {
10703  str0_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[0].first);
10704 
10705  if (0 == str0_base_ptr_)
10706  return;
10707 
10708  str0_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[0].first);
10709 
10710  if (0 == str0_range_ptr_)
10711  return;
10712  }
10713 
10715  {
10716  str1_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[1].first);
10717 
10718  if (0 == str1_base_ptr_)
10719  return;
10720 
10721  str1_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[1].first);
10722 
10723  if (0 == str1_range_ptr_)
10724  return;
10725  }
10726 
10727  initialised_ = str0_base_ptr_ &&
10728  str1_base_ptr_ &&
10729  str0_range_ptr_ &&
10730  str1_range_ptr_ ;
10731 
10732  assert(valid());
10733  }
10734 
10736  {
10737  std::size_t r0 = 0;
10738  std::size_t r1 = 0;
10739 
10740  if (is_true(condition_))
10741  {
10742  consequent_->value();
10743 
10744  const range_t& range = str0_range_ptr_->range_ref();
10745 
10746  if (range(r0, r1, str0_base_ptr_->size()))
10747  {
10748  const std::size_t size = (r1 - r0);
10749 
10750  value_.assign(str0_base_ptr_->base() + r0, size);
10751 
10752  range_.n1_c.second = value_.size();
10753  range_.cache.second = range_.n1_c.second;
10754 
10755  return T(1);
10756  }
10757  }
10758  else
10759  {
10760  alternative_->value();
10761 
10762  const range_t& range = str1_range_ptr_->range_ref();
10763 
10764  if (range(r0, r1, str1_base_ptr_->size()))
10765  {
10766  const std::size_t size = (r1 - r0);
10767 
10768  value_.assign(str1_base_ptr_->base() + r0, size);
10769 
10770  range_.n1_c.second = value_.size();
10771  range_.cache.second = range_.n1_c.second;
10772 
10773  return T(0);
10774  }
10775  }
10776 
10777  return std::numeric_limits<T>::quiet_NaN();
10778  }
10779 
10780  std::string str() const exprtk_override
10781  {
10782  return value_;
10783  }
10784 
10786  {
10787  return &value_[0];
10788  }
10789 
10791  {
10792  return value_.size();
10793  }
10794 
10796  {
10797  return range_;
10798  }
10799 
10801  {
10802  return range_;
10803  }
10804 
10806  {
10808  }
10809 
10811  {
10812  return
10813  initialised_ &&
10814  condition_ && condition_ ->valid() &&
10815  consequent_ && consequent_ ->valid() &&
10816  alternative_&& alternative_->valid() ;
10817  }
10818 
10819  private:
10820 
10821  bool initialised_;
10822  str_base_ptr str0_base_ptr_;
10823  str_base_ptr str1_base_ptr_;
10824  irange_ptr str0_range_ptr_;
10825  irange_ptr str1_range_ptr_;
10826  mutable range_t range_;
10827  mutable std::string value_;
10828 
10832  };
10833 
10834  template <typename T>
10835  class cons_conditional_str_node exprtk_final
10836  : public binary_node <T>
10837  , public string_base_node<T>
10838  , public range_interface <T>
10839  {
10840  public:
10841 
10843  typedef range_t* range_ptr;
10848 
10849  using binary_node<T>::branch;
10850 
10852  expression_ptr consequent)
10853  : binary_node<T>(details::e_default, consequent, condition)
10854  , initialised_(false)
10855  , str0_base_ptr_ (0)
10856  , str0_range_ptr_(0)
10857  , condition_ (condition )
10858  , consequent_(consequent)
10859  {
10860  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
10861  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
10862 
10863  range_.cache.first = range_.n0_c.second;
10864  range_.cache.second = range_.n1_c.second;
10865 
10866  if (is_generally_string_node(branch(0)))
10867  {
10868  str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
10869 
10870  if (0 == str0_base_ptr_)
10871  return;
10872 
10873  str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0));
10874 
10875  if (0 == str0_range_ptr_)
10876  return;
10877  }
10878 
10879  initialised_ = str0_base_ptr_ && str0_range_ptr_ ;
10880  assert(valid());
10881  }
10882 
10884  {
10885  if (is_true(condition_))
10886  {
10887  consequent_->value();
10888 
10889  const range_t& range = str0_range_ptr_->range_ref();
10890 
10891  std::size_t r0 = 0;
10892  std::size_t r1 = 0;
10893 
10894  if (range(r0, r1, str0_base_ptr_->size()))
10895  {
10896  const std::size_t size = (r1 - r0);
10897 
10898  value_.assign(str0_base_ptr_->base() + r0, size);
10899 
10900  range_.n1_c.second = value_.size();
10901  range_.cache.second = range_.n1_c.second;
10902 
10903  return T(1);
10904  }
10905  }
10906 
10907  return std::numeric_limits<T>::quiet_NaN();
10908  }
10909 
10910  std::string str() const
10911  {
10912  return value_;
10913  }
10914 
10915  char_cptr base() const
10916  {
10917  return &value_[0];
10918  }
10919 
10920  std::size_t size() const
10921  {
10922  return value_.size();
10923  }
10924 
10926  {
10927  return range_;
10928  }
10929 
10930  const range_t& range_ref() const
10931  {
10932  return range_;
10933  }
10934 
10936  {
10938  }
10939 
10941  {
10942  return
10943  initialised_ &&
10944  condition_ && condition_ ->valid() &&
10945  consequent_ && consequent_ ->valid() ;
10946  }
10947 
10948  private:
10949 
10950  bool initialised_;
10951  str_base_ptr str0_base_ptr_;
10952  irange_ptr str0_range_ptr_;
10953  mutable range_t range_;
10954  mutable std::string value_;
10955 
10956  expression_ptr condition_;
10957  expression_ptr consequent_;
10958  };
10959 
10960  template <typename T, typename VarArgFunction>
10961  class str_vararg_node exprtk_final
10962  : public expression_node <T>
10963  , public string_base_node<T>
10964  , public range_interface <T>
10965  {
10966  public:
10967 
10969  typedef range_t* range_ptr;
10974  typedef std::pair<expression_ptr,bool> branch_t;
10975 
10976  template <typename Allocator,
10977  template <typename, typename> class Sequence>
10978  explicit str_vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
10979  : initialised_(false)
10980  , str_base_ptr_ (0)
10981  , str_range_ptr_(0)
10982  {
10983  construct_branch_pair(final_node_, const_cast<expression_ptr>(arg_list.back()));
10984 
10985  if (0 == final_node_.first)
10986  return;
10987  else if (!is_generally_string_node(final_node_.first))
10988  return;
10989 
10990  str_base_ptr_ = dynamic_cast<str_base_ptr>(final_node_.first);
10991 
10992  if (0 == str_base_ptr_)
10993  return;
10994 
10995  str_range_ptr_ = dynamic_cast<irange_ptr>(final_node_.first);
10996 
10997  if (0 == str_range_ptr_)
10998  return;
10999 
11000  if (arg_list.size() > 1)
11001  {
11002  const std::size_t arg_list_size = arg_list.size() - 1;
11003 
11004  arg_list_.resize(arg_list_size);
11005 
11006  for (std::size_t i = 0; i < arg_list_size; ++i)
11007  {
11008  if (arg_list[i] && arg_list[i]->valid())
11009  {
11010  construct_branch_pair(arg_list_[i], arg_list[i]);
11011  }
11012  else
11013  {
11014  arg_list_.clear();
11015  return;
11016  }
11017  }
11018 
11019  initialised_ = true;
11020  }
11021 
11022  initialised_ &= str_base_ptr_ && str_range_ptr_;
11023  assert(valid());
11024  }
11025 
11027  {
11028  if (!arg_list_.empty())
11029  {
11030  VarArgFunction::process(arg_list_);
11031  }
11032 
11033  final_node_.first->value();
11034 
11035  return std::numeric_limits<T>::quiet_NaN();
11036  }
11037 
11038  std::string str() const exprtk_override
11039  {
11040  return str_base_ptr_->str();
11041  }
11042 
11044  {
11045  return str_base_ptr_->base();
11046  }
11047 
11049  {
11050  return str_base_ptr_->size();
11051  }
11052 
11054  {
11055  return str_range_ptr_->range_ref();
11056  }
11057 
11059  {
11060  return str_range_ptr_->range_ref();
11061  }
11062 
11064  {
11066  }
11067 
11069  {
11070  return
11071  initialised_ &&
11072  final_node_.first && final_node_.first->valid();
11073  }
11074 
11076  {
11077  expression_node<T>::ndb_t::collect(final_node_ , node_delete_list);
11078  expression_node<T>::ndb_t::collect(arg_list_ , node_delete_list);
11079  }
11080 
11082  {
11083  return std::max(
11086  }
11087 
11088  private:
11089 
11090  bool initialised_;
11092  str_base_ptr str_base_ptr_;
11093  irange_ptr str_range_ptr_;
11094  std::vector<branch_t> arg_list_;
11095  };
11096  #endif
11097 
11098  template <typename T, std::size_t N>
11099  inline T axn(const T a, const T x)
11100  {
11101  // a*x^n
11103  }
11104 
11105  template <typename T, std::size_t N>
11106  inline T axnb(const T a, const T x, const T b)
11107  {
11108  // a*x^n+b
11110  }
11111 
11112  template <typename T>
11113  struct sf_base
11114  {
11121  };
11122 
11123  #define define_sfop3(NN, OP0, OP1) \
11124  template <typename T> \
11125  struct sf##NN##_op : public sf_base<T> \
11126  { \
11127  typedef typename sf_base<T>::Type const Type; \
11128  static inline T process(Type x, Type y, Type z) \
11129  { \
11130  return (OP0); \
11131  } \
11132  static inline std::string id() \
11133  { \
11134  return (OP1); \
11135  } \
11136  }; \
11137 
11138  define_sfop3(00,(x + y) / z ,"(t+t)/t")
11139  define_sfop3(01,(x + y) * z ,"(t+t)*t")
11140  define_sfop3(02,(x + y) - z ,"(t+t)-t")
11141  define_sfop3(03,(x + y) + z ,"(t+t)+t")
11142  define_sfop3(04,(x - y) + z ,"(t-t)+t")
11143  define_sfop3(05,(x - y) / z ,"(t-t)/t")
11144  define_sfop3(06,(x - y) * z ,"(t-t)*t")
11145  define_sfop3(07,(x * y) + z ,"(t*t)+t")
11146  define_sfop3(08,(x * y) - z ,"(t*t)-t")
11147  define_sfop3(09,(x * y) / z ,"(t*t)/t")
11148  define_sfop3(10,(x * y) * z ,"(t*t)*t")
11149  define_sfop3(11,(x / y) + z ,"(t/t)+t")
11150  define_sfop3(12,(x / y) - z ,"(t/t)-t")
11151  define_sfop3(13,(x / y) / z ,"(t/t)/t")
11152  define_sfop3(14,(x / y) * z ,"(t/t)*t")
11153  define_sfop3(15,x / (y + z) ,"t/(t+t)")
11154  define_sfop3(16,x / (y - z) ,"t/(t-t)")
11155  define_sfop3(17,x / (y * z) ,"t/(t*t)")
11156  define_sfop3(18,x / (y / z) ,"t/(t/t)")
11157  define_sfop3(19,x * (y + z) ,"t*(t+t)")
11158  define_sfop3(20,x * (y - z) ,"t*(t-t)")
11159  define_sfop3(21,x * (y * z) ,"t*(t*t)")
11160  define_sfop3(22,x * (y / z) ,"t*(t/t)")
11161  define_sfop3(23,x - (y + z) ,"t-(t+t)")
11162  define_sfop3(24,x - (y - z) ,"t-(t-t)")
11163  define_sfop3(25,x - (y / z) ,"t-(t/t)")
11164  define_sfop3(26,x - (y * z) ,"t-(t*t)")
11165  define_sfop3(27,x + (y * z) ,"t+(t*t)")
11166  define_sfop3(28,x + (y / z) ,"t+(t/t)")
11167  define_sfop3(29,x + (y + z) ,"t+(t+t)")
11168  define_sfop3(30,x + (y - z) ,"t+(t-t)")
11169  define_sfop3(31,(axnb<T,2>(x,y,z))," ")
11170  define_sfop3(32,(axnb<T,3>(x,y,z))," ")
11171  define_sfop3(33,(axnb<T,4>(x,y,z))," ")
11172  define_sfop3(34,(axnb<T,5>(x,y,z))," ")
11173  define_sfop3(35,(axnb<T,6>(x,y,z))," ")
11174  define_sfop3(36,(axnb<T,7>(x,y,z))," ")
11175  define_sfop3(37,(axnb<T,8>(x,y,z))," ")
11176  define_sfop3(38,(axnb<T,9>(x,y,z))," ")
11177  define_sfop3(39,x * numeric::log(y) + z,"")
11178  define_sfop3(40,x * numeric::log(y) - z,"")
11179  define_sfop3(41,x * numeric::log10(y) + z,"")
11180  define_sfop3(42,x * numeric::log10(y) - z,"")
11181  define_sfop3(43,x * numeric::sin(y) + z ,"")
11182  define_sfop3(44,x * numeric::sin(y) - z ,"")
11183  define_sfop3(45,x * numeric::cos(y) + z ,"")
11184  define_sfop3(46,x * numeric::cos(y) - z ,"")
11185  define_sfop3(47,details::is_true(x) ? y : z,"")
11186 
11187  #define define_sfop4(NN, OP0, OP1) \
11188  template <typename T> \
11189  struct sf##NN##_op : public sf_base<T> \
11190  { \
11191  typedef typename sf_base<T>::Type const Type; \
11192  static inline T process(Type x, Type y, Type z, Type w) \
11193  { \
11194  return (OP0); \
11195  } \
11196  static inline std::string id() \
11197  { \
11198  return (OP1); \
11199  } \
11200  }; \
11201 
11202  define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)")
11203  define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)")
11204  define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)")
11205  define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)")
11206  define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)")
11207  define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)")
11208  define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)")
11209  define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)")
11210  define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)")
11211  define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)")
11212  define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)")
11213  define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)")
11214  define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)")
11215  define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)")
11216  define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)")
11217  define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)")
11218  define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)")
11219  define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t")
11220  define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t")
11221  define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t")
11222  define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t")
11223  define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t")
11224  define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t")
11225  define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t")
11226  define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t")
11227  define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)")
11228  define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)")
11229  define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)")
11230  define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)")
11231  define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)")
11232  define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)")
11233  define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)")
11234  define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))")
11235  define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))")
11236  define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))")
11237  define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))")
11238 
11239  define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"")
11240  define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"")
11241  define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"")
11242  define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"")
11243  define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"")
11244  define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"")
11245  define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"")
11246  define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"")
11247  define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"")
11248  define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"")
11249  define_sfop4(94,((x < y) ? z : w),"")
11250  define_sfop4(95,((x <= y) ? z : w),"")
11251  define_sfop4(96,((x > y) ? z : w),"")
11252  define_sfop4(97,((x >= y) ? z : w),"")
11253  define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"")
11254  define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"")
11255 
11256  define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)")
11257  define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)")
11258  define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)")
11259  define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)")
11260  define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)")
11261  define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)")
11262  define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)")
11263  define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)")
11264  define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)")
11265  define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)")
11266  define_sfop4(ext10,((x + y) + (z + w)),"(t+t)+(t+t)")
11267  define_sfop4(ext11,((x + y) * (z - w)),"(t+t)*(t-t)")
11268  define_sfop4(ext12,((x + y) / (z - w)),"(t+t)/(t-t)")
11269  define_sfop4(ext13,((x - y) - (z + w)),"(t-t)-(t+t)")
11270  define_sfop4(ext14,((x - y) + (z + w)),"(t-t)+(t+t)")
11271  define_sfop4(ext15,((x - y) * (z + w)),"(t-t)*(t+t)")
11272  define_sfop4(ext16,((x - y) / (z + w)),"(t-t)/(t+t)")
11273  define_sfop4(ext17,((x * y) - (z + w)),"(t*t)-(t+t)")
11274  define_sfop4(ext18,((x / y) - (z + w)),"(t/t)-(t+t)")
11275  define_sfop4(ext19,((x * y) + (z + w)),"(t*t)+(t+t)")
11276  define_sfop4(ext20,((x / y) + (z + w)),"(t/t)+(t+t)")
11277  define_sfop4(ext21,((x * y) + (z - w)),"(t*t)+(t-t)")
11278  define_sfop4(ext22,((x / y) + (z - w)),"(t/t)+(t-t)")
11279  define_sfop4(ext23,((x * y) - (z - w)),"(t*t)-(t-t)")
11280  define_sfop4(ext24,((x / y) - (z - w)),"(t/t)-(t-t)")
11281  define_sfop4(ext25,((x + y) * (z * w)),"(t+t)*(t*t)")
11282  define_sfop4(ext26,((x + y) * (z / w)),"(t+t)*(t/t)")
11283  define_sfop4(ext27,((x + y) / (z * w)),"(t+t)/(t*t)")
11284  define_sfop4(ext28,((x + y) / (z / w)),"(t+t)/(t/t)")
11285  define_sfop4(ext29,((x - y) / (z * w)),"(t-t)/(t*t)")
11286  define_sfop4(ext30,((x - y) / (z / w)),"(t-t)/(t/t)")
11287  define_sfop4(ext31,((x - y) * (z * w)),"(t-t)*(t*t)")
11288  define_sfop4(ext32,((x - y) * (z / w)),"(t-t)*(t/t)")
11289  define_sfop4(ext33,((x * y) * (z + w)),"(t*t)*(t+t)")
11290  define_sfop4(ext34,((x / y) * (z + w)),"(t/t)*(t+t)")
11291  define_sfop4(ext35,((x * y) / (z + w)),"(t*t)/(t+t)")
11292  define_sfop4(ext36,((x / y) / (z + w)),"(t/t)/(t+t)")
11293  define_sfop4(ext37,((x * y) / (z - w)),"(t*t)/(t-t)")
11294  define_sfop4(ext38,((x / y) / (z - w)),"(t/t)/(t-t)")
11295  define_sfop4(ext39,((x * y) * (z - w)),"(t*t)*(t-t)")
11296  define_sfop4(ext40,((x * y) / (z * w)),"(t*t)/(t*t)")
11297  define_sfop4(ext41,((x / y) * (z / w)),"(t/t)*(t/t)")
11298  define_sfop4(ext42,((x / y) * (z - w)),"(t/t)*(t-t)")
11299  define_sfop4(ext43,((x * y) * (z * w)),"(t*t)*(t*t)")
11300  define_sfop4(ext44,(x + (y * (z / w))),"t+(t*(t/t))")
11301  define_sfop4(ext45,(x - (y * (z / w))),"t-(t*(t/t))")
11302  define_sfop4(ext46,(x + (y / (z * w))),"t+(t/(t*t))")
11303  define_sfop4(ext47,(x - (y / (z * w))),"t-(t/(t*t))")
11304  define_sfop4(ext48,(((x - y) - z) * w),"((t-t)-t)*t")
11305  define_sfop4(ext49,(((x - y) - z) / w),"((t-t)-t)/t")
11306  define_sfop4(ext50,(((x - y) + z) * w),"((t-t)+t)*t")
11307  define_sfop4(ext51,(((x - y) + z) / w),"((t-t)+t)/t")
11308  define_sfop4(ext52,((x + (y - z)) * w),"(t+(t-t))*t")
11309  define_sfop4(ext53,((x + (y - z)) / w),"(t+(t-t))/t")
11310  define_sfop4(ext54,((x + y) / (z + w)),"(t+t)/(t+t)")
11311  define_sfop4(ext55,((x - y) / (z - w)),"(t-t)/(t-t)")
11312  define_sfop4(ext56,((x + y) * (z + w)),"(t+t)*(t+t)")
11313  define_sfop4(ext57,((x - y) * (z - w)),"(t-t)*(t-t)")
11314  define_sfop4(ext58,((x - y) + (z - w)),"(t-t)+(t-t)")
11315  define_sfop4(ext59,((x - y) - (z - w)),"(t-t)-(t-t)")
11316  define_sfop4(ext60,((x / y) + (z * w)),"(t/t)+(t*t)")
11317  define_sfop4(ext61,(((x * y) * z) / w),"((t*t)*t)/t")
11318 
11319  #undef define_sfop3
11320  #undef define_sfop4
11321 
11322  template <typename T, typename SpecialFunction>
11323  class sf3_node exprtk_final : public trinary_node<T>
11324  {
11325  public:
11326 
11327  typedef expression_node<T>* expression_ptr;
11328 
11329  sf3_node(const operator_type& opr,
11330  expression_ptr branch0,
11331  expression_ptr branch1,
11332  expression_ptr branch2)
11333  : trinary_node<T>(opr, branch0, branch1, branch2)
11334  {}
11335 
11336  inline T value() const exprtk_override
11337  {
11338  const T x = trinary_node<T>::branch_[0].first->value();
11339  const T y = trinary_node<T>::branch_[1].first->value();
11340  const T z = trinary_node<T>::branch_[2].first->value();
11341 
11342  return SpecialFunction::process(x, y, z);
11343  }
11344  };
11345 
11346  template <typename T, typename SpecialFunction>
11347  class sf4_node exprtk_final : public quaternary_node<T>
11348  {
11349  public:
11350 
11352 
11354  expression_ptr branch0,
11355  expression_ptr branch1,
11356  expression_ptr branch2,
11357  expression_ptr branch3)
11358  : quaternary_node<T>(opr, branch0, branch1, branch2, branch3)
11359  {}
11360 
11362  {
11363  const T x = quaternary_node<T>::branch_[0].first->value();
11364  const T y = quaternary_node<T>::branch_[1].first->value();
11365  const T z = quaternary_node<T>::branch_[2].first->value();
11366  const T w = quaternary_node<T>::branch_[3].first->value();
11367 
11368  return SpecialFunction::process(x, y, z, w);
11369  }
11370  };
11371 
11372  template <typename T, typename SpecialFunction>
11373  class sf3_var_node exprtk_final : public expression_node<T>
11374  {
11375  public:
11376 
11378 
11379  sf3_var_node(const T& v0, const T& v1, const T& v2)
11380  : v0_(v0)
11381  , v1_(v1)
11382  , v2_(v2)
11383  {}
11384 
11386  {
11387  return SpecialFunction::process(v0_, v1_, v2_);
11388  }
11389 
11391  {
11393  }
11394 
11395  private:
11396 
11397  sf3_var_node(const sf3_var_node<T,SpecialFunction>&) exprtk_delete;
11398  sf3_var_node<T,SpecialFunction>& operator=(const sf3_var_node<T,SpecialFunction>&) exprtk_delete;
11399 
11400  const T& v0_;
11401  const T& v1_;
11402  const T& v2_;
11403  };
11404 
11405  template <typename T, typename SpecialFunction>
11406  class sf4_var_node exprtk_final : public expression_node<T>
11407  {
11408  public:
11409 
11411 
11412  sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
11413  : v0_(v0)
11414  , v1_(v1)
11415  , v2_(v2)
11416  , v3_(v3)
11417  {}
11418 
11420  {
11421  return SpecialFunction::process(v0_, v1_, v2_, v3_);
11422  }
11423 
11425  {
11427  }
11428 
11429  private:
11430 
11431  sf4_var_node(const sf4_var_node<T,SpecialFunction>&) exprtk_delete;
11432  sf4_var_node<T,SpecialFunction>& operator=(const sf4_var_node<T,SpecialFunction>&) exprtk_delete;
11433 
11434  const T& v0_;
11435  const T& v1_;
11436  const T& v2_;
11437  const T& v3_;
11438  };
11439 
11440  template <typename T, typename VarArgFunction>
11441  class vararg_node exprtk_final : public expression_node<T>
11442  {
11443  public:
11444 
11446  typedef std::pair<expression_ptr,bool> branch_t;
11447 
11448  template <typename Allocator,
11449  template <typename, typename> class Sequence>
11450  explicit vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
11451  : initialised_(false)
11452  {
11453  arg_list_.resize(arg_list.size());
11454 
11455  for (std::size_t i = 0; i < arg_list.size(); ++i)
11456  {
11457  if (arg_list[i] && arg_list[i]->valid())
11458  {
11459  construct_branch_pair(arg_list_[i],arg_list[i]);
11460  }
11461  else
11462  {
11463  arg_list_.clear();
11464  return;
11465  }
11466  }
11467 
11468  initialised_ = (arg_list_.size() == arg_list.size());
11469  assert(valid());
11470  }
11471 
11473  {
11474  return VarArgFunction::process(arg_list_);
11475  }
11476 
11478  {
11480  }
11481 
11483  {
11484  return initialised_;
11485  }
11486 
11488  {
11489  expression_node<T>::ndb_t::collect(arg_list_, node_delete_list);
11490  }
11491 
11493  {
11495  }
11496 
11497  private:
11498 
11499  std::vector<branch_t> arg_list_;
11500  bool initialised_;
11501  };
11502 
11503  template <typename T, typename VarArgFunction>
11504  class vararg_varnode exprtk_final : public expression_node<T>
11505  {
11506  public:
11507 
11509 
11510  template <typename Allocator,
11511  template <typename, typename> class Sequence>
11512  explicit vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
11513  : initialised_(false)
11514  {
11515  arg_list_.resize(arg_list.size());
11516 
11517  for (std::size_t i = 0; i < arg_list.size(); ++i)
11518  {
11519  if (arg_list[i] && arg_list[i]->valid() && is_variable_node(arg_list[i]))
11520  {
11521  variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]);
11522  arg_list_[i] = (&var_node_ptr->ref());
11523  }
11524  else
11525  {
11526  arg_list_.clear();
11527  return;
11528  }
11529  }
11530 
11531  initialised_ = (arg_list.size() == arg_list_.size());
11532  assert(valid());
11533  }
11534 
11536  {
11537  return VarArgFunction::process(arg_list_);
11538  }
11539 
11541  {
11543  }
11544 
11546  {
11547  return initialised_;
11548  }
11549 
11550  private:
11551 
11552  std::vector<const T*> arg_list_;
11553  bool initialised_;
11554  };
11555 
11556  template <typename T, typename VecFunction>
11557  class vectorize_node exprtk_final : public expression_node<T>
11558  {
11559  public:
11560 
11562  typedef std::pair<expression_ptr,bool> branch_t;
11563 
11564  explicit vectorize_node(const expression_ptr v)
11565  : ivec_ptr_(0)
11566  {
11567  construct_branch_pair(v_, v);
11568 
11569  if (is_ivector_node(v_.first))
11570  {
11571  ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v_.first);
11572  }
11573  }
11574 
11576  {
11577  v_.first->value();
11578  return VecFunction::process(ivec_ptr_);
11579  }
11580 
11582  {
11584  }
11585 
11587  {
11588  return ivec_ptr_ && v_.first && v_.first->valid();
11589  }
11590 
11592  {
11593  expression_node<T>::ndb_t::collect(v_, node_delete_list);
11594  }
11595 
11597  {
11599  }
11600 
11601  private:
11602 
11605  };
11606 
11607  template <typename T>
11608  class assignment_node exprtk_final : public binary_node<T>
11609  {
11610  public:
11611 
11613  using binary_node<T>::branch;
11614 
11616  expression_ptr branch0,
11617  expression_ptr branch1)
11618  : binary_node<T>(opr, branch0, branch1)
11619  , var_node_ptr_(0)
11620  {
11621  if (is_variable_node(branch(0)))
11622  {
11623  var_node_ptr_ = static_cast<variable_node<T>*>(branch(0));
11624  }
11625  }
11626 
11628  {
11629  T& result = var_node_ptr_->ref();
11630  result = branch(1)->value();
11631 
11632  return result;
11633  }
11634 
11636  {
11637  return var_node_ptr_ && binary_node<T>::valid();
11638  }
11639 
11640  private:
11641 
11642  variable_node<T>* var_node_ptr_;
11643  };
11644 
11645  template <typename T>
11646  class assignment_vec_elem_node exprtk_final : public binary_node<T>
11647  {
11648  public:
11649 
11651  using binary_node<T>::branch;
11652 
11654  expression_ptr branch0,
11655  expression_ptr branch1)
11656  : binary_node<T>(opr, branch0, branch1)
11657  , vec_node_ptr_(0)
11658  {
11659  if (is_vector_elem_node(branch(0)))
11660  {
11661  vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
11662  }
11663 
11664  assert(valid());
11665  }
11666 
11668  {
11669  T& result = vec_node_ptr_->ref();
11670  result = branch(1)->value();
11671 
11672  return result;
11673  }
11674 
11676  {
11677  return vec_node_ptr_ && binary_node<T>::valid();
11678  }
11679 
11680  private:
11681 
11682  vector_elem_node<T>* vec_node_ptr_;
11683  };
11684 
11685  template <typename T>
11686  class assignment_vec_elem_rtc_node exprtk_final : public binary_node<T>
11687  {
11688  public:
11689 
11691  using binary_node<T>::branch;
11692 
11694  expression_ptr branch0,
11695  expression_ptr branch1)
11696  : binary_node<T>(opr, branch0, branch1)
11697  , vec_node_ptr_(0)
11698  {
11699  if (is_vector_elem_rtc_node(branch(0)))
11700  {
11701  vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
11702  }
11703 
11704  assert(valid());
11705  }
11706 
11708  {
11709  T& result = vec_node_ptr_->ref();
11710  result = branch(1)->value();
11711 
11712  return result;
11713  }
11714 
11716  {
11717  return vec_node_ptr_ && binary_node<T>::valid();
11718  }
11719 
11720  private:
11721 
11722  vector_elem_rtc_node<T>* vec_node_ptr_;
11723  };
11724 
11725  template <typename T>
11726  class assignment_rebasevec_elem_node exprtk_final : public binary_node<T>
11727  {
11728  public:
11729 
11732 
11734  expression_ptr branch0,
11735  expression_ptr branch1)
11736  : binary_node<T>(opr, branch0, branch1)
11737  , rbvec_node_ptr_(0)
11738  {
11739  if (is_rebasevector_elem_node(branch(0)))
11740  {
11741  rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0));
11742  }
11743 
11744  assert(valid());
11745  }
11746 
11748  {
11749  T& result = rbvec_node_ptr_->ref();
11750  result = branch(1)->value();
11751 
11752  return result;
11753  }
11754 
11756  {
11757  return rbvec_node_ptr_ && binary_node<T>::valid();
11758  }
11759 
11760  private:
11761 
11762  rebasevector_elem_node<T>* rbvec_node_ptr_;
11763  };
11764 
11765  template <typename T>
11766  class assignment_rebasevec_elem_rtc_node exprtk_final : public binary_node<T>
11767  {
11768  public:
11769 
11772 
11774  expression_ptr branch0,
11775  expression_ptr branch1)
11776  : binary_node<T>(opr, branch0, branch1)
11777  , rbvec_node_ptr_(0)
11778  {
11779  if (is_rebasevector_elem_rtc_node(branch(0)))
11780  {
11781  rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0));
11782  }
11783 
11784  assert(valid());
11785  }
11786 
11788  {
11789  T& result = rbvec_node_ptr_->ref();
11790  result = branch(1)->value();
11791 
11792  return result;
11793  }
11794 
11796  {
11797  return rbvec_node_ptr_ && binary_node<T>::valid();
11798  }
11799 
11800  private:
11801 
11802  rebasevector_elem_rtc_node<T>* rbvec_node_ptr_;
11803  };
11804 
11805  template <typename T>
11806  class assignment_rebasevec_celem_node exprtk_final : public binary_node<T>
11807  {
11808  public:
11809 
11811  using binary_node<T>::branch;
11812 
11814  expression_ptr branch0,
11815  expression_ptr branch1)
11816  : binary_node<T>(opr, branch0, branch1)
11817  , rbvec_node_ptr_(0)
11818  {
11819  if (is_rebasevector_celem_node(branch(0)))
11820  {
11821  rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0));
11822  }
11823 
11824  assert(valid());
11825  }
11826 
11828  {
11829  T& result = rbvec_node_ptr_->ref();
11830  result = branch(1)->value();
11831 
11832  return result;
11833  }
11834 
11836  {
11837  return rbvec_node_ptr_ && binary_node<T>::valid();
11838  }
11839 
11840  private:
11841 
11842  rebasevector_celem_node<T>* rbvec_node_ptr_;
11843  };
11844 
11845  template <typename T>
11846  class assignment_vec_node exprtk_final
11847  : public binary_node <T>
11848  , public vector_interface<T>
11849  {
11850  public:
11851 
11855 
11856  using binary_node<T>::branch;
11857 
11859  expression_ptr branch0,
11860  expression_ptr branch1)
11861  : binary_node<T>(opr, branch0, branch1)
11862  , vec_node_ptr_(0)
11863  {
11864  if (is_vector_node(branch(0)))
11865  {
11866  vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
11867  vds() = vec_node_ptr_->vds();
11868  }
11869 
11870  assert(valid());
11871  }
11872 
11874  {
11875  const T v = branch(1)->value();
11876 
11877  T* vec = vds().data();
11878 
11879  loop_unroll::details lud(size());
11880  const T* upper_bound = vec + lud.upper_bound;
11881 
11882  while (vec < upper_bound)
11883  {
11884  #define exprtk_loop(N) \
11885  vec[N] = v; \
11886 
11887  exprtk_loop( 0) exprtk_loop( 1)
11888  exprtk_loop( 2) exprtk_loop( 3)
11889  #ifndef exprtk_disable_superscalar_unroll
11890  exprtk_loop( 4) exprtk_loop( 5)
11891  exprtk_loop( 6) exprtk_loop( 7)
11892  exprtk_loop( 8) exprtk_loop( 9)
11893  exprtk_loop(10) exprtk_loop(11)
11894  exprtk_loop(12) exprtk_loop(13)
11895  exprtk_loop(14) exprtk_loop(15)
11896  #endif
11897 
11898  vec += lud.batch_size;
11899  }
11900 
11901  switch (lud.remainder)
11902  {
11903  #define case_stmt(N) \
11904  case N : *vec++ = v; \
11905  exprtk_fallthrough \
11906 
11907  #ifndef exprtk_disable_superscalar_unroll
11908  case_stmt(15) case_stmt(14)
11909  case_stmt(13) case_stmt(12)
11910  case_stmt(11) case_stmt(10)
11911  case_stmt( 9) case_stmt( 8)
11912  case_stmt( 7) case_stmt( 6)
11913  case_stmt( 5) case_stmt( 4)
11914  #endif
11915  case_stmt( 3) case_stmt( 2)
11916  case 1 : *vec++ = v;
11917  }
11918 
11919  #undef exprtk_loop
11920  #undef case_stmt
11921 
11922  return vec_node_ptr_->value();
11923  }
11924 
11926  {
11927  return vec_node_ptr_;
11928  }
11929 
11931  {
11932  return vec_node_ptr_;
11933  }
11934 
11936  {
11938  }
11939 
11941  {
11942  return
11943  vec_node_ptr_ &&
11944  (vds().size() <= vec_node_ptr_->vec_holder().base_size()) &&
11946  }
11947 
11949  {
11950  return vec_node_ptr_->vec_holder().size();
11951  }
11952 
11954  {
11955  return vec_node_ptr_->vec_holder().base_size();
11956  }
11957 
11959  {
11960  return vds_;
11961  }
11962 
11964  {
11965  return vds_;
11966  }
11967 
11968  private:
11969 
11971  vds_t vds_;
11972  };
11973 
11974  template <typename T>
11975  class assignment_vecvec_node exprtk_final
11976  : public binary_node <T>
11977  , public vector_interface<T>
11978  {
11979  public:
11980 
11984 
11985  using binary_node<T>::branch;
11986 
11988  expression_ptr branch0,
11989  expression_ptr branch1)
11990  : binary_node<T>(opr, branch0, branch1)
11991  , vec0_node_ptr_(0)
11992  , vec1_node_ptr_(0)
11993  , initialised_(false)
11994  , src_is_ivec_(false)
11995  {
11996  if (is_vector_node(branch(0)))
11997  {
11998  vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
11999  vds() = vec0_node_ptr_->vds();
12000  }
12001 
12002  if (is_vector_node(branch(1)))
12003  {
12004  vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1));
12005  vds_t::match_sizes(vds(),vec1_node_ptr_->vds());
12006  }
12007  else if (is_ivector_node(branch(1)))
12008  {
12009  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
12010 
12011  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
12012  {
12013  vec1_node_ptr_ = vi->vec();
12014 
12015  if (!vi->side_effect())
12016  {
12017  vi->vds() = vds();
12018  src_is_ivec_ = true;
12019  }
12020  else
12021  vds_t::match_sizes(vds(),vi->vds());
12022  }
12023  }
12024 
12025  initialised_ =
12026  vec0_node_ptr_ &&
12027  vec1_node_ptr_ &&
12028  (size() <= base_size()) &&
12029  (vds_.size() <= base_size()) &&
12031 
12032  assert(valid());
12033  }
12034 
12036  {
12037  branch(1)->value();
12038 
12039  if (src_is_ivec_)
12040  return vec0_node_ptr_->value();
12041 
12042  T* vec0 = vec0_node_ptr_->vds().data();
12043  T* vec1 = vec1_node_ptr_->vds().data();
12044 
12045  loop_unroll::details lud(size());
12046  const T* upper_bound = vec0 + lud.upper_bound;
12047 
12048  while (vec0 < upper_bound)
12049  {
12050  #define exprtk_loop(N) \
12051  vec0[N] = vec1[N]; \
12052 
12053  exprtk_loop( 0) exprtk_loop( 1)
12054  exprtk_loop( 2) exprtk_loop( 3)
12055  #ifndef exprtk_disable_superscalar_unroll
12056  exprtk_loop( 4) exprtk_loop( 5)
12057  exprtk_loop( 6) exprtk_loop( 7)
12058  exprtk_loop( 8) exprtk_loop( 9)
12059  exprtk_loop(10) exprtk_loop(11)
12060  exprtk_loop(12) exprtk_loop(13)
12061  exprtk_loop(14) exprtk_loop(15)
12062  #endif
12063 
12064  vec0 += lud.batch_size;
12065  vec1 += lud.batch_size;
12066  }
12067 
12068  switch (lud.remainder)
12069  {
12070  #define case_stmt(N,fall_through) \
12071  case N : *vec0++ = *vec1++; \
12072  fall_through \
12073 
12074  #ifndef exprtk_disable_superscalar_unroll
12081  #endif
12083  case_stmt( 1, (void)0;)
12084  }
12085 
12086  #undef exprtk_loop
12087  #undef case_stmt
12088 
12089  return vec0_node_ptr_->value();
12090  }
12091 
12093  {
12094  return vec0_node_ptr_;
12095  }
12096 
12098  {
12099  return vec0_node_ptr_;
12100  }
12101 
12103  {
12105  }
12106 
12108  {
12109  return initialised_;
12110  }
12111 
12113  {
12114  return std::min(
12115  vec0_node_ptr_->vec_holder().size(),
12116  vec1_node_ptr_->vec_holder().size());
12117  }
12118 
12120  {
12121  return std::min(
12122  vec0_node_ptr_->vec_holder().base_size(),
12123  vec1_node_ptr_->vec_holder().base_size());
12124  }
12125 
12127  {
12128  return vds_;
12129  }
12130 
12132  {
12133  return vds_;
12134  }
12135 
12136  private:
12137 
12138  vector_node<T>* vec0_node_ptr_;
12139  vector_node<T>* vec1_node_ptr_;
12140  bool initialised_;
12142  vds_t vds_;
12143  };
12144 
12145  template <typename T, typename Operation>
12146  class assignment_op_node exprtk_final : public binary_node<T>
12147  {
12148  public:
12149 
12151  using binary_node<T>::branch;
12152 
12154  expression_ptr branch0,
12155  expression_ptr branch1)
12156  : binary_node<T>(opr, branch0, branch1)
12157  , var_node_ptr_(0)
12158  {
12159  if (is_variable_node(branch(0)))
12160  {
12161  var_node_ptr_ = static_cast<variable_node<T>*>(branch(0));
12162  }
12163 
12164  assert(valid());
12165  }
12166 
12168  {
12169  T& v = var_node_ptr_->ref();
12170  v = Operation::process(v,branch(1)->value());
12171 
12172  return v;
12173  }
12174 
12176  {
12177  return var_node_ptr_ && binary_node<T>::valid();
12178  }
12179 
12180  private:
12181 
12182  variable_node<T>* var_node_ptr_;
12183  };
12184 
12185  template <typename T, typename Operation>
12186  class assignment_vec_elem_op_node exprtk_final : public binary_node<T>
12187  {
12188  public:
12189 
12191  using binary_node<T>::branch;
12192 
12194  expression_ptr branch0,
12195  expression_ptr branch1)
12196  : binary_node<T>(opr, branch0, branch1)
12197  , vec_node_ptr_(0)
12198  {
12199  if (is_vector_elem_node(branch(0)))
12200  {
12201  vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0));
12202  }
12203 
12204  assert(valid());
12205  }
12206 
12208  {
12209  T& v = vec_node_ptr_->ref();
12210  v = Operation::process(v,branch(1)->value());
12211 
12212  return v;
12213  }
12214 
12216  {
12217  return vec_node_ptr_ && binary_node<T>::valid();
12218  }
12219 
12220  private:
12221 
12222  vector_elem_node<T>* vec_node_ptr_;
12223  };
12224 
12225  template <typename T, typename Operation>
12226  class assignment_vec_elem_op_rtc_node exprtk_final : public binary_node<T>
12227  {
12228  public:
12229 
12231  using binary_node<T>::branch;
12232 
12234  expression_ptr branch0,
12235  expression_ptr branch1)
12236  : binary_node<T>(opr, branch0, branch1)
12237  , vec_node_ptr_(0)
12238  {
12239  if (is_vector_elem_rtc_node(branch(0)))
12240  {
12241  vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0));
12242  }
12243 
12244  assert(valid());
12245  }
12246 
12248  {
12249  T& v = vec_node_ptr_->ref();
12250  v = Operation::process(v,branch(1)->value());
12251 
12252  return v;
12253  }
12254 
12256  {
12257  return vec_node_ptr_ && binary_node<T>::valid();
12258  }
12259 
12260  private:
12261 
12262  vector_elem_rtc_node<T>* vec_node_ptr_;
12263  };
12264 
12265  template <typename T, typename Operation>
12266  class assignment_vec_celem_op_rtc_node exprtk_final : public binary_node<T>
12267  {
12268  public:
12269 
12271  using binary_node<T>::branch;
12272 
12274  expression_ptr branch0,
12275  expression_ptr branch1)
12276  : binary_node<T>(opr, branch0, branch1)
12277  , vec_node_ptr_(0)
12278  {
12279  if (is_vector_celem_rtc_node(branch(0)))
12280  {
12281  vec_node_ptr_ = static_cast<vector_celem_rtc_node<T>*>(branch(0));
12282  }
12283 
12284  assert(valid());
12285  }
12286 
12288  {
12289  T& v = vec_node_ptr_->ref();
12290  v = Operation::process(v,branch(1)->value());
12291 
12292  return v;
12293  }
12294 
12296  {
12297  return vec_node_ptr_ && binary_node<T>::valid();
12298  }
12299 
12300  private:
12301 
12302  vector_celem_rtc_node<T>* vec_node_ptr_;
12303  };
12304 
12305  template <typename T, typename Operation>
12306  class assignment_rebasevec_elem_op_node exprtk_final : public binary_node<T>
12307  {
12308  public:
12309 
12311  using binary_node<T>::branch;
12312 
12314  expression_ptr branch0,
12315  expression_ptr branch1)
12316  : binary_node<T>(opr, branch0, branch1)
12317  , rbvec_node_ptr_(0)
12318  {
12319  if (is_rebasevector_elem_node(branch(0)))
12320  {
12321  rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0));
12322  }
12323 
12324  assert(valid());
12325  }
12326 
12328  {
12329  T& v = rbvec_node_ptr_->ref();
12330  v = Operation::process(v,branch(1)->value());
12331 
12332  return v;
12333  }
12334 
12336  {
12337  return rbvec_node_ptr_ && binary_node<T>::valid();
12338  }
12339 
12340  private:
12341 
12342  rebasevector_elem_node<T>* rbvec_node_ptr_;
12343  };
12344 
12345  template <typename T, typename Operation>
12346  class assignment_rebasevec_celem_op_node exprtk_final : public binary_node<T>
12347  {
12348  public:
12349 
12351  using binary_node<T>::branch;
12352 
12354  expression_ptr branch0,
12355  expression_ptr branch1)
12356  : binary_node<T>(opr, branch0, branch1)
12357  , rbvec_node_ptr_(0)
12358  {
12359  if (is_rebasevector_celem_node(branch(0)))
12360  {
12361  rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0));
12362  }
12363 
12364  assert(valid());
12365  }
12366 
12368  {
12369  T& v = rbvec_node_ptr_->ref();
12370  v = Operation::process(v,branch(1)->value());
12371 
12372  return v;
12373  }
12374 
12376  {
12377  return rbvec_node_ptr_ && binary_node<T>::valid();
12378  }
12379 
12380  private:
12381 
12382  rebasevector_celem_node<T>* rbvec_node_ptr_;
12383  };
12384 
12385  template <typename T, typename Operation>
12386  class assignment_rebasevec_elem_op_rtc_node exprtk_final : public binary_node<T>
12387  {
12388  public:
12389 
12391  using binary_node<T>::branch;
12392 
12394  expression_ptr branch0,
12395  expression_ptr branch1)
12396  : binary_node<T>(opr, branch0, branch1)
12397  , rbvec_node_ptr_(0)
12398  {
12399  if (is_rebasevector_elem_rtc_node(branch(0)))
12400  {
12401  rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0));
12402  }
12403 
12404  assert(valid());
12405  }
12406 
12408  {
12409  T& v = rbvec_node_ptr_->ref();
12410  v = Operation::process(v,branch(1)->value());
12411 
12412  return v;
12413  }
12414 
12416  {
12417  return rbvec_node_ptr_ && binary_node<T>::valid();
12418  }
12419 
12420  private:
12421 
12422  rebasevector_elem_rtc_node<T>* rbvec_node_ptr_;
12423  };
12424 
12425  template <typename T, typename Operation>
12426  class assignment_rebasevec_celem_op_rtc_node exprtk_final : public binary_node<T>
12427  {
12428  public:
12429 
12431  using binary_node<T>::branch;
12432 
12434  expression_ptr branch0,
12435  expression_ptr branch1)
12436  : binary_node<T>(opr, branch0, branch1)
12437  , rbvec_node_ptr_(0)
12438  {
12439  if (is_rebasevector_celem_rtc_node(branch(0)))
12440  {
12441  rbvec_node_ptr_ = static_cast<rebasevector_celem_rtc_node<T>*>(branch(0));
12442  }
12443 
12444  assert(valid());
12445  }
12446 
12448  {
12449  T& v = rbvec_node_ptr_->ref();
12450  v = Operation::process(v,branch(1)->value());
12451 
12452  return v;
12453  }
12454 
12456  {
12457  return rbvec_node_ptr_ && binary_node<T>::valid();
12458  }
12459 
12460  private:
12461 
12462  rebasevector_celem_rtc_node<T>* rbvec_node_ptr_;
12463  };
12464 
12465  template <typename T, typename Operation>
12466  class assignment_vec_op_node exprtk_final
12467  : public binary_node <T>
12468  , public vector_interface<T>
12469  {
12470  public:
12471 
12475 
12476  using binary_node<T>::branch;
12477 
12479  expression_ptr branch0,
12480  expression_ptr branch1)
12481  : binary_node<T>(opr, branch0, branch1)
12482  , vec_node_ptr_(0)
12483  {
12484  if (is_vector_node(branch(0)))
12485  {
12486  vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
12487  vds() = vec_node_ptr_->vds();
12488  }
12489 
12490  assert(valid());
12491  }
12492 
12494  {
12495  const T v = branch(1)->value();
12496 
12497  T* vec = vds().data();
12498 
12499  loop_unroll::details lud(size());
12500  const T* upper_bound = vec + lud.upper_bound;
12501 
12502  while (vec < upper_bound)
12503  {
12504  #define exprtk_loop(N) \
12505  Operation::assign(vec[N],v); \
12506 
12507  exprtk_loop( 0) exprtk_loop( 1)
12508  exprtk_loop( 2) exprtk_loop( 3)
12509  #ifndef exprtk_disable_superscalar_unroll
12510  exprtk_loop( 4) exprtk_loop( 5)
12511  exprtk_loop( 6) exprtk_loop( 7)
12512  exprtk_loop( 8) exprtk_loop( 9)
12513  exprtk_loop(10) exprtk_loop(11)
12514  exprtk_loop(12) exprtk_loop(13)
12515  exprtk_loop(14) exprtk_loop(15)
12516  #endif
12517 
12518  vec += lud.batch_size;
12519  }
12520 
12521  switch (lud.remainder)
12522  {
12523  #define case_stmt(N,fall_through) \
12524  case N : Operation::assign(*vec++,v); \
12525  fall_through \
12526 
12527  #ifndef exprtk_disable_superscalar_unroll
12534  #endif
12536  case_stmt( 1, (void)0;)
12537  }
12538 
12539  #undef exprtk_loop
12540  #undef case_stmt
12541 
12542  return vec_node_ptr_->value();
12543  }
12544 
12546  {
12547  return vec_node_ptr_;
12548  }
12549 
12551  {
12552  return vec_node_ptr_;
12553  }
12554 
12556  {
12558  }
12559 
12561  {
12562  return
12563  vec_node_ptr_ &&
12564  (size() <= base_size()) &&
12566  }
12567 
12569  {
12570  return vec_node_ptr_->vec_holder().size();
12571  }
12572 
12574  {
12575  return vec_node_ptr_->vec_holder().base_size();
12576  }
12577 
12579  {
12580  return vds_;
12581  }
12582 
12584  {
12585  return vds_;
12586  }
12587 
12589  {
12590  return true;
12591  }
12592 
12593  private:
12594 
12595  vector_node<T>* vec_node_ptr_;
12596  vds_t vds_;
12597  };
12598 
12599  template <typename T, typename Operation>
12600  class assignment_vecvec_op_node exprtk_final
12601  : public binary_node <T>
12602  , public vector_interface<T>
12603  {
12604  public:
12605 
12609 
12610  using binary_node<T>::branch;
12611 
12613  expression_ptr branch0,
12614  expression_ptr branch1)
12615  : binary_node<T>(opr, branch0, branch1)
12616  , vec0_node_ptr_(0)
12617  , vec1_node_ptr_(0)
12618  , initialised_(false)
12619  {
12620  if (is_vector_node(branch(0)))
12621  {
12622  vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0));
12623  vds() = vec0_node_ptr_->vds();
12624  }
12625 
12626  if (is_vector_node(branch(1)))
12627  {
12628  vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1));
12629  vec1_node_ptr_->vds() = vds();
12630  }
12631  else if (is_ivector_node(branch(1)))
12632  {
12633  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
12634 
12635  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
12636  {
12637  vec1_node_ptr_ = vi->vec();
12638  vec1_node_ptr_->vds() = vi->vds();
12639  }
12640  else
12641  vds_t::match_sizes(vds(),vec1_node_ptr_->vds());
12642  }
12643 
12644  initialised_ =
12645  vec0_node_ptr_ &&
12646  vec1_node_ptr_ &&
12647  (size() <= base_size()) &&
12649 
12650  assert(valid());
12651  }
12652 
12654  {
12655  branch(0)->value();
12656  branch(1)->value();
12657 
12658  T* vec0 = vec0_node_ptr_->vds().data();
12659  const T* vec1 = vec1_node_ptr_->vds().data();
12660 
12661  loop_unroll::details lud(size());
12662  const T* upper_bound = vec0 + lud.upper_bound;
12663 
12664  while (vec0 < upper_bound)
12665  {
12666  #define exprtk_loop(N) \
12667  vec0[N] = Operation::process(vec0[N], vec1[N]); \
12668 
12669  exprtk_loop( 0) exprtk_loop( 1)
12670  exprtk_loop( 2) exprtk_loop( 3)
12671  #ifndef exprtk_disable_superscalar_unroll
12672  exprtk_loop( 4) exprtk_loop( 5)
12673  exprtk_loop( 6) exprtk_loop( 7)
12674  exprtk_loop( 8) exprtk_loop( 9)
12675  exprtk_loop(10) exprtk_loop(11)
12676  exprtk_loop(12) exprtk_loop(13)
12677  exprtk_loop(14) exprtk_loop(15)
12678  #endif
12679 
12680  vec0 += lud.batch_size;
12681  vec1 += lud.batch_size;
12682  }
12683 
12684  int i = 0;
12685 
12686  switch (lud.remainder)
12687  {
12688  #define case_stmt(N,fall_through) \
12689  case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
12690  fall_through \
12691 
12692  #ifndef exprtk_disable_superscalar_unroll
12699  #endif
12701  case_stmt( 1, (void)0;)
12702  }
12703 
12704  #undef exprtk_loop
12705  #undef case_stmt
12706 
12707  return vec0_node_ptr_->value();
12708  }
12709 
12711  {
12712  return vec0_node_ptr_;
12713  }
12714 
12716  {
12717  return vec0_node_ptr_;
12718  }
12719 
12721  {
12723  }
12724 
12726  {
12727  return initialised_;
12728  }
12729 
12731  {
12732  return std::min(
12733  vec0_node_ptr_->vec_holder().size(),
12734  vec1_node_ptr_->vec_holder().size());
12735  }
12736 
12738  {
12739  return std::min(
12740  vec0_node_ptr_->vec_holder().base_size(),
12741  vec1_node_ptr_->vec_holder().base_size());
12742  }
12743 
12745  {
12746  return vds_;
12747  }
12748 
12750  {
12751  return vds_;
12752  }
12753 
12755  {
12756  return true;
12757  }
12758 
12759  private:
12760 
12761  vector_node<T>* vec0_node_ptr_;
12762  vector_node<T>* vec1_node_ptr_;
12763  bool initialised_;
12764  vds_t vds_;
12765  };
12766 
12767  template <typename T>
12769  {
12773 
12775  : temp_(0)
12776  , temp_vec_node_(0)
12777  {}
12778 
12779  void clear()
12780  {
12781  delete temp_vec_node_;
12782  delete temp_;
12783  }
12784 
12787  };
12788 
12789  template <typename T>
12791  vec_data_store<T>& vds)
12792  {
12793  memory_context_t<T> result_ctxt;
12794  result_ctxt.temp_ = (vec_holder.rebaseable()) ?
12795  new vector_holder<T>(vec_holder,vds) :
12796  new vector_holder<T>(vds) ;
12797  result_ctxt.temp_vec_node_ = new vector_node <T>(vds,result_ctxt.temp_);
12798  return result_ctxt;
12799  }
12800 
12801  template <typename T>
12803  vector_holder<T>& vec_holder1,
12804  vec_data_store<T>& vds)
12805  {
12806  memory_context_t<T> result_ctxt;
12807 
12808  if (!vec_holder0.rebaseable() && !vec_holder1.rebaseable())
12809  result_ctxt.temp_ = new vector_holder<T>(vds);
12810  else if (vec_holder0.rebaseable() && !vec_holder1.rebaseable())
12811  result_ctxt.temp_ = new vector_holder<T>(vec_holder0,vds);
12812  else if (!vec_holder0.rebaseable() && vec_holder1.rebaseable())
12813  result_ctxt.temp_ = new vector_holder<T>(vec_holder1,vds);
12814  else
12815  {
12816  result_ctxt.temp_ = (vec_holder0.base_size() >= vec_holder1.base_size()) ?
12817  new vector_holder<T>(vec_holder0, vds) :
12818  new vector_holder<T>(vec_holder1, vds) ;
12819  }
12820 
12821  result_ctxt.temp_vec_node_ = new vector_node <T>(vds,result_ctxt.temp_);
12822  return result_ctxt;
12823  }
12824 
12825  template <typename T, typename Operation>
12826  class vec_binop_vecvec_node exprtk_final
12827  : public binary_node <T>
12828  , public vector_interface<T>
12829  {
12830  public:
12831 
12838 
12839  using binary_node<T>::branch;
12840 
12842  expression_ptr branch0,
12843  expression_ptr branch1)
12844  : binary_node<T>(opr, branch0, branch1)
12845  , vec0_node_ptr_(0)
12846  , vec1_node_ptr_(0)
12847  , initialised_(false)
12848  {
12849  bool v0_is_ivec = false;
12850  bool v1_is_ivec = false;
12851 
12852  if (is_vector_node(branch(0)))
12853  {
12854  vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
12855  }
12856  else if (is_ivector_node(branch(0)))
12857  {
12858  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
12859 
12860  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
12861  {
12862  vec0_node_ptr_ = vi->vec();
12863  v0_is_ivec = true;
12864  }
12865  }
12866 
12867  if (is_vector_node(branch(1)))
12868  {
12869  vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1));
12870  }
12871  else if (is_ivector_node(branch(1)))
12872  {
12873  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
12874 
12875  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
12876  {
12877  vec1_node_ptr_ = vi->vec();
12878  v1_is_ivec = true;
12879  }
12880  }
12881 
12882  if (vec0_node_ptr_ && vec1_node_ptr_)
12883  {
12884  vector_holder<T>& vec0 = vec0_node_ptr_->vec_holder();
12885  vector_holder<T>& vec1 = vec1_node_ptr_->vec_holder();
12886 
12887  if (v0_is_ivec && (vec0.base_size() <= vec1.base_size()))
12888  {
12889  vds_ = vds_t(vec0_node_ptr_->vds());
12890  }
12891  else if (v1_is_ivec && (vec1.base_size() <= vec0.base_size()))
12892  {
12893  vds_ = vds_t(vec1_node_ptr_->vds());
12894  }
12895  else
12896  {
12897  vds_ = vds_t(std::min(vec0.base_size(),vec1.base_size()));
12898  }
12899 
12900  memory_context_ = make_memory_context(vec0, vec1, vds());
12901 
12902  initialised_ =
12903  (size() <= base_size()) &&
12905  }
12906 
12907  assert(valid());
12908  }
12909 
12911  {
12912  memory_context_.clear();
12913  }
12914 
12916  {
12917  branch(0)->value();
12918  branch(1)->value();
12919 
12920  const T* vec0 = vec0_node_ptr_->vds().data();
12921  const T* vec1 = vec1_node_ptr_->vds().data();
12922  T* vec2 = vds().data();
12923 
12924  loop_unroll::details lud(size());
12925  const T* upper_bound = vec2 + lud.upper_bound;
12926 
12927  while (vec2 < upper_bound)
12928  {
12929  #define exprtk_loop(N) \
12930  vec2[N] = Operation::process(vec0[N], vec1[N]); \
12931 
12932  exprtk_loop( 0) exprtk_loop( 1)
12933  exprtk_loop( 2) exprtk_loop( 3)
12934  #ifndef exprtk_disable_superscalar_unroll
12935  exprtk_loop( 4) exprtk_loop( 5)
12936  exprtk_loop( 6) exprtk_loop( 7)
12937  exprtk_loop( 8) exprtk_loop( 9)
12938  exprtk_loop(10) exprtk_loop(11)
12939  exprtk_loop(12) exprtk_loop(13)
12940  exprtk_loop(14) exprtk_loop(15)
12941  #endif
12942 
12943  vec0 += lud.batch_size;
12944  vec1 += lud.batch_size;
12945  vec2 += lud.batch_size;
12946  }
12947 
12948  int i = 0;
12949 
12950  switch (lud.remainder)
12951  {
12952  #define case_stmt(N) \
12953  case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \
12954  exprtk_fallthrough \
12955 
12956  #ifndef exprtk_disable_superscalar_unroll
12957  case_stmt(15) case_stmt(14)
12958  case_stmt(13) case_stmt(12)
12959  case_stmt(11) case_stmt(10)
12960  case_stmt( 9) case_stmt( 8)
12961  case_stmt( 7) case_stmt( 6)
12962  case_stmt( 5) case_stmt( 4)
12963  #endif
12964  case_stmt( 3) case_stmt( 2)
12965  case_stmt( 1)
12966  default: break;
12967  }
12968 
12969  #undef exprtk_loop
12970  #undef case_stmt
12971 
12972  return (vds().data())[0];
12973  }
12974 
12976  {
12977  return memory_context_.temp_vec_node_;
12978  }
12979 
12981  {
12982  return memory_context_.temp_vec_node_;
12983  }
12984 
12986  {
12988  }
12989 
12991  {
12992  return initialised_;
12993  }
12994 
12996  {
12997  return std::min(
12998  vec0_node_ptr_->vec_holder().size(),
12999  vec1_node_ptr_->vec_holder().size());
13000  }
13001 
13003  {
13004  return std::min(
13005  vec0_node_ptr_->vec_holder().base_size(),
13006  vec1_node_ptr_->vec_holder().base_size());
13007  }
13008 
13010  {
13011  return vds_;
13012  }
13013 
13015  {
13016  return vds_;
13017  }
13018 
13019  private:
13020 
13023  bool initialised_;
13024  vds_t vds_;
13026  };
13027 
13028  template <typename T, typename Operation>
13029  class vec_binop_vecval_node exprtk_final
13030  : public binary_node <T>
13031  , public vector_interface<T>
13032  {
13033  public:
13034 
13041 
13042  using binary_node<T>::branch;
13043 
13045  expression_ptr branch0,
13046  expression_ptr branch1)
13047  : binary_node<T>(opr, branch0, branch1)
13048  , vec0_node_ptr_(0)
13049  {
13050  bool v0_is_ivec = false;
13051 
13052  if (is_vector_node(branch(0)))
13053  {
13054  vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
13055  }
13056  else if (is_ivector_node(branch(0)))
13057  {
13058  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13059 
13060  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
13061  {
13062  vec0_node_ptr_ = vi->vec();
13063  v0_is_ivec = true;
13064  }
13065  }
13066 
13067  if (vec0_node_ptr_)
13068  {
13069  if (v0_is_ivec)
13070  vds() = vec0_node_ptr_->vds();
13071  else
13072  vds() = vds_t(vec0_node_ptr_->base_size());
13073 
13074  memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds());
13075  }
13076 
13077  assert(valid());
13078  }
13079 
13081  {
13082  memory_context_.clear();
13083  }
13084 
13086  {
13087  branch(0)->value();
13088  const T v = branch(1)->value();
13089 
13090  const T* vec0 = vec0_node_ptr_->vds().data();
13091  T* vec1 = vds().data();
13092 
13093  loop_unroll::details lud(size());
13094  const T* upper_bound = vec0 + lud.upper_bound;
13095 
13096  while (vec0 < upper_bound)
13097  {
13098  #define exprtk_loop(N) \
13099  vec1[N] = Operation::process(vec0[N], v); \
13100 
13101  exprtk_loop( 0) exprtk_loop( 1)
13102  exprtk_loop( 2) exprtk_loop( 3)
13103  #ifndef exprtk_disable_superscalar_unroll
13104  exprtk_loop( 4) exprtk_loop( 5)
13105  exprtk_loop( 6) exprtk_loop( 7)
13106  exprtk_loop( 8) exprtk_loop( 9)
13107  exprtk_loop(10) exprtk_loop(11)
13108  exprtk_loop(12) exprtk_loop(13)
13109  exprtk_loop(14) exprtk_loop(15)
13110  #endif
13111 
13112  vec0 += lud.batch_size;
13113  vec1 += lud.batch_size;
13114  }
13115 
13116  int i = 0;
13117 
13118  switch (lud.remainder)
13119  {
13120  #define case_stmt(N,fall_through) \
13121  case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \
13122  fall_through \
13123 
13124  #ifndef exprtk_disable_superscalar_unroll
13131  #endif
13133  case_stmt( 1, (void)0;)
13134  }
13135 
13136  #undef exprtk_loop
13137  #undef case_stmt
13138 
13139  return (vds().data())[0];
13140  }
13141 
13143  {
13144  return memory_context_.temp_vec_node_;
13145  }
13146 
13148  {
13149  return memory_context_.temp_vec_node_;
13150  }
13151 
13153  {
13155  }
13156 
13158  {
13159  return
13160  vec0_node_ptr_ &&
13161  (size() <= base_size()) &&
13163  }
13164 
13166  {
13167  return vec0_node_ptr_->size();
13168  }
13169 
13171  {
13172  return vec0_node_ptr_->vec_holder().base_size();
13173  }
13174 
13176  {
13177  return vds_;
13178  }
13179 
13181  {
13182  return vds_;
13183  }
13184 
13185  private:
13186 
13187  vector_node_ptr vec0_node_ptr_;
13188  vds_t vds_;
13189  memory_context memory_context_;
13190  };
13191 
13192  template <typename T, typename Operation>
13193  class vec_binop_valvec_node exprtk_final
13194  : public binary_node <T>
13195  , public vector_interface<T>
13196  {
13197  public:
13198 
13205 
13206  using binary_node<T>::branch;
13207 
13209  expression_ptr branch0,
13210  expression_ptr branch1)
13211  : binary_node<T>(opr, branch0, branch1)
13212  , vec1_node_ptr_(0)
13213  {
13214  bool v1_is_ivec = false;
13215 
13216  if (is_vector_node(branch(1)))
13217  {
13218  vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1));
13219  }
13220  else if (is_ivector_node(branch(1)))
13221  {
13222  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13223 
13224  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1))))
13225  {
13226  vec1_node_ptr_ = vi->vec();
13227  v1_is_ivec = true;
13228  }
13229  }
13230 
13231  if (vec1_node_ptr_)
13232  {
13233  if (v1_is_ivec)
13234  vds() = vec1_node_ptr_->vds();
13235  else
13236  vds() = vds_t(vec1_node_ptr_->base_size());
13237 
13238  memory_context_ = make_memory_context(vec1_node_ptr_->vec_holder(), vds());
13239  }
13240 
13241  assert(valid());
13242  }
13243 
13245  {
13246  memory_context_.clear();
13247  }
13248 
13250  {
13251  const T v = branch(0)->value();
13252  branch(1)->value();
13253 
13254  T* vec0 = vds().data();
13255  const T* vec1 = vec1_node_ptr_->vds().data();
13256 
13257  loop_unroll::details lud(size());
13258  const T* upper_bound = vec0 + lud.upper_bound;
13259 
13260  while (vec0 < upper_bound)
13261  {
13262  #define exprtk_loop(N) \
13263  vec0[N] = Operation::process(v, vec1[N]); \
13264 
13265  exprtk_loop( 0) exprtk_loop( 1)
13266  exprtk_loop( 2) exprtk_loop( 3)
13267  #ifndef exprtk_disable_superscalar_unroll
13268  exprtk_loop( 4) exprtk_loop( 5)
13269  exprtk_loop( 6) exprtk_loop( 7)
13270  exprtk_loop( 8) exprtk_loop( 9)
13271  exprtk_loop(10) exprtk_loop(11)
13272  exprtk_loop(12) exprtk_loop(13)
13273  exprtk_loop(14) exprtk_loop(15)
13274  #endif
13275 
13276  vec0 += lud.batch_size;
13277  vec1 += lud.batch_size;
13278  }
13279 
13280  int i = 0;
13281 
13282  switch (lud.remainder)
13283  {
13284  #define case_stmt(N,fall_through) \
13285  case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \
13286  fall_through \
13287 
13288  #ifndef exprtk_disable_superscalar_unroll
13295  #endif
13297  case_stmt( 1, (void)0;)
13298  }
13299 
13300  #undef exprtk_loop
13301  #undef case_stmt
13302 
13303  return (vds().data())[0];
13304  }
13305 
13307  {
13308  return memory_context_.temp_vec_node_;
13309  }
13310 
13312  {
13313  return memory_context_.temp_vec_node_;
13314  }
13315 
13317  {
13319  }
13320 
13322  {
13323  return
13324  vec1_node_ptr_ &&
13325  (size() <= base_size()) &&
13326  (vds_.size() <= base_size()) &&
13328  }
13329 
13331  {
13332  return vec1_node_ptr_->vec_holder().size();
13333  }
13334 
13336  {
13337  return vec1_node_ptr_->vec_holder().base_size();
13338  }
13339 
13341  {
13342  return vds_;
13343  }
13344 
13346  {
13347  return vds_;
13348  }
13349 
13350  private:
13351 
13352  vector_node_ptr vec1_node_ptr_;
13353  vds_t vds_;
13354  memory_context memory_context_;
13355  };
13356 
13357  template <typename T, typename Operation>
13358  class unary_vector_node exprtk_final
13359  : public unary_node <T>
13360  , public vector_interface<T>
13361  {
13362  public:
13363 
13370 
13372 
13374  : unary_node<T>(opr, branch0)
13375  , vec0_node_ptr_(0)
13376  {
13377  bool vec0_is_ivec = false;
13378 
13379  if (is_vector_node(branch(0)))
13380  {
13381  vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0));
13382  }
13383  else if (is_ivector_node(branch(0)))
13384  {
13385  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
13386 
13387  if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0))))
13388  {
13389  vec0_node_ptr_ = vi->vec();
13390  vec0_is_ivec = true;
13391  }
13392  }
13393 
13394  if (vec0_node_ptr_)
13395  {
13396  if (vec0_is_ivec)
13397  vds_ = vec0_node_ptr_->vds();
13398  else
13399  vds_ = vds_t(vec0_node_ptr_->base_size());
13400 
13401  memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds());
13402  }
13403 
13404  assert(valid());
13405  }
13406 
13408  {
13409  memory_context_.clear();
13410  }
13411 
13413  {
13414  branch()->value();
13415 
13416  const T* vec0 = vec0_node_ptr_->vds().data();
13417  T* vec1 = vds().data();
13418 
13419  loop_unroll::details lud(size());
13420  const T* upper_bound = vec0 + lud.upper_bound;
13421 
13422  while (vec0 < upper_bound)
13423  {
13424  #define exprtk_loop(N) \
13425  vec1[N] = Operation::process(vec0[N]); \
13426 
13427  exprtk_loop( 0) exprtk_loop( 1)
13428  exprtk_loop( 2) exprtk_loop( 3)
13429  #ifndef exprtk_disable_superscalar_unroll
13430  exprtk_loop( 4) exprtk_loop( 5)
13431  exprtk_loop( 6) exprtk_loop( 7)
13432  exprtk_loop( 8) exprtk_loop( 9)
13433  exprtk_loop(10) exprtk_loop(11)
13434  exprtk_loop(12) exprtk_loop(13)
13435  exprtk_loop(14) exprtk_loop(15)
13436  #endif
13437 
13438  vec0 += lud.batch_size;
13439  vec1 += lud.batch_size;
13440  }
13441 
13442  int i = 0;
13443 
13444  switch (lud.remainder)
13445  {
13446  #define case_stmt(N) \
13447  case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
13448  exprtk_fallthrough \
13449 
13450  #ifndef exprtk_disable_superscalar_unroll
13451  case_stmt(15) case_stmt(14)
13452  case_stmt(13) case_stmt(12)
13453  case_stmt(11) case_stmt(10)
13454  case_stmt( 9) case_stmt( 8)
13455  case_stmt( 7) case_stmt( 6)
13456  case_stmt( 5) case_stmt( 4)
13457  #endif
13458  case_stmt( 3) case_stmt( 2)
13459  case_stmt( 1)
13460  default: break;
13461  }
13462 
13463  #undef exprtk_loop
13464  #undef case_stmt
13465 
13466  return (vds().data())[0];
13467  }
13468 
13470  {
13471  return memory_context_.temp_vec_node_;
13472  }
13473 
13475  {
13476  return memory_context_.temp_vec_node_;
13477  }
13478 
13480  {
13482  }
13483 
13485  {
13486  return vec0_node_ptr_ && unary_node<T>::valid();
13487  }
13488 
13490  {
13491  return vec0_node_ptr_->vec_holder().size();
13492  }
13493 
13495  {
13496  return vec0_node_ptr_->vec_holder().base_size();
13497  }
13498 
13500  {
13501  return vds_;
13502  }
13503 
13505  {
13506  return vds_;
13507  }
13508 
13509  private:
13510 
13511  vector_node_ptr vec0_node_ptr_;
13512  vds_t vds_;
13513  memory_context memory_context_;
13514  };
13515 
13516  template <typename T>
13517  class conditional_vector_node exprtk_final
13518  : public expression_node <T>
13519  , public vector_interface<T>
13520  {
13521  public:
13522 
13530  typedef std::pair<expression_ptr,bool> branch_t;
13531 
13533  expression_ptr consequent,
13534  expression_ptr alternative)
13535  : consequent_node_ptr_ (0)
13536  , alternative_node_ptr_(0)
13537  , temp_vec_node_ (0)
13538  , temp_ (0)
13539  , result_vec_size_ (0)
13540  , initialised_ (false)
13541  {
13542  construct_branch_pair(condition_ , condition );
13543  construct_branch_pair(consequent_ , consequent );
13544  construct_branch_pair(alternative_, alternative);
13545 
13546  if (details::is_ivector_node(consequent_.first))
13547  {
13548  vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(consequent_.first);
13549 
13550  if (0 != ivec_ptr)
13551  {
13552  consequent_node_ptr_ = ivec_ptr->vec();
13553  }
13554  }
13555 
13556  if (details::is_ivector_node(alternative_.first))
13557  {
13558  vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(alternative_.first);
13559 
13560  if (0 != ivec_ptr)
13561  {
13562  alternative_node_ptr_ = ivec_ptr->vec();
13563  }
13564  }
13565 
13566  if (consequent_node_ptr_ && alternative_node_ptr_)
13567  {
13568  const std::size_t vec_size =
13569  std::max(consequent_node_ptr_ ->vec_holder().base_size(),
13570  alternative_node_ptr_->vec_holder().base_size());
13571 
13572  vds_ = vds_t(vec_size);
13573  memory_context_ = make_memory_context(
13574  consequent_node_ptr_ ->vec_holder(),
13575  alternative_node_ptr_->vec_holder(),
13576  vds());
13577 
13578  initialised_ = (vec_size > 0);
13579  }
13580 
13581  assert(initialised_);
13582  }
13583 
13585  {
13586  memory_context_.clear();
13587  }
13588 
13590  {
13591  T result = T(0);
13592  T* source_vector = 0;
13593  T* result_vector = vds().data();
13594 
13595  if (is_true(condition_))
13596  {
13597  result = consequent_.first->value();
13598  source_vector = consequent_node_ptr_->vds().data();
13599  result_vec_size_ = consequent_node_ptr_->size();
13600  }
13601  else
13602  {
13603  result = alternative_.first->value();
13604  source_vector = alternative_node_ptr_->vds().data();
13605  result_vec_size_ = alternative_node_ptr_->size();
13606  }
13607 
13608  for (std::size_t i = 0; i < result_vec_size_; ++i)
13609  {
13610  result_vector[i] = source_vector[i];
13611  }
13612 
13613  return result;
13614  }
13615 
13617  {
13618  return memory_context_.temp_vec_node_;
13619  }
13620 
13622  {
13623  return memory_context_.temp_vec_node_;
13624  }
13625 
13627  {
13629  }
13630 
13632  {
13633  return
13634  initialised_ &&
13635  condition_ .first && condition_ .first->valid() &&
13636  consequent_ .first && consequent_ .first->valid() &&
13637  alternative_.first && alternative_.first->valid() &&
13638  size() <= base_size();
13639  }
13640 
13642  {
13643  return result_vec_size_;
13644  }
13645 
13647  {
13648  return std::min(
13649  consequent_node_ptr_ ->vec_holder().base_size(),
13650  alternative_node_ptr_->vec_holder().base_size());
13651  }
13652 
13654  {
13655  return vds_;
13656  }
13657 
13659  {
13660  return vds_;
13661  }
13662 
13664  {
13665  expression_node<T>::ndb_t::collect(condition_ , node_delete_list);
13666  expression_node<T>::ndb_t::collect(consequent_ , node_delete_list);
13667  expression_node<T>::ndb_t::collect(alternative_ , node_delete_list);
13668  }
13669 
13671  {
13673  (condition_, consequent_, alternative_);
13674  }
13675 
13676  private:
13677 
13678  branch_t condition_;
13679  branch_t consequent_;
13680  branch_t alternative_;
13685  vds_t vds_;
13686  mutable std::size_t result_vec_size_;
13687  bool initialised_;
13688  memory_context memory_context_;
13689  };
13690 
13691  template <typename T>
13692  class scand_node exprtk_final : public binary_node<T>
13693  {
13694  public:
13695 
13697  using binary_node<T>::branch;
13698 
13700  expression_ptr branch0,
13701  expression_ptr branch1)
13702  : binary_node<T>(opr, branch0, branch1)
13703  {
13704  assert(binary_node<T>::valid());
13705  }
13706 
13708  {
13709  return (
13710  std::not_equal_to<T>()
13711  (T(0),branch(0)->value()) &&
13712  std::not_equal_to<T>()
13713  (T(0),branch(1)->value())
13714  ) ? T(1) : T(0);
13715  }
13716  };
13717 
13718  template <typename T>
13719  class scor_node exprtk_final : public binary_node<T>
13720  {
13721  public:
13722 
13724  using binary_node<T>::branch;
13725 
13727  expression_ptr branch0,
13728  expression_ptr branch1)
13729  : binary_node<T>(opr, branch0, branch1)
13730  {
13731  assert(binary_node<T>::valid());
13732  }
13733 
13735  {
13736  return (
13737  std::not_equal_to<T>()
13738  (T(0),branch(0)->value()) ||
13739  std::not_equal_to<T>()
13740  (T(0),branch(1)->value())
13741  ) ? T(1) : T(0);
13742  }
13743  };
13744 
13745  template <typename T, typename IFunction, std::size_t N>
13746  class function_N_node exprtk_final : public expression_node<T>
13747  {
13748  public:
13749 
13750  // Function of N parameters.
13752  typedef std::pair<expression_ptr,bool> branch_t;
13753  typedef IFunction ifunction;
13754 
13755  explicit function_N_node(ifunction* func)
13756  : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
13757  , parameter_count_(func->param_count)
13758  , initialised_(false)
13759  {}
13760 
13761  template <std::size_t NumBranches>
13762  bool init_branches(expression_ptr (&b)[NumBranches])
13763  {
13764  // Needed for incompetent and broken msvc compiler versions
13765  #ifdef _MSC_VER
13766  #pragma warning(push)
13767  #pragma warning(disable: 4127)
13768  #endif
13769 
13770  if (N != NumBranches)
13771  {
13772  return false;
13773  }
13774 
13775  for (std::size_t i = 0; i < NumBranches; ++i)
13776  {
13777  if (b[i] && b[i]->valid())
13778  branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
13779  else
13780  return false;
13781  }
13782 
13783  initialised_ = function_;
13784  assert(valid());
13785  return initialised_;
13786 
13787  #ifdef _MSC_VER
13788  #pragma warning(pop)
13789  #endif
13790  }
13791 
13792  inline bool operator <(const function_N_node<T,IFunction,N>& fn) const
13793  {
13794  return this < (&fn);
13795  }
13796 
13798  {
13799  // Needed for incompetent and broken msvc compiler versions
13800  #ifdef _MSC_VER
13801  #pragma warning(push)
13802  #pragma warning(disable: 4127)
13803  #endif
13804 
13805  T v[N];
13807  return invoke<T,N>::execute(*function_,v);
13808 
13809  #ifdef _MSC_VER
13810  #pragma warning(pop)
13811  #endif
13812  }
13813 
13815  {
13817  }
13818 
13820  {
13821  return initialised_;
13822  }
13823 
13825  {
13826  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
13827  }
13828 
13830  {
13831  return expression_node<T>::ndb_t::template compute_node_depth<N>(branch_);
13832  }
13833 
13834  template <typename T_, std::size_t BranchCount>
13836  {
13837  static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
13838  {
13839  for (std::size_t i = 0; i < BranchCount; ++i)
13840  {
13841  v[i] = b[i].first->value();
13842  }
13843  }
13844  };
13845 
13846  template <typename T_>
13847  struct evaluate_branches <T_,6>
13848  {
13849  static inline void execute(T_ (&v)[6], const branch_t (&b)[6])
13850  {
13851  v[0] = b[0].first->value();
13852  v[1] = b[1].first->value();
13853  v[2] = b[2].first->value();
13854  v[3] = b[3].first->value();
13855  v[4] = b[4].first->value();
13856  v[5] = b[5].first->value();
13857  }
13858  };
13859 
13860  template <typename T_>
13861  struct evaluate_branches <T_,5>
13862  {
13863  static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
13864  {
13865  v[0] = b[0].first->value();
13866  v[1] = b[1].first->value();
13867  v[2] = b[2].first->value();
13868  v[3] = b[3].first->value();
13869  v[4] = b[4].first->value();
13870  }
13871  };
13872 
13873  template <typename T_>
13874  struct evaluate_branches <T_,4>
13875  {
13876  static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
13877  {
13878  v[0] = b[0].first->value();
13879  v[1] = b[1].first->value();
13880  v[2] = b[2].first->value();
13881  v[3] = b[3].first->value();
13882  }
13883  };
13884 
13885  template <typename T_>
13886  struct evaluate_branches <T_,3>
13887  {
13888  static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
13889  {
13890  v[0] = b[0].first->value();
13891  v[1] = b[1].first->value();
13892  v[2] = b[2].first->value();
13893  }
13894  };
13895 
13896  template <typename T_>
13897  struct evaluate_branches <T_,2>
13898  {
13899  static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
13900  {
13901  v[0] = b[0].first->value();
13902  v[1] = b[1].first->value();
13903  }
13904  };
13905 
13906  template <typename T_>
13907  struct evaluate_branches <T_,1>
13908  {
13909  static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
13910  {
13911  v[0] = b[0].first->value();
13912  }
13913  };
13914 
13915  template <typename T_, std::size_t ParamCount>
13916  struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
13917 
13918  template <typename T_>
13919  struct invoke<T_,20>
13920  {
13921  static inline T_ execute(ifunction& f, T_ (&v)[20])
13922  { 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]); }
13923  };
13924 
13925  template <typename T_>
13926  struct invoke<T_,19>
13927  {
13928  static inline T_ execute(ifunction& f, T_ (&v)[19])
13929  { 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]); }
13930  };
13931 
13932  template <typename T_>
13933  struct invoke<T_,18>
13934  {
13935  static inline T_ execute(ifunction& f, T_ (&v)[18])
13936  { 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]); }
13937  };
13938 
13939  template <typename T_>
13940  struct invoke<T_,17>
13941  {
13942  static inline T_ execute(ifunction& f, T_ (&v)[17])
13943  { 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]); }
13944  };
13945 
13946  template <typename T_>
13947  struct invoke<T_,16>
13948  {
13949  static inline T_ execute(ifunction& f, T_ (&v)[16])
13950  { 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]); }
13951  };
13952 
13953  template <typename T_>
13954  struct invoke<T_,15>
13955  {
13956  static inline T_ execute(ifunction& f, T_ (&v)[15])
13957  { 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]); }
13958  };
13959 
13960  template <typename T_>
13961  struct invoke<T_,14>
13962  {
13963  static inline T_ execute(ifunction& f, T_ (&v)[14])
13964  { 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]); }
13965  };
13966 
13967  template <typename T_>
13968  struct invoke<T_,13>
13969  {
13970  static inline T_ execute(ifunction& f, T_ (&v)[13])
13971  { 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]); }
13972  };
13973 
13974  template <typename T_>
13975  struct invoke<T_,12>
13976  {
13977  static inline T_ execute(ifunction& f, T_ (&v)[12])
13978  { 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]); }
13979  };
13980 
13981  template <typename T_>
13982  struct invoke<T_,11>
13983  {
13984  static inline T_ execute(ifunction& f, T_ (&v)[11])
13985  { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10]); }
13986  };
13987 
13988  template <typename T_>
13989  struct invoke<T_,10>
13990  {
13991  static inline T_ execute(ifunction& f, T_ (&v)[10])
13992  { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]); }
13993  };
13994 
13995  template <typename T_>
13996  struct invoke<T_,9>
13997  {
13998  static inline T_ execute(ifunction& f, T_ (&v)[9])
13999  { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); }
14000  };
14001 
14002  template <typename T_>
14003  struct invoke<T_,8>
14004  {
14005  static inline T_ execute(ifunction& f, T_ (&v)[8])
14006  { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); }
14007  };
14008 
14009  template <typename T_>
14010  struct invoke<T_,7>
14011  {
14012  static inline T_ execute(ifunction& f, T_ (&v)[7])
14013  { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6]); }
14014  };
14015 
14016  template <typename T_>
14017  struct invoke<T_,6>
14018  {
14019  static inline T_ execute(ifunction& f, T_ (&v)[6])
14020  { return f(v[0], v[1], v[2], v[3], v[4], v[5]); }
14021  };
14022 
14023  template <typename T_>
14024  struct invoke<T_,5>
14025  {
14026  static inline T_ execute(ifunction& f, T_ (&v)[5])
14027  { return f(v[0], v[1], v[2], v[3], v[4]); }
14028  };
14029 
14030  template <typename T_>
14031  struct invoke<T_,4>
14032  {
14033  static inline T_ execute(ifunction& f, T_ (&v)[4])
14034  { return f(v[0], v[1], v[2], v[3]); }
14035  };
14036 
14037  template <typename T_>
14038  struct invoke<T_,3>
14039  {
14040  static inline T_ execute(ifunction& f, T_ (&v)[3])
14041  { return f(v[0], v[1], v[2]); }
14042  };
14043 
14044  template <typename T_>
14045  struct invoke<T_,2>
14046  {
14047  static inline T_ execute(ifunction& f, T_ (&v)[2])
14048  { return f(v[0], v[1]); }
14049  };
14050 
14051  template <typename T_>
14052  struct invoke<T_,1>
14053  {
14054  static inline T_ execute(ifunction& f, T_ (&v)[1])
14055  { return f(v[0]); }
14056  };
14057 
14058  private:
14059 
14061  std::size_t parameter_count_;
14062  branch_t branch_[N];
14063  bool initialised_;
14064  };
14065 
14066  template <typename T, typename IFunction>
14067  class function_N_node<T,IFunction,0> exprtk_final : public expression_node<T>
14068  {
14069  public:
14070 
14072  typedef IFunction ifunction;
14073 
14074  explicit function_N_node(ifunction* func)
14075  : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
14076  {
14077  assert(valid());
14078  }
14079 
14080  inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
14081  {
14082  return this < (&fn);
14083  }
14084 
14086  {
14087  return (*function_)();
14088  }
14089 
14091  {
14093  }
14094 
14096  {
14097  return function_;
14098  }
14099 
14100  private:
14101 
14102  ifunction* function_;
14103  };
14104 
14105  template <typename T, typename VarArgFunction>
14106  class vararg_function_node exprtk_final : public expression_node<T>
14107  {
14108  public:
14109 
14111 
14112  vararg_function_node(VarArgFunction* func,
14113  const std::vector<expression_ptr>& arg_list)
14114  : function_(func)
14115  , arg_list_(arg_list)
14116  {
14117  value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
14118  assert(valid());
14119  }
14120 
14121  inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const
14122  {
14123  return this < (&fn);
14124  }
14125 
14127  {
14128  populate_value_list();
14129  return (*function_)(value_list_);
14130  }
14131 
14133  {
14135  }
14136 
14138  {
14139  return function_;
14140  }
14141 
14143  {
14144  for (std::size_t i = 0; i < arg_list_.size(); ++i)
14145  {
14146  if (arg_list_[i] && !details::is_variable_node(arg_list_[i]))
14147  {
14148  node_delete_list.push_back(&arg_list_[i]);
14149  }
14150  }
14151  }
14152 
14154  {
14156  }
14157 
14158  private:
14159 
14160  inline void populate_value_list() const
14161  {
14162  for (std::size_t i = 0; i < arg_list_.size(); ++i)
14163  {
14164  value_list_[i] = arg_list_[i]->value();
14165  }
14166  }
14167 
14168  VarArgFunction* function_;
14169  std::vector<expression_ptr> arg_list_;
14170  mutable std::vector<T> value_list_;
14171  };
14172 
14173  template <typename T, typename GenericFunction>
14175  {
14176  public:
14177 
14180  typedef variable_node<T> variable_node_t;
14187 
14188  typedef std::pair<expression_ptr,bool> branch_t;
14191 
14192  typedef std::vector<T> tmp_vs_t;
14193  typedef std::vector<type_store_t> typestore_list_t;
14194  typedef std::vector<range_data_type_t> range_list_t;
14195 
14196  explicit generic_function_node(const std::vector<expression_ptr>& arg_list,
14197  GenericFunction* func = reinterpret_cast<GenericFunction*>(0))
14198  : function_(func)
14199  , arg_list_(arg_list)
14200  {}
14201 
14203  {
14204  for (std::size_t i = 0; i < vv_list_.size(); ++i)
14205  {
14206  vecview_t& vv = vv_list_[i];
14207  if (vv && typestore_list_[i].vec_data)
14208  {
14209  vv->remove_ref(&typestore_list_[i].vec_data);
14210  typestore_list_[i].vec_data = 0;
14211  }
14212  }
14213  }
14214 
14216  {
14217  expression_node<T>::ndb_t::collect(branch_, node_delete_list);
14218  }
14219 
14221  {
14223  }
14224 
14225  virtual bool init_branches()
14226  {
14227  expr_as_vec1_store_.resize(arg_list_.size(), T(0) );
14228  typestore_list_ .resize(arg_list_.size(), type_store_t() );
14229  range_list_ .resize(arg_list_.size(), range_data_type_t());
14230  branch_ .resize(arg_list_.size(), branch_t(reinterpret_cast<expression_ptr>(0),false));
14231  vv_list_ .resize(arg_list_.size(), vecview_t(0));
14232 
14233  for (std::size_t i = 0; i < arg_list_.size(); ++i)
14234  {
14235  type_store_t& ts = typestore_list_[i];
14236 
14237  if (0 == arg_list_[i])
14238  return false;
14239  else if (is_ivector_node(arg_list_[i]))
14240  {
14241  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
14242 
14243  if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i])))
14244  return false;
14245 
14246  ts.size = vi->size();
14247  ts.data = vi->vds().data();
14248  ts.type = type_store_t::e_vector;
14249 
14250  if (
14251  vi->vec()->vec_holder().rebaseable() &&
14252  vi->vec()->vec_holder().rebaseable_instance()
14253  )
14254  {
14255  vv_list_[i] = vi->vec()->vec_holder().rebaseable_instance();
14256  vv_list_[i]->set_ref(&ts.vec_data);
14257  }
14258  }
14259  #ifndef exprtk_disable_string_capabilities
14260  else if (is_generally_string_node(arg_list_[i]))
14261  {
14262  string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0);
14263 
14264  if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i])))
14265  return false;
14266 
14267  ts.size = sbn->size();
14268  ts.data = reinterpret_cast<void*>(const_cast<char_ptr>(sbn->base()));
14269  ts.type = type_store_t::e_string;
14270 
14271  range_list_[i].data = ts.data;
14272  range_list_[i].size = ts.size;
14273  range_list_[i].type_size = sizeof(char);
14274  range_list_[i].str_node = sbn;
14275 
14276  range_interface_t* ri = reinterpret_cast<range_interface_t*>(0);
14277 
14278  if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i])))
14279  return false;
14280 
14281  const range_t& rp = ri->range_ref();
14282 
14283  if (
14284  rp.const_range() &&
14285  is_const_string_range_node(arg_list_[i])
14286  )
14287  {
14288  ts.size = rp.const_size();
14289  ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second;
14290  range_list_[i].range = reinterpret_cast<range_t*>(0);
14291  }
14292  else
14293  {
14294  range_list_[i].range = &(ri->range_ref());
14295  range_param_list_.push_back(i);
14296  }
14297  }
14298  #endif
14299  else if (is_variable_node(arg_list_[i]))
14300  {
14302 
14303  if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i])))
14304  return false;
14305 
14306  ts.size = 1;
14307  ts.data = &var->ref();
14308  ts.type = type_store_t::e_scalar;
14309  }
14310  else
14311  {
14312  ts.size = 1;
14313  ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]);
14314  ts.type = type_store_t::e_scalar;
14315  }
14316 
14317  branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i]));
14318  }
14319 
14320  return true;
14321  }
14322 
14323  inline bool operator <(const generic_function_node<T,GenericFunction>& fn) const
14324  {
14325  return this < (&fn);
14326  }
14327 
14329  {
14330  if (populate_value_list())
14331  {
14332  typedef typename GenericFunction::parameter_list_t parameter_list_t;
14333 
14334  return (*function_)(parameter_list_t(typestore_list_));
14335  }
14336 
14337  return std::numeric_limits<T>::quiet_NaN();
14338  }
14339 
14341  {
14343  }
14344 
14346  {
14347  return function_;
14348  }
14349 
14350  protected:
14351 
14352  inline virtual bool populate_value_list() const
14353  {
14354  for (std::size_t i = 0; i < branch_.size(); ++i)
14355  {
14356  expr_as_vec1_store_[i] = branch_[i].first->value();
14357  }
14358 
14359  if (!range_param_list_.empty())
14360  {
14361  assert(range_param_list_.size() <= branch_.size());
14362 
14363  for (std::size_t i = 0; i < range_param_list_.size(); ++i)
14364  {
14365  const std::size_t index = range_param_list_[i];
14366  range_data_type_t& rdt = range_list_[index];
14367 
14368  const range_t& rp = (*rdt.range);
14369  std::size_t r0 = 0;
14370  std::size_t r1 = 0;
14371 
14372  const std::size_t data_size =
14373  #ifndef exprtk_disable_string_capabilities
14374  rdt.str_node ? rdt.str_node->size() : rdt.size;
14375  #else
14376  rdt.size;
14377  #endif
14378 
14379  if (!rp(r0, r1, data_size))
14380  {
14381  return false;
14382  }
14383 
14384  type_store_t& ts = typestore_list_[index];
14385 
14386  ts.size = rp.cache_size();
14387  #ifndef exprtk_disable_string_capabilities
14388  if (ts.type == type_store_t::e_string)
14389  ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first;
14390  else
14391  #endif
14392  ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size);
14393  }
14394  }
14395 
14396  return true;
14397  }
14398 
14399  GenericFunction* function_;
14401 
14402  private:
14403 
14404  std::vector<expression_ptr> arg_list_;
14405  std::vector<branch_t> branch_;
14406  std::vector<vecview_t> vv_list_;
14409  std::vector<std::size_t> range_param_list_;
14410  };
14411 
14412  #ifndef exprtk_disable_string_capabilities
14413  template <typename T, typename StringFunction>
14414  class string_function_node : public generic_function_node<T,StringFunction>
14415  , public string_base_node<T>
14416  , public range_interface <T>
14417  {
14418  public:
14419 
14422 
14423  string_function_node(StringFunction* func,
14424  const std::vector<typename gen_function_t::expression_ptr>& arg_list)
14425  : gen_function_t(arg_list,func)
14426  {
14427  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
14428  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
14429  range_.cache.first = range_.n0_c.second;
14430  range_.cache.second = range_.n1_c.second;
14431  assert(valid());
14432  }
14433 
14434  inline bool operator <(const string_function_node<T,StringFunction>& fn) const
14435  {
14436  return this < (&fn);
14437  }
14438 
14440  {
14441  if (gen_function_t::populate_value_list())
14442  {
14443  typedef typename StringFunction::parameter_list_t parameter_list_t;
14444 
14445  const T result =
14446  (*gen_function_t::function_)
14447  (
14448  ret_string_,
14449  parameter_list_t(gen_function_t::typestore_list_)
14450  );
14451 
14452  range_.n1_c.second = ret_string_.size();
14453  range_.cache.second = range_.n1_c.second;
14454 
14455  return result;
14456  }
14457 
14458  return std::numeric_limits<T>::quiet_NaN();
14459  }
14460 
14462  {
14464  }
14465 
14467  {
14468  return gen_function_t::function_;
14469  }
14470 
14471  std::string str() const exprtk_override
14472  {
14473  return ret_string_;
14474  }
14475 
14477  {
14478  return &ret_string_[0];
14479  }
14480 
14482  {
14483  return ret_string_.size();
14484  }
14485 
14487  {
14488  return range_;
14489  }
14490 
14492  {
14493  return range_;
14494  }
14495 
14496  protected:
14497 
14498  mutable range_t range_;
14499  mutable std::string ret_string_;
14500  };
14501  #endif
14502 
14503  template <typename T, typename GenericFunction>
14504  class multimode_genfunction_node : public generic_function_node<T,GenericFunction>
14505  {
14506  public:
14507 
14510 
14511  multimode_genfunction_node(GenericFunction* func,
14512  const std::size_t& param_seq_index,
14513  const std::vector<typename gen_function_t::expression_ptr>& arg_list)
14514  : gen_function_t(arg_list,func)
14515  , param_seq_index_(param_seq_index)
14516  {}
14517 
14519  {
14520  assert(gen_function_t::valid());
14521 
14522  if (gen_function_t::populate_value_list())
14523  {
14524  typedef typename GenericFunction::parameter_list_t parameter_list_t;
14525 
14526  return
14527  (*gen_function_t::function_)
14528  (
14529  param_seq_index_,
14530  parameter_list_t(gen_function_t::typestore_list_)
14531  );
14532  }
14533 
14534  return std::numeric_limits<T>::quiet_NaN();
14535  }
14536 
14538  {
14540  }
14541 
14542  private:
14543 
14544  std::size_t param_seq_index_;
14545  };
14546 
14547  #ifndef exprtk_disable_string_capabilities
14548  template <typename T, typename StringFunction>
14549  class multimode_strfunction_node exprtk_final : public string_function_node<T,StringFunction>
14550  {
14551  public:
14552 
14555 
14556  multimode_strfunction_node(StringFunction* func,
14557  const std::size_t& param_seq_index,
14558  const std::vector<typename str_function_t::expression_ptr>& arg_list)
14559  : str_function_t(func,arg_list)
14560  , param_seq_index_(param_seq_index)
14561  {}
14562 
14564  {
14565  if (str_function_t::populate_value_list())
14566  {
14567  typedef typename StringFunction::parameter_list_t parameter_list_t;
14568 
14569  const T result =
14570  (*str_function_t::function_)
14571  (
14572  param_seq_index_,
14573  str_function_t::ret_string_,
14574  parameter_list_t(str_function_t::typestore_list_)
14575  );
14576 
14577  str_function_t::range_.n1_c.second = str_function_t::ret_string_.size();
14578  str_function_t::range_.cache.second = str_function_t::range_.n1_c.second;
14579 
14580  return result;
14581  }
14582 
14583  return std::numeric_limits<T>::quiet_NaN();
14584  }
14585 
14587  {
14589  }
14590 
14591  private:
14592 
14593  const std::size_t param_seq_index_;
14594  };
14595  #endif
14596 
14598 
14599  template <typename T>
14601  {
14602  public:
14603 
14604  virtual ~null_igenfunc()
14605  {}
14606 
14609 
14610  inline virtual T operator() (parameter_list_t)
14611  {
14612  return std::numeric_limits<T>::quiet_NaN();
14613  }
14614  };
14615 
14616  #ifndef exprtk_disable_return_statement
14617  template <typename T>
14618  class return_node exprtk_final : public generic_function_node<T,null_igenfunc<T> >
14619  {
14620  public:
14621 
14626 
14627  return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list,
14628  results_context_t& rc)
14629  : gen_function_t (arg_list)
14630  , results_context_(&rc)
14631  {}
14632 
14634  {
14635  if (
14636  (0 != results_context_) &&
14637  gen_function_t::populate_value_list()
14638  )
14639  {
14640  typedef typename type_store<T>::parameter_list parameter_list_t;
14641 
14642  results_context_->
14643  assign(parameter_list_t(gen_function_t::typestore_list_));
14644 
14645  throw return_exception();
14646  }
14647 
14648  return std::numeric_limits<T>::quiet_NaN();
14649  }
14650 
14652  {
14654  }
14655 
14657  {
14658  return results_context_;
14659  }
14660 
14661  private:
14662 
14664  };
14665 
14666  template <typename T>
14668  {
14669  public:
14670 
14673  typedef std::pair<expression_ptr,bool> branch_t;
14674 
14676  : results_context_(&rc )
14677  , return_invoked_ (false)
14678  {
14679  construct_branch_pair(body_, body);
14680  assert(valid());
14681  }
14682 
14684  {
14685  try
14686  {
14687  return_invoked_ = false;
14688  results_context_->clear();
14689 
14690  return body_.first->value();
14691  }
14692  catch(const return_exception&)
14693  {
14694  return_invoked_ = true;
14695 
14696  return std::numeric_limits<T>::quiet_NaN();
14697  }
14698  }
14699 
14701  {
14703  }
14704 
14706  {
14707  return results_context_ && body_.first;
14708  }
14709 
14710  inline bool* retinvk_ptr()
14711  {
14712  return &return_invoked_;
14713  }
14714 
14716  {
14717  expression_node<T>::ndb_t::collect(body_, node_delete_list);
14718  }
14719 
14721  {
14723  }
14724 
14725  private:
14726 
14727  results_context_t* results_context_;
14728  mutable bool return_invoked_;
14730  };
14731  #endif
14732 
14733  #define exprtk_define_unary_op(OpName) \
14734  template <typename T> \
14735  struct OpName##_op \
14736  { \
14737  typedef typename functor_t<T>::Type Type; \
14738  typedef typename expression_node<T>::node_type node_t; \
14739  \
14740  static inline T process(Type v) \
14741  { \
14742  return numeric:: OpName (v); \
14743  } \
14744  \
14745  static inline node_t type() \
14746  { \
14747  return expression_node<T>::e_##OpName; \
14748  } \
14749  \
14750  static inline details::operator_type operation() \
14751  { \
14752  return details::e_##OpName; \
14753  } \
14754  }; \
14755 
14757  exprtk_define_unary_op(acos )
14758  exprtk_define_unary_op(acosh)
14759  exprtk_define_unary_op(asin )
14760  exprtk_define_unary_op(asinh)
14761  exprtk_define_unary_op(atan )
14762  exprtk_define_unary_op(atanh)
14763  exprtk_define_unary_op(ceil )
14765  exprtk_define_unary_op(cosh )
14771  exprtk_define_unary_op(erfc )
14773  exprtk_define_unary_op(expm1)
14774  exprtk_define_unary_op(floor)
14775  exprtk_define_unary_op(frac )
14778  exprtk_define_unary_op(log10)
14780  exprtk_define_unary_op(log1p)
14781  exprtk_define_unary_op(ncdf )
14783  exprtk_define_unary_op(notl )
14786  exprtk_define_unary_op(round)
14790  exprtk_define_unary_op(sinc )
14791  exprtk_define_unary_op(sinh )
14792  exprtk_define_unary_op(sqrt )
14794  exprtk_define_unary_op(tanh )
14795  exprtk_define_unary_op(trunc)
14796  #undef exprtk_define_unary_op
14797 
14798  template <typename T>
14799  struct opr_base
14800  {
14801  typedef typename details::functor_t<T>::Type Type;
14802  typedef typename details::functor_t<T>::RefType RefType;
14803  typedef typename details::functor_t<T> functor_t;
14804  typedef typename functor_t::qfunc_t quaternary_functor_t;
14805  typedef typename functor_t::tfunc_t trinary_functor_t;
14806  typedef typename functor_t::bfunc_t binary_functor_t;
14807  typedef typename functor_t::ufunc_t unary_functor_t;
14808  };
14809 
14810  template <typename T>
14811  struct add_op : public opr_base<T>
14812  {
14813  typedef typename opr_base<T>::Type Type;
14814  typedef typename opr_base<T>::RefType RefType;
14815 
14816  static inline T process(Type t1, Type t2) { return t1 + t2; }
14817  static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; }
14818  static inline void assign(RefType t1, Type t2) { t1 += t2; }
14819  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; }
14821  };
14822 
14823  template <typename T>
14824  struct mul_op : public opr_base<T>
14825  {
14826  typedef typename opr_base<T>::Type Type;
14827  typedef typename opr_base<T>::RefType RefType;
14828 
14829  static inline T process(Type t1, Type t2) { return t1 * t2; }
14830  static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; }
14831  static inline void assign(RefType t1, Type t2) { t1 *= t2; }
14832  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; }
14834  };
14835 
14836  template <typename T>
14837  struct sub_op : public opr_base<T>
14838  {
14839  typedef typename opr_base<T>::Type Type;
14840  typedef typename opr_base<T>::RefType RefType;
14841 
14842  static inline T process(Type t1, Type t2) { return t1 - t2; }
14843  static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; }
14844  static inline void assign(RefType t1, Type t2) { t1 -= t2; }
14845  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; }
14847  };
14848 
14849  template <typename T>
14850  struct div_op : public opr_base<T>
14851  {
14852  typedef typename opr_base<T>::Type Type;
14853  typedef typename opr_base<T>::RefType RefType;
14854 
14855  static inline T process(Type t1, Type t2) { return t1 / t2; }
14856  static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; }
14857  static inline void assign(RefType t1, Type t2) { t1 /= t2; }
14858  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; }
14860  };
14861 
14862  template <typename T>
14863  struct mod_op : public opr_base<T>
14864  {
14865  typedef typename opr_base<T>::Type Type;
14866  typedef typename opr_base<T>::RefType RefType;
14867 
14868  static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
14869  static inline void assign(RefType t1, Type t2) { t1 = numeric::modulus<T>(t1,t2); }
14870  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; }
14872  };
14873 
14874  template <typename T>
14875  struct pow_op : public opr_base<T>
14876  {
14877  typedef typename opr_base<T>::Type Type;
14878  typedef typename opr_base<T>::RefType RefType;
14879 
14880  static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
14881  static inline void assign(RefType t1, Type t2) { t1 = numeric::pow<T>(t1,t2); }
14882  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; }
14884  };
14885 
14886  template <typename T>
14887  struct lt_op : public opr_base<T>
14888  {
14889  typedef typename opr_base<T>::Type Type;
14890 
14891  static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); }
14892  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
14893  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; }
14894  static inline details::operator_type operation() { return details::e_lt; }
14895  };
14896 
14897  template <typename T>
14898  struct lte_op : public opr_base<T>
14899  {
14900  typedef typename opr_base<T>::Type Type;
14901 
14902  static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); }
14903  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
14904  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; }
14906  };
14907 
14908  template <typename T>
14909  struct gt_op : public opr_base<T>
14910  {
14911  typedef typename opr_base<T>::Type Type;
14912 
14913  static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); }
14914  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
14915  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; }
14916  static inline details::operator_type operation() { return details::e_gt; }
14917  };
14918 
14919  template <typename T>
14920  struct gte_op : public opr_base<T>
14921  {
14922  typedef typename opr_base<T>::Type Type;
14923 
14924  static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); }
14925  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
14926  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; }
14928  };
14929 
14930  template <typename T>
14931  struct eq_op : public opr_base<T>
14932  {
14933  typedef typename opr_base<T>::Type Type;
14934  static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); }
14935  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
14936  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
14937  static inline details::operator_type operation() { return details::e_eq; }
14938  };
14939 
14940  template <typename T>
14941  struct equal_op : public opr_base<T>
14942  {
14943  typedef typename opr_base<T>::Type Type;
14944 
14945  static inline T process(Type t1, Type t2) { return numeric::equal(t1,t2); }
14946  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
14947  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
14949  };
14950 
14951  template <typename T>
14952  struct ne_op : public opr_base<T>
14953  {
14954  typedef typename opr_base<T>::Type Type;
14955 
14956  static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); }
14957  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
14958  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; }
14959  static inline details::operator_type operation() { return details::e_ne; }
14960  };
14961 
14962  template <typename T>
14963  struct and_op : public opr_base<T>
14964  {
14965  typedef typename opr_base<T>::Type Type;
14966 
14967  static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
14968  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; }
14970  };
14971 
14972  template <typename T>
14973  struct nand_op : public opr_base<T>
14974  {
14975  typedef typename opr_base<T>::Type Type;
14976 
14977  static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
14980  };
14981 
14982  template <typename T>
14983  struct or_op : public opr_base<T>
14984  {
14985  typedef typename opr_base<T>::Type Type;
14986 
14987  static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
14988  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; }
14989  static inline details::operator_type operation() { return details::e_or; }
14990  };
14991 
14992  template <typename T>
14993  struct nor_op : public opr_base<T>
14994  {
14995  typedef typename opr_base<T>::Type Type;
14996 
14997  static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
14998  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
15000  };
15001 
15002  template <typename T>
15003  struct xor_op : public opr_base<T>
15004  {
15005  typedef typename opr_base<T>::Type Type;
15006 
15007  static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); }
15008  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
15010  };
15011 
15012  template <typename T>
15013  struct xnor_op : public opr_base<T>
15014  {
15015  typedef typename opr_base<T>::Type Type;
15016 
15017  static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); }
15018  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
15020  };
15021 
15022  template <typename T>
15023  struct in_op : public opr_base<T>
15024  {
15025  typedef typename opr_base<T>::Type Type;
15026 
15027  static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
15028  static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
15029  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; }
15030  static inline details::operator_type operation() { return details::e_in; }
15031  };
15032 
15033  template <typename T>
15034  struct like_op : public opr_base<T>
15035  {
15036  typedef typename opr_base<T>::Type Type;
15037 
15038  static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
15039  static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
15042  };
15043 
15044  template <typename T>
15045  struct ilike_op : public opr_base<T>
15046  {
15047  typedef typename opr_base<T>::Type Type;
15048 
15049  static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
15050  static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
15053  };
15054 
15055  template <typename T>
15056  struct inrange_op : public opr_base<T>
15057  {
15058  typedef typename opr_base<T>::Type Type;
15059 
15060  static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
15061  static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
15062  {
15063  return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0);
15064  }
15067  };
15068 
15069  template <typename T>
15071  {
15072  return n->value();
15073  }
15074 
15075  template <typename T>
15076  inline T value(std::pair<details::expression_node<T>*,bool> n)
15077  {
15078  return n.first->value();
15079  }
15080 
15081  template <typename T>
15082  inline T value(const T* t)
15083  {
15084  return (*t);
15085  }
15086 
15087  template <typename T>
15088  inline T value(const T& t)
15089  {
15090  return t;
15091  }
15092 
15093  template <typename T>
15094  struct vararg_add_op exprtk_final : public opr_base<T>
15095  {
15096  typedef typename opr_base<T>::Type Type;
15097 
15098  template <typename Type,
15099  typename Allocator,
15100  template <typename, typename> class Sequence>
15101  static inline T process(const Sequence<Type,Allocator>& arg_list)
15102  {
15103  switch (arg_list.size())
15104  {
15105  case 0 : return T(0);
15106  case 1 : return process_1(arg_list);
15107  case 2 : return process_2(arg_list);
15108  case 3 : return process_3(arg_list);
15109  case 4 : return process_4(arg_list);
15110  case 5 : return process_5(arg_list);
15111  default :
15112  {
15113  T result = T(0);
15114 
15115  for (std::size_t i = 0; i < arg_list.size(); ++i)
15116  {
15117  result += value(arg_list[i]);
15118  }
15119 
15120  return result;
15121  }
15122  }
15123  }
15124 
15125  template <typename Sequence>
15126  static inline T process_1(const Sequence& arg_list)
15127  {
15128  return value(arg_list[0]);
15129  }
15130 
15131  template <typename Sequence>
15132  static inline T process_2(const Sequence& arg_list)
15133  {
15134  return value(arg_list[0]) + value(arg_list[1]);
15135  }
15136 
15137  template <typename Sequence>
15138  static inline T process_3(const Sequence& arg_list)
15139  {
15140  return value(arg_list[0]) + value(arg_list[1]) +
15141  value(arg_list[2]) ;
15142  }
15143 
15144  template <typename Sequence>
15145  static inline T process_4(const Sequence& arg_list)
15146  {
15147  return value(arg_list[0]) + value(arg_list[1]) +
15148  value(arg_list[2]) + value(arg_list[3]) ;
15149  }
15150 
15151  template <typename Sequence>
15152  static inline T process_5(const Sequence& arg_list)
15153  {
15154  return value(arg_list[0]) + value(arg_list[1]) +
15155  value(arg_list[2]) + value(arg_list[3]) +
15156  value(arg_list[4]) ;
15157  }
15158  };
15159 
15160  template <typename T>
15161  struct vararg_mul_op exprtk_final : public opr_base<T>
15162  {
15163  typedef typename opr_base<T>::Type Type;
15164 
15165  template <typename Type,
15166  typename Allocator,
15167  template <typename, typename> class Sequence>
15168  static inline T process(const Sequence<Type,Allocator>& arg_list)
15169  {
15170  switch (arg_list.size())
15171  {
15172  case 0 : return T(0);
15173  case 1 : return process_1(arg_list);
15174  case 2 : return process_2(arg_list);
15175  case 3 : return process_3(arg_list);
15176  case 4 : return process_4(arg_list);
15177  case 5 : return process_5(arg_list);
15178  default :
15179  {
15180  T result = T(value(arg_list[0]));
15181 
15182  for (std::size_t i = 1; i < arg_list.size(); ++i)
15183  {
15184  result *= value(arg_list[i]);
15185  }
15186 
15187  return result;
15188  }
15189  }
15190  }
15191 
15192  template <typename Sequence>
15193  static inline T process_1(const Sequence& arg_list)
15194  {
15195  return value(arg_list[0]);
15196  }
15197 
15198  template <typename Sequence>
15199  static inline T process_2(const Sequence& arg_list)
15200  {
15201  return value(arg_list[0]) * value(arg_list[1]);
15202  }
15203 
15204  template <typename Sequence>
15205  static inline T process_3(const Sequence& arg_list)
15206  {
15207  return value(arg_list[0]) * value(arg_list[1]) *
15208  value(arg_list[2]) ;
15209  }
15210 
15211  template <typename Sequence>
15212  static inline T process_4(const Sequence& arg_list)
15213  {
15214  return value(arg_list[0]) * value(arg_list[1]) *
15215  value(arg_list[2]) * value(arg_list[3]) ;
15216  }
15217 
15218  template <typename Sequence>
15219  static inline T process_5(const Sequence& arg_list)
15220  {
15221  return value(arg_list[0]) * value(arg_list[1]) *
15222  value(arg_list[2]) * value(arg_list[3]) *
15223  value(arg_list[4]) ;
15224  }
15225  };
15226 
15227  template <typename T>
15228  struct vararg_avg_op exprtk_final : public opr_base<T>
15229  {
15230  typedef typename opr_base<T>::Type Type;
15231 
15232  template <typename Type,
15233  typename Allocator,
15234  template <typename, typename> class Sequence>
15235  static inline T process(const Sequence<Type,Allocator>& arg_list)
15236  {
15237  switch (arg_list.size())
15238  {
15239  case 0 : return T(0);
15240  case 1 : return process_1(arg_list);
15241  case 2 : return process_2(arg_list);
15242  case 3 : return process_3(arg_list);
15243  case 4 : return process_4(arg_list);
15244  case 5 : return process_5(arg_list);
15245  default : return vararg_add_op<T>::process(arg_list) / T(arg_list.size());
15246  }
15247  }
15248 
15249  template <typename Sequence>
15250  static inline T process_1(const Sequence& arg_list)
15251  {
15252  return value(arg_list[0]);
15253  }
15254 
15255  template <typename Sequence>
15256  static inline T process_2(const Sequence& arg_list)
15257  {
15258  return (value(arg_list[0]) + value(arg_list[1])) / T(2);
15259  }
15260 
15261  template <typename Sequence>
15262  static inline T process_3(const Sequence& arg_list)
15263  {
15264  return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3);
15265  }
15266 
15267  template <typename Sequence>
15268  static inline T process_4(const Sequence& arg_list)
15269  {
15270  return (value(arg_list[0]) + value(arg_list[1]) +
15271  value(arg_list[2]) + value(arg_list[3])) / T(4);
15272  }
15273 
15274  template <typename Sequence>
15275  static inline T process_5(const Sequence& arg_list)
15276  {
15277  return (value(arg_list[0]) + value(arg_list[1]) +
15278  value(arg_list[2]) + value(arg_list[3]) +
15279  value(arg_list[4])) / T(5);
15280  }
15281  };
15282 
15283  template <typename T>
15284  struct vararg_min_op exprtk_final : public opr_base<T>
15285  {
15286  typedef typename opr_base<T>::Type Type;
15287 
15288  template <typename Type,
15289  typename Allocator,
15290  template <typename, typename> class Sequence>
15291  static inline T process(const Sequence<Type,Allocator>& arg_list)
15292  {
15293  switch (arg_list.size())
15294  {
15295  case 0 : return T(0);
15296  case 1 : return process_1(arg_list);
15297  case 2 : return process_2(arg_list);
15298  case 3 : return process_3(arg_list);
15299  case 4 : return process_4(arg_list);
15300  case 5 : return process_5(arg_list);
15301  default :
15302  {
15303  T result = T(value(arg_list[0]));
15304 
15305  for (std::size_t i = 1; i < arg_list.size(); ++i)
15306  {
15307  const T v = value(arg_list[i]);
15308 
15309  if (v < result)
15310  result = v;
15311  }
15312 
15313  return result;
15314  }
15315  }
15316  }
15317 
15318  template <typename Sequence>
15319  static inline T process_1(const Sequence& arg_list)
15320  {
15321  return value(arg_list[0]);
15322  }
15323 
15324  template <typename Sequence>
15325  static inline T process_2(const Sequence& arg_list)
15326  {
15327  return std::min<T>(value(arg_list[0]),value(arg_list[1]));
15328  }
15329 
15330  template <typename Sequence>
15331  static inline T process_3(const Sequence& arg_list)
15332  {
15333  return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
15334  }
15335 
15336  template <typename Sequence>
15337  static inline T process_4(const Sequence& arg_list)
15338  {
15339  return std::min<T>(
15340  std::min<T>(value(arg_list[0]), value(arg_list[1])),
15341  std::min<T>(value(arg_list[2]), value(arg_list[3])));
15342  }
15343 
15344  template <typename Sequence>
15345  static inline T process_5(const Sequence& arg_list)
15346  {
15347  return std::min<T>(
15348  std::min<T>(std::min<T>(value(arg_list[0]), value(arg_list[1])),
15349  std::min<T>(value(arg_list[2]), value(arg_list[3]))),
15350  value(arg_list[4]));
15351  }
15352  };
15353 
15354  template <typename T>
15355  struct vararg_max_op exprtk_final : public opr_base<T>
15356  {
15357  typedef typename opr_base<T>::Type Type;
15358 
15359  template <typename Type,
15360  typename Allocator,
15361  template <typename, typename> class Sequence>
15362  static inline T process(const Sequence<Type,Allocator>& arg_list)
15363  {
15364  switch (arg_list.size())
15365  {
15366  case 0 : return T(0);
15367  case 1 : return process_1(arg_list);
15368  case 2 : return process_2(arg_list);
15369  case 3 : return process_3(arg_list);
15370  case 4 : return process_4(arg_list);
15371  case 5 : return process_5(arg_list);
15372  default :
15373  {
15374  T result = T(value(arg_list[0]));
15375 
15376  for (std::size_t i = 1; i < arg_list.size(); ++i)
15377  {
15378  const T v = value(arg_list[i]);
15379 
15380  if (v > result)
15381  result = v;
15382  }
15383 
15384  return result;
15385  }
15386  }
15387  }
15388 
15389  template <typename Sequence>
15390  static inline T process_1(const Sequence& arg_list)
15391  {
15392  return value(arg_list[0]);
15393  }
15394 
15395  template <typename Sequence>
15396  static inline T process_2(const Sequence& arg_list)
15397  {
15398  return std::max<T>(value(arg_list[0]),value(arg_list[1]));
15399  }
15400 
15401  template <typename Sequence>
15402  static inline T process_3(const Sequence& arg_list)
15403  {
15404  return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
15405  }
15406 
15407  template <typename Sequence>
15408  static inline T process_4(const Sequence& arg_list)
15409  {
15410  return std::max<T>(
15411  std::max<T>(value(arg_list[0]), value(arg_list[1])),
15412  std::max<T>(value(arg_list[2]), value(arg_list[3])));
15413  }
15414 
15415  template <typename Sequence>
15416  static inline T process_5(const Sequence& arg_list)
15417  {
15418  return std::max<T>(
15419  std::max<T>(std::max<T>(value(arg_list[0]), value(arg_list[1])),
15420  std::max<T>(value(arg_list[2]), value(arg_list[3]))),
15421  value(arg_list[4]));
15422  }
15423  };
15424 
15425  template <typename T>
15426  struct vararg_mand_op exprtk_final : public opr_base<T>
15427  {
15428  typedef typename opr_base<T>::Type Type;
15429 
15430  template <typename Type,
15431  typename Allocator,
15432  template <typename, typename> class Sequence>
15433  static inline T process(const Sequence<Type,Allocator>& arg_list)
15434  {
15435  switch (arg_list.size())
15436  {
15437  case 1 : return process_1(arg_list);
15438  case 2 : return process_2(arg_list);
15439  case 3 : return process_3(arg_list);
15440  case 4 : return process_4(arg_list);
15441  case 5 : return process_5(arg_list);
15442  default :
15443  {
15444  for (std::size_t i = 0; i < arg_list.size(); ++i)
15445  {
15446  if (std::equal_to<T>()(T(0), value(arg_list[i])))
15447  return T(0);
15448  }
15449 
15450  return T(1);
15451  }
15452  }
15453  }
15454 
15455  template <typename Sequence>
15456  static inline T process_1(const Sequence& arg_list)
15457  {
15458  return std::not_equal_to<T>()
15459  (T(0), value(arg_list[0])) ? T(1) : T(0);
15460  }
15461 
15462  template <typename Sequence>
15463  static inline T process_2(const Sequence& arg_list)
15464  {
15465  return (
15466  std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
15467  std::not_equal_to<T>()(T(0), value(arg_list[1]))
15468  ) ? T(1) : T(0);
15469  }
15470 
15471  template <typename Sequence>
15472  static inline T process_3(const Sequence& arg_list)
15473  {
15474  return (
15475  std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
15476  std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
15477  std::not_equal_to<T>()(T(0), value(arg_list[2]))
15478  ) ? T(1) : T(0);
15479  }
15480 
15481  template <typename Sequence>
15482  static inline T process_4(const Sequence& arg_list)
15483  {
15484  return (
15485  std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
15486  std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
15487  std::not_equal_to<T>()(T(0), value(arg_list[2])) &&
15488  std::not_equal_to<T>()(T(0), value(arg_list[3]))
15489  ) ? T(1) : T(0);
15490  }
15491 
15492  template <typename Sequence>
15493  static inline T process_5(const Sequence& arg_list)
15494  {
15495  return (
15496  std::not_equal_to<T>()(T(0), value(arg_list[0])) &&
15497  std::not_equal_to<T>()(T(0), value(arg_list[1])) &&
15498  std::not_equal_to<T>()(T(0), value(arg_list[2])) &&
15499  std::not_equal_to<T>()(T(0), value(arg_list[3])) &&
15500  std::not_equal_to<T>()(T(0), value(arg_list[4]))
15501  ) ? T(1) : T(0);
15502  }
15503  };
15504 
15505  template <typename T>
15506  struct vararg_mor_op exprtk_final : public opr_base<T>
15507  {
15508  typedef typename opr_base<T>::Type Type;
15509 
15510  template <typename Type,
15511  typename Allocator,
15512  template <typename, typename> class Sequence>
15513  static inline T process(const Sequence<Type,Allocator>& arg_list)
15514  {
15515  switch (arg_list.size())
15516  {
15517  case 1 : return process_1(arg_list);
15518  case 2 : return process_2(arg_list);
15519  case 3 : return process_3(arg_list);
15520  case 4 : return process_4(arg_list);
15521  case 5 : return process_5(arg_list);
15522  default :
15523  {
15524  for (std::size_t i = 0; i < arg_list.size(); ++i)
15525  {
15526  if (std::not_equal_to<T>()(T(0), value(arg_list[i])))
15527  return T(1);
15528  }
15529 
15530  return T(0);
15531  }
15532  }
15533  }
15534 
15535  template <typename Sequence>
15536  static inline T process_1(const Sequence& arg_list)
15537  {
15538  return std::not_equal_to<T>()
15539  (T(0), value(arg_list[0])) ? T(1) : T(0);
15540  }
15541 
15542  template <typename Sequence>
15543  static inline T process_2(const Sequence& arg_list)
15544  {
15545  return (
15546  std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
15547  std::not_equal_to<T>()(T(0), value(arg_list[1]))
15548  ) ? T(1) : T(0);
15549  }
15550 
15551  template <typename Sequence>
15552  static inline T process_3(const Sequence& arg_list)
15553  {
15554  return (
15555  std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
15556  std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
15557  std::not_equal_to<T>()(T(0), value(arg_list[2]))
15558  ) ? T(1) : T(0);
15559  }
15560 
15561  template <typename Sequence>
15562  static inline T process_4(const Sequence& arg_list)
15563  {
15564  return (
15565  std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
15566  std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
15567  std::not_equal_to<T>()(T(0), value(arg_list[2])) ||
15568  std::not_equal_to<T>()(T(0), value(arg_list[3]))
15569  ) ? T(1) : T(0);
15570  }
15571 
15572  template <typename Sequence>
15573  static inline T process_5(const Sequence& arg_list)
15574  {
15575  return (
15576  std::not_equal_to<T>()(T(0), value(arg_list[0])) ||
15577  std::not_equal_to<T>()(T(0), value(arg_list[1])) ||
15578  std::not_equal_to<T>()(T(0), value(arg_list[2])) ||
15579  std::not_equal_to<T>()(T(0), value(arg_list[3])) ||
15580  std::not_equal_to<T>()(T(0), value(arg_list[4]))
15581  ) ? T(1) : T(0);
15582  }
15583  };
15584 
15585  template <typename T>
15586  struct vararg_multi_op exprtk_final : public opr_base<T>
15587  {
15588  typedef typename opr_base<T>::Type Type;
15589 
15590  template <typename Type,
15591  typename Allocator,
15592  template <typename, typename> class Sequence>
15593  static inline T process(const Sequence<Type,Allocator>& arg_list)
15594  {
15595  switch (arg_list.size())
15596  {
15597  case 0 : return std::numeric_limits<T>::quiet_NaN();
15598  case 1 : return process_1(arg_list);
15599  case 2 : return process_2(arg_list);
15600  case 3 : return process_3(arg_list);
15601  case 4 : return process_4(arg_list);
15602  case 5 : return process_5(arg_list);
15603  case 6 : return process_6(arg_list);
15604  case 7 : return process_7(arg_list);
15605  case 8 : return process_8(arg_list);
15606  default :
15607  {
15608  for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
15609  {
15610  value(arg_list[i]);
15611  }
15612  return value(arg_list.back());
15613  }
15614  }
15615  }
15616 
15617  template <typename Sequence>
15618  static inline T process_1(const Sequence& arg_list)
15619  {
15620  return value(arg_list[0]);
15621  }
15622 
15623  template <typename Sequence>
15624  static inline T process_2(const Sequence& arg_list)
15625  {
15626  value(arg_list[0]);
15627  return value(arg_list[1]);
15628  }
15629 
15630  template <typename Sequence>
15631  static inline T process_3(const Sequence& arg_list)
15632  {
15633  value(arg_list[0]);
15634  value(arg_list[1]);
15635  return value(arg_list[2]);
15636  }
15637 
15638  template <typename Sequence>
15639  static inline T process_4(const Sequence& arg_list)
15640  {
15641  value(arg_list[0]);
15642  value(arg_list[1]);
15643  value(arg_list[2]);
15644  return value(arg_list[3]);
15645  }
15646 
15647  template <typename Sequence>
15648  static inline T process_5(const Sequence& arg_list)
15649  {
15650  value(arg_list[0]);
15651  value(arg_list[1]);
15652  value(arg_list[2]);
15653  value(arg_list[3]);
15654  return value(arg_list[4]);
15655  }
15656 
15657  template <typename Sequence>
15658  static inline T process_6(const Sequence& arg_list)
15659  {
15660  value(arg_list[0]);
15661  value(arg_list[1]);
15662  value(arg_list[2]);
15663  value(arg_list[3]);
15664  value(arg_list[4]);
15665  return value(arg_list[5]);
15666  }
15667 
15668  template <typename Sequence>
15669  static inline T process_7(const Sequence& arg_list)
15670  {
15671  value(arg_list[0]);
15672  value(arg_list[1]);
15673  value(arg_list[2]);
15674  value(arg_list[3]);
15675  value(arg_list[4]);
15676  value(arg_list[5]);
15677  return value(arg_list[6]);
15678  }
15679 
15680  template <typename Sequence>
15681  static inline T process_8(const Sequence& arg_list)
15682  {
15683  value(arg_list[0]);
15684  value(arg_list[1]);
15685  value(arg_list[2]);
15686  value(arg_list[3]);
15687  value(arg_list[4]);
15688  value(arg_list[5]);
15689  value(arg_list[6]);
15690  return value(arg_list[7]);
15691  }
15692  };
15693 
15694  template <typename T>
15695  struct vec_add_op
15696  {
15698 
15699  static inline T process(const ivector_ptr v)
15700  {
15701  const T* vec = v->vec()->vds().data();
15702  const std::size_t vec_size = v->size();
15703 
15704  loop_unroll::details lud(vec_size);
15705 
15706  if (vec_size <= static_cast<std::size_t>(lud.batch_size))
15707  {
15708  T result = T(0);
15709  int i = 0;
15710 
15711  switch (vec_size)
15712  {
15713  #define case_stmt(N,fall_through) \
15714  case N : result += vec[i++]; \
15715  fall_through \
15716 
15717  #ifndef exprtk_disable_superscalar_unroll
15724 
15725  #endif
15727  case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;)
15728  }
15729 
15730  #undef case_stmt
15731 
15732  return result;
15733  }
15734 
15735  T r[] = {
15736  T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0),
15737  T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0)
15738  };
15739 
15740  const T* upper_bound = vec + lud.upper_bound;
15741 
15742  while (vec < upper_bound)
15743  {
15744  #define exprtk_loop(N) \
15745  r[N] += vec[N]; \
15746 
15747  exprtk_loop( 0) exprtk_loop( 1)
15748  exprtk_loop( 2) exprtk_loop( 3)
15749  #ifndef exprtk_disable_superscalar_unroll
15750  exprtk_loop( 4) exprtk_loop( 5)
15751  exprtk_loop( 6) exprtk_loop( 7)
15752  exprtk_loop( 8) exprtk_loop( 9)
15753  exprtk_loop(10) exprtk_loop(11)
15754  exprtk_loop(12) exprtk_loop(13)
15755  exprtk_loop(14) exprtk_loop(15)
15756  #endif
15757 
15758  vec += lud.batch_size;
15759  }
15760 
15761  int i = 0;
15762 
15763  switch (lud.remainder)
15764  {
15765  #define case_stmt(N,fall_through) \
15766  case N : r[0] += vec[i++]; \
15767  fall_through \
15768 
15769  #ifndef exprtk_disable_superscalar_unroll
15776  #endif
15778  case_stmt( 1, (void)0;)
15779  }
15780 
15781  #undef exprtk_loop
15782  #undef case_stmt
15783 
15784  return (r[ 0] + r[ 1] + r[ 2] + r[ 3])
15785  #ifndef exprtk_disable_superscalar_unroll
15786  + (r[ 4] + r[ 5] + r[ 6] + r[ 7])
15787  + (r[ 8] + r[ 9] + r[10] + r[11])
15788  + (r[12] + r[13] + r[14] + r[15])
15789  #endif
15790  ;
15791  }
15792  };
15793 
15794  template <typename T>
15795  struct vec_mul_op
15796  {
15798 
15799  static inline T process(const ivector_ptr v)
15800  {
15801  const T* vec = v->vec()->vds().data();
15802  const std::size_t vec_size = v->vec()->size();
15803 
15804  loop_unroll::details lud(vec_size);
15805 
15806  if (vec_size <= static_cast<std::size_t>(lud.batch_size))
15807  {
15808  T result = T(1);
15809  int i = 0;
15810 
15811  switch (vec_size)
15812  {
15813  #define case_stmt(N,fall_through) \
15814  case N : result *= vec[i++]; \
15815  fall_through \
15816 
15817  #ifndef exprtk_disable_superscalar_unroll
15824  #endif
15826  case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;)
15827  }
15828 
15829  #undef case_stmt
15830 
15831  return result;
15832  }
15833 
15834  T r[] = {
15835  T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1),
15836  T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1)
15837  };
15838 
15839  const T* upper_bound = vec + lud.upper_bound;
15840 
15841  while (vec < upper_bound)
15842  {
15843  #define exprtk_loop(N) \
15844  r[N] *= vec[N]; \
15845 
15846  exprtk_loop( 0) exprtk_loop( 1)
15847  exprtk_loop( 2) exprtk_loop( 3)
15848  #ifndef exprtk_disable_superscalar_unroll
15849  exprtk_loop( 4) exprtk_loop( 5)
15850  exprtk_loop( 6) exprtk_loop( 7)
15851  exprtk_loop( 8) exprtk_loop( 9)
15852  exprtk_loop(10) exprtk_loop(11)
15853  exprtk_loop(12) exprtk_loop(13)
15854  exprtk_loop(14) exprtk_loop(15)
15855  #endif
15856 
15857  vec += lud.batch_size;
15858  }
15859 
15860  int i = 0;
15861 
15862  switch (lud.remainder)
15863  {
15864  #define case_stmt(N,fall_through) \
15865  case N : r[0] *= vec[i++]; \
15866  fall_through \
15867 
15868  #ifndef exprtk_disable_superscalar_unroll
15875  #endif
15877  case_stmt( 1, (void)0;)
15878  }
15879 
15880  #undef exprtk_loop
15881  #undef case_stmt
15882 
15883  return (r[ 0] * r[ 1] * r[ 2] * r[ 3])
15884  #ifndef exprtk_disable_superscalar_unroll
15885  + (r[ 4] * r[ 5] * r[ 6] * r[ 7])
15886  + (r[ 8] * r[ 9] * r[10] * r[11])
15887  + (r[12] * r[13] * r[14] * r[15])
15888  #endif
15889  ;
15890  }
15891  };
15892 
15893  template <typename T>
15894  struct vec_avg_op
15895  {
15897 
15898  static inline T process(const ivector_ptr v)
15899  {
15900  const T vec_size = T(v->vec()->size());
15901  return vec_add_op<T>::process(v) / vec_size;
15902  }
15903  };
15904 
15905  template <typename T>
15906  struct vec_min_op
15907  {
15909 
15910  static inline T process(const ivector_ptr v)
15911  {
15912  const T* vec = v->vec()->vds().data();
15913  const std::size_t vec_size = v->vec()->size();
15914 
15915  T result = vec[0];
15916 
15917  for (std::size_t i = 1; i < vec_size; ++i)
15918  {
15919  const T v_i = vec[i];
15920 
15921  if (v_i < result)
15922  result = v_i;
15923  }
15924 
15925  return result;
15926  }
15927  };
15928 
15929  template <typename T>
15930  struct vec_max_op
15931  {
15933 
15934  static inline T process(const ivector_ptr v)
15935  {
15936  const T* vec = v->vec()->vds().data();
15937  const std::size_t vec_size = v->vec()->size();
15938 
15939  T result = vec[0];
15940 
15941  for (std::size_t i = 1; i < vec_size; ++i)
15942  {
15943  const T v_i = vec[i];
15944 
15945  if (v_i > result)
15946  result = v_i;
15947  }
15948 
15949  return result;
15950  }
15951  };
15952 
15953  template <typename T>
15954  class vov_base_node : public expression_node<T>
15955  {
15956  public:
15957 
15958  virtual ~vov_base_node()
15959  {}
15960 
15961  inline virtual operator_type operation() const
15962  {
15963  return details::e_default;
15964  }
15965 
15966  virtual const T& v0() const = 0;
15967 
15968  virtual const T& v1() const = 0;
15969  };
15970 
15971  template <typename T>
15972  class cov_base_node : public expression_node<T>
15973  {
15974  public:
15975 
15976  virtual ~cov_base_node()
15977  {}
15978 
15979  inline virtual operator_type operation() const
15980  {
15981  return details::e_default;
15982  }
15983 
15984  virtual const T c() const = 0;
15985 
15986  virtual const T& v() const = 0;
15987  };
15988 
15989  template <typename T>
15990  class voc_base_node : public expression_node<T>
15991  {
15992  public:
15993 
15994  virtual ~voc_base_node()
15995  {}
15996 
15997  inline virtual operator_type operation() const
15998  {
15999  return details::e_default;
16000  }
16001 
16002  virtual const T c() const = 0;
16003 
16004  virtual const T& v() const = 0;
16005  };
16006 
16007  template <typename T>
16008  class vob_base_node : public expression_node<T>
16009  {
16010  public:
16011 
16012  virtual ~vob_base_node()
16013  {}
16014 
16015  virtual const T& v() const = 0;
16016  };
16017 
16018  template <typename T>
16019  class bov_base_node : public expression_node<T>
16020  {
16021  public:
16022 
16023  virtual ~bov_base_node()
16024  {}
16025 
16026  virtual const T& v() const = 0;
16027  };
16028 
16029  template <typename T>
16030  class cob_base_node : public expression_node<T>
16031  {
16032  public:
16033 
16034  virtual ~cob_base_node()
16035  {}
16036 
16037  inline virtual operator_type operation() const
16038  {
16039  return details::e_default;
16040  }
16041 
16042  virtual const T c() const = 0;
16043 
16044  virtual void set_c(const T) = 0;
16045 
16046  virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
16047  };
16048 
16049  template <typename T>
16050  class boc_base_node : public expression_node<T>
16051  {
16052  public:
16053 
16054  virtual ~boc_base_node()
16055  {}
16056 
16057  inline virtual operator_type operation() const
16058  {
16059  return details::e_default;
16060  }
16061 
16062  virtual const T c() const = 0;
16063 
16064  virtual void set_c(const T) = 0;
16065 
16066  virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
16067  };
16068 
16069  template <typename T>
16070  class uv_base_node : public expression_node<T>
16071  {
16072  public:
16073 
16074  virtual ~uv_base_node()
16075  {}
16076 
16077  inline virtual operator_type operation() const
16078  {
16079  return details::e_default;
16080  }
16081 
16082  virtual const T& v() const = 0;
16083  };
16084 
16085  template <typename T>
16086  class sos_base_node : public expression_node<T>
16087  {
16088  public:
16089 
16090  virtual ~sos_base_node()
16091  {}
16092 
16093  inline virtual operator_type operation() const
16094  {
16095  return details::e_default;
16096  }
16097  };
16098 
16099  template <typename T>
16101  {
16102  public:
16103 
16105  {}
16106 
16107  inline virtual operator_type operation() const
16108  {
16109  return details::e_default;
16110  }
16111  };
16112 
16113  template <typename T>
16115  {
16116  public:
16117 
16119  {}
16120 
16121  virtual std::string type_id() const = 0;
16122  };
16123 
16124  template <typename T>
16126  {
16127  public:
16128 
16130  {}
16131 
16132  virtual std::string type_id() const = 0;
16133  };
16134 
16135  template <typename T, typename Operation>
16136  class unary_variable_node exprtk_final : public uv_base_node<T>
16137  {
16138  public:
16139 
16141  typedef Operation operation_t;
16142 
16143  explicit unary_variable_node(const T& var)
16144  : v_(var)
16145  {}
16146 
16148  {
16149  return Operation::process(v_);
16150  }
16151 
16153  {
16154  return Operation::type();
16155  }
16156 
16158  {
16159  return Operation::operation();
16160  }
16161 
16162  inline const T& v() const exprtk_override
16163  {
16164  return v_;
16165  }
16166 
16167  private:
16168 
16169  unary_variable_node(const unary_variable_node<T,Operation>&) exprtk_delete;
16170  unary_variable_node<T,Operation>& operator=(const unary_variable_node<T,Operation>&) exprtk_delete;
16171 
16172  const T& v_;
16173  };
16174 
16175  template <typename T>
16176  class uvouv_node exprtk_final : public expression_node<T>
16177  {
16178  public:
16179 
16180  // UOpr1(v0) Op UOpr2(v1)
16182  typedef typename functor_t::bfunc_t bfunc_t;
16183  typedef typename functor_t::ufunc_t ufunc_t;
16185 
16186  explicit uvouv_node(const T& var0,const T& var1,
16187  ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
16188  : v0_(var0)
16189  , v1_(var1)
16190  , u0_(uf0 )
16191  , u1_(uf1 )
16192  , f_ (bf )
16193  {}
16194 
16196  {
16197  return f_(u0_(v0_),u1_(v1_));
16198  }
16199 
16201  {
16203  }
16204 
16205  inline const T& v0()
16206  {
16207  return v0_;
16208  }
16209 
16210  inline const T& v1()
16211  {
16212  return v1_;
16213  }
16214 
16215  inline ufunc_t u0()
16216  {
16217  return u0_;
16218  }
16219 
16220  inline ufunc_t u1()
16221  {
16222  return u1_;
16223  }
16224 
16225  inline ufunc_t f()
16226  {
16227  return f_;
16228  }
16229 
16230  private:
16231 
16232  uvouv_node(const uvouv_node<T>&) exprtk_delete;
16233  uvouv_node<T>& operator=(const uvouv_node<T>&) exprtk_delete;
16234 
16235  const T& v0_;
16236  const T& v1_;
16237  const ufunc_t u0_;
16238  const ufunc_t u1_;
16239  const bfunc_t f_;
16240  };
16241 
16242  template <typename T, typename Operation>
16243  class unary_branch_node exprtk_final : public expression_node<T>
16244  {
16245  public:
16246 
16247  typedef Operation operation_t;
16249  typedef std::pair<expression_ptr,bool> branch_t;
16250 
16252  {
16253  construct_branch_pair(branch_, branch);
16254  }
16255 
16257  {
16258  return Operation::process(branch_.first->value());
16259  }
16260 
16262  {
16263  return Operation::type();
16264  }
16265 
16267  {
16268  return branch_.first && branch_.first->valid();
16269  }
16270 
16272  {
16273  return Operation::operation();
16274  }
16275 
16276  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
16277  {
16278  return branch_.first;
16279  }
16280 
16281  inline void release()
16282  {
16283  branch_.second = false;
16284  }
16285 
16287  {
16288  expression_node<T>::ndb_t::collect(branch_, node_delete_list);
16289  }
16290 
16292  {
16294  }
16295 
16296  private:
16297 
16298  unary_branch_node(const unary_branch_node<T,Operation>&) exprtk_delete;
16299  unary_branch_node<T,Operation>& operator=(const unary_branch_node<T,Operation>&) exprtk_delete;
16300 
16301  branch_t branch_;
16302  };
16303 
16304  template <typename T> struct is_const { enum {result = 0}; };
16305  template <typename T> struct is_const <const T> { enum {result = 1}; };
16306  template <typename T> struct is_const_ref { enum {result = 0}; };
16307  template <typename T> struct is_const_ref <const T&> { enum {result = 1}; };
16308  template <typename T> struct is_ref { enum {result = 0}; };
16309  template <typename T> struct is_ref<T&> { enum {result = 1}; };
16310  template <typename T> struct is_ref<const T&> { enum {result = 0}; };
16311 
16312  template <std::size_t State>
16313  struct param_to_str { static std::string result() { static const std::string r("v"); return r; } };
16314 
16315  template <>
16316  struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } };
16317 
16318  #define exprtk_crtype(Type) \
16319  param_to_str<is_const_ref< Type >::result>::result() \
16320 
16321  template <typename T>
16323  {
16325  typedef typename functor_t::bfunc_t bfunc_t;
16326 
16327  struct mode0
16328  {
16329  static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
16330  {
16331  // (T0 o0 T1) o1 T2
16332  return bf1(bf0(t0,t1),t2);
16333  }
16334 
16335  template <typename T0, typename T1, typename T2>
16336  static inline std::string id()
16337  {
16338  static const std::string result = "(" + exprtk_crtype(T0) + "o" +
16339  exprtk_crtype(T1) + ")o(" +
16340  exprtk_crtype(T2) + ")" ;
16341  return result;
16342  }
16343  };
16344 
16345  struct mode1
16346  {
16347  static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
16348  {
16349  // T0 o0 (T1 o1 T2)
16350  return bf0(t0,bf1(t1,t2));
16351  }
16352 
16353  template <typename T0, typename T1, typename T2>
16354  static inline std::string id()
16355  {
16356  static const std::string result = "(" + exprtk_crtype(T0) + ")o(" +
16357  exprtk_crtype(T1) + "o" +
16358  exprtk_crtype(T2) + ")" ;
16359  return result;
16360  }
16361  };
16362  };
16363 
16364  template <typename T>
16366  {
16368  typedef typename functor_t::bfunc_t bfunc_t;
16369 
16370  struct mode0
16371  {
16372  static inline T process(const T& t0, const T& t1,
16373  const T& t2, const T& t3,
16374  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
16375  {
16376  // (T0 o0 T1) o1 (T2 o2 T3)
16377  return bf1(bf0(t0,t1),bf2(t2,t3));
16378  }
16379 
16380  template <typename T0, typename T1, typename T2, typename T3>
16381  static inline std::string id()
16382  {
16383  static const std::string result = "(" + exprtk_crtype(T0) + "o" +
16384  exprtk_crtype(T1) + ")o" +
16385  "(" + exprtk_crtype(T2) + "o" +
16386  exprtk_crtype(T3) + ")" ;
16387  return result;
16388  }
16389  };
16390 
16391  struct mode1
16392  {
16393  static inline T process(const T& t0, const T& t1,
16394  const T& t2, const T& t3,
16395  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
16396  {
16397  // (T0 o0 (T1 o1 (T2 o2 T3))
16398  return bf0(t0,bf1(t1,bf2(t2,t3)));
16399  }
16400  template <typename T0, typename T1, typename T2, typename T3>
16401  static inline std::string id()
16402  {
16403  static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
16404  exprtk_crtype(T1) + ")o(" +
16405  exprtk_crtype(T2) + "o" +
16406  exprtk_crtype(T3) + "))" ;
16407  return result;
16408  }
16409  };
16410 
16411  struct mode2
16412  {
16413  static inline T process(const T& t0, const T& t1,
16414  const T& t2, const T& t3,
16415  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
16416  {
16417  // (T0 o0 ((T1 o1 T2) o2 T3)
16418  return bf0(t0,bf2(bf1(t1,t2),t3));
16419  }
16420 
16421  template <typename T0, typename T1, typename T2, typename T3>
16422  static inline std::string id()
16423  {
16424  static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
16425  exprtk_crtype(T1) + "o" +
16426  exprtk_crtype(T2) + ")o(" +
16427  exprtk_crtype(T3) + "))" ;
16428  return result;
16429  }
16430  };
16431 
16432  struct mode3
16433  {
16434  static inline T process(const T& t0, const T& t1,
16435  const T& t2, const T& t3,
16436  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
16437  {
16438  // (((T0 o0 T1) o1 T2) o2 T3)
16439  return bf2(bf1(bf0(t0,t1),t2),t3);
16440  }
16441 
16442  template <typename T0, typename T1, typename T2, typename T3>
16443  static inline std::string id()
16444  {
16445  static const std::string result = "((" + exprtk_crtype(T0) + "o" +
16446  exprtk_crtype(T1) + ")o(" +
16447  exprtk_crtype(T2) + "))o(" +
16448  exprtk_crtype(T3) + ")";
16449  return result;
16450  }
16451  };
16452 
16453  struct mode4
16454  {
16455  static inline T process(const T& t0, const T& t1,
16456  const T& t2, const T& t3,
16457  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
16458  {
16459  // ((T0 o0 (T1 o1 T2)) o2 T3
16460  return bf2(bf0(t0,bf1(t1,t2)),t3);
16461  }
16462 
16463  template <typename T0, typename T1, typename T2, typename T3>
16464  static inline std::string id()
16465  {
16466  static const std::string result = "((" + exprtk_crtype(T0) + ")o(" +
16467  exprtk_crtype(T1) + "o" +
16468  exprtk_crtype(T2) + "))o(" +
16469  exprtk_crtype(T3) + ")" ;
16470  return result;
16471  }
16472  };
16473  };
16474 
16475  #undef exprtk_crtype
16476 
16477  template <typename T, typename T0, typename T1>
16478  struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; };
16479  template <typename T, typename T0, typename T1>
16481 
16482  #define synthesis_node_type_define(T0_, T1_, v_) \
16483  template <typename T, typename T0, typename T1> \
16484  struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
16485  template <typename T, typename T0, typename T1> \
16486  const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
16487 
16488  synthesis_node_type_define(const T0&, const T1&, e_vov)
16491  synthesis_node_type_define( T0&, T1&, e_none)
16493  synthesis_node_type_define( T0&, const T1 , e_none)
16497  #undef synthesis_node_type_define
16498 
16499  template <typename T, typename T0, typename T1, typename T2>
16500  struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; };
16501  template <typename T, typename T0, typename T1, typename T2>
16503 
16504  #define synthesis_node_type_define(T0_, T1_, T2_, v_) \
16505  template <typename T, typename T0, typename T1, typename T2> \
16506  struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
16507  template <typename T, typename T0, typename T1, typename T2> \
16508  const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
16509 
16510  synthesis_node_type_define(const T0&, const T1&, const T2&, e_vovov)
16519  #undef synthesis_node_type_define
16520 
16521  template <typename T, typename T0, typename T1, typename T2, typename T3>
16522  struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; };
16523  template <typename T, typename T0, typename T1, typename T2, typename T3>
16525 
16526  #define synthesis_node_type_define(T0_, T1_, T2_, T3_, v_) \
16527  template <typename T, typename T0, typename T1, typename T2, typename T3> \
16528  struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
16529  template <typename T, typename T0, typename T1, typename T2, typename T3> \
16530  const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
16531 
16532  synthesis_node_type_define(const T0&, const T1&, const T2&, const T3&, e_vovovov)
16548  #undef synthesis_node_type_define
16549 
16550  template <typename T, typename T0, typename T1>
16551  class T0oT1 exprtk_final : public expression_node<T>
16552  {
16553  public:
16554 
16556  typedef typename functor_t::bfunc_t bfunc_t;
16557  typedef T value_type;
16558  typedef T0oT1<T,T0,T1> node_type;
16559 
16560  T0oT1(T0 p0, T1 p1, const bfunc_t p2)
16561  : t0_(p0)
16562  , t1_(p1)
16563  , f_ (p2)
16564  {}
16565 
16567  {
16568  static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result;
16569  return result;
16570  }
16571 
16573  {
16574  return e_default;
16575  }
16576 
16578  {
16579  return f_(t0_,t1_);
16580  }
16581 
16582  inline T0 t0() const
16583  {
16584  return t0_;
16585  }
16586 
16587  inline T1 t1() const
16588  {
16589  return t1_;
16590  }
16591 
16592  inline bfunc_t f() const
16593  {
16594  return f_;
16595  }
16596 
16597  template <typename Allocator>
16598  static inline expression_node<T>* allocate(Allocator& allocator,
16599  T0 p0, T1 p1,
16600  bfunc_t p2)
16601  {
16602  return allocator
16603  .template allocate_type<node_type, T0, T1, bfunc_t&>
16604  (p0, p1, p2);
16605  }
16606 
16607  private:
16608 
16609  T0oT1(const T0oT1<T,T0,T1>&) exprtk_delete;
16610  T0oT1<T,T0,T1>& operator=(const T0oT1<T,T0,T1>&) { return (*this); }
16611 
16614  const bfunc_t f_;
16615  };
16616 
16617  template <typename T, typename T0, typename T1, typename T2, typename ProcessMode>
16618  class T0oT1oT2 exprtk_final : public T0oT1oT2_base_node<T>
16619  {
16620  public:
16621 
16623  typedef typename functor_t::bfunc_t bfunc_t;
16624  typedef T value_type;
16625  typedef T0oT1oT2<T,T0,T1,T2,ProcessMode> node_type;
16626  typedef ProcessMode process_mode_t;
16627 
16628  T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
16629  : t0_(p0)
16630  , t1_(p1)
16631  , t2_(p2)
16632  , f0_(p3)
16633  , f1_(p4)
16634  {}
16635 
16637  {
16639  return result;
16640  }
16641 
16643  {
16644  return e_default;
16645  }
16646 
16648  {
16649  return ProcessMode::process(t0_, t1_, t2_, f0_, f1_);
16650  }
16651 
16652  inline T0 t0() const
16653  {
16654  return t0_;
16655  }
16656 
16657  inline T1 t1() const
16658  {
16659  return t1_;
16660  }
16661 
16662  inline T2 t2() const
16663  {
16664  return t2_;
16665  }
16666 
16667  bfunc_t f0() const
16668  {
16669  return f0_;
16670  }
16671 
16672  bfunc_t f1() const
16673  {
16674  return f1_;
16675  }
16676 
16678  {
16679  return id();
16680  }
16681 
16682  static inline std::string id()
16683  {
16684  return process_mode_t::template id<T0,T1,T2>();
16685  }
16686 
16687  template <typename Allocator>
16688  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
16689  {
16690  return allocator
16691  .template allocate_type<node_type, T0, T1, T2, bfunc_t, bfunc_t>
16692  (p0, p1, p2, p3, p4);
16693  }
16694 
16695  private:
16696 
16699 
16700  T0 t0_;
16701  T1 t1_;
16703  const bfunc_t f0_;
16704  const bfunc_t f1_;
16705  };
16706 
16707  template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode>
16708  class T0oT1oT2oT3 exprtk_final : public T0oT1oT2oT3_base_node<T>
16709  {
16710  public:
16711 
16713  typedef typename functor_t::bfunc_t bfunc_t;
16714  typedef T value_type;
16715  typedef T0_ T0;
16716  typedef T1_ T1;
16717  typedef T2_ T2;
16718  typedef T3_ T3;
16719  typedef T0oT1oT2oT3<T,T0,T1,T2,T3,ProcessMode> node_type;
16720  typedef ProcessMode process_mode_t;
16721 
16722  T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
16723  : t0_(p0)
16724  , t1_(p1)
16725  , t2_(p2)
16726  , t3_(p3)
16727  , f0_(p4)
16728  , f1_(p5)
16729  , f2_(p6)
16730  {}
16731 
16733  {
16734  return ProcessMode::process(t0_, t1_, t2_, t3_, f0_, f1_, f2_);
16735  }
16736 
16737  inline T0 t0() const
16738  {
16739  return t0_;
16740  }
16741 
16742  inline T1 t1() const
16743  {
16744  return t1_;
16745  }
16746 
16747  inline T2 t2() const
16748  {
16749  return t2_;
16750  }
16751 
16752  inline T3 t3() const
16753  {
16754  return t3_;
16755  }
16756 
16757  inline bfunc_t f0() const
16758  {
16759  return f0_;
16760  }
16761 
16762  inline bfunc_t f1() const
16763  {
16764  return f1_;
16765  }
16766 
16767  inline bfunc_t f2() const
16768  {
16769  return f2_;
16770  }
16771 
16772  inline std::string type_id() const exprtk_override
16773  {
16774  return id();
16775  }
16776 
16777  static inline std::string id()
16778  {
16779  return process_mode_t::template id<T0, T1, T2, T3>();
16780  }
16781 
16782  template <typename Allocator>
16783  static inline expression_node<T>* allocate(Allocator& allocator,
16784  T0 p0, T1 p1, T2 p2, T3 p3,
16785  bfunc_t p4, bfunc_t p5, bfunc_t p6)
16786  {
16787  return allocator
16788  .template allocate_type<node_type, T0, T1, T2, T3, bfunc_t, bfunc_t>
16789  (p0, p1, p2, p3, p4, p5, p6);
16790  }
16791 
16792  private:
16793 
16796 
16797  T0 t0_;
16798  T1 t1_;
16799  T2 t2_;
16801  const bfunc_t f0_;
16802  const bfunc_t f1_;
16803  const bfunc_t f2_;
16804  };
16805 
16806  template <typename T, typename T0, typename T1, typename T2>
16807  class T0oT1oT2_sf3 exprtk_final : public T0oT1oT2_base_node<T>
16808  {
16809  public:
16810 
16812  typedef typename functor_t::tfunc_t tfunc_t;
16813  typedef T value_type;
16814  typedef T0oT1oT2_sf3<T,T0,T1,T2> node_type;
16815 
16816  T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
16817  : t0_(p0)
16818  , t1_(p1)
16819  , t2_(p2)
16820  , f_ (p3)
16821  {}
16822 
16824  {
16826  return result;
16827  }
16828 
16830  {
16831  return e_default;
16832  }
16833 
16835  {
16836  return f_(t0_, t1_, t2_);
16837  }
16838 
16839  inline T0 t0() const
16840  {
16841  return t0_;
16842  }
16843 
16844  inline T1 t1() const
16845  {
16846  return t1_;
16847  }
16848 
16849  inline T2 t2() const
16850  {
16851  return t2_;
16852  }
16853 
16854  tfunc_t f() const
16855  {
16856  return f_;
16857  }
16858 
16859  std::string type_id() const
16860  {
16861  return id();
16862  }
16863 
16864  static inline std::string id()
16865  {
16866  return "sf3";
16867  }
16868 
16869  template <typename Allocator>
16870  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
16871  {
16872  return allocator
16873  .template allocate_type<node_type, T0, T1, T2, tfunc_t>
16874  (p0, p1, p2, p3);
16875  }
16876 
16877  private:
16878 
16881 
16882  T0 t0_;
16883  T1 t1_;
16884  T2 t2_;
16885  const tfunc_t f_;
16886  };
16887 
16888  template <typename T, typename T0, typename T1, typename T2>
16890  {
16891  public:
16892 
16894  {}
16895 
16896  virtual T0 t0() const = 0;
16897 
16898  virtual T1 t1() const = 0;
16899 
16900  virtual T2 t2() const = 0;
16901  };
16902 
16903  template <typename T, typename T0, typename T1, typename T2, typename SF3Operation>
16904  class T0oT1oT2_sf3ext exprtk_final : public sf3ext_type_node<T,T0,T1,T2>
16905  {
16906  public:
16907 
16908  typedef T value_type;
16909  typedef T0oT1oT2_sf3ext<T, T0, T1, T2, SF3Operation> node_type;
16910 
16911  T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
16912  : t0_(p0)
16913  , t1_(p1)
16914  , t2_(p2)
16915  {}
16916 
16918  {
16920  return result;
16921  }
16922 
16924  {
16925  return e_default;
16926  }
16927 
16929  {
16930  return SF3Operation::process(t0_, t1_, t2_);
16931  }
16932 
16934  {
16935  return t0_;
16936  }
16937 
16939  {
16940  return t1_;
16941  }
16942 
16944  {
16945  return t2_;
16946  }
16947 
16949  {
16950  return id();
16951  }
16952 
16953  static inline std::string id()
16954  {
16955  return SF3Operation::id();
16956  }
16957 
16958  template <typename Allocator>
16959  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2)
16960  {
16961  return allocator
16962  .template allocate_type<node_type, T0, T1, T2>
16963  (p0, p1, p2);
16964  }
16965 
16966  private:
16967 
16970 
16971  T0 t0_;
16972  T1 t1_;
16973  T2 t2_;
16974  };
16975 
16976  template <typename T>
16977  inline bool is_sf3ext_node(const expression_node<T>* n)
16978  {
16979  switch (n->type())
16980  {
16981  case expression_node<T>::e_vovov : return true;
16982  case expression_node<T>::e_vovoc : return true;
16983  case expression_node<T>::e_vocov : return true;
16984  case expression_node<T>::e_covov : return true;
16985  case expression_node<T>::e_covoc : return true;
16986  default : return false;
16987  }
16988  }
16989 
16990  template <typename T, typename T0, typename T1, typename T2, typename T3>
16991  class T0oT1oT2oT3_sf4 exprtk_final : public T0oT1oT2_base_node<T>
16992  {
16993  public:
16994 
16996  typedef typename functor_t::qfunc_t qfunc_t;
16997  typedef T value_type;
16998  typedef T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> node_type;
16999 
17000  T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
17001  : t0_(p0)
17002  , t1_(p1)
17003  , t2_(p2)
17004  , t3_(p3)
17005  , f_ (p4)
17006  {}
17007 
17009  {
17011  return result;
17012  }
17013 
17015  {
17016  return e_default;
17017  }
17018 
17020  {
17021  return f_(t0_, t1_, t2_, t3_);
17022  }
17023 
17024  inline T0 t0() const
17025  {
17026  return t0_;
17027  }
17028 
17029  inline T1 t1() const
17030  {
17031  return t1_;
17032  }
17033 
17034  inline T2 t2() const
17035  {
17036  return t2_;
17037  }
17038 
17039  inline T3 t3() const
17040  {
17041  return t3_;
17042  }
17043 
17044  qfunc_t f() const
17045  {
17046  return f_;
17047  }
17048 
17049  std::string type_id() const
17050  {
17051  return id();
17052  }
17053 
17054  static inline std::string id()
17055  {
17056  return "sf4";
17057  }
17058 
17059  template <typename Allocator>
17060  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
17061  {
17062  return allocator
17063  .template allocate_type<node_type, T0, T1, T2, T3, qfunc_t>
17064  (p0, p1, p2, p3, p4);
17065  }
17066 
17067  private:
17068 
17071 
17072  T0 t0_;
17073  T1 t1_;
17074  T2 t2_;
17075  T3 t3_;
17076  const qfunc_t f_;
17077  };
17078 
17079  template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation>
17080  class T0oT1oT2oT3_sf4ext exprtk_final : public T0oT1oT2oT3_base_node<T>
17081  {
17082  public:
17083 
17084  typedef T value_type;
17085  typedef T0oT1oT2oT3_sf4ext<T, T0, T1, T2, T3, SF4Operation> node_type;
17086 
17087  T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
17088  : t0_(p0)
17089  , t1_(p1)
17090  , t2_(p2)
17091  , t3_(p3)
17092  {}
17093 
17095  {
17097  return result;
17098  }
17099 
17101  {
17102  return SF4Operation::process(t0_, t1_, t2_, t3_);
17103  }
17104 
17105  inline T0 t0() const
17106  {
17107  return t0_;
17108  }
17109 
17110  inline T1 t1() const
17111  {
17112  return t1_;
17113  }
17114 
17115  inline T2 t2() const
17116  {
17117  return t2_;
17118  }
17119 
17120  inline T3 t3() const
17121  {
17122  return t3_;
17123  }
17124 
17126  {
17127  return id();
17128  }
17129 
17130  static inline std::string id()
17131  {
17132  return SF4Operation::id();
17133  }
17134 
17135  template <typename Allocator>
17136  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3)
17137  {
17138  return allocator
17139  .template allocate_type<node_type, T0, T1, T2, T3>
17140  (p0, p1, p2, p3);
17141  }
17142 
17143  private:
17144 
17147 
17148  T0 t0_;
17149  T1 t1_;
17150  T2 t2_;
17151  T3 t3_;
17152  };
17153 
17154  template <typename T>
17155  inline bool is_sf4ext_node(const expression_node<T>* n)
17156  {
17157  switch (n->type())
17158  {
17159  case expression_node<T>::e_vovovov : return true;
17160  case expression_node<T>::e_vovovoc : return true;
17161  case expression_node<T>::e_vovocov : return true;
17162  case expression_node<T>::e_vocovov : return true;
17163  case expression_node<T>::e_covovov : return true;
17164  case expression_node<T>::e_covocov : return true;
17165  case expression_node<T>::e_vocovoc : return true;
17166  case expression_node<T>::e_covovoc : return true;
17167  case expression_node<T>::e_vococov : return true;
17168  default : return false;
17169  }
17170  }
17171 
17172  template <typename T, typename T0, typename T1>
17174  {
17175  typedef details::T0oT1<T, T0, T1> type0;
17176  };
17177 
17178  template <typename T, typename T0, typename T1, typename T2>
17180  {
17181  typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode0> type0;
17182  typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode1> type1;
17183  typedef details::T0oT1oT2_sf3<T, T0, T1, T2> sf3_type;
17185  };
17186 
17187  template <typename T, typename T0, typename T1, typename T2, typename T3>
17189  {
17190  typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode0> type0;
17191  typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode1> type1;
17192  typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode2> type2;
17193  typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode3> type3;
17194  typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode4> type4;
17195  typedef details::T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> sf4_type;
17196  };
17197 
17198  template <typename T, typename Operation>
17199  class vov_node exprtk_final : public vov_base_node<T>
17200  {
17201  public:
17202 
17204  typedef Operation operation_t;
17205 
17206  // variable op variable node
17207  explicit vov_node(const T& var0, const T& var1)
17208  : v0_(var0)
17209  , v1_(var1)
17210  {}
17211 
17213  {
17214  return Operation::process(v0_,v1_);
17215  }
17216 
17218  {
17219  return Operation::type();
17220  }
17221 
17223  {
17224  return Operation::operation();
17225  }
17226 
17227  inline const T& v0() const exprtk_override
17228  {
17229  return v0_;
17230  }
17231 
17232  inline const T& v1() const exprtk_override
17233  {
17234  return v1_;
17235  }
17236 
17237  protected:
17238 
17239  const T& v0_;
17240  const T& v1_;
17241 
17242  private:
17243 
17244  vov_node(const vov_node<T,Operation>&) exprtk_delete;
17245  vov_node<T,Operation>& operator=(const vov_node<T,Operation>&) exprtk_delete;
17246  };
17247 
17248  template <typename T, typename Operation>
17249  class cov_node exprtk_final : public cov_base_node<T>
17250  {
17251  public:
17252 
17254  typedef Operation operation_t;
17255 
17256  // constant op variable node
17257  explicit cov_node(const T& const_var, const T& var)
17258  : c_(const_var)
17259  , v_(var)
17260  {}
17261 
17263  {
17264  return Operation::process(c_,v_);
17265  }
17266 
17268  {
17269  return Operation::type();
17270  }
17271 
17273  {
17274  return Operation::operation();
17275  }
17276 
17277  inline const T c() const exprtk_override
17278  {
17279  return c_;
17280  }
17281 
17282  inline const T& v() const exprtk_override
17283  {
17284  return v_;
17285  }
17286 
17287  protected:
17288 
17289  const T c_;
17290  const T& v_;
17291 
17292  private:
17293 
17294  cov_node(const cov_node<T,Operation>&) exprtk_delete;
17295  cov_node<T,Operation>& operator=(const cov_node<T,Operation>&) exprtk_delete;
17296  };
17297 
17298  template <typename T, typename Operation>
17299  class voc_node exprtk_final : public voc_base_node<T>
17300  {
17301  public:
17302 
17304  typedef Operation operation_t;
17305 
17306  // variable op constant node
17307  explicit voc_node(const T& var, const T& const_var)
17308  : v_(var)
17309  , c_(const_var)
17310  {}
17311 
17313  {
17314  return Operation::process(v_,c_);
17315  }
17316 
17318  {
17319  return Operation::operation();
17320  }
17321 
17322  inline const T c() const exprtk_override
17323  {
17324  return c_;
17325  }
17326 
17327  inline const T& v() const exprtk_override
17328  {
17329  return v_;
17330  }
17331 
17332  protected:
17333 
17334  const T& v_;
17335  const T c_;
17336 
17337  private:
17338 
17339  voc_node(const voc_node<T,Operation>&) exprtk_delete;
17340  voc_node<T,Operation>& operator=(const voc_node<T,Operation>&) exprtk_delete;
17341  };
17342 
17343  template <typename T, typename Operation>
17344  class vob_node exprtk_final : public vob_base_node<T>
17345  {
17346  public:
17347 
17349  typedef std::pair<expression_ptr,bool> branch_t;
17350  typedef Operation operation_t;
17351 
17352  // variable op binary node
17353  explicit vob_node(const T& var, const expression_ptr branch)
17354  : v_(var)
17355  {
17356  construct_branch_pair(branch_, branch);
17357  assert(valid());
17358  }
17359 
17361  {
17362  return Operation::process(v_,branch_.first->value());
17363  }
17364 
17365  inline const T& v() const exprtk_override
17366  {
17367  return v_;
17368  }
17369 
17371  {
17372  return branch_.first && branch_.first->valid();
17373  }
17374 
17375  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
17376  {
17377  return branch_.first;
17378  }
17379 
17381  {
17382  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
17383  }
17384 
17386  {
17388  }
17389 
17390  private:
17391 
17392  vob_node(const vob_node<T,Operation>&) exprtk_delete;
17393  vob_node<T,Operation>& operator=(const vob_node<T,Operation>&) exprtk_delete;
17394 
17395  const T& v_;
17396  branch_t branch_;
17397  };
17398 
17399  template <typename T, typename Operation>
17400  class bov_node exprtk_final : public bov_base_node<T>
17401  {
17402  public:
17403 
17405  typedef std::pair<expression_ptr,bool> branch_t;
17406  typedef Operation operation_t;
17407 
17408  // binary node op variable node
17409  explicit bov_node(const expression_ptr branch, const T& var)
17410  : v_(var)
17411  {
17412  construct_branch_pair(branch_, branch);
17413  assert(valid());
17414  }
17415 
17417  {
17418  return Operation::process(branch_.first->value(),v_);
17419  }
17420 
17421  inline const T& v() const exprtk_override
17422  {
17423  return v_;
17424  }
17425 
17427  {
17428  return branch_.first && branch_.first->valid();
17429  }
17430 
17431  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
17432  {
17433  return branch_.first;
17434  }
17435 
17437  {
17438  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
17439  }
17440 
17442  {
17444  }
17445 
17446  private:
17447 
17448  bov_node(const bov_node<T,Operation>&) exprtk_delete;
17449  bov_node<T,Operation>& operator=(const bov_node<T,Operation>&) exprtk_delete;
17450 
17451  const T& v_;
17452  branch_t branch_;
17453  };
17454 
17455  template <typename T, typename Operation>
17456  class cob_node exprtk_final : public cob_base_node<T>
17457  {
17458  public:
17459 
17461  typedef std::pair<expression_ptr,bool> branch_t;
17462  typedef Operation operation_t;
17463 
17464  // constant op variable node
17465  explicit cob_node(const T const_var, const expression_ptr branch)
17466  : c_(const_var)
17467  {
17468  construct_branch_pair(branch_, branch);
17469  assert(valid());
17470  }
17471 
17473  {
17474  return Operation::process(c_,branch_.first->value());
17475  }
17476 
17478  {
17479  return Operation::operation();
17480  }
17481 
17482  inline const T c() const exprtk_override
17483  {
17484  return c_;
17485  }
17486 
17487  inline void set_c(const T new_c) exprtk_override
17488  {
17489  (*const_cast<T*>(&c_)) = new_c;
17490  }
17491 
17493  {
17494  return branch_.first && branch_.first->valid();
17495  }
17496 
17497  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
17498  {
17499  return branch_.first;
17500  }
17501 
17502  inline expression_node<T>* move_branch(const std::size_t&) exprtk_override
17503  {
17504  branch_.second = false;
17505  return branch_.first;
17506  }
17507 
17509  {
17510  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
17511  }
17512 
17514  {
17516  }
17517 
17518  private:
17519 
17520  cob_node(const cob_node<T,Operation>&) exprtk_delete;
17521  cob_node<T,Operation>& operator=(const cob_node<T,Operation>&) exprtk_delete;
17522 
17523  const T c_;
17524  branch_t branch_;
17525  };
17526 
17527  template <typename T, typename Operation>
17528  class boc_node exprtk_final : public boc_base_node<T>
17529  {
17530  public:
17531 
17533  typedef std::pair<expression_ptr,bool> branch_t;
17534  typedef Operation operation_t;
17535 
17536  // binary node op constant node
17537  explicit boc_node(const expression_ptr branch, const T const_var)
17538  : c_(const_var)
17539  {
17540  construct_branch_pair(branch_, branch);
17541  assert(valid());
17542  }
17543 
17545  {
17546  return Operation::process(branch_.first->value(),c_);
17547  }
17548 
17550  {
17551  return Operation::operation();
17552  }
17553 
17554  inline const T c() const exprtk_override
17555  {
17556  return c_;
17557  }
17558 
17559  inline void set_c(const T new_c) exprtk_override
17560  {
17561  (*const_cast<T*>(&c_)) = new_c;
17562  }
17563 
17565  {
17566  return branch_.first && branch_.first->valid();
17567  }
17568 
17569  inline expression_node<T>* branch(const std::size_t&) const exprtk_override
17570  {
17571  return branch_.first;
17572  }
17573 
17574  inline expression_node<T>* move_branch(const std::size_t&) exprtk_override
17575  {
17576  branch_.second = false;
17577  return branch_.first;
17578  }
17579 
17581  {
17582  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
17583  }
17584 
17586  {
17588  }
17589 
17590  private:
17591 
17592  boc_node(const boc_node<T,Operation>&) exprtk_delete;
17593  boc_node<T,Operation>& operator=(const boc_node<T,Operation>&) exprtk_delete;
17594 
17595  const T c_;
17596  branch_t branch_;
17597  };
17598 
17599  #ifndef exprtk_disable_string_capabilities
17600  template <typename T, typename SType0, typename SType1, typename Operation>
17601  class sos_node exprtk_final : public sos_base_node<T>
17602  {
17603  public:
17604 
17606  typedef Operation operation_t;
17607 
17608  // string op string node
17609  explicit sos_node(SType0 p0, SType1 p1)
17610  : s0_(p0)
17611  , s1_(p1)
17612  {}
17613 
17615  {
17616  return Operation::process(s0_,s1_);
17617  }
17618 
17620  {
17621  return Operation::type();
17622  }
17623 
17625  {
17626  return Operation::operation();
17627  }
17628 
17629  inline std::string& s0()
17630  {
17631  return s0_;
17632  }
17633 
17634  inline std::string& s1()
17635  {
17636  return s1_;
17637  }
17638 
17639  protected:
17640 
17641  SType0 s0_;
17642  SType1 s1_;
17643 
17644  private:
17645 
17646  sos_node(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete;
17647  sos_node<T,SType0,SType1,Operation>& operator=(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete;
17648  };
17649 
17650  template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
17651  class str_xrox_node exprtk_final : public sos_base_node<T>
17652  {
17653  public:
17654 
17656  typedef Operation operation_t;
17657  typedef str_xrox_node<T,SType0,SType1,RangePack,Operation> node_type;
17658 
17659  // string-range op string node
17660  explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
17661  : s0_ (p0 )
17662  , s1_ (p1 )
17663  , rp0_(rp0)
17664  {}
17665 
17667  {
17668  rp0_.free();
17669  }
17670 
17672  {
17673  std::size_t r0 = 0;
17674  std::size_t r1 = 0;
17675 
17676  if (rp0_(r0, r1, s0_.size()))
17677  return Operation::process(s0_.substr(r0, (r1 - r0) + 1), s1_);
17678  else
17679  return T(0);
17680  }
17681 
17683  {
17684  return Operation::type();
17685  }
17686 
17688  {
17689  return Operation::operation();
17690  }
17691 
17692  inline std::string& s0()
17693  {
17694  return s0_;
17695  }
17696 
17697  inline std::string& s1()
17698  {
17699  return s1_;
17700  }
17701 
17702  protected:
17703 
17704  SType0 s0_;
17705  SType1 s1_;
17706  RangePack rp0_;
17707 
17708  private:
17709 
17712  };
17713 
17714  template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
17715  class str_xoxr_node exprtk_final : public sos_base_node<T>
17716  {
17717  public:
17718 
17720  typedef Operation operation_t;
17721  typedef str_xoxr_node<T,SType0,SType1,RangePack,Operation> node_type;
17722 
17723  // string op string range node
17724  explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
17725  : s0_ (p0 )
17726  , s1_ (p1 )
17727  , rp1_(rp1)
17728  {}
17729 
17731  {
17732  rp1_.free();
17733  }
17734 
17736  {
17737  std::size_t r0 = 0;
17738  std::size_t r1 = 0;
17739 
17740  if (rp1_(r0, r1, s1_.size()))
17741  {
17742  return Operation::process
17743  (
17744  s0_,
17745  s1_.substr(r0, (r1 - r0) + 1)
17746  );
17747  }
17748  else
17749  return T(0);
17750  }
17751 
17753  {
17754  return Operation::type();
17755  }
17756 
17758  {
17759  return Operation::operation();
17760  }
17761 
17762  inline std::string& s0()
17763  {
17764  return s0_;
17765  }
17766 
17767  inline std::string& s1()
17768  {
17769  return s1_;
17770  }
17771 
17772  protected:
17773 
17774  SType0 s0_;
17775  SType1 s1_;
17776  RangePack rp1_;
17777 
17778  private:
17779 
17782  };
17783 
17784  template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
17785  class str_xroxr_node exprtk_final : public sos_base_node<T>
17786  {
17787  public:
17788 
17790  typedef Operation operation_t;
17791  typedef str_xroxr_node<T,SType0,SType1,RangePack,Operation> node_type;
17792 
17793  // string-range op string-range node
17794  explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
17795  : s0_ (p0 )
17796  , s1_ (p1 )
17797  , rp0_(rp0)
17798  , rp1_(rp1)
17799  {}
17800 
17802  {
17803  rp0_.free();
17804  rp1_.free();
17805  }
17806 
17808  {
17809  std::size_t r0_0 = 0;
17810  std::size_t r0_1 = 0;
17811  std::size_t r1_0 = 0;
17812  std::size_t r1_1 = 0;
17813 
17814  if (
17815  rp0_(r0_0, r1_0, s0_.size()) &&
17816  rp1_(r0_1, r1_1, s1_.size())
17817  )
17818  {
17819  return Operation::process
17820  (
17821  s0_.substr(r0_0, (r1_0 - r0_0) + 1),
17822  s1_.substr(r0_1, (r1_1 - r0_1) + 1)
17823  );
17824  }
17825  else
17826  return T(0);
17827  }
17828 
17830  {
17831  return Operation::type();
17832  }
17833 
17835  {
17836  return Operation::operation();
17837  }
17838 
17839  inline std::string& s0()
17840  {
17841  return s0_;
17842  }
17843 
17844  inline std::string& s1()
17845  {
17846  return s1_;
17847  }
17848 
17849  protected:
17850 
17851  SType0 s0_;
17852  SType1 s1_;
17853  RangePack rp0_;
17854  RangePack rp1_;
17855 
17856  private:
17857 
17860  };
17861 
17862  template <typename T, typename Operation>
17863  class str_sogens_node exprtk_final : public binary_node<T>
17864  {
17865  public:
17866 
17870  typedef range_t* range_ptr;
17873 
17874  using binary_node<T>::branch;
17875 
17877  expression_ptr branch0,
17878  expression_ptr branch1)
17879  : binary_node<T>(opr, branch0, branch1)
17880  , str0_base_ptr_ (0)
17881  , str1_base_ptr_ (0)
17882  , str0_range_ptr_(0)
17883  , str1_range_ptr_(0)
17884  , initialised_ (false)
17885  {
17886  if (is_generally_string_node(branch(0)))
17887  {
17888  str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0));
17889 
17890  if (0 == str0_base_ptr_)
17891  return;
17892 
17893  irange_ptr range = dynamic_cast<irange_ptr>(branch(0));
17894 
17895  if (0 == range)
17896  return;
17897 
17898  str0_range_ptr_ = &(range->range_ref());
17899  }
17900 
17901  if (is_generally_string_node(branch(1)))
17902  {
17903  str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1));
17904 
17905  if (0 == str1_base_ptr_)
17906  return;
17907 
17908  irange_ptr range = dynamic_cast<irange_ptr>(branch(1));
17909 
17910  if (0 == range)
17911  return;
17912 
17913  str1_range_ptr_ = &(range->range_ref());
17914  }
17915 
17916  initialised_ =
17917  str0_base_ptr_ &&
17918  str1_base_ptr_ &&
17919  str0_range_ptr_ &&
17920  str1_range_ptr_;
17921 
17922  assert(valid());
17923  }
17924 
17926  {
17927  branch(0)->value();
17928  branch(1)->value();
17929 
17930  std::size_t str0_r0 = 0;
17931  std::size_t str0_r1 = 0;
17932 
17933  std::size_t str1_r0 = 0;
17934  std::size_t str1_r1 = 0;
17935 
17936  const range_t& range0 = (*str0_range_ptr_);
17937  const range_t& range1 = (*str1_range_ptr_);
17938 
17939  if (
17940  range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
17941  range1(str1_r0, str1_r1, str1_base_ptr_->size())
17942  )
17943  {
17944  return Operation::process
17945  (
17946  str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0)),
17947  str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0))
17948  );
17949  }
17950 
17951  return std::numeric_limits<T>::quiet_NaN();
17952  }
17953 
17955  {
17956  return Operation::type();
17957  }
17958 
17960  {
17961  return initialised_;
17962  }
17963 
17964  private:
17965 
17966  str_sogens_node(const str_sogens_node<T,Operation>&) exprtk_delete;
17967  str_sogens_node<T,Operation>& operator=(const str_sogens_node<T,Operation>&) exprtk_delete;
17968 
17969  str_base_ptr str0_base_ptr_;
17970  str_base_ptr str1_base_ptr_;
17971  range_ptr str0_range_ptr_;
17972  range_ptr str1_range_ptr_;
17973  bool initialised_;
17974  };
17975 
17976  template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
17977  class sosos_node exprtk_final : public sosos_base_node<T>
17978  {
17979  public:
17980 
17982  typedef Operation operation_t;
17983  typedef sosos_node<T, SType0, SType1, SType2, Operation> node_type;
17984 
17985  // string op string op string node
17986  explicit sosos_node(SType0 p0, SType1 p1, SType2 p2)
17987  : s0_(p0)
17988  , s1_(p1)
17989  , s2_(p2)
17990  {}
17991 
17993  {
17994  return Operation::process(s0_, s1_, s2_);
17995  }
17996 
17998  {
17999  return Operation::type();
18000  }
18001 
18003  {
18004  return Operation::operation();
18005  }
18006 
18007  inline std::string& s0()
18008  {
18009  return s0_;
18010  }
18011 
18012  inline std::string& s1()
18013  {
18014  return s1_;
18015  }
18016 
18017  inline std::string& s2()
18018  {
18019  return s2_;
18020  }
18021 
18022  protected:
18023 
18024  SType0 s0_;
18025  SType1 s1_;
18026  SType2 s2_;
18027 
18028  private:
18029 
18032  };
18033  #endif
18034 
18035  template <typename T, typename PowOp>
18036  class ipow_node exprtk_final: public expression_node<T>
18037  {
18038  public:
18039 
18041  typedef PowOp operation_t;
18042 
18043  explicit ipow_node(const T& v)
18044  : v_(v)
18045  {}
18046 
18048  {
18049  return PowOp::result(v_);
18050  }
18051 
18053  {
18055  }
18056 
18057  private:
18058 
18059  ipow_node(const ipow_node<T,PowOp>&) exprtk_delete;
18060  ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&) exprtk_delete;
18061 
18062  const T& v_;
18063  };
18064 
18065  template <typename T, typename PowOp>
18066  class bipow_node exprtk_final : public expression_node<T>
18067  {
18068  public:
18069 
18071  typedef std::pair<expression_ptr, bool> branch_t;
18072  typedef PowOp operation_t;
18073 
18074  explicit bipow_node(expression_ptr branch)
18075  {
18076  construct_branch_pair(branch_, branch);
18077  assert(valid());
18078  }
18079 
18081  {
18082  return PowOp::result(branch_.first->value());
18083  }
18084 
18086  {
18088  }
18089 
18091  {
18092  return branch_.first && branch_.first->valid();
18093  }
18094 
18096  {
18097  expression_node<T>::ndb_t::collect(branch_, node_delete_list);
18098  }
18099 
18101  {
18103  }
18104 
18105  private:
18106 
18107  bipow_node(const bipow_node<T,PowOp>&) exprtk_delete;
18108  bipow_node<T,PowOp>& operator=(const bipow_node<T,PowOp>&) exprtk_delete;
18109 
18110  branch_t branch_;
18111  };
18112 
18113  template <typename T, typename PowOp>
18114  class ipowinv_node exprtk_final : public expression_node<T>
18115  {
18116  public:
18117 
18119  typedef PowOp operation_t;
18120 
18121  explicit ipowinv_node(const T& v)
18122  : v_(v)
18123  {}
18124 
18126  {
18127  return (T(1) / PowOp::result(v_));
18128  }
18129 
18131  {
18133  }
18134 
18135  private:
18136 
18137  ipowinv_node(const ipowinv_node<T,PowOp>&) exprtk_delete;
18138  ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&) exprtk_delete;
18139 
18140  const T& v_;
18141  };
18142 
18143  template <typename T, typename PowOp>
18144  class bipowinv_node exprtk_final : public expression_node<T>
18145  {
18146  public:
18147 
18149  typedef std::pair<expression_ptr, bool> branch_t;
18150  typedef PowOp operation_t;
18151 
18153  {
18154  construct_branch_pair(branch_, branch);
18155  assert(valid());
18156  }
18157 
18159  {
18160  return (T(1) / PowOp::result(branch_.first->value()));
18161  }
18162 
18164  {
18166  }
18167 
18169  {
18170  return branch_.first && branch_.first->valid();
18171  }
18172 
18174  {
18175  expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
18176  }
18177 
18179  {
18181  }
18182 
18183  private:
18184 
18185  bipowinv_node(const bipowinv_node<T,PowOp>&) exprtk_delete;
18186  bipowinv_node<T,PowOp>& operator=(const bipowinv_node<T,PowOp>&) exprtk_delete;
18187 
18188  branch_t branch_;
18189  };
18190 
18191  template <typename T>
18192  inline bool is_vov_node(const expression_node<T>* node)
18193  {
18194  return (0 != dynamic_cast<const vov_base_node<T>*>(node));
18195  }
18196 
18197  template <typename T>
18198  inline bool is_cov_node(const expression_node<T>* node)
18199  {
18200  return (0 != dynamic_cast<const cov_base_node<T>*>(node));
18201  }
18202 
18203  template <typename T>
18204  inline bool is_voc_node(const expression_node<T>* node)
18205  {
18206  return (0 != dynamic_cast<const voc_base_node<T>*>(node));
18207  }
18208 
18209  template <typename T>
18210  inline bool is_cob_node(const expression_node<T>* node)
18211  {
18212  return (0 != dynamic_cast<const cob_base_node<T>*>(node));
18213  }
18214 
18215  template <typename T>
18216  inline bool is_boc_node(const expression_node<T>* node)
18217  {
18218  return (0 != dynamic_cast<const boc_base_node<T>*>(node));
18219  }
18220 
18221  template <typename T>
18222  inline bool is_t0ot1ot2_node(const expression_node<T>* node)
18223  {
18224  return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node));
18225  }
18226 
18227  template <typename T>
18228  inline bool is_t0ot1ot2ot3_node(const expression_node<T>* node)
18229  {
18230  return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node));
18231  }
18232 
18233  template <typename T>
18234  inline bool is_uv_node(const expression_node<T>* node)
18235  {
18236  return (0 != dynamic_cast<const uv_base_node<T>*>(node));
18237  }
18238 
18239  template <typename T>
18240  inline bool is_string_node(const expression_node<T>* node)
18241  {
18242  return node && (expression_node<T>::e_stringvar == node->type());
18243  }
18244 
18245  template <typename T>
18246  inline bool is_string_range_node(const expression_node<T>* node)
18247  {
18248  return node && (expression_node<T>::e_stringvarrng == node->type());
18249  }
18250 
18251  template <typename T>
18252  inline bool is_const_string_node(const expression_node<T>* node)
18253  {
18254  return node && (expression_node<T>::e_stringconst == node->type());
18255  }
18256 
18257  template <typename T>
18259  {
18260  return node && (expression_node<T>::e_cstringvarrng == node->type());
18261  }
18262 
18263  template <typename T>
18265  {
18266  return node && (expression_node<T>::e_strass == node->type());
18267  }
18268 
18269  template <typename T>
18271  {
18272  return node && (expression_node<T>::e_strconcat == node->type());
18273  }
18274 
18275  template <typename T>
18277  {
18278  return node && (expression_node<T>::e_strfunction == node->type());
18279  }
18280 
18281  template <typename T>
18283  {
18284  return node && (expression_node<T>::e_strcondition == node->type());
18285  }
18286 
18287  template <typename T>
18289  {
18290  return node && (expression_node<T>::e_strccondition == node->type());
18291  }
18292 
18293  template <typename T>
18295  {
18296  return node && (expression_node<T>::e_stringvararg == node->type());
18297  }
18298 
18299  template <typename T>
18301  {
18302  return node && (expression_node<T>::e_strgenrange == node->type());
18303  }
18304 
18305  template <typename T>
18307  {
18308  if (node)
18309  {
18310  switch (node->type())
18311  {
18322  case expression_node<T>::e_stringvararg : return true;
18323  default : return false;
18324  }
18325  }
18326 
18327  return false;
18328  }
18329 
18331  {
18332  public:
18333 
18334  template <typename ResultNode, typename OpType, typename ExprNode>
18335  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1])
18336  {
18338  allocate<ResultNode>(operation, branch[0]);
18339  result->node_depth();
18340  return result;
18341  }
18342 
18343  template <typename ResultNode, typename OpType, typename ExprNode>
18344  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[2])
18345  {
18347  allocate<ResultNode>(operation, branch[0], branch[1]);
18348  result->node_depth();
18349  return result;
18350  }
18351 
18352  template <typename ResultNode, typename OpType, typename ExprNode>
18353  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[3])
18354  {
18356  allocate<ResultNode>(operation, branch[0], branch[1], branch[2]);
18357  result->node_depth();
18358  return result;
18359  }
18360 
18361  template <typename ResultNode, typename OpType, typename ExprNode>
18362  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[4])
18363  {
18365  allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3]);
18366  result->node_depth();
18367  return result;
18368  }
18369 
18370  template <typename ResultNode, typename OpType, typename ExprNode>
18371  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5])
18372  {
18374  allocate<ResultNode>(operation, branch[0],branch[1], branch[2], branch[3], branch[4]);
18375  result->node_depth();
18376  return result;
18377  }
18378 
18379  template <typename ResultNode, typename OpType, typename ExprNode>
18380  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6])
18381  {
18383  allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3], branch[4], branch[5]);
18384  result->node_depth();
18385  return result;
18386  }
18387 
18388  template <typename node_type>
18390  {
18391  return (new node_type());
18392  }
18393 
18394  template <typename node_type,
18395  typename Type,
18396  typename Allocator,
18397  template <typename, typename> class Sequence>
18398  inline expression_node<typename node_type::value_type>* allocate(const Sequence<Type,Allocator>& seq) const
18399  {
18401  result = (new node_type(seq));
18402  result->node_depth();
18403  return result;
18404  }
18405 
18406  template <typename node_type, typename T1>
18408  {
18410  result = (new node_type(t1));
18411  result->node_depth();
18412  return result;
18413  }
18414 
18415  template <typename node_type, typename T1>
18417  {
18419  result = (new node_type(t1));
18420  result->node_depth();
18421  return result;
18422  }
18423 
18424  template <typename node_type,
18425  typename T1, typename T2>
18427  {
18429  result = (new node_type(t1, t2));
18430  result->node_depth();
18431  return result;
18432  }
18433 
18434  template <typename node_type,
18435  typename T1, typename T2>
18437  {
18439  result = (new node_type(t1, t2));
18440  result->node_depth();
18441  return result;
18442  }
18443 
18444  template <typename node_type,
18445  typename T1, typename T2>
18447  {
18449  result = (new node_type(t1, t2));
18450  result->node_depth();
18451  return result;
18452  }
18453 
18454  template <typename node_type,
18455  typename T1, typename T2>
18457  {
18459  result = (new node_type(t1, t2));
18460  result->node_depth();
18461  return result;
18462  }
18463 
18464  template <typename node_type,
18465  typename T1, typename T2>
18467  {
18469  result = (new node_type(t1, t2));
18470  result->node_depth();
18471  return result;
18472  }
18473 
18474  template <typename node_type,
18475  typename T1, typename T2, typename T3>
18477  {
18479  result = (new node_type(t1, t2, t3));
18480  result->node_depth();
18481  return result;
18482  }
18483 
18484  template <typename node_type,
18485  typename T1, typename T2, typename T3, typename T4>
18487  {
18489  result = (new node_type(t1, t2, t3, t4));
18490  result->node_depth();
18491  return result;
18492  }
18493 
18494  template <typename node_type,
18495  typename T1, typename T2, typename T3>
18497  {
18499  result = (new node_type(t1, t2, t3));
18500  result->node_depth();
18501  return result;
18502  }
18503 
18504  template <typename node_type,
18505  typename T1, typename T2, typename T3, typename T4>
18507  {
18509  result = (new node_type(t1, t2, t3, t4));
18510  result->node_depth();
18511  return result;
18512  }
18513 
18514  template <typename node_type,
18515  typename T1, typename T2, typename T3, typename T4, typename T5>
18516  inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
18517  {
18519  result = (new node_type(t1, t2, t3, t4, t5));
18520  result->node_depth();
18521  return result;
18522  }
18523 
18524  template <typename node_type,
18525  typename T1, typename T2, typename T3>
18527  const T3& t3) const
18528  {
18530  result = (new node_type(t1, t2, t3));
18531  result->node_depth();
18532  return result;
18533  }
18534 
18535  template <typename node_type,
18536  typename T1, typename T2,
18537  typename T3, typename T4>
18539  const T3& t3, const T4& t4) const
18540  {
18542  result = (new node_type(t1, t2, t3, t4));
18543  result->node_depth();
18544  return result;
18545  }
18546 
18547  template <typename node_type,
18548  typename T1, typename T2,
18549  typename T3, typename T4, typename T5>
18551  const T3& t3, const T4& t4,
18552  const T5& t5) const
18553  {
18555  result = (new node_type(t1, t2, t3, t4, t5));
18556  result->node_depth();
18557  return result;
18558  }
18559 
18560  template <typename node_type,
18561  typename T1, typename T2,
18562  typename T3, typename T4, typename T5, typename T6>
18564  const T3& t3, const T4& t4,
18565  const T5& t5, const T6& t6) const
18566  {
18568  result = (new node_type(t1, t2, t3, t4, t5, t6));
18569  result->node_depth();
18570  return result;
18571  }
18572 
18573  template <typename node_type,
18574  typename T1, typename T2,
18575  typename T3, typename T4,
18576  typename T5, typename T6, typename T7>
18578  const T3& t3, const T4& t4,
18579  const T5& t5, const T6& t6,
18580  const T7& t7) const
18581  {
18583  result = (new node_type(t1, t2, t3, t4, t5, t6, t7));
18584  result->node_depth();
18585  return result;
18586  }
18587 
18588  template <typename node_type,
18589  typename T1, typename T2,
18590  typename T3, typename T4,
18591  typename T5, typename T6,
18592  typename T7, typename T8>
18594  const T3& t3, const T4& t4,
18595  const T5& t5, const T6& t6,
18596  const T7& t7, const T8& t8) const
18597  {
18599  result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8));
18600  result->node_depth();
18601  return result;
18602  }
18603 
18604  template <typename node_type,
18605  typename T1, typename T2,
18606  typename T3, typename T4,
18607  typename T5, typename T6,
18608  typename T7, typename T8, typename T9>
18610  const T3& t3, const T4& t4,
18611  const T5& t5, const T6& t6,
18612  const T7& t7, const T8& t8,
18613  const T9& t9) const
18614  {
18616  result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9));
18617  result->node_depth();
18618  return result;
18619  }
18620 
18621  template <typename node_type,
18622  typename T1, typename T2,
18623  typename T3, typename T4,
18624  typename T5, typename T6,
18625  typename T7, typename T8,
18626  typename T9, typename T10>
18628  const T3& t3, const T4& t4,
18629  const T5& t5, const T6& t6,
18630  const T7& t7, const T8& t8,
18631  const T9& t9, const T10& t10) const
18632  {
18634  result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10));
18635  result->node_depth();
18636  return result;
18637  }
18638 
18639  template <typename node_type,
18640  typename T1, typename T2, typename T3>
18642  {
18644  result = (new node_type(t1, t2, t3));
18645  result->node_depth();
18646  return result;
18647  }
18648 
18649  template <typename node_type,
18650  typename T1, typename T2,
18651  typename T3, typename T4>
18653  T3 t3, T4 t4) const
18654  {
18656  result = (new node_type(t1, t2, t3, t4));
18657  result->node_depth();
18658  return result;
18659  }
18660 
18661  template <typename node_type,
18662  typename T1, typename T2,
18663  typename T3, typename T4,
18664  typename T5>
18666  T3 t3, T4 t4,
18667  T5 t5) const
18668  {
18670  result = (new node_type(t1, t2, t3, t4, t5));
18671  result->node_depth();
18672  return result;
18673  }
18674 
18675  template <typename node_type,
18676  typename T1, typename T2,
18677  typename T3, typename T4,
18678  typename T5, typename T6>
18680  T3 t3, T4 t4,
18681  T5 t5, T6 t6) const
18682  {
18684  result = (new node_type(t1, t2, t3, t4, t5, t6));
18685  result->node_depth();
18686  return result;
18687  }
18688 
18689  template <typename node_type,
18690  typename T1, typename T2,
18691  typename T3, typename T4,
18692  typename T5, typename T6, typename T7>
18694  T3 t3, T4 t4,
18695  T5 t5, T6 t6,
18696  T7 t7) const
18697  {
18699  result = (new node_type(t1, t2, t3, t4, t5, t6, t7));
18700  result->node_depth();
18701  return result;
18702  }
18703 
18704  template <typename T>
18705  void inline free(expression_node<T>*& e) const
18706  {
18707  exprtk_debug(("node_allocator::free() - deleting expression_node "
18708  "type: %03d addr: %p\n",
18709  static_cast<int>(e->type()),
18710  reinterpret_cast<void*>(e)));
18711  delete e;
18712  e = 0;
18713  }
18714  };
18715 
18716  inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
18717  {
18718  #define register_op(Symbol, Type, Args) \
18719  m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
18720 
18721  register_op("abs" , e_abs , 1)
18722  register_op("acos" , e_acos , 1)
18723  register_op("acosh" , e_acosh , 1)
18724  register_op("asin" , e_asin , 1)
18725  register_op("asinh" , e_asinh , 1)
18726  register_op("atan" , e_atan , 1)
18727  register_op("atanh" , e_atanh , 1)
18728  register_op("ceil" , e_ceil , 1)
18729  register_op("cos" , e_cos , 1)
18730  register_op("cosh" , e_cosh , 1)
18731  register_op("exp" , e_exp , 1)
18732  register_op("expm1" , e_expm1 , 1)
18733  register_op("floor" , e_floor , 1)
18734  register_op("log" , e_log , 1)
18735  register_op("log10" , e_log10 , 1)
18736  register_op("log2" , e_log2 , 1)
18737  register_op("log1p" , e_log1p , 1)
18738  register_op("round" , e_round , 1)
18739  register_op("sin" , e_sin , 1)
18740  register_op("sinc" , e_sinc , 1)
18741  register_op("sinh" , e_sinh , 1)
18742  register_op("sec" , e_sec , 1)
18743  register_op("csc" , e_csc , 1)
18744  register_op("sqrt" , e_sqrt , 1)
18745  register_op("tan" , e_tan , 1)
18746  register_op("tanh" , e_tanh , 1)
18747  register_op("cot" , e_cot , 1)
18748  register_op("rad2deg" , e_r2d , 1)
18749  register_op("deg2rad" , e_d2r , 1)
18750  register_op("deg2grad" , e_d2g , 1)
18751  register_op("grad2deg" , e_g2d , 1)
18752  register_op("sgn" , e_sgn , 1)
18753  register_op("not" , e_notl , 1)
18754  register_op("erf" , e_erf , 1)
18755  register_op("erfc" , e_erfc , 1)
18756  register_op("ncdf" , e_ncdf , 1)
18757  register_op("frac" , e_frac , 1)
18758  register_op("trunc" , e_trunc , 1)
18759  register_op("atan2" , e_atan2 , 2)
18760  register_op("mod" , e_mod , 2)
18761  register_op("logn" , e_logn , 2)
18762  register_op("pow" , e_pow , 2)
18763  register_op("root" , e_root , 2)
18764  register_op("roundn" , e_roundn , 2)
18765  register_op("equal" , e_equal , 2)
18766  register_op("not_equal" , e_nequal , 2)
18767  register_op("hypot" , e_hypot , 2)
18768  register_op("shr" , e_shr , 2)
18769  register_op("shl" , e_shl , 2)
18770  register_op("clamp" , e_clamp , 3)
18771  register_op("iclamp" , e_iclamp , 3)
18772  register_op("inrange" , e_inrange , 3)
18773  #undef register_op
18774  }
18775 
18776  } // namespace details
18777 
18779  {
18780  public:
18781 
18783  : allow_zero_parameters_(false)
18784  , has_side_effects_(true)
18785  , min_num_args_(0)
18786  , max_num_args_(std::numeric_limits<std::size_t>::max())
18787  {}
18788 
18789  inline bool& allow_zero_parameters()
18790  {
18791  return allow_zero_parameters_;
18792  }
18793 
18794  inline bool& has_side_effects()
18795  {
18796  return has_side_effects_;
18797  }
18798 
18799  std::size_t& min_num_args()
18800  {
18801  return min_num_args_;
18802  }
18803 
18804  std::size_t& max_num_args()
18805  {
18806  return max_num_args_;
18807  }
18808 
18809  private:
18810 
18813  std::size_t min_num_args_;
18814  std::size_t max_num_args_;
18815  };
18816 
18817  template <typename FunctionType>
18818  void enable_zero_parameters(FunctionType& func)
18819  {
18820  func.allow_zero_parameters() = true;
18821 
18822  if (0 != func.min_num_args())
18823  {
18824  func.min_num_args() = 0;
18825  }
18826  }
18827 
18828  template <typename FunctionType>
18829  void disable_zero_parameters(FunctionType& func)
18830  {
18831  func.allow_zero_parameters() = false;
18832  }
18833 
18834  template <typename FunctionType>
18835  void enable_has_side_effects(FunctionType& func)
18836  {
18837  func.has_side_effects() = true;
18838  }
18839 
18840  template <typename FunctionType>
18841  void disable_has_side_effects(FunctionType& func)
18842  {
18843  func.has_side_effects() = false;
18844  }
18845 
18846  template <typename FunctionType>
18847  void set_min_num_args(FunctionType& func, const std::size_t& num_args)
18848  {
18849  func.min_num_args() = num_args;
18850 
18851  if ((0 != func.min_num_args()) && func.allow_zero_parameters())
18852  func.allow_zero_parameters() = false;
18853  }
18854 
18855  template <typename FunctionType>
18856  void set_max_num_args(FunctionType& func, const std::size_t& num_args)
18857  {
18858  func.max_num_args() = num_args;
18859  }
18860 
18861  template <typename T>
18863  {
18864  public:
18865 
18866  explicit ifunction(const std::size_t& pc)
18867  : param_count(pc)
18868  {}
18869 
18870  virtual ~ifunction()
18871  {}
18872 
18873  #define empty_method_body(N) \
18874  { \
18875  exprtk_debug(("ifunction::operator() - Operator(" #N ") has not been overridden\n")); \
18876  return std::numeric_limits<T>::quiet_NaN(); \
18877  } \
18878 
18879  inline virtual T operator() ()
18881 
18882  inline virtual T operator() (const T&)
18884 
18885  inline virtual T operator() (const T&,const T&)
18887 
18888  inline virtual T operator() (const T&, const T&, const T&)
18890 
18891  inline virtual T operator() (const T&, const T&, const T&, const T&)
18893 
18894  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&)
18896 
18897  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&)
18899 
18900  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18902 
18903  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18905 
18906  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18908 
18909  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18911 
18912  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18913  const T&)
18915 
18916  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18917  const T&, const T&)
18919 
18920  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18921  const T&, const T&, const T&)
18923 
18924  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18925  const T&, const T&, const T&, const T&)
18927 
18928  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18929  const T&, const T&, const T&, const T&, const T&)
18931 
18932  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18933  const T&, const T&, const T&, const T&, const T&, const T&)
18935 
18936  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18937  const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18939 
18940  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18941  const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18943 
18944  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18945  const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18947 
18948  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
18949  const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
18950  empty_method_body(20)
18951 
18952  #undef empty_method_body
18953 
18954  std::size_t param_count;
18955  };
18956 
18957  template <typename T>
18959  {
18960  public:
18961 
18963  {}
18964 
18965  inline virtual T operator() (const std::vector<T>&)
18966  {
18967  exprtk_debug(("ivararg_function::operator() - Operator has not been overridden\n"));
18968  return std::numeric_limits<T>::quiet_NaN();
18969  }
18970  };
18971 
18972  template <typename T>
18974  {
18975  public:
18976 
18978  {
18979  e_rtrn_scalar = 0,
18980  e_rtrn_string = 1,
18981  e_rtrn_overload = 2
18982  };
18983 
18984  typedef T type;
18987 
18988  explicit igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar)
18989  : parameter_sequence(param_seq)
18990  , rtrn_type(rtr_type)
18991  {}
18992 
18994  {}
18995 
18996  #define igeneric_function_empty_body(N) \
18997  { \
18998  exprtk_debug(("igeneric_function::operator() - Operator(" #N ") has not been overridden\n")); \
18999  return std::numeric_limits<T>::quiet_NaN(); \
19000  } \
19001 
19002  // f(i_0,i_1,....,i_N) --> Scalar
19003  inline virtual T operator() (parameter_list_t)
19005 
19006  // f(i_0,i_1,....,i_N) --> String
19007  inline virtual T operator() (std::string&, parameter_list_t)
19009 
19010  // f(psi,i_0,i_1,....,i_N) --> Scalar
19011  inline virtual T operator() (const std::size_t&, parameter_list_t)
19013 
19014  // f(psi,i_0,i_1,....,i_N) --> String
19015  inline virtual T operator() (const std::size_t&, std::string&, parameter_list_t)
19017 
19018  #undef igeneric_function_empty_body
19019 
19020  std::string parameter_sequence;
19022  };
19023 
19024  #ifndef exprtk_disable_string_capabilities
19025  template <typename T>
19027  {
19028  public:
19029 
19030  typedef typename details::stringvar_node<T> stringvar_node_t;
19031 
19032  stringvar_base(const std::string& name, stringvar_node_t* svn)
19033  : name_(name)
19034  , string_varnode_(svn)
19035  {}
19036 
19037  bool valid() const
19038  {
19039  return !name_.empty() && (0 != string_varnode_);
19040  }
19041 
19042  std::string name() const
19043  {
19044  assert(string_varnode_);
19045  return name_;
19046  }
19047 
19048  void rebase(std::string& s)
19049  {
19050  assert(string_varnode_);
19051  string_varnode_->rebase(s);
19052  }
19053 
19054  private:
19055 
19056  std::string name_;
19058  };
19059  #endif
19060 
19061  template <typename T> class parser;
19062  template <typename T> class expression_helper;
19063 
19064  template <typename T>
19066  {
19067  public:
19068 
19070  {
19072  e_mutable = 1,
19073  e_immutable = 2
19074  };
19075 
19076  typedef T (*ff00_functor)();
19077  typedef T (*ff01_functor)(T);
19078  typedef T (*ff02_functor)(T, T);
19079  typedef T (*ff03_functor)(T, T, T);
19080  typedef T (*ff04_functor)(T, T, T, T);
19081  typedef T (*ff05_functor)(T, T, T, T, T);
19082  typedef T (*ff06_functor)(T, T, T, T, T, T);
19083  typedef T (*ff07_functor)(T, T, T, T, T, T, T);
19084  typedef T (*ff08_functor)(T, T, T, T, T, T, T, T);
19085  typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T);
19086  typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T);
19087  typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T);
19088  typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T);
19089  typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T);
19090  typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T);
19091  typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T);
19092 
19093  protected:
19094 
19095  struct freefunc00 exprtk_final : public exprtk::ifunction<T>
19096  {
19098 
19099  explicit freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {}
19100  inline T operator() () exprtk_override
19101  { return f(); }
19102  ff00_functor f;
19103  };
19104 
19105  struct freefunc01 exprtk_final : public exprtk::ifunction<T>
19106  {
19108 
19109  explicit freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {}
19110  inline T operator() (const T& v0) exprtk_override
19111  { return f(v0); }
19112  ff01_functor f;
19113  };
19114 
19115  struct freefunc02 exprtk_final : public exprtk::ifunction<T>
19116  {
19118 
19119  explicit freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {}
19120  inline T operator() (const T& v0, const T& v1) exprtk_override
19121  { return f(v0, v1); }
19122  ff02_functor f;
19123  };
19124 
19125  struct freefunc03 exprtk_final : public exprtk::ifunction<T>
19126  {
19128 
19129  explicit freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {}
19130  inline T operator() (const T& v0, const T& v1, const T& v2) exprtk_override
19131  { return f(v0, v1, v2); }
19132  ff03_functor f;
19133  };
19134 
19135  struct freefunc04 exprtk_final : public exprtk::ifunction<T>
19136  {
19138 
19139  explicit freefunc04(ff04_functor ff) : exprtk::ifunction<T>(4), f(ff) {}
19140  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3) exprtk_override
19141  { return f(v0, v1, v2, v3); }
19142  ff04_functor f;
19143  };
19144 
19145  struct freefunc05 : public exprtk::ifunction<T>
19146  {
19148 
19149  explicit freefunc05(ff05_functor ff) : exprtk::ifunction<T>(5), f(ff) {}
19150  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) exprtk_override
19151  { return f(v0, v1, v2, v3, v4); }
19152  ff05_functor f;
19153  };
19154 
19155  struct freefunc06 exprtk_final : public exprtk::ifunction<T>
19156  {
19158 
19159  explicit freefunc06(ff06_functor ff) : exprtk::ifunction<T>(6), f(ff) {}
19160  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) exprtk_override
19161  { return f(v0, v1, v2, v3, v4, v5); }
19162  ff06_functor f;
19163  };
19164 
19165  struct freefunc07 exprtk_final : public exprtk::ifunction<T>
19166  {
19168 
19169  explicit freefunc07(ff07_functor ff) : exprtk::ifunction<T>(7), f(ff) {}
19170  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19171  const T& v5, const T& v6) exprtk_override
19172  { return f(v0, v1, v2, v3, v4, v5, v6); }
19173  ff07_functor f;
19174  };
19175 
19176  struct freefunc08 exprtk_final : public exprtk::ifunction<T>
19177  {
19179 
19180  explicit freefunc08(ff08_functor ff) : exprtk::ifunction<T>(8), f(ff) {}
19181  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19182  const T& v5, const T& v6, const T& v7) exprtk_override
19183  { return f(v0, v1, v2, v3, v4, v5, v6, v7); }
19184  ff08_functor f;
19185  };
19186 
19187  struct freefunc09 exprtk_final : public exprtk::ifunction<T>
19188  {
19190 
19191  explicit freefunc09(ff09_functor ff) : exprtk::ifunction<T>(9), f(ff) {}
19192  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19193  const T& v5, const T& v6, const T& v7, const T& v8) exprtk_override
19194  { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); }
19195  ff09_functor f;
19196  };
19197 
19198  struct freefunc10 exprtk_final : public exprtk::ifunction<T>
19199  {
19201 
19202  explicit freefunc10(ff10_functor ff) : exprtk::ifunction<T>(10), f(ff) {}
19203  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19204  const T& v5, const T& v6, const T& v7, const T& v8, const T& v9) exprtk_override
19205  { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); }
19206  ff10_functor f;
19207  };
19208 
19209  struct freefunc11 exprtk_final : public exprtk::ifunction<T>
19210  {
19212 
19213  explicit freefunc11(ff11_functor ff) : exprtk::ifunction<T>(11), f(ff) {}
19214  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
19215  const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10) exprtk_override
19216  { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); }
19217  ff11_functor f;
19218  };
19219 
19220  struct freefunc12 exprtk_final : public exprtk::ifunction<T>
19221  {
19223 
19224  explicit freefunc12(ff12_functor ff) : exprtk::ifunction<T>(12), f(ff) {}
19225  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19226  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19227  const T& v10, const T& v11) exprtk_override
19228  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11); }
19229  ff12_functor f;
19230  };
19231 
19232  struct freefunc13 exprtk_final : public exprtk::ifunction<T>
19233  {
19235 
19236  explicit freefunc13(ff13_functor ff) : exprtk::ifunction<T>(13), f(ff) {}
19237  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19238  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19239  const T& v10, const T& v11, const T& v12) exprtk_override
19240  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12); }
19241  ff13_functor f;
19242  };
19243 
19244  struct freefunc14 exprtk_final : public exprtk::ifunction<T>
19245  {
19247 
19248  explicit freefunc14(ff14_functor ff) : exprtk::ifunction<T>(14), f(ff) {}
19249  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19250  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19251  const T& v10, const T& v11, const T& v12, const T& v13) exprtk_override
19252  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13); }
19253  ff14_functor f;
19254  };
19255 
19256  struct freefunc15 exprtk_final : public exprtk::ifunction<T>
19257  {
19259 
19260  explicit freefunc15(ff15_functor ff) : exprtk::ifunction<T>(15), f(ff) {}
19261  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
19262  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
19263  const T& v10, const T& v11, const T& v12, const T& v13, const T& v14) exprtk_override
19264  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14); }
19265  ff15_functor f;
19266  };
19267 
19268  template <typename Type, typename RawType>
19269  struct type_store
19270  {
19272  typedef typename details::variable_node<T> variable_node_t;
19277  #ifndef exprtk_disable_string_capabilities
19278  typedef typename details::stringvar_node<T> stringvar_node_t;
19279  #endif
19280 
19281  typedef Type type_t;
19282  typedef type_t* type_ptr;
19283  typedef std::pair<bool,type_ptr> type_pair_t;
19284  typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t;
19285  typedef typename type_map_t::iterator tm_itr_t;
19286  typedef typename type_map_t::const_iterator tm_const_itr_t;
19287 
19288  enum { lut_size = 256 };
19289 
19291  std::size_t size;
19292 
19294  : size(0)
19295  {}
19296 
19297  struct deleter
19298  {
19299  #define exprtk_define_process(Type) \
19300  static inline void process(std::pair<bool,Type*>& n) \
19301  { \
19302  delete n.second; \
19303  } \
19304 
19307  #ifndef exprtk_disable_string_capabilities
19309  #endif
19310 
19311  #undef exprtk_define_process
19312 
19313  template <typename DeleteType>
19314  static inline void process(std::pair<bool,DeleteType*>&)
19315  {}
19316  };
19317 
19318  inline bool symbol_exists(const std::string& symbol_name) const
19319  {
19320  if (symbol_name.empty())
19321  return false;
19322  else if (map.end() != map.find(symbol_name))
19323  return true;
19324  else
19325  return false;
19326  }
19327 
19328  template <typename PtrType>
19329  inline std::string entity_name(const PtrType& ptr) const
19330  {
19331  if (map.empty())
19332  return std::string();
19333 
19334  tm_const_itr_t itr = map.begin();
19335 
19336  while (map.end() != itr)
19337  {
19338  if (itr->second.second == ptr)
19339  {
19340  return itr->first;
19341  }
19342  else
19343  ++itr;
19344  }
19345 
19346  return std::string();
19347  }
19348 
19349  inline bool is_constant(const std::string& symbol_name) const
19350  {
19351  if (symbol_name.empty())
19352  return false;
19353  else
19354  {
19355  const tm_const_itr_t itr = map.find(symbol_name);
19356 
19357  if (map.end() == itr)
19358  return false;
19359  else
19360  return (*itr).second.first;
19361  }
19362  }
19363 
19364  template <typename Tie, typename RType>
19365  inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const)
19366  {
19367  if (symbol_name.size() > 1)
19368  {
19369  for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
19370  {
19371  if (details::imatch(symbol_name, details::reserved_symbols[i]))
19372  {
19373  return false;
19374  }
19375  }
19376  }
19377 
19378  const tm_itr_t itr = map.find(symbol_name);
19379 
19380  if (map.end() == itr)
19381  {
19382  map[symbol_name] = Tie::make(t,is_const);
19383  ++size;
19384  }
19385 
19386  return true;
19387  }
19388 
19389  struct tie_array
19390  {
19391  static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false)
19392  {
19393  return std::make_pair(is_const, new vector_t(v.first, v.second));
19394  }
19395  };
19396 
19397  struct tie_stdvec
19398  {
19399  template <typename Allocator>
19400  static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false)
19401  {
19402  return std::make_pair(is_const, new vector_t(v));
19403  }
19404  };
19405 
19407  {
19408  static inline std::pair<bool,vector_t*> make(exprtk::vector_view<T>& v, const bool is_const = false)
19409  {
19410  return std::make_pair(is_const, new vector_t(v));
19411  }
19412  };
19413 
19414  struct tie_stddeq
19415  {
19416  template <typename Allocator>
19417  static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false)
19418  {
19419  return std::make_pair(is_const, new vector_t(v));
19420  }
19421  };
19422 
19423  template <std::size_t v_size>
19424  inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false)
19425  {
19426  return add_impl<tie_array,std::pair<T*,std::size_t> >
19427  (symbol_name, std::make_pair(v,v_size), is_const);
19428  }
19429 
19430  inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false)
19431  {
19432  return add_impl<tie_array,std::pair<T*,std::size_t> >
19433  (symbol_name, std::make_pair(v,v_size), is_const);
19434  }
19435 
19436  template <typename Allocator>
19437  inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false)
19438  {
19439  return add_impl<tie_stdvec,std::vector<T,Allocator>&>
19440  (symbol_name, v, is_const);
19441  }
19442 
19443  inline bool add(const std::string& symbol_name, exprtk::vector_view<T>& v, const bool is_const = false)
19444  {
19445  return add_impl<tie_vecview,exprtk::vector_view<T>&>
19446  (symbol_name, v, is_const);
19447  }
19448 
19449  template <typename Allocator>
19450  inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
19451  {
19452  return add_impl<tie_stddeq,std::deque<T,Allocator>&>
19453  (symbol_name, v, is_const);
19454  }
19455 
19456  inline bool add(const std::string& symbol_name, RawType& t_, const bool is_const = false)
19457  {
19458  struct tie
19459  {
19460  static inline std::pair<bool,variable_node_t*> make(T& t, const bool is_constant = false)
19461  {
19462  return std::make_pair(is_constant, new variable_node_t(t));
19463  }
19464 
19465  #ifndef exprtk_disable_string_capabilities
19466  static inline std::pair<bool,stringvar_node_t*> make(std::string& t, const bool is_constant = false)
19467  {
19468  return std::make_pair(is_constant, new stringvar_node_t(t));
19469  }
19470  #endif
19471 
19472  static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false)
19473  {
19474  return std::make_pair(is_constant,&t);
19475  }
19476 
19477  static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_constant = false)
19478  {
19479  return std::make_pair(is_constant,&t);
19480  }
19481 
19482  static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false)
19483  {
19484  return std::make_pair(is_constant,&t);
19485  }
19486  };
19487 
19488  const tm_itr_t itr = map.find(symbol_name);
19489 
19490  if (map.end() == itr)
19491  {
19492  map[symbol_name] = tie::make(t_,is_const);
19493  ++size;
19494  }
19495 
19496  return true;
19497  }
19498 
19499  inline type_ptr get(const std::string& symbol_name) const
19500  {
19501  const tm_const_itr_t itr = map.find(symbol_name);
19502 
19503  if (map.end() == itr)
19504  return reinterpret_cast<type_ptr>(0);
19505  else
19506  return itr->second.second;
19507  }
19508 
19509  template <typename TType, typename TRawType, typename PtrType>
19510  struct ptr_match
19511  {
19512  static inline bool test(const PtrType, const void*)
19513  {
19514  return false;
19515  }
19516  };
19517 
19518  template <typename TType, typename TRawType>
19519  struct ptr_match<TType,TRawType,variable_node_t*>
19520  {
19521  static inline bool test(const variable_node_t* p, const void* ptr)
19522  {
19523  exprtk_debug(("ptr_match::test() - %p <--> %p\n", reinterpret_cast<const void*>(&(p->ref())), ptr));
19524  return (&(p->ref()) == ptr);
19525  }
19526  };
19527 
19528  inline type_ptr get_from_varptr(const void* ptr) const
19529  {
19530  tm_const_itr_t itr = map.begin();
19531 
19532  while (map.end() != itr)
19533  {
19534  type_ptr ret_ptr = itr->second.second;
19535 
19536  if (ptr_match<Type,RawType,type_ptr>::test(ret_ptr,ptr))
19537  {
19538  return ret_ptr;
19539  }
19540 
19541  ++itr;
19542  }
19543 
19544  return type_ptr(0);
19545  }
19546 
19547  inline bool remove(const std::string& symbol_name, const bool delete_node = true)
19548  {
19549  const tm_itr_t itr = map.find(symbol_name);
19550 
19551  if (map.end() != itr)
19552  {
19553  if (delete_node)
19554  {
19555  deleter::process((*itr).second);
19556  }
19557 
19558  map.erase(itr);
19559  --size;
19560 
19561  return true;
19562  }
19563  else
19564  return false;
19565  }
19566 
19567  inline RawType& type_ref(const std::string& symbol_name)
19568  {
19569  struct init_type
19570  {
19571  static inline double set(double) { return (0.0); }
19572  static inline double set(long double) { return (0.0); }
19573  static inline float set(float) { return (0.0f); }
19574  static inline std::string set(std::string) { return std::string(""); }
19575  };
19576 
19577  static RawType null_type = init_type::set(RawType());
19578 
19579  const tm_const_itr_t itr = map.find(symbol_name);
19580 
19581  if (map.end() == itr)
19582  return null_type;
19583  else
19584  return itr->second.second->ref();
19585  }
19586 
19587  inline void clear(const bool delete_node = true)
19588  {
19589  if (!map.empty())
19590  {
19591  if (delete_node)
19592  {
19593  tm_itr_t itr = map.begin();
19594  tm_itr_t end = map.end ();
19595 
19596  while (end != itr)
19597  {
19598  deleter::process((*itr).second);
19599  ++itr;
19600  }
19601  }
19602 
19603  map.clear();
19604  }
19605 
19606  size = 0;
19607  }
19608 
19609  template <typename Allocator,
19610  template <typename, typename> class Sequence>
19611  inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const
19612  {
19613  std::size_t count = 0;
19614 
19615  if (!map.empty())
19616  {
19617  tm_const_itr_t itr = map.begin();
19618  tm_const_itr_t end = map.end ();
19619 
19620  while (end != itr)
19621  {
19622  list.push_back(std::make_pair((*itr).first,itr->second.second->ref()));
19623  ++itr;
19624  ++count;
19625  }
19626  }
19627 
19628  return count;
19629  }
19630 
19631  template <typename Allocator,
19632  template <typename, typename> class Sequence>
19633  inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const
19634  {
19635  std::size_t count = 0;
19636 
19637  if (!map.empty())
19638  {
19639  tm_const_itr_t itr = map.begin();
19640  tm_const_itr_t end = map.end ();
19641 
19642  while (end != itr)
19643  {
19644  vlist.push_back((*itr).first);
19645  ++itr;
19646  ++count;
19647  }
19648  }
19649 
19650  return count;
19651  }
19652  };
19653 
19655  typedef typename details::variable_node<T> variable_t;
19658  #ifndef exprtk_disable_string_capabilities
19659  typedef typename details::stringvar_node<T> stringvar_t;
19661  #endif
19668 
19669  static const std::size_t lut_size = 256;
19670 
19671  // Symbol Table Holder
19673  {
19674  struct st_data
19675  {
19683  #ifndef exprtk_disable_string_capabilities
19685  #endif
19686 
19688  {
19689  for (std::size_t i = 0; i < details::reserved_words_size; ++i)
19690  {
19691  reserved_symbol_table_.insert(details::reserved_words[i]);
19692  }
19693 
19694  for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
19695  {
19696  reserved_symbol_table_.insert(details::reserved_symbols[i]);
19697  }
19698  }
19699 
19701  {
19702  for (std::size_t i = 0; i < free_function_list_.size(); ++i)
19703  {
19704  delete free_function_list_[i];
19705  }
19706  }
19707 
19708  inline bool is_reserved_symbol(const std::string& symbol) const
19709  {
19710  return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
19711  }
19712 
19713  static inline st_data* create()
19714  {
19715  return (new st_data);
19716  }
19717 
19718  static inline void destroy(st_data*& sd)
19719  {
19720  delete sd;
19721  sd = reinterpret_cast<st_data*>(0);
19722  }
19723 
19724  std::list<T> local_symbol_list_;
19725  std::list<std::string> local_stringvar_list_;
19726  std::set<std::string> reserved_symbol_table_;
19727  std::vector<ifunction<T>*> free_function_list_;
19728  };
19729 
19731  : ref_count(1)
19732  , data_(st_data::create())
19733  , mutability_(e_mutable)
19734  {}
19735 
19737  : ref_count(1)
19738  , data_(data)
19739  , mutability_(e_mutable)
19740  {}
19741 
19743  {
19744  if (data_ && (0 == ref_count))
19745  {
19746  st_data::destroy(data_);
19747  }
19748  }
19749 
19750  static inline control_block* create()
19751  {
19752  return (new control_block);
19753  }
19754 
19755  template <typename SymTab>
19756  static inline void destroy(control_block*& cntrl_blck, SymTab* sym_tab)
19757  {
19758  if (cntrl_blck)
19759  {
19760  if (
19761  (0 != cntrl_blck->ref_count) &&
19762  (0 == --cntrl_blck->ref_count)
19763  )
19764  {
19765  if (sym_tab)
19766  sym_tab->clear();
19767 
19768  delete cntrl_blck;
19769  }
19770 
19771  cntrl_blck = 0;
19772  }
19773  }
19774 
19776  {
19777  mutability_ = mutability;
19778  }
19779 
19780  std::size_t ref_count;
19783  };
19784 
19785  public:
19786 
19787  explicit symbol_table(const symtab_mutability_type mutability = e_mutable)
19788  : control_block_(control_block::create())
19789  {
19790  control_block_->set_mutability(mutability);
19791  clear();
19792  }
19793 
19795  {
19796  exprtk::details::dump_ptr("~symbol_table", this);
19797  control_block::destroy(control_block_, this);
19798  }
19799 
19801  {
19802  control_block_ = st.control_block_;
19803  control_block_->ref_count++;
19804  }
19805 
19807  {
19808  if (this != &st)
19809  {
19810  control_block::destroy(control_block_,reinterpret_cast<symbol_table<T>*>(0));
19811 
19812  control_block_ = st.control_block_;
19813  control_block_->ref_count++;
19814  }
19815 
19816  return (*this);
19817  }
19818 
19819  inline bool operator==(const symbol_table<T>& st) const
19820  {
19821  return (this == &st) || (control_block_ == st.control_block_);
19822  }
19823 
19825  {
19826  return valid() ? control_block_->mutability_ : e_unknown;
19827  }
19828 
19829  inline void clear_variables(const bool delete_node = true)
19830  {
19831  local_data().variable_store.clear(delete_node);
19832  }
19833 
19834  inline void clear_functions()
19835  {
19836  local_data().function_store.clear();
19837  }
19838 
19839  inline void clear_strings()
19840  {
19841  #ifndef exprtk_disable_string_capabilities
19842  local_data().stringvar_store.clear();
19843  #endif
19844  }
19845 
19846  inline void clear_vectors()
19847  {
19848  local_data().vector_store.clear();
19849  }
19850 
19852  {
19853  local_data().local_symbol_list_.clear();
19854  }
19855 
19856  inline void clear()
19857  {
19858  if (!valid()) return;
19859  clear_variables ();
19860  clear_functions ();
19861  clear_strings ();
19862  clear_vectors ();
19863  clear_local_constants();
19864  }
19865 
19866  inline std::size_t variable_count() const
19867  {
19868  if (valid())
19869  return local_data().variable_store.size;
19870  else
19871  return 0;
19872  }
19873 
19874  #ifndef exprtk_disable_string_capabilities
19875  inline std::size_t stringvar_count() const
19876  {
19877  if (valid())
19878  return local_data().stringvar_store.size;
19879  else
19880  return 0;
19881  }
19882  #endif
19883 
19884  inline std::size_t function_count() const
19885  {
19886  if (valid())
19887  return local_data().function_store.size;
19888  else
19889  return 0;
19890  }
19891 
19892  inline std::size_t vector_count() const
19893  {
19894  if (valid())
19895  return local_data().vector_store.size;
19896  else
19897  return 0;
19898  }
19899 
19900  inline variable_ptr get_variable(const std::string& variable_name) const
19901  {
19902  if (!valid())
19903  return reinterpret_cast<variable_ptr>(0);
19904  else if (!valid_symbol(variable_name))
19905  return reinterpret_cast<variable_ptr>(0);
19906  else
19907  return local_data().variable_store.get(variable_name);
19908  }
19909 
19910  inline variable_ptr get_variable(const T& var_ref) const
19911  {
19912  if (!valid())
19913  return reinterpret_cast<variable_ptr>(0);
19914  else
19915  return local_data().variable_store.get_from_varptr(
19916  reinterpret_cast<const void*>(&var_ref));
19917  }
19918 
19919  #ifndef exprtk_disable_string_capabilities
19920  inline stringvar_ptr get_stringvar(const std::string& string_name) const
19921  {
19922  if (!valid())
19923  return reinterpret_cast<stringvar_ptr>(0);
19924  else if (!valid_symbol(string_name))
19925  return reinterpret_cast<stringvar_ptr>(0);
19926  else
19927  return local_data().stringvar_store.get(string_name);
19928  }
19929 
19930  inline stringvar_base<T> get_stringvar_base(const std::string& string_name) const
19931  {
19932  static stringvar_base<T> null_stringvar_base("",reinterpret_cast<stringvar_ptr>(0));
19933  if (!valid())
19934  return null_stringvar_base;
19935  else if (!valid_symbol(string_name))
19936  return null_stringvar_base;
19937 
19938  stringvar_ptr stringvar = local_data().stringvar_store.get(string_name);
19939 
19940  if (0 == stringvar)
19941  {
19942  return null_stringvar_base;
19943  }
19944 
19945  return stringvar_base<T>(string_name,stringvar);
19946  }
19947  #endif
19948 
19949  inline function_ptr get_function(const std::string& function_name) const
19950  {
19951  if (!valid())
19952  return reinterpret_cast<function_ptr>(0);
19953  else if (!valid_symbol(function_name))
19954  return reinterpret_cast<function_ptr>(0);
19955  else
19956  return local_data().function_store.get(function_name);
19957  }
19958 
19959  inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
19960  {
19961  if (!valid())
19962  return reinterpret_cast<vararg_function_ptr>(0);
19963  else if (!valid_symbol(vararg_function_name))
19964  return reinterpret_cast<vararg_function_ptr>(0);
19965  else
19966  return local_data().vararg_function_store.get(vararg_function_name);
19967  }
19968 
19969  inline generic_function_ptr get_generic_function(const std::string& function_name) const
19970  {
19971  if (!valid())
19972  return reinterpret_cast<generic_function_ptr>(0);
19973  else if (!valid_symbol(function_name))
19974  return reinterpret_cast<generic_function_ptr>(0);
19975  else
19976  return local_data().generic_function_store.get(function_name);
19977  }
19978 
19979  inline generic_function_ptr get_string_function(const std::string& function_name) const
19980  {
19981  if (!valid())
19982  return reinterpret_cast<generic_function_ptr>(0);
19983  else if (!valid_symbol(function_name))
19984  return reinterpret_cast<generic_function_ptr>(0);
19985  else
19986  return local_data().string_function_store.get(function_name);
19987  }
19988 
19989  inline generic_function_ptr get_overload_function(const std::string& function_name) const
19990  {
19991  if (!valid())
19992  return reinterpret_cast<generic_function_ptr>(0);
19993  else if (!valid_symbol(function_name))
19994  return reinterpret_cast<generic_function_ptr>(0);
19995  else
19996  return local_data().overload_function_store.get(function_name);
19997  }
19998 
20000 
20001  inline vector_holder_ptr get_vector(const std::string& vector_name) const
20002  {
20003  if (!valid())
20004  return reinterpret_cast<vector_holder_ptr>(0);
20005  else if (!valid_symbol(vector_name))
20006  return reinterpret_cast<vector_holder_ptr>(0);
20007  else
20008  return local_data().vector_store.get(vector_name);
20009  }
20010 
20011  inline T& variable_ref(const std::string& symbol_name)
20012  {
20013  static T null_var = T(0);
20014  if (!valid())
20015  return null_var;
20016  else if (!valid_symbol(symbol_name))
20017  return null_var;
20018  else
20019  return local_data().variable_store.type_ref(symbol_name);
20020  }
20021 
20022  #ifndef exprtk_disable_string_capabilities
20023  inline std::string& stringvar_ref(const std::string& symbol_name)
20024  {
20025  static std::string null_stringvar;
20026  if (!valid())
20027  return null_stringvar;
20028  else if (!valid_symbol(symbol_name))
20029  return null_stringvar;
20030  else
20031  return local_data().stringvar_store.type_ref(symbol_name);
20032  }
20033  #endif
20034 
20035  inline bool is_constant_node(const std::string& symbol_name) const
20036  {
20037  if (!valid())
20038  return false;
20039  else if (!valid_symbol(symbol_name))
20040  return false;
20041  else
20042  return local_data().variable_store.is_constant(symbol_name);
20043  }
20044 
20045  #ifndef exprtk_disable_string_capabilities
20046  inline bool is_constant_string(const std::string& symbol_name) const
20047  {
20048  if (!valid())
20049  return false;
20050  else if (!valid_symbol(symbol_name))
20051  return false;
20052  else if (!local_data().stringvar_store.symbol_exists(symbol_name))
20053  return false;
20054  else
20055  return local_data().stringvar_store.is_constant(symbol_name);
20056  }
20057  #endif
20058 
20059  inline bool create_variable(const std::string& variable_name, const T& value = T(0))
20060  {
20061  if (!valid())
20062  return false;
20063  else if (!valid_symbol(variable_name))
20064  return false;
20065  else if (symbol_exists(variable_name))
20066  return false;
20067 
20068  local_data().local_symbol_list_.push_back(value);
20069  T& t = local_data().local_symbol_list_.back();
20070 
20071  return add_variable(variable_name,t);
20072  }
20073 
20074  #ifndef exprtk_disable_string_capabilities
20075  inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string(""))
20076  {
20077  if (!valid())
20078  return false;
20079  else if (!valid_symbol(stringvar_name))
20080  return false;
20081  else if (symbol_exists(stringvar_name))
20082  return false;
20083 
20084  local_data().local_stringvar_list_.push_back(value);
20085  std::string& s = local_data().local_stringvar_list_.back();
20086 
20087  return add_stringvar(stringvar_name,s);
20088  }
20089  #endif
20090 
20091  inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false)
20092  {
20093  if (!valid())
20094  return false;
20095  else if (!valid_symbol(variable_name))
20096  return false;
20097  else if (symbol_exists(variable_name))
20098  return false;
20099  else
20100  return local_data().variable_store.add(variable_name, t, is_constant);
20101  }
20102 
20103  inline bool add_constant(const std::string& constant_name, const T& value)
20104  {
20105  if (!valid())
20106  return false;
20107  else if (!valid_symbol(constant_name))
20108  return false;
20109  else if (symbol_exists(constant_name))
20110  return false;
20111 
20112  local_data().local_symbol_list_.push_back(value);
20113  T& t = local_data().local_symbol_list_.back();
20114 
20115  return add_variable(constant_name, t, true);
20116  }
20117 
20118  #ifndef exprtk_disable_string_capabilities
20119  inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false)
20120  {
20121  if (!valid())
20122  return false;
20123  else if (!valid_symbol(stringvar_name))
20124  return false;
20125  else if (symbol_exists(stringvar_name))
20126  return false;
20127  else
20128  return local_data().stringvar_store.add(stringvar_name, s, is_constant);
20129  }
20130  #endif
20131 
20132  inline bool add_function(const std::string& function_name, function_t& function)
20133  {
20134  if (!valid())
20135  return false;
20136  else if (!valid_symbol(function_name))
20137  return false;
20138  else if (symbol_exists(function_name))
20139  return false;
20140  else
20141  return local_data().function_store.add(function_name,function);
20142  }
20143 
20144  inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
20145  {
20146  if (!valid())
20147  return false;
20148  else if (!valid_symbol(vararg_function_name))
20149  return false;
20150  else if (symbol_exists(vararg_function_name))
20151  return false;
20152  else
20153  return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
20154  }
20155 
20156  inline bool add_function(const std::string& function_name, generic_function_t& function)
20157  {
20158  if (!valid())
20159  return false;
20160  else if (!valid_symbol(function_name))
20161  return false;
20162  else if (symbol_exists(function_name))
20163  return false;
20164  else
20165  {
20166  switch (function.rtrn_type)
20167  {
20168  case generic_function_t::e_rtrn_scalar :
20169  return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20170  local_data().generic_function_store.add(function_name,function) : false;
20171 
20172  case generic_function_t::e_rtrn_string :
20173  return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20174  local_data().string_function_store.add(function_name,function) : false;
20175 
20176  case generic_function_t::e_rtrn_overload :
20177  return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ?
20178  local_data().overload_function_store.add(function_name,function) : false;
20179  }
20180  }
20181 
20182  return false;
20183  }
20184 
20185  #define exprtk_define_freefunction(NN) \
20186  inline bool add_function(const std::string& function_name, ff##NN##_functor function) \
20187  { \
20188  if (!valid()) \
20189  { return false; } \
20190  if (!valid_symbol(function_name)) \
20191  { return false; } \
20192  if (symbol_exists(function_name)) \
20193  { return false; } \
20194  \
20195  exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
20196  \
20197  local_data().free_function_list_.push_back(ifunc); \
20198  \
20199  return add_function(function_name,(*local_data().free_function_list_.back())); \
20200  } \
20201 
20210 
20211  #undef exprtk_define_freefunction
20212 
20213  inline bool add_reserved_function(const std::string& function_name, function_t& function)
20214  {
20215  if (!valid())
20216  return false;
20217  else if (!valid_symbol(function_name,false))
20218  return false;
20219  else if (symbol_exists(function_name,false))
20220  return false;
20221  else
20222  return local_data().function_store.add(function_name,function);
20223  }
20224 
20225  inline bool add_reserved_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
20226  {
20227  if (!valid())
20228  return false;
20229  else if (!valid_symbol(vararg_function_name,false))
20230  return false;
20231  else if (symbol_exists(vararg_function_name,false))
20232  return false;
20233  else
20234  return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
20235  }
20236 
20237  inline bool add_reserved_function(const std::string& function_name, generic_function_t& function)
20238  {
20239  if (!valid())
20240  return false;
20241  else if (!valid_symbol(function_name,false))
20242  return false;
20243  else if (symbol_exists(function_name,false))
20244  return false;
20245  else
20246  {
20247  switch (function.rtrn_type)
20248  {
20249  case generic_function_t::e_rtrn_scalar :
20250  return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20251  local_data().generic_function_store.add(function_name,function) : false;
20252 
20253  case generic_function_t::e_rtrn_string :
20254  return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ?
20255  local_data().string_function_store.add(function_name,function) : false;
20256 
20257  case generic_function_t::e_rtrn_overload :
20258  return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ?
20259  local_data().overload_function_store.add(function_name,function) : false;
20260  }
20261  }
20262 
20263  return false;
20264  }
20265 
20266  template <std::size_t N>
20267  inline bool add_vector(const std::string& vector_name, T (&v)[N])
20268  {
20269  if (!valid())
20270  return false;
20271  else if (!valid_symbol(vector_name))
20272  return false;
20273  else if (symbol_exists(vector_name))
20274  return false;
20275  else
20276  return local_data().vector_store.add(vector_name,v);
20277  }
20278 
20279  inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size)
20280  {
20281  if (!valid())
20282  return false;
20283  else if (!valid_symbol(vector_name))
20284  return false;
20285  else if (symbol_exists(vector_name))
20286  return false;
20287  else if (0 == v_size)
20288  return false;
20289  else
20290  return local_data().vector_store.add(vector_name, v, v_size);
20291  }
20292 
20293  template <typename Allocator>
20294  inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v)
20295  {
20296  if (!valid())
20297  return false;
20298  else if (!valid_symbol(vector_name))
20299  return false;
20300  else if (symbol_exists(vector_name))
20301  return false;
20302  else if (0 == v.size())
20303  return false;
20304  else
20305  return local_data().vector_store.add(vector_name,v);
20306  }
20307 
20308  inline bool add_vector(const std::string& vector_name, exprtk::vector_view<T>& v)
20309  {
20310  if (!valid())
20311  return false;
20312  else if (!valid_symbol(vector_name))
20313  return false;
20314  else if (symbol_exists(vector_name))
20315  return false;
20316  else if (0 == v.size())
20317  return false;
20318  else
20319  return local_data().vector_store.add(vector_name,v);
20320  }
20321 
20322  inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
20323  {
20324  if (!valid())
20325  return false;
20326  else
20327  return local_data().variable_store.remove(variable_name, delete_node);
20328  }
20329 
20330  #ifndef exprtk_disable_string_capabilities
20331  inline bool remove_stringvar(const std::string& string_name)
20332  {
20333  if (!valid())
20334  return false;
20335  else
20336  return local_data().stringvar_store.remove(string_name);
20337  }
20338  #endif
20339 
20340  inline bool remove_function(const std::string& function_name)
20341  {
20342  if (!valid())
20343  return false;
20344  else
20345  return local_data().function_store.remove(function_name);
20346  }
20347 
20348  inline bool remove_vararg_function(const std::string& vararg_function_name)
20349  {
20350  if (!valid())
20351  return false;
20352  else
20353  return local_data().vararg_function_store.remove(vararg_function_name);
20354  }
20355 
20356  inline bool remove_vector(const std::string& vector_name)
20357  {
20358  if (!valid())
20359  return false;
20360  else
20361  return local_data().vector_store.remove(vector_name);
20362  }
20363 
20364  inline bool add_constants()
20365  {
20366  return add_pi () &&
20367  add_epsilon () &&
20368  add_infinity() ;
20369  }
20370 
20371  inline bool add_pi()
20372  {
20373  const typename details::numeric::details::number_type<T>::type num_type;
20374  static const T local_pi = details::numeric::details::const_pi_impl<T>(num_type);
20375  return add_constant("pi",local_pi);
20376  }
20377 
20378  inline bool add_epsilon()
20379  {
20380  static const T local_epsilon = details::numeric::details::epsilon_type<T>::value();
20381  return add_constant("epsilon",local_epsilon);
20382  }
20383 
20384  inline bool add_infinity()
20385  {
20386  static const T local_infinity = std::numeric_limits<T>::infinity();
20387  return add_constant("inf",local_infinity);
20388  }
20389 
20390  template <typename Package>
20391  inline bool add_package(Package& package)
20392  {
20393  return package.register_package(*this);
20394  }
20395 
20396  template <typename Allocator,
20397  template <typename, typename> class Sequence>
20398  inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const
20399  {
20400  if (!valid())
20401  return 0;
20402  else
20403  return local_data().variable_store.get_list(vlist);
20404  }
20405 
20406  template <typename Allocator,
20407  template <typename, typename> class Sequence>
20408  inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const
20409  {
20410  if (!valid())
20411  return 0;
20412  else
20413  return local_data().variable_store.get_list(vlist);
20414  }
20415 
20416  #ifndef exprtk_disable_string_capabilities
20417  template <typename Allocator,
20418  template <typename, typename> class Sequence>
20419  inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const
20420  {
20421  if (!valid())
20422  return 0;
20423  else
20424  return local_data().stringvar_store.get_list(svlist);
20425  }
20426 
20427  template <typename Allocator,
20428  template <typename, typename> class Sequence>
20429  inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const
20430  {
20431  if (!valid())
20432  return 0;
20433  else
20434  return local_data().stringvar_store.get_list(svlist);
20435  }
20436  #endif
20437 
20438  template <typename Allocator,
20439  template <typename, typename> class Sequence>
20440  inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vec_list) const
20441  {
20442  if (!valid())
20443  return 0;
20444  else
20445  return local_data().vector_store.get_list(vec_list);
20446  }
20447 
20448  template <typename Allocator,
20449  template <typename, typename> class Sequence>
20450  inline std::size_t get_function_list(Sequence<std::string,Allocator>& function_list) const
20451  {
20452  if (!valid())
20453  return 0;
20454 
20455  std::vector<std::string> function_names;
20456  std::size_t count = 0;
20457 
20458  count += local_data().function_store .get_list(function_names);
20459  count += local_data().vararg_function_store .get_list(function_names);
20460  count += local_data().generic_function_store .get_list(function_names);
20461  count += local_data().string_function_store .get_list(function_names);
20462  count += local_data().overload_function_store.get_list(function_names);
20463 
20464  std::set<std::string> function_set;
20465 
20466  for (std::size_t i = 0; i < function_names.size(); ++i)
20467  {
20468  function_set.insert(function_names[i]);
20469  }
20470 
20471  std::copy(function_set.begin(),function_set.end(),
20472  std::back_inserter(function_list));
20473 
20474  return count;
20475  }
20476 
20477  inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const
20478  {
20479  /*
20480  Function will return true if symbol_name exists as either a
20481  reserved symbol, variable, stringvar, vector or function name
20482  in any of the type stores.
20483  */
20484  if (!valid())
20485  return false;
20486  else if (local_data().variable_store.symbol_exists(symbol_name))
20487  return true;
20488  #ifndef exprtk_disable_string_capabilities
20489  else if (local_data().stringvar_store.symbol_exists(symbol_name))
20490  return true;
20491  #endif
20492  else if (local_data().vector_store.symbol_exists(symbol_name))
20493  return true;
20494  else if (local_data().function_store.symbol_exists(symbol_name))
20495  return true;
20496  else if (check_reserved_symb && local_data().is_reserved_symbol(symbol_name))
20497  return true;
20498  else
20499  return false;
20500  }
20501 
20502  inline bool is_variable(const std::string& variable_name) const
20503  {
20504  if (!valid())
20505  return false;
20506  else
20507  return local_data().variable_store.symbol_exists(variable_name);
20508  }
20509 
20510  #ifndef exprtk_disable_string_capabilities
20511  inline bool is_stringvar(const std::string& stringvar_name) const
20512  {
20513  if (!valid())
20514  return false;
20515  else
20516  return local_data().stringvar_store.symbol_exists(stringvar_name);
20517  }
20518 
20519  inline bool is_conststr_stringvar(const std::string& symbol_name) const
20520  {
20521  if (!valid())
20522  return false;
20523  else if (!valid_symbol(symbol_name))
20524  return false;
20525  else if (!local_data().stringvar_store.symbol_exists(symbol_name))
20526  return false;
20527 
20528  return (
20529  local_data().stringvar_store.symbol_exists(symbol_name) ||
20530  local_data().stringvar_store.is_constant (symbol_name)
20531  );
20532  }
20533  #endif
20534 
20535  inline bool is_function(const std::string& function_name) const
20536  {
20537  if (!valid())
20538  return false;
20539  else
20540  return local_data().function_store.symbol_exists(function_name);
20541  }
20542 
20543  inline bool is_vararg_function(const std::string& vararg_function_name) const
20544  {
20545  if (!valid())
20546  return false;
20547  else
20548  return local_data().vararg_function_store.symbol_exists(vararg_function_name);
20549  }
20550 
20551  inline bool is_vector(const std::string& vector_name) const
20552  {
20553  if (!valid())
20554  return false;
20555  else
20556  return local_data().vector_store.symbol_exists(vector_name);
20557  }
20558 
20559  inline std::string get_variable_name(const expression_ptr& ptr) const
20560  {
20561  return local_data().variable_store.entity_name(ptr);
20562  }
20563 
20564  inline std::string get_vector_name(const vector_holder_ptr& ptr) const
20565  {
20566  return local_data().vector_store.entity_name(ptr);
20567  }
20568 
20569  #ifndef exprtk_disable_string_capabilities
20570  inline std::string get_stringvar_name(const expression_ptr& ptr) const
20571  {
20572  return local_data().stringvar_store.entity_name(ptr);
20573  }
20574 
20575  inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const
20576  {
20577  return local_data().stringvar_store.entity_name(ptr);
20578  }
20579  #endif
20580 
20581  inline bool valid() const
20582  {
20583  // Symbol table sanity check.
20584  return control_block_ && control_block_->data_;
20585  }
20586 
20587  inline void load_from(const symbol_table<T>& st)
20588  {
20589  {
20590  std::vector<std::string> name_list;
20591 
20592  st.local_data().function_store.get_list(name_list);
20593 
20594  if (!name_list.empty())
20595  {
20596  for (std::size_t i = 0; i < name_list.size(); ++i)
20597  {
20598  exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]);
20599  add_function(name_list[i],ifunc);
20600  }
20601  }
20602  }
20603 
20604  {
20605  std::vector<std::string> name_list;
20606 
20607  st.local_data().vararg_function_store.get_list(name_list);
20608 
20609  if (!name_list.empty())
20610  {
20611  for (std::size_t i = 0; i < name_list.size(); ++i)
20612  {
20613  exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]);
20614  add_function(name_list[i],ivafunc);
20615  }
20616  }
20617  }
20618 
20619  {
20620  std::vector<std::string> name_list;
20621 
20622  st.local_data().generic_function_store.get_list(name_list);
20623 
20624  if (!name_list.empty())
20625  {
20626  for (std::size_t i = 0; i < name_list.size(); ++i)
20627  {
20628  exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]);
20629  add_function(name_list[i],ifunc);
20630  }
20631  }
20632  }
20633 
20634  {
20635  std::vector<std::string> name_list;
20636 
20637  st.local_data().string_function_store.get_list(name_list);
20638 
20639  if (!name_list.empty())
20640  {
20641  for (std::size_t i = 0; i < name_list.size(); ++i)
20642  {
20643  exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]);
20644  add_function(name_list[i],ifunc);
20645  }
20646  }
20647  }
20648 
20649  {
20650  std::vector<std::string> name_list;
20651 
20652  st.local_data().overload_function_store.get_list(name_list);
20653 
20654  if (!name_list.empty())
20655  {
20656  for (std::size_t i = 0; i < name_list.size(); ++i)
20657  {
20658  exprtk::igeneric_function<T>& ifunc = *st.get_overload_function(name_list[i]);
20659  add_function(name_list[i],ifunc);
20660  }
20661  }
20662  }
20663  }
20664 
20665  inline void load_variables_from(const symbol_table<T>& st)
20666  {
20667  std::vector<std::string> name_list;
20668 
20669  st.local_data().variable_store.get_list(name_list);
20670 
20671  if (!name_list.empty())
20672  {
20673  for (std::size_t i = 0; i < name_list.size(); ++i)
20674  {
20675  T& variable = st.get_variable(name_list[i])->ref();
20676  add_variable(name_list[i], variable);
20677  }
20678  }
20679  }
20680 
20681  inline void load_vectors_from(const symbol_table<T>& st)
20682  {
20683  std::vector<std::string> name_list;
20684 
20685  st.local_data().vector_store.get_list(name_list);
20686 
20687  if (!name_list.empty())
20688  {
20689  for (std::size_t i = 0; i < name_list.size(); ++i)
20690  {
20691  vector_holder_t& vecholder = *st.get_vector(name_list[i]);
20692  add_vector(name_list[i], vecholder.data(), vecholder.size());
20693  }
20694  }
20695  }
20696 
20697  private:
20698 
20699  inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const
20700  {
20701  if (symbol.empty())
20702  return false;
20703  else if (!details::is_letter(symbol[0]))
20704  return false;
20705  else if (symbol.size() > 1)
20706  {
20707  for (std::size_t i = 1; i < symbol.size(); ++i)
20708  {
20709  if (
20710  !details::is_letter_or_digit(symbol[i]) &&
20711  ('_' != symbol[i])
20712  )
20713  {
20714  if ((i < (symbol.size() - 1)) && ('.' == symbol[i]))
20715  continue;
20716  else
20717  return false;
20718  }
20719  }
20720  }
20721 
20722  return (check_reserved_symb) ? (!local_data().is_reserved_symbol(symbol)) : true;
20723  }
20724 
20725  inline bool valid_function(const std::string& symbol) const
20726  {
20727  if (symbol.empty())
20728  return false;
20729  else if (!details::is_letter(symbol[0]))
20730  return false;
20731  else if (symbol.size() > 1)
20732  {
20733  for (std::size_t i = 1; i < symbol.size(); ++i)
20734  {
20735  if (
20736  !details::is_letter_or_digit(symbol[i]) &&
20737  ('_' != symbol[i])
20738  )
20739  {
20740  if ((i < (symbol.size() - 1)) && ('.' == symbol[i]))
20741  continue;
20742  else
20743  return false;
20744  }
20745  }
20746  }
20747 
20748  return true;
20749  }
20750 
20752 
20754  {
20755  return *(control_block_->data_);
20756  }
20757 
20758  inline const local_data_t& local_data() const
20759  {
20760  return *(control_block_->data_);
20761  }
20762 
20764 
20765  friend class parser<T>;
20766  }; // class symbol_table
20767 
20768  template <typename T>
20769  class function_compositor;
20770 
20771  template <typename T>
20773  {
20774  private:
20775 
20778  typedef std::vector<symbol_table<T> > symtab_list_t;
20779 
20781  {
20783  {
20789  e_string
20790  };
20791 
20792  struct data_pack
20793  {
20795  : pointer(0)
20796  , type(e_unknown)
20797  , size(0)
20798  {}
20799 
20800  data_pack(void* ptr, const data_type dt, const std::size_t sz = 0)
20801  : pointer(ptr)
20802  , type(dt)
20803  , size(sz)
20804  {}
20805 
20806  void* pointer;
20808  std::size_t size;
20809  };
20810 
20811  typedef std::vector<data_pack> local_data_list_t;
20814 
20816  : ref_count(0)
20817  , expr (0)
20818  , results (0)
20819  , retinv_null(false)
20820  , return_invoked(&retinv_null)
20821  {}
20822 
20824  : ref_count(1)
20825  , expr (e)
20826  , results (0)
20827  , retinv_null(false)
20828  , return_invoked(&retinv_null)
20829  {}
20830 
20832  {
20833  if (expr && details::branch_deletable(expr))
20834  {
20835  destroy_node(expr);
20836  }
20837 
20838  if (!local_data_list.empty())
20839  {
20840  for (std::size_t i = 0; i < local_data_list.size(); ++i)
20841  {
20842  switch (local_data_list[i].type)
20843  {
20844  case e_expr : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer);
20845  break;
20846 
20847  case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer);
20848  break;
20849 
20850  case e_data : delete reinterpret_cast<T*>(local_data_list[i].pointer);
20851  break;
20852 
20853  case e_vecdata : delete [] reinterpret_cast<T*>(local_data_list[i].pointer);
20854  break;
20855 
20856  case e_string : delete reinterpret_cast<std::string*>(local_data_list[i].pointer);
20857  break;
20858 
20859  default : break;
20860  }
20861  }
20862  }
20863 
20864  if (results)
20865  {
20866  delete results;
20867  }
20868  }
20869 
20871  {
20872  return new control_block(e);
20873  }
20874 
20875  static inline void destroy(cntrl_blck_ptr_t& cntrl_blck)
20876  {
20877  if (cntrl_blck)
20878  {
20879  if (
20880  (0 != cntrl_blck->ref_count) &&
20881  (0 == --cntrl_blck->ref_count)
20882  )
20883  {
20884  delete cntrl_blck;
20885  }
20886 
20887  cntrl_blck = 0;
20888  }
20889  }
20890 
20891  std::size_t ref_count;
20896  bool* return_invoked;
20897 
20898  friend class function_compositor<T>;
20899  };
20900 
20901  public:
20902 
20904  : control_block_(0)
20905  {
20906  set_expression(new details::null_node<T>());
20907  }
20908 
20910  : control_block_ (e.control_block_ )
20911  , symbol_table_list_(e.symbol_table_list_)
20912  {
20913  control_block_->ref_count++;
20914  }
20915 
20917  : control_block_(0)
20918  {
20919  set_expression(new details::null_node<T>());
20920  symbol_table_list_.push_back(symbol_table);
20921  }
20922 
20924  {
20925  if (this != &e)
20926  {
20927  if (control_block_)
20928  {
20929  if (
20930  (0 != control_block_->ref_count) &&
20931  (0 == --control_block_->ref_count)
20932  )
20933  {
20934  delete control_block_;
20935  }
20936 
20937  control_block_ = 0;
20938  }
20939 
20940  control_block_ = e.control_block_;
20941  control_block_->ref_count++;
20942  symbol_table_list_ = e.symbol_table_list_;
20943  }
20944 
20945  return *this;
20946  }
20947 
20948  inline bool operator==(const expression<T>& e) const
20949  {
20950  return (this == &e);
20951  }
20952 
20953  inline bool operator!() const
20954  {
20955  return (
20956  (0 == control_block_ ) ||
20957  (0 == control_block_->expr)
20958  );
20959  }
20960 
20962  {
20963  exprtk::details::dump_ptr("expression::release", this);
20964  control_block::destroy(control_block_);
20965 
20966  return (*this);
20967  }
20968 
20970  {
20971  control_block::destroy(control_block_);
20972  }
20973 
20974  inline T value() const
20975  {
20976  assert(control_block_ );
20977  assert(control_block_->expr);
20978 
20979  return control_block_->expr->value();
20980  }
20981 
20982  inline T operator() () const
20983  {
20984  return value();
20985  }
20986 
20987  inline operator T() const
20988  {
20989  return value();
20990  }
20991 
20992  inline operator bool() const
20993  {
20994  return details::is_true(value());
20995  }
20996 
20998  {
20999  for (std::size_t i = 0; i < symbol_table_list_.size(); ++i)
21000  {
21001  if (&st == &symbol_table_list_[i])
21002  {
21003  return;
21004  }
21005  }
21006 
21007  symbol_table_list_.push_back(st);
21008  }
21009 
21010  inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const
21011  {
21012  return symbol_table_list_[index];
21013  }
21014 
21015  inline symbol_table<T>& get_symbol_table(const std::size_t& index = 0)
21016  {
21017  return symbol_table_list_[index];
21018  }
21019 
21021 
21022  inline const results_context_t& results() const
21023  {
21024  if (control_block_->results)
21025  return (*control_block_->results);
21026  else
21027  {
21028  static const results_context_t null_results;
21029  return null_results;
21030  }
21031  }
21032 
21033  inline bool return_invoked() const
21034  {
21035  return (*control_block_->return_invoked);
21036  }
21037 
21038  private:
21039 
21041  {
21042  return symbol_table_list_;
21043  }
21044 
21045  inline void set_expression(const expression_ptr expr)
21046  {
21047  if (expr)
21048  {
21049  if (control_block_)
21050  {
21051  if (0 == --control_block_->ref_count)
21052  {
21053  delete control_block_;
21054  }
21055  }
21056 
21057  control_block_ = control_block::create(expr);
21058  }
21059  }
21060 
21062  {
21063  if (expr)
21064  {
21065  if (control_block_)
21066  {
21067  control_block_->
21068  local_data_list.push_back(
21069  typename expression<T>::control_block::
21070  data_pack(reinterpret_cast<void*>(expr),
21071  control_block::e_expr));
21072  }
21073  }
21074  }
21075 
21076  inline void register_local_var(vector_holder_ptr vec_holder)
21077  {
21078  if (vec_holder)
21079  {
21080  if (control_block_)
21081  {
21082  control_block_->
21083  local_data_list.push_back(
21084  typename expression<T>::control_block::
21085  data_pack(reinterpret_cast<void*>(vec_holder),
21086  control_block::e_vecholder));
21087  }
21088  }
21089  }
21090 
21091  inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0)
21092  {
21093  if (data)
21094  {
21095  if (control_block_)
21096  {
21097  typename control_block::data_type dt = control_block::e_data;
21098 
21099  switch (data_mode)
21100  {
21101  case 0 : dt = control_block::e_data; break;
21102  case 1 : dt = control_block::e_vecdata; break;
21103  case 2 : dt = control_block::e_string; break;
21104  }
21105 
21106  control_block_->
21107  local_data_list.push_back(
21108  typename expression<T>::control_block::
21109  data_pack(reinterpret_cast<void*>(data), dt, size));
21110  }
21111  }
21112  }
21113 
21115  {
21116  if (control_block_)
21117  {
21118  return control_block_->local_data_list;
21119  }
21120  else
21121  {
21122  static typename control_block::local_data_list_t null_local_data_list;
21123  return null_local_data_list;
21124  }
21125  }
21126 
21128  {
21129  if (control_block_ && rc)
21130  {
21131  control_block_->results = rc;
21132  }
21133  }
21134 
21135  inline void set_retinvk(bool* retinvk_ptr)
21136  {
21137  if (control_block_)
21138  {
21139  control_block_->return_invoked = retinvk_ptr;
21140  }
21141  }
21142 
21144  symtab_list_t symbol_table_list_;
21145 
21146  friend class parser<T>;
21147  friend class expression_helper<T>;
21148  friend class function_compositor<T>;
21149  template <typename TT>
21150  friend bool is_valid(const expression<TT>& expr);
21151  }; // class expression
21152 
21153  template <typename T>
21155  {
21156  public:
21157 
21158  static inline bool is_constant(const expression<T>& expr)
21159  {
21161  }
21162 
21163  static inline bool is_variable(const expression<T>& expr)
21164  {
21166  }
21167 
21168  static inline bool is_unary(const expression<T>& expr)
21169  {
21171  }
21172 
21173  static inline bool is_binary(const expression<T>& expr)
21174  {
21176  }
21177 
21178  static inline bool is_function(const expression<T>& expr)
21179  {
21181  }
21182 
21183  static inline bool is_null(const expression<T>& expr)
21184  {
21186  }
21187  };
21188 
21189  template <typename T>
21190  inline bool is_valid(const expression<T>& expr)
21191  {
21192  return expr.control_block_ && !expression_helper<T>::is_null(expr);
21193  }
21194 
21195  namespace parser_error
21196  {
21198  {
21201  e_token = 2,
21204  e_lexer = 6,
21207  e_parser = 9
21208  };
21209 
21210  struct type
21211  {
21213  : mode(parser_error::e_unknown)
21214  , line_no (0)
21215  , column_no(0)
21216  {}
21217 
21220  std::string diagnostic;
21221  std::string src_location;
21222  std::string error_line;
21223  std::size_t line_no;
21224  std::size_t column_no;
21225  };
21226 
21227  inline type make_error(const error_mode mode,
21228  const std::string& diagnostic = "",
21229  const std::string& src_location = "")
21230  {
21231  type t;
21232  t.mode = mode;
21233  t.token.type = lexer::token::e_error;
21234  t.diagnostic = diagnostic;
21235  t.src_location = src_location;
21236  exprtk_debug(("%s\n", diagnostic .c_str()));
21237  return t;
21238  }
21239 
21240  inline type make_error(const error_mode mode,
21241  const lexer::token& tk,
21242  const std::string& diagnostic = "",
21243  const std::string& src_location = "")
21244  {
21245  type t;
21246  t.mode = mode;
21247  t.token = tk;
21248  t.diagnostic = diagnostic;
21249  t.src_location = src_location;
21250  exprtk_debug(("%s\n", diagnostic .c_str()));
21251  return t;
21252  }
21253 
21254  inline std::string to_str(error_mode mode)
21255  {
21256  switch (mode)
21257  {
21258  case e_unknown : return std::string("Unknown Error");
21259  case e_syntax : return std::string("Syntax Error" );
21260  case e_token : return std::string("Token Error" );
21261  case e_numeric : return std::string("Numeric Error");
21262  case e_symtab : return std::string("Symbol Error" );
21263  case e_lexer : return std::string("Lexer Error" );
21264  case e_helper : return std::string("Helper Error" );
21265  case e_parser : return std::string("Parser Error" );
21266  default : return std::string("Unknown Error");
21267  }
21268  }
21269 
21270  inline bool update_error(type& error, const std::string& expression)
21271  {
21272  if (
21273  expression.empty() ||
21274  (error.token.position > expression.size()) ||
21276  )
21277  {
21278  return false;
21279  }
21280 
21281  std::size_t error_line_start = 0;
21282 
21283  for (std::size_t i = error.token.position; i > 0; --i)
21284  {
21285  const details::char_t c = expression[i];
21286 
21287  if (('\n' == c) || ('\r' == c))
21288  {
21289  error_line_start = i + 1;
21290  break;
21291  }
21292  }
21293 
21294  std::size_t next_nl_position = std::min(expression.size(),
21295  expression.find_first_of('\n',error.token.position + 1));
21296 
21297  error.column_no = error.token.position - error_line_start;
21298  error.error_line = expression.substr(error_line_start,
21299  next_nl_position - error_line_start);
21300 
21301  error.line_no = 0;
21302 
21303  for (std::size_t i = 0; i < next_nl_position; ++i)
21304  {
21305  if ('\n' == expression[i])
21306  ++error.line_no;
21307  }
21308 
21309  return true;
21310  }
21311 
21312  inline void dump_error(const type& error)
21313  {
21314  printf("Position: %02d Type: [%s] Msg: %s\n",
21315  static_cast<int>(error.token.position),
21316  exprtk::parser_error::to_str(error.mode).c_str(),
21317  error.diagnostic.c_str());
21318  }
21319  }
21320 
21321  namespace details
21322  {
21323  template <typename Parser>
21324  inline void disable_type_checking(Parser& p)
21325  {
21326  p.state_.type_check_enabled = false;
21327  }
21328  }
21329 
21330  template <typename T>
21332  {
21333  private:
21334 
21336  {
21337  e_level00, e_level01, e_level02, e_level03, e_level04,
21338  e_level05, e_level06, e_level07, e_level08, e_level09,
21339  e_level10, e_level11, e_level12, e_level13, e_level14
21340  };
21341 
21342  typedef const T& cref_t;
21343  typedef const T const_t;
21344  typedef ifunction<T> F;
21351  typedef details::literal_node<T> literal_node_t;
21356  typedef details::conditional_node<T> conditional_node_t;
21357  typedef details::cons_conditional_node<T> cons_conditional_node_t;
21361  typedef details::while_loop_rtc_node<T> while_loop_rtc_node_t;
21362  typedef details::repeat_until_loop_rtc_node<T> repeat_until_loop_rtc_node_t;
21363  typedef details::for_loop_rtc_node<T> for_loop_rtc_node_t;
21364  #ifndef exprtk_disable_break_continue
21368  typedef details::while_loop_bc_rtc_node<T> while_loop_bc_rtc_node_t;
21369  typedef details::repeat_until_loop_bc_rtc_node<T> repeat_until_loop_bc_rtc_node_t;
21370  typedef details::for_loop_bc_rtc_node<T> for_loop_bc_rtc_node_t;
21371  #endif
21373  typedef details::variable_node<T> variable_node_t;
21374  typedef details::vector_elem_node<T> vector_elem_node_t;
21375  typedef details::vector_celem_node<T> vector_celem_node_t;
21376  typedef details::vector_elem_rtc_node<T> vector_elem_rtc_node_t;
21377  typedef details::vector_celem_rtc_node<T> vector_celem_rtc_node_t;
21378  typedef details::rebasevector_elem_node<T> rebasevector_elem_node_t;
21379  typedef details::rebasevector_celem_node<T> rebasevector_celem_node_t;
21380  typedef details::rebasevector_elem_rtc_node<T> rebasevector_elem_rtc_node_t;
21381  typedef details::rebasevector_celem_rtc_node<T> rebasevector_celem_rtc_node_t;
21383  typedef details::vector_size_node<T> vector_size_node_t;
21385  #ifndef exprtk_disable_string_capabilities
21386  typedef details::stringvar_node<T> stringvar_node_t;
21387  typedef details::string_literal_node<T> string_literal_node_t;
21388  typedef details::string_range_node<T> string_range_node_t;
21389  typedef details::const_string_range_node<T> const_string_range_node_t;
21390  typedef details::generic_string_range_node<T> generic_string_range_node_t;
21391  typedef details::string_concat_node<T> string_concat_node_t;
21392  typedef details::assignment_string_node<T> assignment_string_node_t;
21393  typedef details::assignment_string_range_node<T> assignment_string_range_node_t;
21394  typedef details::conditional_string_node<T> conditional_string_node_t;
21395  typedef details::cons_conditional_str_node<T> cons_conditional_str_node_t;
21396  #endif
21397  typedef details::assignment_node<T> assignment_node_t;
21398  typedef details::assignment_vec_elem_node<T> assignment_vec_elem_node_t;
21399  typedef details::assignment_vec_elem_rtc_node<T> assignment_vec_elem_rtc_node_t;
21400  typedef details::assignment_rebasevec_elem_node<T> assignment_rebasevec_elem_node_t;
21401  typedef details::assignment_rebasevec_elem_rtc_node<T> assignment_rebasevec_elem_rtc_node_t;
21402  typedef details::assignment_rebasevec_celem_node<T> assignment_rebasevec_celem_node_t;
21403  typedef details::assignment_vec_node<T> assignment_vec_node_t;
21404  typedef details::assignment_vecvec_node<T> assignment_vecvec_node_t;
21405  typedef details::conditional_vector_node<T> conditional_vector_node_t;
21406  typedef details::scand_node<T> scand_node_t;
21407  typedef details::scor_node<T> scor_node_t;
21415 
21421 
21423 
21424  typedef std::map<operator_t, unary_functor_t > unary_op_map_t;
21425  typedef std::map<operator_t, binary_functor_t > binary_op_map_t;
21426  typedef std::map<operator_t, trinary_functor_t> trinary_op_map_t;
21427 
21428  typedef std::map<std::string,std::pair<trinary_functor_t ,operator_t> > sf3_map_t;
21429  typedef std::map<std::string,std::pair<quaternary_functor_t,operator_t> > sf4_map_t;
21430 
21431  typedef std::map<binary_functor_t,operator_t> inv_binary_op_map_t;
21432  typedef std::multimap<std::string,details::base_operation_t,details::ilesscompare> base_ops_map_t;
21433  typedef std::set<std::string,details::ilesscompare> disabled_func_set_t;
21434 
21438 
21446 
21452 
21457 
21459 
21460  typedef parser_helper prsrhlpr_t;
21461 
21463  {
21465  {
21470  e_string
21471  };
21472 
21477  #ifndef exprtk_disable_string_capabilities
21479  #endif
21480 
21482  : name("???")
21483  , size (std::numeric_limits<std::size_t>::max())
21484  , index(std::numeric_limits<std::size_t>::max())
21485  , depth(std::numeric_limits<std::size_t>::max())
21486  , ref_count(0)
21487  , ip_index (0)
21488  , type (e_none)
21489  , active (false)
21490  , data (0)
21491  , var_node (0)
21492  , vec_node (0)
21493  #ifndef exprtk_disable_string_capabilities
21494  , str_node(0)
21495  #endif
21496  {}
21497 
21498  bool operator < (const scope_element& se) const
21499  {
21500  if (ip_index < se.ip_index)
21501  return true;
21502  else if (ip_index > se.ip_index)
21503  return false;
21504  else if (depth < se.depth)
21505  return true;
21506  else if (depth > se.depth)
21507  return false;
21508  else if (index < se.index)
21509  return true;
21510  else if (index > se.index)
21511  return false;
21512  else
21513  return (name < se.name);
21514  }
21515 
21516  void clear()
21517  {
21518  name = "???";
21522  type = e_none;
21523  active = false;
21524  ref_count = 0;
21525  ip_index = 0;
21526  data = 0;
21527  var_node = 0;
21528  vec_node = 0;
21529  #ifndef exprtk_disable_string_capabilities
21530  str_node = 0;
21531  #endif
21532  }
21533 
21534  std::string name;
21535  std::size_t size;
21536  std::size_t index;
21537  std::size_t depth;
21538  std::size_t ref_count;
21539  std::size_t ip_index;
21541  bool active;
21542  void* data;
21545  #ifndef exprtk_disable_string_capabilities
21547  #endif
21548  };
21549 
21551  {
21552  public:
21553 
21557 
21559  : parser_(p)
21560  , input_param_cnt_(0)
21561  {}
21562 
21563  inline std::size_t size() const
21564  {
21565  return element_.size();
21566  }
21567 
21568  inline bool empty() const
21569  {
21570  return element_.empty();
21571  }
21572 
21573  inline scope_element& get_element(const std::size_t& index)
21574  {
21575  if (index < element_.size())
21576  return element_[index];
21577  else
21578  return null_element_;
21579  }
21580 
21581  inline scope_element& get_element(const std::string& var_name,
21582  const std::size_t index = std::numeric_limits<std::size_t>::max())
21583  {
21584  const std::size_t current_depth = parser_.state_.scope_depth;
21585 
21586  for (std::size_t i = 0; i < element_.size(); ++i)
21587  {
21588  scope_element& se = element_[i];
21589 
21590  if (se.depth > current_depth)
21591  continue;
21592  else if (
21593  details::imatch(se.name, var_name) &&
21594  (se.index == index)
21595  )
21596  return se;
21597  }
21598 
21599  return null_element_;
21600  }
21601 
21602  inline scope_element& get_active_element(const std::string& var_name,
21603  const std::size_t index = std::numeric_limits<std::size_t>::max())
21604  {
21605  const std::size_t current_depth = parser_.state_.scope_depth;
21606 
21607  for (std::size_t i = 0; i < element_.size(); ++i)
21608  {
21609  scope_element& se = element_[i];
21610 
21611  if (se.depth > current_depth)
21612  continue;
21613  else if (
21614  details::imatch(se.name, var_name) &&
21615  (se.index == index) &&
21616  (se.active)
21617  )
21618  return se;
21619  }
21620 
21621  return null_element_;
21622  }
21623 
21624  inline bool add_element(const scope_element& se)
21625  {
21626  for (std::size_t i = 0; i < element_.size(); ++i)
21627  {
21628  scope_element& cse = element_[i];
21629 
21630  if (
21631  details::imatch(cse.name, se.name) &&
21632  (cse.depth <= se.depth) &&
21633  (cse.index == se.index) &&
21634  (cse.size == se.size ) &&
21635  (cse.type == se.type ) &&
21636  (cse.active)
21637  )
21638  return false;
21639  }
21640 
21641  element_.push_back(se);
21642  std::sort(element_.begin(),element_.end());
21643 
21644  return true;
21645  }
21646 
21647  inline void deactivate(const std::size_t& scope_depth)
21648  {
21649  exprtk_debug(("deactivate() - Scope depth: %d\n",
21650  static_cast<int>(parser_.state_.scope_depth)));
21651 
21652  for (std::size_t i = 0; i < element_.size(); ++i)
21653  {
21654  scope_element& se = element_[i];
21655 
21656  if (se.active && (se.depth >= scope_depth))
21657  {
21658  exprtk_debug(("deactivate() - element[%02d] '%s'\n",
21659  static_cast<int>(i),
21660  se.name.c_str()));
21661 
21662  se.active = false;
21663  }
21664  }
21665  }
21666 
21667  inline void free_element(scope_element& se)
21668  {
21669  exprtk_debug(("free_element() - se[%s]\n", se.name.c_str()));
21670 
21671  switch (se.type)
21672  {
21673  case scope_element::e_variable : delete reinterpret_cast<T*>(se.data);
21674  delete se.var_node;
21675  break;
21676 
21677  case scope_element::e_vector : delete[] reinterpret_cast<T*>(se.data);
21678  delete se.vec_node;
21679  break;
21680 
21681  case scope_element::e_vecelem : delete se.var_node;
21682  break;
21683 
21684  #ifndef exprtk_disable_string_capabilities
21685  case scope_element::e_string : delete reinterpret_cast<std::string*>(se.data);
21686  delete se.str_node;
21687  break;
21688  #endif
21689 
21690  default : return;
21691  }
21692 
21693  se.clear();
21694  }
21695 
21696  inline void cleanup()
21697  {
21698  for (std::size_t i = 0; i < element_.size(); ++i)
21699  {
21700  free_element(element_[i]);
21701  }
21702 
21703  element_.clear();
21704 
21705  input_param_cnt_ = 0;
21706  }
21707 
21708  inline std::size_t next_ip_index()
21709  {
21710  return ++input_param_cnt_;
21711  }
21712 
21714  {
21715  for (std::size_t i = 0; i < element_.size(); ++i)
21716  {
21717  scope_element& se = element_[i];
21718 
21719  if (
21720  se.active &&
21721  se.var_node &&
21723  )
21724  {
21725  variable_node_ptr vn = reinterpret_cast<variable_node_ptr>(se.var_node);
21726 
21727  if (&(vn->ref()) == (&v))
21728  {
21729  return se.var_node;
21730  }
21731  }
21732  }
21733 
21734  return expression_node_ptr(0);
21735  }
21736 
21737  inline std::string get_vector_name(const T* data)
21738  {
21739  for (std::size_t i = 0; i < element_.size(); ++i)
21740  {
21741  scope_element& se = element_[i];
21742 
21743  if (
21744  se.active &&
21745  se.vec_node &&
21746  (se.vec_node->data() == data)
21747  )
21748  {
21749  return se.name;
21750  }
21751  }
21752 
21753  return "neo-vector";
21754  }
21755 
21756  private:
21757 
21760 
21762  std::vector<scope_element> element_;
21764  std::size_t input_param_cnt_;
21765  };
21766 
21768  {
21769  public:
21770 
21772 
21774  : parser_(p)
21775  {
21776  parser_.state_.scope_depth++;
21777  #ifdef exprtk_enable_debugging
21778  const std::string depth(2 * parser_.state_.scope_depth,'-');
21779  exprtk_debug(("%s> Scope Depth: %02d\n",
21780  depth.c_str(),
21781  static_cast<int>(parser_.state_.scope_depth)));
21782  #endif
21783  }
21784 
21786  {
21787  parser_.sem_.deactivate(parser_.state_.scope_depth);
21788  parser_.state_.scope_depth--;
21789  #ifdef exprtk_enable_debugging
21790  const std::string depth(2 * parser_.state_.scope_depth,'-');
21791  exprtk_debug(("<%s Scope Depth: %02d\n",
21792  depth.c_str(),
21793  static_cast<int>(parser_.state_.scope_depth)));
21794  #endif
21795  }
21796 
21797  private:
21798 
21801 
21803  };
21804 
21805  template <typename T_>
21807  {
21808  static inline bool is_within(const T_& v, const T_& begin, const T_& end)
21809  {
21810  assert(begin <= end);
21811  return (begin <= v) && (v < end);
21812  }
21813 
21814  static inline bool is_less(const T_& v, const T_& begin)
21815  {
21816  return (v < begin);
21817  }
21818 
21819  static inline bool is_greater(const T_& v, const T_& end)
21820  {
21821  return (end <= v);
21822  }
21823 
21824  static inline bool end_inclusive()
21825  {
21826  return false;
21827  }
21828  };
21829 
21830  template <typename T_>
21832  {
21833  static inline bool is_within(const T_& v, const T_& begin, const T_& end)
21834  {
21835  assert(begin <= end);
21836  return (begin <= v) && (v <= end);
21837  }
21838 
21839  static inline bool is_less(const T_& v, const T_& begin)
21840  {
21841  return (v < begin);
21842  }
21843 
21844  static inline bool is_greater(const T_& v, const T_& end)
21845  {
21846  return (end < v);
21847  }
21848 
21849  static inline bool end_inclusive()
21850  {
21851  return true;
21852  }
21853  };
21854 
21855  template <typename IntervalPointType,
21856  typename RangePolicy = halfopen_range_policy<IntervalPointType> >
21858  {
21859  public:
21860 
21861  typedef IntervalPointType interval_point_t;
21862  typedef std::pair<interval_point_t, interval_point_t> interval_t;
21863  typedef std::map<interval_point_t, interval_t> interval_map_t;
21864  typedef typename interval_map_t::const_iterator interval_map_citr_t;
21865 
21866  std::size_t size() const
21867  {
21868  return interval_map_.size();
21869  }
21870 
21871  void reset()
21872  {
21873  interval_map_.clear();
21874  }
21875 
21876  bool in_interval(const interval_point_t point, interval_t& interval) const
21877  {
21878  interval_map_citr_t itr = RangePolicy::end_inclusive() ?
21879  interval_map_.lower_bound(point):
21880  interval_map_.upper_bound(point);
21881 
21882  for (; itr != interval_map_.end(); ++itr)
21883  {
21884  const interval_point_t& begin = itr->second.first;
21885  const interval_point_t& end = itr->second.second;
21886 
21887  if (RangePolicy::is_within(point, begin, end))
21888  {
21889  interval = interval_t(begin,end);
21890  return true;
21891  }
21892  else if (RangePolicy::is_greater(point, end))
21893  {
21894  break;
21895  }
21896  }
21897 
21898  return false;
21899  }
21900 
21901  bool in_interval(const interval_point_t point) const
21902  {
21903  interval_t interval;
21904  return in_interval(point,interval);
21905  }
21906 
21907  bool add_interval(const interval_point_t begin, const interval_point_t end)
21908  {
21909  if ((end <= begin) || in_interval(begin) || in_interval(end))
21910  {
21911  return false;
21912  }
21913 
21914  interval_map_[end] = std::make_pair(begin, end);
21915 
21916  return true;
21917  }
21918 
21919  bool add_interval(const interval_t interval)
21920  {
21921  return add_interval(interval.first, interval.second);
21922  }
21923 
21924  private:
21925 
21927  };
21928 
21930  {
21931  public:
21932 
21934 
21936  : parser_(p)
21937  , limit_exceeded_(false)
21938  {
21939  if (++parser_.state_.stack_depth > parser_.settings_.max_stack_depth_)
21940  {
21941  limit_exceeded_ = true;
21942  parser_.set_error(make_error(
21944  "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) +
21945  " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_),
21947  }
21948  }
21949 
21951  {
21952  assert(parser_.state_.stack_depth > 0);
21953  parser_.state_.stack_depth--;
21954  }
21955 
21956  bool operator!()
21957  {
21958  return limit_exceeded_;
21959  }
21960 
21961  private:
21962 
21965 
21968  };
21969 
21971  {
21973 
21977  #ifndef exprtk_disable_string_capabilities
21979  #endif
21983 
21985  {
21987  : symbol_table(0)
21988  , variable(0)
21989  {}
21990 
21993  };
21994 
21996  {
21998  : symbol_table(0)
21999  , vector_holder(0)
22000  {}
22001 
22004  };
22005 
22006  #ifndef exprtk_disable_string_capabilities
22008  {
22010  : symbol_table(0)
22011  , str_var(0)
22012  {}
22013 
22016  };
22017  #endif
22018 
22019  inline bool empty() const
22020  {
22021  return symtab_list_.empty();
22022  }
22023 
22024  inline void clear()
22025  {
22026  symtab_list_.clear();
22027  }
22028 
22029  inline bool valid() const
22030  {
22031  if (!empty())
22032  {
22033  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22034  {
22035  if (symtab_list_[i].valid())
22036  return true;
22037  }
22038  }
22039 
22040  return false;
22041  }
22042 
22043  inline bool valid_symbol(const std::string& symbol) const
22044  {
22045  if (!symtab_list_.empty())
22046  return symtab_list_[0].valid_symbol(symbol);
22047  else
22048  return false;
22049  }
22050 
22051  inline bool valid_function_name(const std::string& symbol) const
22052  {
22053  if (!symtab_list_.empty())
22054  return symtab_list_[0].valid_function(symbol);
22055  else
22056  return false;
22057  }
22058 
22059  inline variable_context get_variable_context(const std::string& variable_name) const
22060  {
22061  variable_context result;
22062  if (!valid_symbol(variable_name))
22063  return result;
22064 
22065  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22066  {
22067  if (!symtab_list_[i].valid())
22068  {
22069  continue;
22070  }
22071 
22072  result.variable = local_data(i)
22073  .variable_store.get(variable_name);
22074  if (result.variable)
22075  {
22076  result.symbol_table = &symtab_list_[i];
22077  break;
22078  }
22079  }
22080 
22081  return result;
22082  }
22083 
22084  inline variable_ptr get_variable(const std::string& variable_name) const
22085  {
22086  if (!valid_symbol(variable_name))
22087  return reinterpret_cast<variable_ptr>(0);
22088 
22089  variable_ptr result = reinterpret_cast<variable_ptr>(0);
22090 
22091  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22092  {
22093  if (!symtab_list_[i].valid())
22094  continue;
22095  else
22096  result = local_data(i)
22097  .variable_store.get(variable_name);
22098 
22099  if (result) break;
22100  }
22101 
22102  return result;
22103  }
22104 
22105  inline variable_ptr get_variable(const T& var_ref) const
22106  {
22107  variable_ptr result = reinterpret_cast<variable_ptr>(0);
22108 
22109  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22110  {
22111  if (!symtab_list_[i].valid())
22112  continue;
22113  else
22114  result = local_data(i).variable_store
22115  .get_from_varptr(reinterpret_cast<const void*>(&var_ref));
22116 
22117  if (result) break;
22118  }
22119 
22120  return result;
22121  }
22122 
22123  #ifndef exprtk_disable_string_capabilities
22124  inline string_context get_string_context(const std::string& string_name) const
22125  {
22126  string_context result;
22127 
22128  if (!valid_symbol(string_name))
22129  return result;
22130 
22131  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22132  {
22133  if (!symtab_list_[i].valid())
22134  {
22135  continue;
22136  }
22137 
22138  result.str_var = local_data(i).stringvar_store.get(string_name);
22139 
22140  if (result.str_var)
22141  {
22142  result.symbol_table = &symtab_list_[i];
22143  break;
22144  }
22145  }
22146 
22147  return result;
22148  }
22149 
22150  inline stringvar_ptr get_stringvar(const std::string& string_name) const
22151  {
22152  if (!valid_symbol(string_name))
22153  return reinterpret_cast<stringvar_ptr>(0);
22154 
22155  stringvar_ptr result = reinterpret_cast<stringvar_ptr>(0);
22156 
22157  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22158  {
22159  if (!symtab_list_[i].valid())
22160  continue;
22161  else
22162  result = local_data(i)
22163  .stringvar_store.get(string_name);
22164 
22165  if (result) break;
22166  }
22167 
22168  return result;
22169  }
22170  #endif
22171 
22172  inline function_ptr get_function(const std::string& function_name) const
22173  {
22174  if (!valid_function_name(function_name))
22175  return reinterpret_cast<function_ptr>(0);
22176 
22177  function_ptr result = reinterpret_cast<function_ptr>(0);
22178 
22179  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22180  {
22181  if (!symtab_list_[i].valid())
22182  continue;
22183  else
22184  result = local_data(i)
22185  .function_store.get(function_name);
22186 
22187  if (result) break;
22188  }
22189 
22190  return result;
22191  }
22192 
22193  inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
22194  {
22195  if (!valid_function_name(vararg_function_name))
22196  return reinterpret_cast<vararg_function_ptr>(0);
22197 
22198  vararg_function_ptr result = reinterpret_cast<vararg_function_ptr>(0);
22199 
22200  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22201  {
22202  if (!symtab_list_[i].valid())
22203  continue;
22204  else
22205  result = local_data(i)
22206  .vararg_function_store.get(vararg_function_name);
22207 
22208  if (result) break;
22209  }
22210 
22211  return result;
22212  }
22213 
22214  inline generic_function_ptr get_generic_function(const std::string& function_name) const
22215  {
22216  if (!valid_function_name(function_name))
22217  return reinterpret_cast<generic_function_ptr>(0);
22218 
22219  generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
22220 
22221  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22222  {
22223  if (!symtab_list_[i].valid())
22224  continue;
22225  else
22226  result = local_data(i)
22227  .generic_function_store.get(function_name);
22228 
22229  if (result) break;
22230  }
22231 
22232  return result;
22233  }
22234 
22235  inline generic_function_ptr get_string_function(const std::string& function_name) const
22236  {
22237  if (!valid_function_name(function_name))
22238  return reinterpret_cast<generic_function_ptr>(0);
22239 
22240  generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
22241 
22242  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22243  {
22244  if (!symtab_list_[i].valid())
22245  continue;
22246  else
22247  result =
22248  local_data(i).string_function_store.get(function_name);
22249 
22250  if (result) break;
22251  }
22252 
22253  return result;
22254  }
22255 
22256  inline generic_function_ptr get_overload_function(const std::string& function_name) const
22257  {
22258  if (!valid_function_name(function_name))
22259  return reinterpret_cast<generic_function_ptr>(0);
22260 
22261  generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
22262 
22263  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22264  {
22265  if (!symtab_list_[i].valid())
22266  continue;
22267  else
22268  result =
22269  local_data(i).overload_function_store.get(function_name);
22270 
22271  if (result) break;
22272  }
22273 
22274  return result;
22275  }
22276 
22277  inline vector_context get_vector_context(const std::string& vector_name) const
22278  {
22279  vector_context result;
22280  if (!valid_symbol(vector_name))
22281  return result;
22282 
22283  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22284  {
22285  if (!symtab_list_[i].valid())
22286  {
22287  continue;
22288  }
22289 
22290  result.vector_holder = local_data(i).vector_store.get(vector_name);
22291 
22292  if (result.vector_holder)
22293  {
22294  result.symbol_table = &symtab_list_[i];
22295  break;
22296  }
22297  }
22298 
22299  return result;
22300  }
22301 
22302  inline vector_holder_ptr get_vector(const std::string& vector_name) const
22303  {
22304  if (!valid_symbol(vector_name))
22305  return reinterpret_cast<vector_holder_ptr>(0);
22306 
22307  vector_holder_ptr result = reinterpret_cast<vector_holder_ptr>(0);
22308 
22309  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22310  {
22311  if (!symtab_list_[i].valid())
22312  {
22313  continue;
22314  }
22315 
22316  result = local_data(i).vector_store.get(vector_name);
22317 
22318  if (result)
22319  {
22320  break;
22321  }
22322  }
22323 
22324  return result;
22325  }
22326 
22327  inline bool is_constant_node(const std::string& symbol_name) const
22328  {
22329  if (!valid_symbol(symbol_name))
22330  return false;
22331 
22332  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22333  {
22334  if (!symtab_list_[i].valid())
22335  {
22336  continue;
22337  }
22338 
22339  if (local_data(i).variable_store.is_constant(symbol_name))
22340  {
22341  return true;
22342  }
22343  }
22344 
22345  return false;
22346  }
22347 
22348  #ifndef exprtk_disable_string_capabilities
22349  inline bool is_constant_string(const std::string& symbol_name) const
22350  {
22351  if (!valid_symbol(symbol_name))
22352  return false;
22353 
22354  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22355  {
22356  if (!symtab_list_[i].valid())
22357  continue;
22358  else if (!local_data(i).stringvar_store.symbol_exists(symbol_name))
22359  continue;
22360  else if (local_data(i).stringvar_store.is_constant(symbol_name))
22361  return true;
22362  }
22363 
22364  return false;
22365  }
22366  #endif
22367 
22368  inline bool symbol_exists(const std::string& symbol) const
22369  {
22370  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22371  {
22372  if (!symtab_list_[i].valid())
22373  {
22374  continue;
22375  }
22376 
22377  if (symtab_list_[i].symbol_exists(symbol))
22378  {
22379  return true;
22380  }
22381  }
22382 
22383  return false;
22384  }
22385 
22386  inline bool is_variable(const std::string& variable_name) const
22387  {
22388  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22389  {
22390  if (!symtab_list_[i].valid())
22391  continue;
22392  else if (
22393  symtab_list_[i].local_data().variable_store
22394  .symbol_exists(variable_name)
22395  )
22396  return true;
22397  }
22398 
22399  return false;
22400  }
22401 
22402  #ifndef exprtk_disable_string_capabilities
22403  inline bool is_stringvar(const std::string& stringvar_name) const
22404  {
22405  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22406  {
22407  if (!symtab_list_[i].valid())
22408  continue;
22409  else if (
22410  symtab_list_[i].local_data().stringvar_store
22411  .symbol_exists(stringvar_name)
22412  )
22413  return true;
22414  }
22415 
22416  return false;
22417  }
22418 
22419  inline bool is_conststr_stringvar(const std::string& symbol_name) const
22420  {
22421  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22422  {
22423  if (!symtab_list_[i].valid())
22424  continue;
22425  else if (
22426  symtab_list_[i].local_data().stringvar_store
22427  .symbol_exists(symbol_name)
22428  )
22429  {
22430  return (
22431  local_data(i).stringvar_store.symbol_exists(symbol_name) ||
22432  local_data(i).stringvar_store.is_constant (symbol_name)
22433  );
22434 
22435  }
22436  }
22437 
22438  return false;
22439  }
22440  #endif
22441 
22442  inline bool is_function(const std::string& function_name) const
22443  {
22444  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22445  {
22446  if (!symtab_list_[i].valid())
22447  continue;
22448  else if (
22449  local_data(i).vararg_function_store
22450  .symbol_exists(function_name)
22451  )
22452  return true;
22453  }
22454 
22455  return false;
22456  }
22457 
22458  inline bool is_vararg_function(const std::string& vararg_function_name) const
22459  {
22460  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22461  {
22462  if (!symtab_list_[i].valid())
22463  continue;
22464  else if (
22465  local_data(i).vararg_function_store
22466  .symbol_exists(vararg_function_name)
22467  )
22468  return true;
22469  }
22470 
22471  return false;
22472  }
22473 
22474  inline bool is_vector(const std::string& vector_name) const
22475  {
22476  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
22477  {
22478  if (!symtab_list_[i].valid())
22479  continue;
22480  else if (
22481  local_data(i).vector_store
22482  .symbol_exists(vector_name)
22483  )
22484  return true;
22485  }
22486 
22487  return false;
22488  }
22489 
22490  inline std::string get_variable_name(const expression_node_ptr& ptr) const
22491  {
22492  return local_data().variable_store.entity_name(ptr);
22493  }
22494 
22495  inline std::string get_vector_name(const vector_holder_ptr& ptr) const
22496  {
22497  return local_data().vector_store.entity_name(ptr);
22498  }
22499 
22500  #ifndef exprtk_disable_string_capabilities
22501  inline std::string get_stringvar_name(const expression_node_ptr& ptr) const
22502  {
22503  return local_data().stringvar_store.entity_name(ptr);
22504  }
22505 
22506  inline std::string get_conststr_stringvar_name(const expression_node_ptr& ptr) const
22507  {
22508  return local_data().stringvar_store.entity_name(ptr);
22509  }
22510  #endif
22511 
22512  inline local_data_t& local_data(const std::size_t& index = 0)
22513  {
22514  return symtab_list_[index].local_data();
22515  }
22516 
22517  inline const local_data_t& local_data(const std::size_t& index = 0) const
22518  {
22519  return symtab_list_[index].local_data();
22520  }
22521 
22522  inline symbol_table_t& get_symbol_table(const std::size_t& index = 0)
22523  {
22524  return symtab_list_[index];
22525  }
22526  };
22527 
22529  {
22531  : type_check_enabled(true)
22532  {
22533  reset();
22534  }
22535 
22536  void reset()
22537  {
22538  parsing_return_stmt = false;
22539  parsing_break_stmt = false;
22540  return_stmt_present = false;
22541  side_effect_present = false;
22542  scope_depth = 0;
22543  stack_depth = 0;
22544  parsing_loop_stmt_count = 0;
22545  }
22546 
22547  #ifndef exprtk_enable_debugging
22548  void activate_side_effect(const std::string&)
22549  #else
22550  void activate_side_effect(const std::string& source)
22551  #endif
22552  {
22553  if (!side_effect_present)
22554  {
22555  side_effect_present = true;
22556 
22557  exprtk_debug(("activate_side_effect() - caller: %s\n", source.c_str()));
22558  }
22559  }
22560 
22566  std::size_t scope_depth;
22567  std::size_t stack_depth;
22569  };
22570 
22571  public:
22572 
22574  {
22575 
22577  {
22578  e_usr_unknown_type = 0,
22579  e_usr_variable_type = 1,
22580  e_usr_constant_type = 2
22581  };
22582 
22584  {
22585  e_usrmode_default = 0,
22586  e_usrmode_extended = 1
22587  };
22588 
22590 
22591  unknown_symbol_resolver(const usr_mode m = e_usrmode_default)
22592  : mode(m)
22593  {}
22594 
22596  {}
22597 
22598  virtual bool process(const std::string& /*unknown_symbol*/,
22599  usr_symbol_type& st,
22600  T& default_value,
22601  std::string& error_message)
22602  {
22603  if (e_usrmode_default != mode)
22604  return false;
22605 
22606  st = e_usr_variable_type;
22607  default_value = T(0);
22608  error_message.clear();
22609 
22610  return true;
22611  }
22612 
22613  virtual bool process(const std::string& /* unknown_symbol */,
22614  symbol_table_t& /* symbol_table */,
22615  std::string& /* error_message */)
22616  {
22617  return false;
22618  }
22619  };
22620 
22622  {
22623  e_ct_none = 0,
22624  e_ct_variables = 1,
22625  e_ct_functions = 2,
22626  e_ct_assignments = 4
22627  };
22628 
22630  {
22631  e_st_unknown = 0,
22632  e_st_variable = 1,
22633  e_st_vector = 2,
22634  e_st_vecelem = 3,
22635  e_st_string = 4,
22636  e_st_function = 5,
22637  e_st_local_variable = 6,
22638  e_st_local_vector = 7,
22639  e_st_local_string = 8
22640  };
22641 
22643  {
22644  public:
22645 
22646  typedef std::pair<std::string,symbol_type> symbol_t;
22647  typedef std::vector<symbol_t> symbol_list_t;
22648 
22649  dependent_entity_collector(const std::size_t options = e_ct_none)
22650  : options_(options)
22651  , collect_variables_ ((options_ & e_ct_variables ) == e_ct_variables )
22652  , collect_functions_ ((options_ & e_ct_functions ) == e_ct_functions )
22653  , collect_assignments_((options_ & e_ct_assignments) == e_ct_assignments)
22654  , return_present_ (false)
22655  , final_stmt_return_(false)
22656  {}
22657 
22658  template <typename Allocator,
22659  template <typename, typename> class Sequence>
22660  inline std::size_t symbols(Sequence<symbol_t,Allocator>& symbols_list)
22661  {
22662  if (!collect_variables_ && !collect_functions_)
22663  return 0;
22664  else if (symbol_name_list_.empty())
22665  return 0;
22666 
22667  for (std::size_t i = 0; i < symbol_name_list_.size(); ++i)
22668  {
22669  details::case_normalise(symbol_name_list_[i].first);
22670  }
22671 
22672  std::sort(symbol_name_list_.begin(), symbol_name_list_.end());
22673 
22674  std::unique_copy
22675  (
22676  symbol_name_list_.begin(),
22677  symbol_name_list_.end (),
22678  std::back_inserter(symbols_list)
22679  );
22680 
22681  return symbols_list.size();
22682  }
22683 
22684  template <typename Allocator,
22685  template <typename, typename> class Sequence>
22686  inline std::size_t assignment_symbols(Sequence<symbol_t,Allocator>& assignment_list)
22687  {
22688  if (!collect_assignments_)
22689  return 0;
22690  else if (assignment_name_list_.empty())
22691  return 0;
22692 
22693  for (std::size_t i = 0; i < assignment_name_list_.size(); ++i)
22694  {
22695  details::case_normalise(assignment_name_list_[i].first);
22696  }
22697 
22698  std::sort(assignment_name_list_.begin(),assignment_name_list_.end());
22699 
22700  std::unique_copy
22701  (
22702  assignment_name_list_.begin(),
22703  assignment_name_list_.end (),
22704  std::back_inserter(assignment_list)
22705  );
22706 
22707  return assignment_list.size();
22708  }
22709 
22710  void clear()
22711  {
22712  symbol_name_list_ .clear();
22713  assignment_name_list_.clear();
22714  retparam_list_ .clear();
22715  return_present_ = false;
22716  final_stmt_return_ = false;
22717  }
22718 
22720  {
22721  return collect_variables_;
22722  }
22723 
22725  {
22726  return collect_functions_;
22727  }
22728 
22730  {
22731  return collect_assignments_;
22732  }
22733 
22734  bool return_present() const
22735  {
22736  return return_present_;
22737  }
22738 
22739  bool final_stmt_return() const
22740  {
22741  return final_stmt_return_;
22742  }
22743 
22744  typedef std::vector<std::string> retparam_list_t;
22745 
22747  {
22748  return retparam_list_;
22749  }
22750 
22751  private:
22752 
22753  inline void add_symbol(const std::string& symbol, const symbol_type st)
22754  {
22755  switch (st)
22756  {
22757  case e_st_variable :
22758  case e_st_vector :
22759  case e_st_string :
22760  case e_st_local_variable :
22761  case e_st_local_vector :
22762  case e_st_local_string : if (collect_variables_)
22763  symbol_name_list_
22764  .push_back(std::make_pair(symbol, st));
22765  break;
22766 
22767  case e_st_function : if (collect_functions_)
22768  symbol_name_list_
22769  .push_back(std::make_pair(symbol, st));
22770  break;
22771 
22772  default : return;
22773  }
22774  }
22775 
22776  inline void add_assignment(const std::string& symbol, const symbol_type st)
22777  {
22778  switch (st)
22779  {
22780  case e_st_variable :
22781  case e_st_vector :
22782  case e_st_string : if (collect_assignments_)
22783  assignment_name_list_
22784  .push_back(std::make_pair(symbol, st));
22785  break;
22786 
22787  default : return;
22788  }
22789  }
22790 
22791  std::size_t options_;
22799  retparam_list_t retparam_list_;
22800 
22801  friend class parser<T>;
22802  };
22803 
22805  {
22806  private:
22807 
22808  typedef std::set<std::string,details::ilesscompare> disabled_entity_set_t;
22809  typedef disabled_entity_set_t::iterator des_itr_t;
22810 
22811  public:
22812 
22814  {
22816  e_replacer = 1,
22817  e_joiner = 2,
22818  e_numeric_check = 4,
22819  e_bracket_check = 8,
22820  e_sequence_check = 16,
22821  e_commutative_check = 32,
22822  e_strength_reduction = 64,
22823  e_disable_vardef = 128,
22824  e_collect_vars = 256,
22825  e_collect_funcs = 512,
22826  e_collect_assings = 1024,
22827  e_disable_usr_on_rsrvd = 2048,
22828  e_disable_zero_return = 4096
22829  };
22830 
22832  {
22833  e_bf_unknown = 0,
22834  e_bf_abs , e_bf_acos , e_bf_acosh , e_bf_asin ,
22835  e_bf_asinh , e_bf_atan , e_bf_atan2 , e_bf_atanh ,
22836  e_bf_avg , e_bf_ceil , e_bf_clamp , e_bf_cos ,
22837  e_bf_cosh , e_bf_cot , e_bf_csc , e_bf_equal ,
22838  e_bf_erf , e_bf_erfc , e_bf_exp , e_bf_expm1 ,
22839  e_bf_floor , e_bf_frac , e_bf_hypot , e_bf_iclamp ,
22840  e_bf_like , e_bf_log , e_bf_log10 , e_bf_log1p ,
22841  e_bf_log2 , e_bf_logn , e_bf_mand , e_bf_max ,
22842  e_bf_min , e_bf_mod , e_bf_mor , e_bf_mul ,
22843  e_bf_ncdf , e_bf_pow , e_bf_root , e_bf_round ,
22844  e_bf_roundn , e_bf_sec , e_bf_sgn , e_bf_sin ,
22845  e_bf_sinc , e_bf_sinh , e_bf_sqrt , e_bf_sum ,
22846  e_bf_swap , e_bf_tan , e_bf_tanh , e_bf_trunc ,
22847  e_bf_not_equal , e_bf_inrange , e_bf_deg2grad , e_bf_deg2rad ,
22848  e_bf_rad2deg , e_bf_grad2deg
22849  };
22850 
22852  {
22853  e_ctrl_unknown = 0,
22859  e_ctrl_return
22860  };
22861 
22863  {
22864  e_logic_unknown = 0,
22865  e_logic_and, e_logic_nand , e_logic_nor ,
22866  e_logic_not, e_logic_or , e_logic_xnor,
22867  e_logic_xor, e_logic_scand, e_logic_scor
22868  };
22869 
22871  {
22872  e_arith_unknown = 0,
22873  e_arith_add, e_arith_sub, e_arith_mul,
22874  e_arith_div, e_arith_mod, e_arith_pow
22875  };
22876 
22878  {
22879  e_assign_unknown = 0,
22880  e_assign_assign, e_assign_addass, e_assign_subass,
22881  e_assign_mulass, e_assign_divass, e_assign_modass
22882  };
22883 
22885  {
22886  e_ineq_unknown = 0,
22887  e_ineq_lt , e_ineq_lte, e_ineq_eq ,
22888  e_ineq_equal, e_ineq_ne , e_ineq_nequal,
22889  e_ineq_gte , e_ineq_gt
22890  };
22891 
22892  static const std::size_t default_compile_all_opts =
22893  e_replacer +
22894  e_joiner +
22895  e_numeric_check +
22896  e_bracket_check +
22897  e_sequence_check +
22898  e_commutative_check +
22899  e_strength_reduction;
22900 
22901  settings_store(const std::size_t compile_options = default_compile_all_opts)
22902  : max_stack_depth_(400)
22903  , max_node_depth_(10000)
22904  , max_local_vector_size_(2000000000)
22905  {
22906  load_compile_options(compile_options);
22907  }
22908 
22910  {
22911  disabled_func_set_.clear();
22912  return (*this);
22913  }
22914 
22916  {
22917  disabled_ctrl_set_.clear();
22918  return (*this);
22919  }
22920 
22922  {
22923  disabled_logic_set_.clear();
22924  return (*this);
22925  }
22926 
22928  {
22929  disabled_arithmetic_set_.clear();
22930  return (*this);
22931  }
22932 
22934  {
22935  disabled_assignment_set_.clear();
22936  return (*this);
22937  }
22938 
22940  {
22941  disabled_inequality_set_.clear();
22942  return (*this);
22943  }
22944 
22946  {
22947  disable_vardef_ = false;
22948  return (*this);
22949  }
22950 
22952  {
22953  enable_commutative_check_ = true;
22954  return (*this);
22955  }
22956 
22958  {
22959  enable_strength_reduction_ = true;
22960  return (*this);
22961  }
22962 
22964  {
22965  std::copy(details::base_function_list,
22967  std::insert_iterator<disabled_entity_set_t>
22968  (disabled_func_set_, disabled_func_set_.begin()));
22969  return (*this);
22970  }
22971 
22973  {
22974  std::copy(details::cntrl_struct_list,
22976  std::insert_iterator<disabled_entity_set_t>
22977  (disabled_ctrl_set_, disabled_ctrl_set_.begin()));
22978  return (*this);
22979  }
22980 
22982  {
22983  std::copy(details::logic_ops_list,
22985  std::insert_iterator<disabled_entity_set_t>
22986  (disabled_logic_set_, disabled_logic_set_.begin()));
22987  return (*this);
22988  }
22989 
22991  {
22992  std::copy(details::arithmetic_ops_list,
22994  std::insert_iterator<disabled_entity_set_t>
22995  (disabled_arithmetic_set_, disabled_arithmetic_set_.begin()));
22996  return (*this);
22997  }
22998 
23000  {
23001  std::copy(details::assignment_ops_list,
23003  std::insert_iterator<disabled_entity_set_t>
23004  (disabled_assignment_set_, disabled_assignment_set_.begin()));
23005  return (*this);
23006  }
23007 
23009  {
23010  std::copy(details::inequality_ops_list,
23012  std::insert_iterator<disabled_entity_set_t>
23013  (disabled_inequality_set_, disabled_inequality_set_.begin()));
23014  return (*this);
23015  }
23016 
23018  {
23019  disable_vardef_ = true;
23020  return (*this);
23021  }
23022 
23024  {
23025  enable_commutative_check_ = false;
23026  return (*this);
23027  }
23028 
23030  {
23031  enable_strength_reduction_ = false;
23032  return (*this);
23033  }
23034 
23035  bool replacer_enabled () const { return enable_replacer_; }
23036  bool commutative_check_enabled () const { return enable_commutative_check_; }
23037  bool joiner_enabled () const { return enable_joiner_; }
23038  bool numeric_check_enabled () const { return enable_numeric_check_; }
23039  bool bracket_check_enabled () const { return enable_bracket_check_; }
23040  bool sequence_check_enabled () const { return enable_sequence_check_; }
23041  bool strength_reduction_enabled () const { return enable_strength_reduction_; }
23042  bool collect_variables_enabled () const { return enable_collect_vars_; }
23043  bool collect_functions_enabled () const { return enable_collect_funcs_; }
23044  bool collect_assignments_enabled() const { return enable_collect_assings_; }
23045  bool vardef_disabled () const { return disable_vardef_; }
23046  bool rsrvd_sym_usr_disabled () const { return disable_rsrvd_sym_usr_; }
23047  bool zero_return_disabled () const { return disable_zero_return_; }
23048 
23049  bool function_enabled(const std::string& function_name) const
23050  {
23051  if (disabled_func_set_.empty())
23052  return true;
23053  else
23054  return (disabled_func_set_.end() == disabled_func_set_.find(function_name));
23055  }
23056 
23057  bool control_struct_enabled(const std::string& control_struct) const
23058  {
23059  if (disabled_ctrl_set_.empty())
23060  return true;
23061  else
23062  return (disabled_ctrl_set_.end() == disabled_ctrl_set_.find(control_struct));
23063  }
23064 
23065  bool logic_enabled(const std::string& logic_operation) const
23066  {
23067  if (disabled_logic_set_.empty())
23068  return true;
23069  else
23070  return (disabled_logic_set_.end() == disabled_logic_set_.find(logic_operation));
23071  }
23072 
23073  bool arithmetic_enabled(const details::operator_type& arithmetic_operation) const
23074  {
23075  if (disabled_logic_set_.empty())
23076  return true;
23077  else
23078  return disabled_arithmetic_set_.end() == disabled_arithmetic_set_
23079  .find(arith_opr_to_string(arithmetic_operation));
23080  }
23081 
23082  bool assignment_enabled(const details::operator_type& assignment) const
23083  {
23084  if (disabled_assignment_set_.empty())
23085  return true;
23086  else
23087  return disabled_assignment_set_.end() == disabled_assignment_set_
23088  .find(assign_opr_to_string(assignment));
23089  }
23090 
23091  bool inequality_enabled(const details::operator_type& inequality) const
23092  {
23093  if (disabled_inequality_set_.empty())
23094  return true;
23095  else
23096  return disabled_inequality_set_.end() == disabled_inequality_set_
23097  .find(inequality_opr_to_string(inequality));
23098  }
23099 
23100  bool function_disabled(const std::string& function_name) const
23101  {
23102  if (disabled_func_set_.empty())
23103  return false;
23104  else
23105  return (disabled_func_set_.end() != disabled_func_set_.find(function_name));
23106  }
23107 
23108  bool control_struct_disabled(const std::string& control_struct) const
23109  {
23110  if (disabled_ctrl_set_.empty())
23111  return false;
23112  else
23113  return (disabled_ctrl_set_.end() != disabled_ctrl_set_.find(control_struct));
23114  }
23115 
23116  bool logic_disabled(const std::string& logic_operation) const
23117  {
23118  if (disabled_logic_set_.empty())
23119  return false;
23120  else
23121  return (disabled_logic_set_.end() != disabled_logic_set_.find(logic_operation));
23122  }
23123 
23124  bool assignment_disabled(const details::operator_type assignment_operation) const
23125  {
23126  if (disabled_assignment_set_.empty())
23127  return false;
23128  else
23129  return disabled_assignment_set_.end() != disabled_assignment_set_
23130  .find(assign_opr_to_string(assignment_operation));
23131  }
23132 
23133  bool logic_disabled(const details::operator_type logic_operation) const
23134  {
23135  if (disabled_logic_set_.empty())
23136  return false;
23137  else
23138  return disabled_logic_set_.end() != disabled_logic_set_
23139  .find(logic_opr_to_string(logic_operation));
23140  }
23141 
23142  bool arithmetic_disabled(const details::operator_type arithmetic_operation) const
23143  {
23144  if (disabled_arithmetic_set_.empty())
23145  return false;
23146  else
23147  return disabled_arithmetic_set_.end() != disabled_arithmetic_set_
23148  .find(arith_opr_to_string(arithmetic_operation));
23149  }
23150 
23151  bool inequality_disabled(const details::operator_type& inequality) const
23152  {
23153  if (disabled_inequality_set_.empty())
23154  return false;
23155  else
23156  return disabled_inequality_set_.end() != disabled_inequality_set_
23157  .find(inequality_opr_to_string(inequality));
23158  }
23159 
23161  {
23162  if (
23163  (e_bf_unknown != bf) &&
23164  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1))
23165  )
23166  {
23167  disabled_func_set_.insert(details::base_function_list[bf - 1]);
23168  }
23169 
23170  return (*this);
23171  }
23172 
23174  {
23175  if (
23176  (e_ctrl_unknown != ctrl_struct) &&
23177  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1))
23178  )
23179  {
23180  disabled_ctrl_set_.insert(details::cntrl_struct_list[ctrl_struct - 1]);
23181  }
23182 
23183  return (*this);
23184  }
23185 
23187  {
23188  if (
23189  (e_logic_unknown != logic) &&
23190  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1))
23191  )
23192  {
23193  disabled_logic_set_.insert(details::logic_ops_list[logic - 1]);
23194  }
23195 
23196  return (*this);
23197  }
23198 
23200  {
23201  if (
23202  (e_arith_unknown != arithmetic) &&
23203  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1))
23204  )
23205  {
23206  disabled_arithmetic_set_.insert(details::arithmetic_ops_list[arithmetic - 1]);
23207  }
23208 
23209  return (*this);
23210  }
23211 
23213  {
23214  if (
23215  (e_assign_unknown != assignment) &&
23216  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1))
23217  )
23218  {
23219  disabled_assignment_set_.insert(details::assignment_ops_list[assignment - 1]);
23220  }
23221 
23222  return (*this);
23223  }
23224 
23226  {
23227  if (
23228  (e_ineq_unknown != inequality) &&
23229  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1))
23230  )
23231  {
23232  disabled_inequality_set_.insert(details::inequality_ops_list[inequality - 1]);
23233  }
23234 
23235  return (*this);
23236  }
23237 
23239  {
23240  if (
23241  (e_bf_unknown != bf) &&
23242  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1))
23243  )
23244  {
23245  const des_itr_t itr = disabled_func_set_.find(details::base_function_list[bf - 1]);
23246 
23247  if (disabled_func_set_.end() != itr)
23248  {
23249  disabled_func_set_.erase(itr);
23250  }
23251  }
23252 
23253  return (*this);
23254  }
23255 
23257  {
23258  if (
23259  (e_ctrl_unknown != ctrl_struct) &&
23260  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1))
23261  )
23262  {
23263  const des_itr_t itr = disabled_ctrl_set_.find(details::cntrl_struct_list[ctrl_struct - 1]);
23264 
23265  if (disabled_ctrl_set_.end() != itr)
23266  {
23267  disabled_ctrl_set_.erase(itr);
23268  }
23269  }
23270 
23271  return (*this);
23272  }
23273 
23275  {
23276  if (
23277  (e_logic_unknown != logic) &&
23278  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1))
23279  )
23280  {
23281  const des_itr_t itr = disabled_logic_set_.find(details::logic_ops_list[logic - 1]);
23282 
23283  if (disabled_logic_set_.end() != itr)
23284  {
23285  disabled_logic_set_.erase(itr);
23286  }
23287  }
23288 
23289  return (*this);
23290  }
23291 
23293  {
23294  if (
23295  (e_arith_unknown != arithmetic) &&
23296  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1))
23297  )
23298  {
23299  const des_itr_t itr = disabled_arithmetic_set_.find(details::arithmetic_ops_list[arithmetic - 1]);
23300 
23301  if (disabled_arithmetic_set_.end() != itr)
23302  {
23303  disabled_arithmetic_set_.erase(itr);
23304  }
23305  }
23306 
23307  return (*this);
23308  }
23309 
23311  {
23312  if (
23313  (e_assign_unknown != assignment) &&
23314  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1))
23315  )
23316  {
23317  const des_itr_t itr = disabled_assignment_set_.find(details::assignment_ops_list[assignment - 1]);
23318 
23319  if (disabled_assignment_set_.end() != itr)
23320  {
23321  disabled_assignment_set_.erase(itr);
23322  }
23323  }
23324 
23325  return (*this);
23326  }
23327 
23329  {
23330  if (
23331  (e_ineq_unknown != inequality) &&
23332  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1))
23333  )
23334  {
23335  const des_itr_t itr = disabled_inequality_set_.find(details::inequality_ops_list[inequality - 1]);
23336 
23337  if (disabled_inequality_set_.end() != itr)
23338  {
23339  disabled_inequality_set_.erase(itr);
23340  }
23341  }
23342 
23343  return (*this);
23344  }
23345 
23346  void set_max_stack_depth(const std::size_t max_stack_depth)
23347  {
23348  max_stack_depth_ = max_stack_depth;
23349  }
23350 
23351  void set_max_node_depth(const std::size_t max_node_depth)
23352  {
23353  max_node_depth_ = max_node_depth;
23354  }
23355 
23356  void set_max_local_vector_size(const std::size_t max_local_vector_size)
23357  {
23358  max_local_vector_size_ = max_local_vector_size;
23359  }
23360 
23361  std::size_t max_stack_depth() const
23362  {
23363  return max_stack_depth_;
23364  }
23365 
23366  std::size_t max_node_depth() const
23367  {
23368  return max_node_depth_;
23369  }
23370 
23371  std::size_t max_local_vector_size() const
23372  {
23373  return max_local_vector_size_;
23374  }
23375 
23376  private:
23377 
23378  void load_compile_options(const std::size_t compile_options)
23379  {
23380  enable_replacer_ = (compile_options & e_replacer ) == e_replacer;
23381  enable_joiner_ = (compile_options & e_joiner ) == e_joiner;
23382  enable_numeric_check_ = (compile_options & e_numeric_check ) == e_numeric_check;
23383  enable_bracket_check_ = (compile_options & e_bracket_check ) == e_bracket_check;
23384  enable_sequence_check_ = (compile_options & e_sequence_check ) == e_sequence_check;
23385  enable_commutative_check_ = (compile_options & e_commutative_check ) == e_commutative_check;
23386  enable_strength_reduction_ = (compile_options & e_strength_reduction ) == e_strength_reduction;
23387  enable_collect_vars_ = (compile_options & e_collect_vars ) == e_collect_vars;
23388  enable_collect_funcs_ = (compile_options & e_collect_funcs ) == e_collect_funcs;
23389  enable_collect_assings_ = (compile_options & e_collect_assings ) == e_collect_assings;
23390  disable_vardef_ = (compile_options & e_disable_vardef ) == e_disable_vardef;
23391  disable_rsrvd_sym_usr_ = (compile_options & e_disable_usr_on_rsrvd) == e_disable_usr_on_rsrvd;
23392  disable_zero_return_ = (compile_options & e_disable_zero_return ) == e_disable_zero_return;
23393  }
23394 
23396  {
23397  switch (opr)
23398  {
23399  case details::e_assign : return ":=";
23400  case details::e_addass : return "+=";
23401  case details::e_subass : return "-=";
23402  case details::e_mulass : return "*=";
23403  case details::e_divass : return "/=";
23404  case details::e_modass : return "%=";
23405  default : return "" ;
23406  }
23407  }
23408 
23410  {
23411  switch (opr)
23412  {
23413  case details::e_add : return "+";
23414  case details::e_sub : return "-";
23415  case details::e_mul : return "*";
23416  case details::e_div : return "/";
23417  case details::e_mod : return "%";
23418  case details::e_pow : return "^";
23419  default : return "" ;
23420  }
23421  }
23422 
23424  {
23425  switch (opr)
23426  {
23427  case details::e_lt : return "<" ;
23428  case details::e_lte : return "<=";
23429  case details::e_eq : return "==";
23430  case details::e_equal : return "=" ;
23431  case details::e_ne : return "!=";
23432  case details::e_nequal: return "<>";
23433  case details::e_gte : return ">=";
23434  case details::e_gt : return ">" ;
23435  default : return "" ;
23436  }
23437  }
23438 
23440  {
23441  switch (opr)
23442  {
23443  case details::e_and : return "and" ;
23444  case details::e_or : return "or" ;
23445  case details::e_xor : return "xor" ;
23446  case details::e_nand : return "nand";
23447  case details::e_nor : return "nor" ;
23448  case details::e_xnor : return "xnor";
23449  case details::e_notl : return "not" ;
23450  default : return "" ;
23451  }
23452  }
23453 
23467 
23474 
23475  std::size_t max_stack_depth_;
23476  std::size_t max_node_depth_;
23478 
23479  friend class parser<T>;
23480  };
23481 
23483 
23484  explicit parser(const settings_t& settings = settings_t())
23485  : settings_(settings)
23486  , resolve_unknown_symbol_(false)
23487  , results_context_(0)
23488  , unknown_symbol_resolver_(reinterpret_cast<unknown_symbol_resolver*>(0))
23489  #ifdef _MSC_VER
23490  #pragma warning(push)
23491  #pragma warning (disable:4355)
23492  #endif
23493  , sem_(*this)
23494  #ifdef _MSC_VER
23495  #pragma warning(pop)
23496  #endif
23497  , operator_joiner_2_(2)
23498  , operator_joiner_3_(3)
23499  , loop_runtime_check_(0)
23500  , vector_access_runtime_check_(0)
23501  , compilation_check_ptr_(0)
23502  {
23503  init_precompilation();
23504 
23505  load_operations_map (base_ops_map_ );
23506  load_unary_operations_map (unary_op_map_ );
23507  load_binary_operations_map (binary_op_map_ );
23508  load_inv_binary_operations_map(inv_binary_op_map_);
23509  load_sf3_map (sf3_map_ );
23510  load_sf4_map (sf4_map_ );
23511 
23512  expression_generator_.init_synthesize_map();
23513  expression_generator_.set_parser(*this);
23514  expression_generator_.set_uom (unary_op_map_ );
23515  expression_generator_.set_bom (binary_op_map_ );
23516  expression_generator_.set_ibom(inv_binary_op_map_);
23517  expression_generator_.set_sf3m(sf3_map_ );
23518  expression_generator_.set_sf4m(sf4_map_ );
23519  expression_generator_.set_strength_reduction_state(settings_.strength_reduction_enabled());
23520  }
23521 
23523  {}
23524 
23525  inline void init_precompilation()
23526  {
23527  dec_.collect_variables() =
23528  settings_.collect_variables_enabled();
23529 
23530  dec_.collect_functions() =
23531  settings_.collect_functions_enabled();
23532 
23533  dec_.collect_assignments() =
23534  settings_.collect_assignments_enabled();
23535 
23536  if (settings_.replacer_enabled())
23537  {
23538  symbol_replacer_.clear();
23539  symbol_replacer_.add_replace("true" , "1", lexer::token::e_number);
23540  symbol_replacer_.add_replace("false", "0", lexer::token::e_number);
23541  helper_assembly_.token_modifier_list.clear();
23542  helper_assembly_.register_modifier(&symbol_replacer_);
23543  }
23544 
23545  if (settings_.commutative_check_enabled())
23546  {
23547  for (std::size_t i = 0; i < details::reserved_words_size; ++i)
23548  {
23549  commutative_inserter_.ignore_symbol(details::reserved_words[i]);
23550  }
23551 
23552  helper_assembly_.token_inserter_list.clear();
23553  helper_assembly_.register_inserter(&commutative_inserter_);
23554  }
23555 
23556  if (settings_.joiner_enabled())
23557  {
23558  helper_assembly_.token_joiner_list.clear();
23559  helper_assembly_.register_joiner(&operator_joiner_2_);
23560  helper_assembly_.register_joiner(&operator_joiner_3_);
23561  }
23562 
23563  if (
23564  settings_.numeric_check_enabled () ||
23565  settings_.bracket_check_enabled () ||
23566  settings_.sequence_check_enabled()
23567  )
23568  {
23569  helper_assembly_.token_scanner_list.clear();
23570 
23571  if (settings_.numeric_check_enabled())
23572  {
23573  helper_assembly_.register_scanner(&numeric_checker_);
23574  }
23575 
23576  if (settings_.bracket_check_enabled())
23577  {
23578  helper_assembly_.register_scanner(&bracket_checker_);
23579  }
23580 
23581  if (settings_.sequence_check_enabled())
23582  {
23583  helper_assembly_.register_scanner(&sequence_validator_ );
23584  helper_assembly_.register_scanner(&sequence_validator_3tkns_);
23585  }
23586  }
23587  }
23588 
23589  inline bool compile(const std::string& expression_string, expression<T>& expr)
23590  {
23591  state_ .reset();
23592  error_list_ .clear();
23593  brkcnt_list_ .clear();
23594  synthesis_error_ .clear();
23595  immutable_memory_map_.reset();
23596  immutable_symtok_map_.clear();
23597  current_state_stack_ .clear();
23598  sem_ .cleanup();
23599 
23600  return_cleanup();
23601 
23602  expression_generator_.set_allocator(node_allocator_);
23603 
23604  if (expression_string.empty())
23605  {
23606  set_error(make_error(
23608  "ERR001 - Empty expression!",
23610 
23611  return false;
23612  }
23613 
23614  if (!init(expression_string))
23615  {
23616  process_lexer_errors();
23617  return false;
23618  }
23619 
23620  if (lexer().empty())
23621  {
23622  set_error(make_error(
23624  "ERR002 - Empty expression!",
23626 
23627  return false;
23628  }
23629 
23630  if (halt_compilation_check())
23631  {
23632  return false;
23633  }
23634 
23635  if (!run_assemblies())
23636  {
23637  return false;
23638  }
23639 
23640  if (halt_compilation_check())
23641  {
23642  return false;
23643  }
23644 
23645  symtab_store_.symtab_list_ = expr.get_symbol_table_list();
23646  dec_.clear();
23647 
23648  lexer().begin();
23649 
23650  next_token();
23651 
23652  expression_node_ptr e = parse_corpus();
23653 
23654  if ((0 != e) && (token_t::e_eof == current_token().type))
23655  {
23656  bool* retinvk_ptr = 0;
23657 
23658  if (state_.return_stmt_present)
23659  {
23660  dec_.return_present_ = true;
23661 
23662  e = expression_generator_
23663  .return_envelope(e, results_context_, retinvk_ptr);
23664  }
23665 
23666  expr.set_expression(e);
23667  expr.set_retinvk(retinvk_ptr);
23668 
23669  register_local_vars(expr);
23670  register_return_results(expr);
23671 
23672  return !(!expr);
23673  }
23674  else
23675  {
23676  if (error_list_.empty())
23677  {
23678  set_error(make_error(
23680  current_token(),
23681  "ERR003 - Invalid expression encountered",
23683  }
23684 
23685  if ((0 != e) && branch_deletable(e))
23686  {
23687  destroy_node(e);
23688  }
23689 
23690  dec_.clear ();
23691  sem_.cleanup ();
23692  return_cleanup();
23693 
23694  return false;
23695  }
23696  }
23697 
23698  inline expression_t compile(const std::string& expression_string, symbol_table_t& symtab)
23699  {
23702  compile(expression_string,expression);
23703  return expression;
23704  }
23705 
23707  {
23708  for (std::size_t i = 0; i < lexer().size(); ++i)
23709  {
23710  if (lexer()[i].is_error())
23711  {
23712  std::string diagnostic = "ERR004 - ";
23713 
23714  switch (lexer()[i].type)
23715  {
23716  case lexer::token::e_error : diagnostic += "General token error";
23717  break;
23718 
23719  case lexer::token::e_err_symbol : diagnostic += "Symbol error";
23720  break;
23721 
23722  case lexer::token::e_err_number : diagnostic += "Invalid numeric token";
23723  break;
23724 
23725  case lexer::token::e_err_string : diagnostic += "Invalid string token";
23726  break;
23727 
23728  case lexer::token::e_err_sfunc : diagnostic += "Invalid special function token";
23729  break;
23730 
23731  default : diagnostic += "Unknown compiler error";
23732  }
23733 
23734  set_error(make_error(
23736  lexer()[i],
23737  diagnostic + ": " + lexer()[i].value,
23739  }
23740  }
23741  }
23742 
23743  inline bool run_assemblies()
23744  {
23745  if (settings_.commutative_check_enabled())
23746  {
23747  helper_assembly_.run_inserters(lexer());
23748  }
23749 
23750  if (settings_.joiner_enabled())
23751  {
23752  helper_assembly_.run_joiners(lexer());
23753  }
23754 
23755  if (settings_.replacer_enabled())
23756  {
23757  helper_assembly_.run_modifiers(lexer());
23758  }
23759 
23760  if (
23761  settings_.numeric_check_enabled () ||
23762  settings_.bracket_check_enabled () ||
23763  settings_.sequence_check_enabled()
23764  )
23765  {
23766  if (!helper_assembly_.run_scanners(lexer()))
23767  {
23768  if (helper_assembly_.error_token_scanner)
23769  {
23770  lexer::helper::bracket_checker* bracket_checker_ptr = 0;
23771  lexer::helper::numeric_checker<T>* numeric_checker_ptr = 0;
23772  lexer::helper::sequence_validator* sequence_validator_ptr = 0;
23773  lexer::helper::sequence_validator_3tokens* sequence_validator3_ptr = 0;
23774 
23775  if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner)))
23776  {
23777  set_error(make_error(
23779  bracket_checker_ptr->error_token(),
23780  "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'",
23782  }
23783  else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker<T>*>(helper_assembly_.error_token_scanner)))
23784  {
23785  for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i)
23786  {
23787  lexer::token error_token = lexer()[numeric_checker_ptr->error_index(i)];
23788 
23789  set_error(make_error(
23791  error_token,
23792  "ERR006 - Invalid numeric token: '" + error_token.value + "'",
23794  }
23795 
23796  if (numeric_checker_ptr->error_count())
23797  {
23798  numeric_checker_ptr->clear_errors();
23799  }
23800  }
23801  else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner)))
23802  {
23803  for (std::size_t i = 0; i < sequence_validator_ptr->error_count(); ++i)
23804  {
23805  std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i);
23806 
23807  set_error(make_error(
23809  error_token.first,
23810  "ERR007 - Invalid token sequence: '" +
23811  error_token.first.value + "' and '" +
23812  error_token.second.value + "'",
23814  }
23815 
23816  if (sequence_validator_ptr->error_count())
23817  {
23818  sequence_validator_ptr->clear_errors();
23819  }
23820  }
23821  else if (0 != (sequence_validator3_ptr = dynamic_cast<lexer::helper::sequence_validator_3tokens*>(helper_assembly_.error_token_scanner)))
23822  {
23823  for (std::size_t i = 0; i < sequence_validator3_ptr->error_count(); ++i)
23824  {
23825  std::pair<lexer::token,lexer::token> error_token = sequence_validator3_ptr->error(i);
23826 
23827  set_error(make_error(
23829  error_token.first,
23830  "ERR008 - Invalid token sequence: '" +
23831  error_token.first.value + "' and '" +
23832  error_token.second.value + "'",
23834  }
23835 
23836  if (sequence_validator3_ptr->error_count())
23837  {
23838  sequence_validator3_ptr->clear_errors();
23839  }
23840  }
23841  }
23842 
23843  return false;
23844  }
23845  }
23846 
23847  return true;
23848  }
23849 
23851  {
23852  return settings_;
23853  }
23854 
23855  inline parser_error::type get_error(const std::size_t& index) const
23856  {
23857  if (index < error_list_.size())
23858  return error_list_[index];
23859  else
23860  throw std::invalid_argument("parser::get_error() - Invalid error index specified");
23861  }
23862 
23863  inline std::string error() const
23864  {
23865  if (!error_list_.empty())
23866  {
23867  return error_list_[0].diagnostic;
23868  }
23869  else
23870  return std::string("No Error");
23871  }
23872 
23873  inline std::size_t error_count() const
23874  {
23875  return error_list_.size();
23876  }
23877 
23879  {
23880  return dec_;
23881  }
23882 
23883  inline bool replace_symbol(const std::string& old_symbol, const std::string& new_symbol)
23884  {
23885  if (!settings_.replacer_enabled())
23886  return false;
23887  else if (details::is_reserved_word(old_symbol))
23888  return false;
23889  else
23890  return symbol_replacer_.add_replace(old_symbol,new_symbol,lexer::token::e_symbol);
23891  }
23892 
23893  inline bool remove_replace_symbol(const std::string& symbol)
23894  {
23895  if (!settings_.replacer_enabled())
23896  return false;
23897  else if (details::is_reserved_word(symbol))
23898  return false;
23899  else
23900  return symbol_replacer_.remove(symbol);
23901  }
23902 
23904  {
23905  resolve_unknown_symbol_ = true;
23906 
23907  if (usr)
23908  unknown_symbol_resolver_ = usr;
23909  else
23910  unknown_symbol_resolver_ = &default_usr_;
23911  }
23912 
23914  {
23915  enable_unknown_symbol_resolver(&usr);
23916  }
23917 
23919  {
23920  resolve_unknown_symbol_ = false;
23921  unknown_symbol_resolver_ = &default_usr_;
23922  }
23923 
23925  {
23926  loop_runtime_check_ = &lrtchk;
23927  }
23928 
23930  {
23931  vector_access_runtime_check_ = &vartchk;
23932  }
23933 
23935  {
23936  compilation_check_ptr_ = &compchk;
23937  }
23938 
23940  {
23941  loop_runtime_check_ = loop_runtime_check_ptr(0);
23942  }
23943 
23945  {
23946  vector_access_runtime_check_ = vector_access_runtime_check_ptr(0);
23947  }
23948 
23950  {
23951  compilation_check_ptr_ = compilation_check_ptr(0);
23952  }
23953 
23954  private:
23955 
23956  inline bool valid_base_operation(const std::string& symbol) const
23957  {
23958  const std::size_t length = symbol.size();
23959 
23960  if (
23961  (length < 3) || // Shortest base op symbol length
23962  (length > 9) // Longest base op symbol length
23963  )
23964  return false;
23965  else
23966  return settings_.function_enabled(symbol) &&
23967  (base_ops_map_.end() != base_ops_map_.find(symbol));
23968  }
23969 
23970  inline bool valid_vararg_operation(const std::string& symbol) const
23971  {
23972  static const std::string s_sum = "sum" ;
23973  static const std::string s_mul = "mul" ;
23974  static const std::string s_avg = "avg" ;
23975  static const std::string s_min = "min" ;
23976  static const std::string s_max = "max" ;
23977  static const std::string s_mand = "mand";
23978  static const std::string s_mor = "mor" ;
23979  static const std::string s_multi = "~" ;
23980  static const std::string s_mswitch = "[*]" ;
23981 
23982  return
23983  (
23984  details::imatch(symbol,s_sum ) ||
23985  details::imatch(symbol,s_mul ) ||
23986  details::imatch(symbol,s_avg ) ||
23987  details::imatch(symbol,s_min ) ||
23988  details::imatch(symbol,s_max ) ||
23989  details::imatch(symbol,s_mand ) ||
23990  details::imatch(symbol,s_mor ) ||
23991  details::imatch(symbol,s_multi ) ||
23992  details::imatch(symbol,s_mswitch)
23993  ) &&
23994  settings_.function_enabled(symbol);
23995  }
23996 
23998  {
23999  return settings_.logic_disabled(operation);
24000  }
24001 
24003  {
24004  return settings_.arithmetic_disabled(operation);
24005  }
24006 
24008  {
24009  return settings_.assignment_disabled(operation);
24010  }
24011 
24013  {
24014  return settings_.inequality_disabled(operation);
24015  }
24016 
24017  #ifdef exprtk_enable_debugging
24018  inline void next_token()
24019  {
24020  const std::string ct_str = current_token().value;
24021  const std::size_t ct_pos = current_token().position;
24022  parser_helper::next_token();
24023  const std::string depth(2 * state_.scope_depth,' ');
24024  exprtk_debug(("%s"
24025  "prev[%s | %04d] --> curr[%s | %04d] stack_level: %3d\n",
24026  depth.c_str(),
24027  ct_str.c_str(),
24028  static_cast<unsigned int>(ct_pos),
24029  current_token().value.c_str(),
24030  static_cast<unsigned int>(current_token().position),
24031  static_cast<unsigned int>(state_.stack_depth)));
24032  }
24033  #endif
24034 
24036  {
24037  std::vector<expression_node_ptr> arg_list;
24038  std::vector<bool> side_effect_list;
24039 
24040  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
24041 
24042  lexer::token begin_token;
24043  lexer::token end_token;
24044 
24045  for ( ; ; )
24046  {
24047  state_.side_effect_present = false;
24048 
24049  begin_token = current_token();
24050 
24051  expression_node_ptr arg = parse_expression();
24052 
24053  if (0 == arg)
24054  {
24055  if (error_list_.empty())
24056  {
24057  set_error(make_error(
24059  current_token(),
24060  "ERR009 - Invalid expression encountered",
24062  }
24063 
24064  return error_node();
24065  }
24066  else
24067  {
24068  arg_list.push_back(arg);
24069 
24070  side_effect_list.push_back(state_.side_effect_present);
24071 
24072  end_token = current_token();
24073 
24074  const std::string sub_expr = construct_subexpr(begin_token, end_token);
24075 
24076  exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n",
24077  static_cast<int>(arg_list.size() - 1),
24078  sub_expr.c_str()));
24079 
24080  exprtk_debug(("parse_corpus(%02d) - Side effect present: %s\n",
24081  static_cast<int>(arg_list.size() - 1),
24082  state_.side_effect_present ? "true" : "false"));
24083 
24084  exprtk_debug(("-------------------------------------------------\n"));
24085  }
24086 
24087  if (token_is(token_t::e_eof,prsrhlpr_t::e_hold))
24088  {
24089  if (lexer().finished())
24090  break;
24091  else
24092  next_token();
24093  }
24094  }
24095 
24096  if (
24097  !arg_list.empty() &&
24098  is_return_node(arg_list.back())
24099  )
24100  {
24101  dec_.final_stmt_return_ = true;
24102  }
24103 
24104  const expression_node_ptr result = simplify(arg_list,side_effect_list);
24105 
24106  sdd.delete_ptr = (0 == result);
24107 
24108  return result;
24109  }
24110 
24111  std::string construct_subexpr(lexer::token& begin_token, lexer::token& end_token)
24112  {
24113  std::string result = lexer().substr(begin_token.position,end_token.position);
24114 
24115  for (std::size_t i = 0; i < result.size(); ++i)
24116  {
24117  if (details::is_whitespace(result[i])) result[i] = ' ';
24118  }
24119 
24120  return result;
24121  }
24122 
24123  static const precedence_level default_precedence = e_level00;
24124 
24125  struct state_t
24126  {
24127  inline void set(const precedence_level& l,
24128  const precedence_level& r,
24129  const details::operator_type& o,
24130  const token_t tkn = token_t())
24131  {
24132  left = l;
24133  right = r;
24134  operation = o;
24135  token = tkn;
24136  }
24137 
24138  inline void reset()
24139  {
24140  left = e_level00;
24141  right = e_level00;
24142  operation = details::e_default;
24143  }
24144 
24149  };
24150 
24151  inline void push_current_state(const state_t current_state)
24152  {
24153  current_state_stack_.push_back(current_state);
24154  }
24155 
24156  inline void pop_current_state()
24157  {
24158  if (!current_state_stack_.empty())
24159  {
24160  current_state_stack_.pop_back();
24161  }
24162  }
24163 
24164  inline state_t current_state() const
24165  {
24166  return (!current_state_stack_.empty()) ?
24167  current_state_stack_.back() :
24168  state_t();
24169  }
24170 
24172  {
24174 
24175  if (compilation_check_ptr_ && !compilation_check_ptr_->continue_compilation(context))
24176  {
24177  const std::string error_message =
24178  !context.error_message.empty() ? " Details: " + context.error_message : "";
24179 
24180  set_error(make_error(
24182  token_t(),
24183  "ERR010 - Internal compilation check failed." + error_message,
24185 
24186  return true;
24187  }
24188 
24189  return false;
24190  }
24191 
24193  {
24194  if (halt_compilation_check())
24195  {
24196  return error_node();
24197  }
24198 
24199  stack_limit_handler slh(*this);
24200 
24201  if (!slh)
24202  {
24203  return error_node();
24204  }
24205 
24206  expression_node_ptr expression = parse_branch(precedence);
24207 
24208  if (0 == expression)
24209  {
24210  return error_node();
24211  }
24212 
24213  bool break_loop = false;
24214 
24215  state_t current_state;
24216 
24217  for ( ; ; )
24218  {
24219  current_state.reset();
24220 
24221  switch (current_token().type)
24222  {
24223  case token_t::e_assign : current_state.set(e_level00, e_level00, details::e_assign, current_token()); break;
24224  case token_t::e_addass : current_state.set(e_level00, e_level00, details::e_addass, current_token()); break;
24225  case token_t::e_subass : current_state.set(e_level00, e_level00, details::e_subass, current_token()); break;
24226  case token_t::e_mulass : current_state.set(e_level00, e_level00, details::e_mulass, current_token()); break;
24227  case token_t::e_divass : current_state.set(e_level00, e_level00, details::e_divass, current_token()); break;
24228  case token_t::e_modass : current_state.set(e_level00, e_level00, details::e_modass, current_token()); break;
24229  case token_t::e_swap : current_state.set(e_level00, e_level00, details::e_swap , current_token()); break;
24230  case token_t::e_lt : current_state.set(e_level05, e_level06, details::e_lt , current_token()); break;
24231  case token_t::e_lte : current_state.set(e_level05, e_level06, details::e_lte , current_token()); break;
24232  case token_t::e_eq : current_state.set(e_level05, e_level06, details::e_eq , current_token()); break;
24233  case token_t::e_ne : current_state.set(e_level05, e_level06, details::e_ne , current_token()); break;
24234  case token_t::e_gte : current_state.set(e_level05, e_level06, details::e_gte , current_token()); break;
24235  case token_t::e_gt : current_state.set(e_level05, e_level06, details::e_gt , current_token()); break;
24236  case token_t::e_add : current_state.set(e_level07, e_level08, details::e_add , current_token()); break;
24237  case token_t::e_sub : current_state.set(e_level07, e_level08, details::e_sub , current_token()); break;
24238  case token_t::e_div : current_state.set(e_level10, e_level11, details::e_div , current_token()); break;
24239  case token_t::e_mul : current_state.set(e_level10, e_level11, details::e_mul , current_token()); break;
24240  case token_t::e_mod : current_state.set(e_level10, e_level11, details::e_mod , current_token()); break;
24241  case token_t::e_pow : current_state.set(e_level12, e_level12, details::e_pow , current_token()); break;
24242  default :
24243  if (token_t::e_symbol == current_token().type)
24244  {
24245  static const std::string s_and = "and" ;
24246  static const std::string s_nand = "nand" ;
24247  static const std::string s_or = "or" ;
24248  static const std::string s_nor = "nor" ;
24249  static const std::string s_xor = "xor" ;
24250  static const std::string s_xnor = "xnor" ;
24251  static const std::string s_in = "in" ;
24252  static const std::string s_like = "like" ;
24253  static const std::string s_ilike = "ilike";
24254  static const std::string s_and1 = "&" ;
24255  static const std::string s_or1 = "|" ;
24256  static const std::string s_not = "not" ;
24257 
24258  if (details::imatch(current_token().value,s_and))
24259  {
24260  current_state.set(e_level03, e_level04, details::e_and, current_token());
24261  break;
24262  }
24263  else if (details::imatch(current_token().value,s_and1))
24264  {
24265  #ifndef exprtk_disable_sc_andor
24266  current_state.set(e_level03, e_level04, details::e_scand, current_token());
24267  #else
24268  current_state.set(e_level03, e_level04, details::e_and, current_token());
24269  #endif
24270  break;
24271  }
24272  else if (details::imatch(current_token().value,s_nand))
24273  {
24274  current_state.set(e_level03, e_level04, details::e_nand, current_token());
24275  break;
24276  }
24277  else if (details::imatch(current_token().value,s_or))
24278  {
24279  current_state.set(e_level01, e_level02, details::e_or, current_token());
24280  break;
24281  }
24282  else if (details::imatch(current_token().value,s_or1))
24283  {
24284  #ifndef exprtk_disable_sc_andor
24285  current_state.set(e_level01, e_level02, details::e_scor, current_token());
24286  #else
24287  current_state.set(e_level01, e_level02, details::e_or, current_token());
24288  #endif
24289  break;
24290  }
24291  else if (details::imatch(current_token().value,s_nor))
24292  {
24293  current_state.set(e_level01, e_level02, details::e_nor, current_token());
24294  break;
24295  }
24296  else if (details::imatch(current_token().value,s_xor))
24297  {
24298  current_state.set(e_level01, e_level02, details::e_xor, current_token());
24299  break;
24300  }
24301  else if (details::imatch(current_token().value,s_xnor))
24302  {
24303  current_state.set(e_level01, e_level02, details::e_xnor, current_token());
24304  break;
24305  }
24306  else if (details::imatch(current_token().value,s_in))
24307  {
24308  current_state.set(e_level04, e_level04, details::e_in, current_token());
24309  break;
24310  }
24311  else if (details::imatch(current_token().value,s_like))
24312  {
24313  current_state.set(e_level04, e_level04, details::e_like, current_token());
24314  break;
24315  }
24316  else if (details::imatch(current_token().value,s_ilike))
24317  {
24318  current_state.set(e_level04, e_level04, details::e_ilike, current_token());
24319  break;
24320  }
24321  else if (details::imatch(current_token().value,s_not))
24322  {
24323  break;
24324  }
24325  }
24326 
24327  break_loop = true;
24328  }
24329 
24330  if (break_loop)
24331  {
24332  parse_pending_string_rangesize(expression);
24333  break;
24334  }
24335  else if (current_state.left < precedence)
24336  break;
24337 
24338  const lexer::token prev_token = current_token();
24339 
24340  next_token();
24341 
24342  expression_node_ptr right_branch = error_node();
24343  expression_node_ptr new_expression = error_node();
24344 
24345  if (is_invalid_logic_operation(current_state.operation))
24346  {
24347  free_node(node_allocator_,expression);
24348 
24349  set_error(make_error(
24351  prev_token,
24352  "ERR011 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'",
24354 
24355  return error_node();
24356  }
24357  else if (is_invalid_arithmetic_operation(current_state.operation))
24358  {
24359  free_node(node_allocator_,expression);
24360 
24361  set_error(make_error(
24363  prev_token,
24364  "ERR012 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'",
24366 
24367  return error_node();
24368  }
24369  else if (is_invalid_inequality_operation(current_state.operation))
24370  {
24371  free_node(node_allocator_,expression);
24372 
24373  set_error(make_error(
24375  prev_token,
24376  "ERR013 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
24378 
24379  return error_node();
24380  }
24381  else if (is_invalid_assignment_operation(current_state.operation))
24382  {
24383  free_node(node_allocator_,expression);
24384 
24385  set_error(make_error(
24387  prev_token,
24388  "ERR014 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'",
24390 
24391  return error_node();
24392  }
24393 
24394  if (0 != (right_branch = parse_expression(current_state.right)))
24395  {
24396  if (
24398  details::is_return_node(right_branch)
24399  )
24400  {
24401  free_node(node_allocator_, expression );
24402  free_node(node_allocator_, right_branch);
24403 
24404  set_error(make_error(
24406  prev_token,
24407  "ERR015 - Return statements cannot be part of sub-expressions",
24409 
24410  return error_node();
24411  }
24412 
24413  push_current_state(current_state);
24414 
24415  new_expression = expression_generator_
24416  (
24417  current_state.operation,
24418  expression,
24419  right_branch
24420  );
24421 
24422  pop_current_state();
24423  }
24424 
24425  if (0 == new_expression)
24426  {
24427  if (error_list_.empty())
24428  {
24429  set_error(make_error(
24431  prev_token,
24432  !synthesis_error_.empty() ?
24433  synthesis_error_ :
24434  "ERR016 - General parsing error at token: '" + prev_token.value + "'",
24436  }
24437 
24438  free_node(node_allocator_, expression );
24439  free_node(node_allocator_, right_branch);
24440 
24441  return error_node();
24442  }
24443  else
24444  {
24445  if (
24446  token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
24447  (e_level00 == precedence)
24448  )
24449  {
24450  expression = parse_ternary_conditional_statement(new_expression);
24451  }
24452  else
24453  expression = new_expression;
24454 
24455  parse_pending_string_rangesize(expression);
24456  }
24457  }
24458 
24459  if ((0 != expression) && (expression->node_depth() > settings_.max_node_depth_))
24460  {
24461  set_error(make_error(
24463  current_token(),
24464  "ERR017 - Expression depth of " + details::to_str(static_cast<int>(expression->node_depth())) +
24465  " exceeds maximum allowed expression depth of " + details::to_str(static_cast<int>(settings_.max_node_depth_)),
24467 
24468  free_node(node_allocator_,expression);
24469 
24470  return error_node();
24471  }
24472 
24473  return expression;
24474  }
24475 
24477  {
24478  {
24479  typedef details::unary_branch_node<T,details::neg_op<T> > ubn_t;
24480  ubn_t* n = dynamic_cast<ubn_t*>(node);
24481 
24482  if (n)
24483  {
24484  expression_node_ptr un_r = n->branch(0);
24485  n->release();
24486  free_node(node_allocator_,node);
24487  node = un_r;
24488 
24489  return true;
24490  }
24491  }
24492 
24493  {
24494  typedef details::unary_variable_node<T,details::neg_op<T> > uvn_t;
24495 
24496  uvn_t* n = dynamic_cast<uvn_t*>(node);
24497 
24498  if (n)
24499  {
24500  const T& v = n->v();
24501  expression_node_ptr return_node = error_node();
24502 
24503  if (
24504  (0 != (return_node = symtab_store_.get_variable(v))) ||
24505  (0 != (return_node = sem_ .get_variable(v)))
24506  )
24507  {
24508  free_node(node_allocator_,node);
24509  node = return_node;
24510 
24511  return true;
24512  }
24513  else
24514  {
24515  set_error(make_error(
24517  current_token(),
24518  "ERR018 - Failed to find variable node in symbol table",
24520 
24521  free_node(node_allocator_,node);
24522 
24523  return false;
24524  }
24525  }
24526  }
24527 
24528  return false;
24529  }
24530 
24532  {
24533  return reinterpret_cast<expression_node_ptr>(0);
24534  }
24535 
24537  {
24539  : delete_ptr(true)
24540  , parser_(pr)
24541  , expression_(expression)
24542  {}
24543 
24545  {
24546  if (delete_ptr)
24547  {
24548  free_node(parser_.node_allocator_, expression_);
24549  }
24550  }
24551 
24555 
24556  private:
24557 
24560  };
24561 
24562  template <typename Type, std::size_t N>
24564  {
24565  typedef Type* ptr_t;
24566 
24568  : delete_ptr(true)
24569  , parser_(pr)
24570  , p_(&p)
24571  {}
24572 
24574  : delete_ptr(true)
24575  , parser_(pr)
24576  , p_(&p[0])
24577  {}
24578 
24580  {
24581  if (delete_ptr)
24582  {
24583  for (std::size_t i = 0; i < N; ++i)
24584  {
24585  free_node(parser_.node_allocator_, p_[i]);
24586  }
24587  }
24588  }
24589 
24593 
24594  private:
24595 
24598  };
24599 
24600  template <typename Type>
24602  {
24603  typedef Type* ptr_t;
24604 
24605  scoped_deq_delete(parser<T>& pr, std::deque<ptr_t>& deq)
24606  : delete_ptr(true)
24607  , parser_(pr)
24608  , deq_(deq)
24609  {}
24610 
24612  {
24613  if (delete_ptr && !deq_.empty())
24614  {
24615  for (std::size_t i = 0; i < deq_.size(); ++i)
24616  {
24617  free_node(parser_.node_allocator_,deq_[i]);
24618  }
24619 
24620  deq_.clear();
24621  }
24622  }
24623 
24626  std::deque<ptr_t>& deq_;
24627 
24628  private:
24629 
24632  };
24633 
24634  template <typename Type>
24636  {
24637  typedef Type* ptr_t;
24638 
24639  scoped_vec_delete(parser<T>& pr, std::vector<ptr_t>& vec)
24640  : delete_ptr(true)
24641  , parser_(pr)
24642  , vec_(vec)
24643  {}
24644 
24646  {
24647  if (delete_ptr && !vec_.empty())
24648  {
24649  for (std::size_t i = 0; i < vec_.size(); ++i)
24650  {
24651  free_node(parser_.node_allocator_,vec_[i]);
24652  }
24653 
24654  vec_.clear();
24655  }
24656  }
24657 
24660  std::vector<ptr_t>& vec_;
24661 
24662  private:
24663 
24666  };
24667 
24669  {
24670  explicit scoped_bool_negator(bool& bb)
24671  : b(bb)
24672  { b = !b; }
24673 
24675  { b = !b; }
24676 
24677  bool& b;
24678  };
24679 
24681  {
24682  explicit scoped_bool_or_restorer(bool& bb)
24683  : b(bb)
24684  , original_value_(bb)
24685  {}
24686 
24688  {
24689  b = b || original_value_;
24690  }
24691 
24692  bool& b;
24694  };
24695 
24697  {
24698  explicit scoped_inc_dec(std::size_t& v)
24699  : v_(v)
24700  { ++v_; }
24701 
24703  {
24704  assert(v_ > 0);
24705  --v_;
24706  }
24707 
24708  std::size_t& v_;
24709  };
24710 
24711  inline expression_node_ptr parse_function_invocation(ifunction<T>* function, const std::string& function_name)
24712  {
24713  expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0);
24714 
24715  switch (function->param_count)
24716  {
24717  case 0 : func_node = parse_function_call_0 (function,function_name); break;
24718  case 1 : func_node = parse_function_call< 1>(function,function_name); break;
24719  case 2 : func_node = parse_function_call< 2>(function,function_name); break;
24720  case 3 : func_node = parse_function_call< 3>(function,function_name); break;
24721  case 4 : func_node = parse_function_call< 4>(function,function_name); break;
24722  case 5 : func_node = parse_function_call< 5>(function,function_name); break;
24723  case 6 : func_node = parse_function_call< 6>(function,function_name); break;
24724  case 7 : func_node = parse_function_call< 7>(function,function_name); break;
24725  case 8 : func_node = parse_function_call< 8>(function,function_name); break;
24726  case 9 : func_node = parse_function_call< 9>(function,function_name); break;
24727  case 10 : func_node = parse_function_call<10>(function,function_name); break;
24728  case 11 : func_node = parse_function_call<11>(function,function_name); break;
24729  case 12 : func_node = parse_function_call<12>(function,function_name); break;
24730  case 13 : func_node = parse_function_call<13>(function,function_name); break;
24731  case 14 : func_node = parse_function_call<14>(function,function_name); break;
24732  case 15 : func_node = parse_function_call<15>(function,function_name); break;
24733  case 16 : func_node = parse_function_call<16>(function,function_name); break;
24734  case 17 : func_node = parse_function_call<17>(function,function_name); break;
24735  case 18 : func_node = parse_function_call<18>(function,function_name); break;
24736  case 19 : func_node = parse_function_call<19>(function,function_name); break;
24737  case 20 : func_node = parse_function_call<20>(function,function_name); break;
24738  default : {
24739  set_error(make_error(
24741  current_token(),
24742  "ERR019 - Invalid number of parameters for function: '" + function_name + "'",
24744 
24745  return error_node();
24746  }
24747  }
24748 
24749  if (func_node)
24750  return func_node;
24751  else
24752  {
24753  set_error(make_error(
24755  current_token(),
24756  "ERR020 - Failed to generate call to function: '" + function_name + "'",
24758 
24759  return error_node();
24760  }
24761  }
24762 
24763  template <std::size_t NumberofParameters>
24764  inline expression_node_ptr parse_function_call(ifunction<T>* function, const std::string& function_name)
24765  {
24766  #ifdef _MSC_VER
24767  #pragma warning(push)
24768  #pragma warning(disable: 4127)
24769  #endif
24770  if (0 == NumberofParameters)
24771  {
24772  set_error(make_error(
24774  current_token(),
24775  "ERR021 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
24777 
24778  return error_node();
24779  }
24780  #ifdef _MSC_VER
24781  #pragma warning(pop)
24782  #endif
24783 
24784  expression_node_ptr branch[NumberofParameters];
24785  expression_node_ptr result = error_node();
24786 
24787  std::fill_n(branch, NumberofParameters, reinterpret_cast<expression_node_ptr>(0));
24788 
24790 
24791  next_token();
24792 
24793  if (!token_is(token_t::e_lbracket))
24794  {
24795  set_error(make_error(
24797  current_token(),
24798  "ERR022 - Expecting argument list for function: '" + function_name + "'",
24800 
24801  return error_node();
24802  }
24803 
24804  for (int i = 0; i < static_cast<int>(NumberofParameters); ++i)
24805  {
24806  branch[i] = parse_expression();
24807 
24808  if (0 == branch[i])
24809  {
24810  set_error(make_error(
24812  current_token(),
24813  "ERR023 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
24815 
24816  return error_node();
24817  }
24818  else if (i < static_cast<int>(NumberofParameters - 1))
24819  {
24820  if (!token_is(token_t::e_comma))
24821  {
24822  set_error(make_error(
24824  current_token(),
24825  "ERR024 - Invalid number of arguments for function: '" + function_name + "'",
24827 
24828  return error_node();
24829  }
24830  }
24831  }
24832 
24833  if (!token_is(token_t::e_rbracket))
24834  {
24835  set_error(make_error(
24837  current_token(),
24838  "ERR025 - Invalid number of arguments for function: '" + function_name + "'",
24840 
24841  return error_node();
24842  }
24843  else
24844  result = expression_generator_.function(function,branch);
24845 
24846  sd.delete_ptr = (0 == result);
24847 
24848  return result;
24849  }
24850 
24851  inline expression_node_ptr parse_function_call_0(ifunction<T>* function, const std::string& function_name)
24852  {
24853  expression_node_ptr result = expression_generator_.function(function);
24854 
24855  state_.side_effect_present = function->has_side_effects();
24856 
24857  next_token();
24858 
24859  if (
24860  token_is(token_t::e_lbracket) &&
24861  !token_is(token_t::e_rbracket)
24862  )
24863  {
24864  set_error(make_error(
24866  current_token(),
24867  "ERR026 - Expecting '()' to proceed call to function: '" + function_name + "'",
24869 
24870  free_node(node_allocator_,result);
24871 
24872  return error_node();
24873  }
24874  else
24875  return result;
24876  }
24877 
24878  template <std::size_t MaxNumberofParameters>
24879  inline std::size_t parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters], const std::string& function_name = "")
24880  {
24881  std::fill_n(param_list, MaxNumberofParameters, reinterpret_cast<expression_node_ptr>(0));
24882 
24884 
24885  next_token();
24886 
24887  if (!token_is(token_t::e_lbracket))
24888  {
24889  set_error(make_error(
24891  current_token(),
24892  "ERR027 - Expected a '(' at start of function call to '" + function_name +
24893  "', instead got: '" + current_token().value + "'",
24895 
24896  return 0;
24897  }
24898 
24899  if (token_is(token_t::e_rbracket, e_hold))
24900  {
24901  set_error(make_error(
24903  current_token(),
24904  "ERR028 - Expected at least one input parameter for function call '" + function_name + "'",
24906 
24907  return 0;
24908  }
24909 
24910  std::size_t param_index = 0;
24911 
24912  for (; param_index < MaxNumberofParameters; ++param_index)
24913  {
24914  param_list[param_index] = parse_expression();
24915 
24916  if (0 == param_list[param_index])
24917  return 0;
24918  else if (token_is(token_t::e_rbracket))
24919  {
24920  sd.delete_ptr = false;
24921  break;
24922  }
24923  else if (token_is(token_t::e_comma))
24924  continue;
24925  else
24926  {
24927  set_error(make_error(
24929  current_token(),
24930  "ERR029 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
24932 
24933  return 0;
24934  }
24935  }
24936 
24937  if (sd.delete_ptr)
24938  {
24939  set_error(make_error(
24941  current_token(),
24942  "ERR030 - Invalid number of input parameters passed to function '" + function_name + "'",
24944 
24945  return 0;
24946  }
24947 
24948  return (param_index + 1);
24949  }
24950 
24952  {
24953  typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t;
24954 
24955  const std::string operation_name = current_token().value;
24956  const token_t diagnostic_token = current_token();
24957 
24958  map_range_t itr_range = base_ops_map_.equal_range(operation_name);
24959 
24960  if (0 == std::distance(itr_range.first,itr_range.second))
24961  {
24962  set_error(make_error(
24964  diagnostic_token,
24965  "ERR031 - No entry found for base operation: " + operation_name,
24967 
24968  return error_node();
24969  }
24970 
24971  static const std::size_t MaxNumberofParameters = 4;
24972  expression_node_ptr param_list[MaxNumberofParameters] = {0};
24973 
24974  const std::size_t parameter_count = parse_base_function_call(param_list, operation_name);
24975 
24976  if ((parameter_count > 0) && (parameter_count <= MaxNumberofParameters))
24977  {
24978  for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr)
24979  {
24980  const details::base_operation_t& operation = itr->second;
24981 
24982  if (operation.num_params == parameter_count)
24983  {
24984  switch (parameter_count)
24985  {
24986  #define base_opr_case(N) \
24987  case N : { \
24988  expression_node_ptr pl##N[N] = {0}; \
24989  std::copy(param_list, param_list + N, pl##N); \
24990  lodge_symbol(operation_name, e_st_function); \
24991  return expression_generator_(operation.type, pl##N); \
24992  } \
24993 
24994  base_opr_case(1)
24995  base_opr_case(2)
24996  base_opr_case(3)
24997  base_opr_case(4)
24998  #undef base_opr_case
24999  }
25000  }
25001  }
25002  }
25003 
25004  for (std::size_t i = 0; i < MaxNumberofParameters; ++i)
25005  {
25006  free_node(node_allocator_, param_list[i]);
25007  }
25008 
25009  set_error(make_error(
25011  diagnostic_token,
25012  "ERR032 - Invalid number of input parameters for call to function: '" + operation_name + "'",
25014 
25015  return error_node();
25016  }
25017 
25019  {
25020  // Parse: [if][(][condition][,][consequent][,][alternative][)]
25021 
25022  expression_node_ptr consequent = error_node();
25023  expression_node_ptr alternative = error_node();
25024 
25025  bool result = true;
25026 
25027  if (!token_is(token_t::e_comma))
25028  {
25029  set_error(make_error(
25031  current_token(),
25032  "ERR033 - Expected ',' between if-statement condition and consequent",
25034 
25035  result = false;
25036  }
25037  else if (0 == (consequent = parse_expression()))
25038  {
25039  set_error(make_error(
25041  current_token(),
25042  "ERR034 - Failed to parse consequent for if-statement",
25044 
25045  result = false;
25046  }
25047  else if (!token_is(token_t::e_comma))
25048  {
25049  set_error(make_error(
25051  current_token(),
25052  "ERR035 - Expected ',' between if-statement consequent and alternative",
25054 
25055  result = false;
25056  }
25057  else if (0 == (alternative = parse_expression()))
25058  {
25059  set_error(make_error(
25061  current_token(),
25062  "ERR036 - Failed to parse alternative for if-statement",
25064 
25065  result = false;
25066  }
25067  else if (!token_is(token_t::e_rbracket))
25068  {
25069  set_error(make_error(
25071  current_token(),
25072  "ERR037 - Expected ')' at the end of if-statement",
25074 
25075  result = false;
25076  }
25077 
25078  #ifndef exprtk_disable_string_capabilities
25079  if (result)
25080  {
25081  const bool consq_is_str = is_generally_string_node(consequent );
25082  const bool alter_is_str = is_generally_string_node(alternative);
25083 
25084  if (consq_is_str || alter_is_str)
25085  {
25086  if (consq_is_str && alter_is_str)
25087  {
25088  expression_node_ptr result_node =
25089  expression_generator_
25090  .conditional_string(condition, consequent, alternative);
25091 
25092  if (result_node && result_node->valid())
25093  {
25094  return result_node;
25095  }
25096 
25097  set_error(make_error(
25099  current_token(),
25100  "ERR038 - Failed to synthesize node: conditional_string",
25102 
25103  free_node(node_allocator_, result_node);
25104  return error_node();
25105  }
25106 
25107  set_error(make_error(
25109  current_token(),
25110  "ERR039 - Return types of if-statement differ: string/non-string",
25112 
25113  result = false;
25114  }
25115  }
25116  #endif
25117 
25118  if (result)
25119  {
25120  const bool consq_is_vec = is_ivector_node(consequent );
25121  const bool alter_is_vec = is_ivector_node(alternative);
25122 
25123  if (consq_is_vec || alter_is_vec)
25124  {
25125  if (consq_is_vec && alter_is_vec)
25126  {
25127  return expression_generator_
25128  .conditional_vector(condition, consequent, alternative);
25129  }
25130 
25131  set_error(make_error(
25133  current_token(),
25134  "ERR040 - Return types of if-statement differ: vector/non-vector",
25136 
25137  result = false;
25138  }
25139  }
25140 
25141  if (!result)
25142  {
25143  free_node(node_allocator_, condition );
25144  free_node(node_allocator_, consequent );
25145  free_node(node_allocator_, alternative);
25146 
25147  return error_node();
25148  }
25149  else
25150  return expression_generator_
25151  .conditional(condition, consequent, alternative);
25152  }
25153 
25155  {
25156  expression_node_ptr consequent = error_node();
25157  expression_node_ptr alternative = error_node();
25158 
25159  bool result = true;
25160 
25161  if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
25162  {
25163  if (0 == (consequent = parse_multi_sequence("if-statement-01")))
25164  {
25165  set_error(make_error(
25167  current_token(),
25168  "ERR041 - Failed to parse body of consequent for if-statement",
25170 
25171  result = false;
25172  }
25173  else if
25174  (
25175  !settings_.commutative_check_enabled() &&
25176  !token_is("else",prsrhlpr_t::e_hold) &&
25177  !token_is_loop(prsrhlpr_t::e_hold) &&
25178  !token_is_arithmetic_opr(prsrhlpr_t::e_hold) &&
25179  !token_is_right_bracket (prsrhlpr_t::e_hold) &&
25180  !token_is_ineq_opr (prsrhlpr_t::e_hold) &&
25181  !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
25182  !token_is(token_t::e_eof)
25183  )
25184  {
25185  set_error(make_error(
25187  current_token(),
25188  "ERR042 - Expected ';' at the end of the consequent for if-statement (1)",
25190 
25191  result = false;
25192  }
25193  }
25194  else
25195  {
25196  if (
25197  settings_.commutative_check_enabled() &&
25198  token_is(token_t::e_mul,prsrhlpr_t::e_hold)
25199  )
25200  {
25201  next_token();
25202  }
25203 
25204  if (0 != (consequent = parse_expression()))
25205  {
25206  if (!token_is(token_t::e_eof))
25207  {
25208  set_error(make_error(
25210  current_token(),
25211  "ERR043 - Expected ';' at the end of the consequent for if-statement (2)",
25213 
25214  result = false;
25215  }
25216  }
25217  else
25218  {
25219  set_error(make_error(
25221  current_token(),
25222  "ERR044 - Failed to parse body of consequent for if-statement",
25224 
25225  result = false;
25226  }
25227  }
25228 
25229  if (result)
25230  {
25231  if (details::imatch(current_token().value,"else"))
25232  {
25233  next_token();
25234 
25235  if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
25236  {
25237  if (0 == (alternative = parse_multi_sequence("else-statement-01")))
25238  {
25239  set_error(make_error(
25241  current_token(),
25242  "ERR045 - Failed to parse body of the 'else' for if-statement",
25244 
25245  result = false;
25246  }
25247  }
25248  else if (details::imatch(current_token().value,"if"))
25249  {
25250  if (0 == (alternative = parse_conditional_statement()))
25251  {
25252  set_error(make_error(
25254  current_token(),
25255  "ERR046 - Failed to parse body of if-else statement",
25257 
25258  result = false;
25259  }
25260  }
25261  else if (0 != (alternative = parse_expression()))
25262  {
25263  if (
25264  !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
25265  !token_is(token_t::e_eof)
25266  )
25267  {
25268  set_error(make_error(
25270  current_token(),
25271  "ERR047 - Expected ';' at the end of the 'else-if' for the if-statement",
25273 
25274  result = false;
25275  }
25276  }
25277  else
25278  {
25279  set_error(make_error(
25281  current_token(),
25282  "ERR048 - Failed to parse body of the 'else' for if-statement",
25284 
25285  result = false;
25286  }
25287  }
25288  }
25289 
25290  #ifndef exprtk_disable_string_capabilities
25291  if (result)
25292  {
25293  const bool consq_is_str = is_generally_string_node(consequent );
25294  const bool alter_is_str = is_generally_string_node(alternative);
25295 
25296  if (consq_is_str || alter_is_str)
25297  {
25298  if (consq_is_str && alter_is_str)
25299  {
25300  return expression_generator_
25301  .conditional_string(condition, consequent, alternative);
25302  }
25303 
25304  set_error(make_error(
25306  current_token(),
25307  "ERR049 - Return types of if-statement differ: string/non-string",
25309 
25310  result = false;
25311  }
25312  }
25313  #endif
25314 
25315  if (result)
25316  {
25317  const bool consq_is_vec = is_ivector_node(consequent );
25318  const bool alter_is_vec = is_ivector_node(alternative);
25319 
25320  if (consq_is_vec || alter_is_vec)
25321  {
25322  if (consq_is_vec && alter_is_vec)
25323  {
25324  return expression_generator_
25325  .conditional_vector(condition, consequent, alternative);
25326  }
25327 
25328  set_error(make_error(
25330  current_token(),
25331  "ERR050 - Return types of if-statement differ: vector/non-vector",
25333 
25334  result = false;
25335  }
25336  }
25337 
25338  if (!result)
25339  {
25340  free_node(node_allocator_, condition );
25341  free_node(node_allocator_, consequent );
25342  free_node(node_allocator_, alternative);
25343 
25344  return error_node();
25345  }
25346  else
25347  return expression_generator_
25348  .conditional(condition, consequent, alternative);
25349  }
25350 
25352  {
25353  expression_node_ptr condition = error_node();
25354 
25355  next_token();
25356 
25357  if (!token_is(token_t::e_lbracket))
25358  {
25359  set_error(make_error(
25361  current_token(),
25362  "ERR051 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
25364 
25365  return error_node();
25366  }
25367  else if (0 == (condition = parse_expression()))
25368  {
25369  set_error(make_error(
25371  current_token(),
25372  "ERR052 - Failed to parse condition for if-statement",
25374 
25375  return error_node();
25376  }
25377  else if (token_is(token_t::e_comma,prsrhlpr_t::e_hold))
25378  {
25379  // if (x,y,z)
25380  return parse_conditional_statement_01(condition);
25381  }
25382  else if (token_is(token_t::e_rbracket))
25383  {
25384  /*
25385  00. if (x) y;
25386  01. if (x) y; else z;
25387  02. if (x) y; else {z0; ... zn;}
25388  03. if (x) y; else if (z) w;
25389  04. if (x) y; else if (z) w; else u;
25390  05. if (x) y; else if (z) w; else {u0; ... un;}
25391  06. if (x) y; else if (z) {w0; ... wn;}
25392  07. if (x) {y0; ... yn;}
25393  08. if (x) {y0; ... yn;} else z;
25394  09. if (x) {y0; ... yn;} else {z0; ... zn;};
25395  10. if (x) {y0; ... yn;} else if (z) w;
25396  11. if (x) {y0; ... yn;} else if (z) w; else u;
25397  12. if (x) {y0; ... nex;} else if (z) w; else {u0 ... un;}
25398  13. if (x) {y0; ... yn;} else if (z) {w0; ... wn;}
25399  */
25400  return parse_conditional_statement_02(condition);
25401  }
25402 
25403  set_error(make_error(
25405  current_token(),
25406  "ERR053 - Invalid if-statement",
25408 
25409  free_node(node_allocator_,condition);
25410 
25411  return error_node();
25412  }
25413 
25415  {
25416  // Parse: [condition][?][consequent][:][alternative]
25417  expression_node_ptr consequent = error_node();
25418  expression_node_ptr alternative = error_node();
25419 
25420  bool result = true;
25421 
25422  if (0 == condition)
25423  {
25424  set_error(make_error(
25426  current_token(),
25427  "ERR054 - Encountered invalid condition branch for ternary if-statement",
25429 
25430  return error_node();
25431  }
25432  else if (!token_is(token_t::e_ternary))
25433  {
25434  set_error(make_error(
25436  current_token(),
25437  "ERR055 - Expected '?' after condition of ternary if-statement",
25439 
25440  result = false;
25441  }
25442  else if (0 == (consequent = parse_expression()))
25443  {
25444  set_error(make_error(
25446  current_token(),
25447  "ERR056 - Failed to parse consequent for ternary if-statement",
25449 
25450  result = false;
25451  }
25452  else if (!token_is(token_t::e_colon))
25453  {
25454  set_error(make_error(
25456  current_token(),
25457  "ERR057 - Expected ':' between ternary if-statement consequent and alternative",
25459 
25460  result = false;
25461  }
25462  else if (0 == (alternative = parse_expression()))
25463  {
25464  set_error(make_error(
25466  current_token(),
25467  "ERR058 - Failed to parse alternative for ternary if-statement",
25469 
25470  result = false;
25471  }
25472 
25473  #ifndef exprtk_disable_string_capabilities
25474  if (result)
25475  {
25476  const bool consq_is_str = is_generally_string_node(consequent );
25477  const bool alter_is_str = is_generally_string_node(alternative);
25478 
25479  if (consq_is_str || alter_is_str)
25480  {
25481  if (consq_is_str && alter_is_str)
25482  {
25483  return expression_generator_
25484  .conditional_string(condition, consequent, alternative);
25485  }
25486 
25487  set_error(make_error(
25489  current_token(),
25490  "ERR059 - Return types of ternary differ: string/non-string",
25492 
25493  result = false;
25494  }
25495  }
25496  #endif
25497 
25498  if (result)
25499  {
25500  const bool consq_is_vec = is_ivector_node(consequent );
25501  const bool alter_is_vec = is_ivector_node(alternative);
25502 
25503  if (consq_is_vec || alter_is_vec)
25504  {
25505  if (consq_is_vec && alter_is_vec)
25506  {
25507  return expression_generator_
25508  .conditional_vector(condition, consequent, alternative);
25509  }
25510 
25511  set_error(make_error(
25513  current_token(),
25514  "ERR060 - Return types of ternary differ: vector/non-vector",
25516 
25517  result = false;
25518  }
25519  }
25520 
25521  if (!result)
25522  {
25523  free_node(node_allocator_, condition );
25524  free_node(node_allocator_, consequent );
25525  free_node(node_allocator_, alternative);
25526 
25527  return error_node();
25528  }
25529  else
25530  return expression_generator_
25531  .conditional(condition, consequent, alternative);
25532  }
25533 
25535  {
25536  if (settings_.logic_disabled("not"))
25537  {
25538  set_error(make_error(
25540  current_token(),
25541  "ERR061 - Invalid or disabled logic operation 'not'",
25543 
25544  return error_node();
25545  }
25546 
25547  return parse_base_operation();
25548  }
25549 
25551  {
25552  assert(!brkcnt_list_.empty());
25553  brkcnt_list_.pop_front();
25554  }
25555 
25557  {
25558  // Parse: [while][(][test expr][)][{][expression][}]
25559  expression_node_ptr condition = error_node();
25560  expression_node_ptr branch = error_node();
25561  expression_node_ptr result_node = error_node();
25562 
25563  bool result = true;
25564 
25565  next_token();
25566 
25567  if (!token_is(token_t::e_lbracket))
25568  {
25569  set_error(make_error(
25571  current_token(),
25572  "ERR062 - Expected '(' at start of while-loop condition statement",
25574 
25575  return error_node();
25576  }
25577  else if (0 == (condition = parse_expression()))
25578  {
25579  set_error(make_error(
25581  current_token(),
25582  "ERR063 - Failed to parse condition for while-loop",
25584 
25585  return error_node();
25586  }
25587  else if (!token_is(token_t::e_rbracket))
25588  {
25589  set_error(make_error(
25591  current_token(),
25592  "ERR064 - Expected ')' at end of while-loop condition statement",
25594 
25595  result = false;
25596  }
25597 
25598  brkcnt_list_.push_front(false);
25599 
25600  if (result)
25601  {
25602  scoped_inc_dec sid(state_.parsing_loop_stmt_count);
25603 
25604  if (0 == (branch = parse_multi_sequence("while-loop", true)))
25605  {
25606  set_error(make_error(
25608  current_token(),
25609  "ERR065 - Failed to parse body of while-loop"));
25610  result = false;
25611  }
25612  else if (0 == (result_node = expression_generator_.while_loop(condition,
25613  branch,
25614  brkcnt_list_.front())))
25615  {
25616  set_error(make_error(
25618  current_token(),
25619  "ERR066 - Failed to synthesize while-loop",
25621 
25622  result = false;
25623  }
25624  }
25625 
25626  handle_brkcnt_scope_exit();
25627 
25628  if (!result)
25629  {
25630  free_node(node_allocator_, branch );
25631  free_node(node_allocator_, condition );
25632  free_node(node_allocator_, result_node);
25633 
25634  return error_node();
25635  }
25636 
25637  if (result_node && result_node->valid())
25638  {
25639  return result_node;
25640  }
25641 
25642  set_error(make_error(
25644  current_token(),
25645  "ERR067 - Failed to synthesize 'valid' while-loop",
25647 
25648  free_node(node_allocator_, result_node);
25649 
25650  return error_node();
25651  }
25652 
25654  {
25655  // Parse: [repeat][{][expression][}][until][(][test expr][)]
25656  expression_node_ptr condition = error_node();
25657  expression_node_ptr branch = error_node();
25658  next_token();
25659 
25660  std::vector<expression_node_ptr> arg_list;
25661  std::vector<bool> side_effect_list;
25662 
25663  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
25664 
25665  brkcnt_list_.push_front(false);
25666 
25667  if (details::imatch(current_token().value,"until"))
25668  {
25669  next_token();
25670  branch = node_allocator_.allocate<details::null_node<T> >();
25671  }
25672  else
25673  {
25674  const token_t::token_type separator = token_t::e_eof;
25675 
25676  scope_handler sh(*this);
25677 
25678  scoped_bool_or_restorer sbr(state_.side_effect_present);
25679 
25680  scoped_inc_dec sid(state_.parsing_loop_stmt_count);
25681 
25682  for ( ; ; )
25683  {
25684  state_.side_effect_present = false;
25685 
25686  expression_node_ptr arg = parse_expression();
25687 
25688  if (0 == arg)
25689  return error_node();
25690  else
25691  {
25692  arg_list.push_back(arg);
25693  side_effect_list.push_back(state_.side_effect_present);
25694  }
25695 
25696  if (details::imatch(current_token().value,"until"))
25697  {
25698  next_token();
25699  break;
25700  }
25701 
25702  const bool is_next_until = peek_token_is(token_t::e_symbol) &&
25703  peek_token_is("until");
25704 
25705  if (!token_is(separator) && is_next_until)
25706  {
25707  set_error(make_error(
25709  current_token(),
25710  "ERR068 - Expected '" + token_t::to_str(separator) + "' in body of repeat until loop",
25712 
25713  return error_node();
25714  }
25715 
25716  if (details::imatch(current_token().value,"until"))
25717  {
25718  next_token();
25719  break;
25720  }
25721  }
25722 
25723  branch = simplify(arg_list,side_effect_list);
25724 
25725  sdd.delete_ptr = (0 == branch);
25726 
25727  if (sdd.delete_ptr)
25728  {
25729  set_error(make_error(
25731  current_token(),
25732  "ERR069 - Failed to parse body of repeat until loop",
25734 
25735  return error_node();
25736  }
25737  }
25738 
25739  if (!token_is(token_t::e_lbracket))
25740  {
25741  set_error(make_error(
25743  current_token(),
25744  "ERR070 - Expected '(' before condition statement of repeat until loop",
25746 
25747  free_node(node_allocator_,branch);
25748  return error_node();
25749  }
25750  else if (0 == (condition = parse_expression()))
25751  {
25752  set_error(make_error(
25754  current_token(),
25755  "ERR071 - Failed to parse condition for repeat until loop",
25757 
25758  free_node(node_allocator_,branch);
25759  return error_node();
25760  }
25761  else if (!token_is(token_t::e_rbracket))
25762  {
25763  set_error(make_error(
25765  current_token(),
25766  "ERR072 - Expected ')' after condition of repeat until loop",
25768 
25769  free_node(node_allocator_, branch );
25770  free_node(node_allocator_, condition);
25771 
25772  return error_node();
25773  }
25774 
25775  expression_node_ptr result_node =
25776  expression_generator_
25777  .repeat_until_loop(
25778  condition,
25779  branch,
25780  brkcnt_list_.front());
25781 
25782  if (0 == result_node)
25783  {
25784  set_error(make_error(
25786  current_token(),
25787  "ERR073 - Failed to synthesize repeat until loop",
25789 
25790  free_node(node_allocator_,condition);
25791 
25792  return error_node();
25793  }
25794 
25795  handle_brkcnt_scope_exit();
25796 
25797  if (result_node && result_node->valid())
25798  {
25799  return result_node;
25800  }
25801 
25802  set_error(make_error(
25804  current_token(),
25805  "ERR074 - Failed to synthesize 'valid' repeat until loop",
25807 
25808  free_node(node_allocator_, result_node);
25809 
25810  return error_node();
25811  }
25812 
25814  {
25815  expression_node_ptr initialiser = error_node();
25816  expression_node_ptr condition = error_node();
25817  expression_node_ptr incrementor = error_node();
25818  expression_node_ptr loop_body = error_node();
25819 
25820  scope_element* se = 0;
25821  bool result = true;
25822 
25823  next_token();
25824 
25825  scope_handler sh(*this);
25826 
25827  if (!token_is(token_t::e_lbracket))
25828  {
25829  set_error(make_error(
25831  current_token(),
25832  "ERR075 - Expected '(' at start of for-loop",
25834 
25835  return error_node();
25836  }
25837 
25838  if (!token_is(token_t::e_eof))
25839  {
25840  if (
25841  !token_is(token_t::e_symbol,prsrhlpr_t::e_hold) &&
25842  details::imatch(current_token().value,"var")
25843  )
25844  {
25845  next_token();
25846 
25847  if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
25848  {
25849  set_error(make_error(
25851  current_token(),
25852  "ERR076 - Expected a variable at the start of initialiser section of for-loop",
25854 
25855  return error_node();
25856  }
25857  else if (!peek_token_is(token_t::e_assign))
25858  {
25859  set_error(make_error(
25861  current_token(),
25862  "ERR077 - Expected variable assignment of initialiser section of for-loop",
25864 
25865  return error_node();
25866  }
25867 
25868  const std::string loop_counter_symbol = current_token().value;
25869 
25870  se = &sem_.get_element(loop_counter_symbol);
25871 
25872  if ((se->name == loop_counter_symbol) && se->active)
25873  {
25874  set_error(make_error(
25876  current_token(),
25877  "ERR078 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
25879 
25880  return error_node();
25881  }
25882  else if (!symtab_store_.is_variable(loop_counter_symbol))
25883  {
25884  if (
25885  !se->active &&
25886  (se->name == loop_counter_symbol) &&
25887  (se->type == scope_element::e_variable)
25888  )
25889  {
25890  se->active = true;
25891  se->ref_count++;
25892  }
25893  else
25894  {
25895  scope_element nse;
25896  nse.name = loop_counter_symbol;
25897  nse.active = true;
25898  nse.ref_count = 1;
25899  nse.type = scope_element::e_variable;
25900  nse.depth = state_.scope_depth;
25901  nse.data = new T(T(0));
25902  nse.var_node = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data));
25903 
25904  if (!sem_.add_element(nse))
25905  {
25906  set_error(make_error(
25908  current_token(),
25909  "ERR079 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
25911 
25912  sem_.free_element(nse);
25913 
25914  result = false;
25915  }
25916  else
25917  {
25918  exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n", nse.name.c_str()));
25919 
25920  state_.activate_side_effect("parse_for_loop()");
25921  }
25922  }
25923  }
25924  }
25925 
25926  if (0 == (initialiser = parse_expression()))
25927  {
25928  set_error(make_error(
25930  current_token(),
25931  "ERR080 - Failed to parse initialiser of for-loop",
25933 
25934  result = false;
25935  }
25936  else if (!token_is(token_t::e_eof))
25937  {
25938  set_error(make_error(
25940  current_token(),
25941  "ERR081 - Expected ';' after initialiser of for-loop",
25943 
25944  result = false;
25945  }
25946  }
25947 
25948  if (!token_is(token_t::e_eof))
25949  {
25950  if (0 == (condition = parse_expression()))
25951  {
25952  set_error(make_error(
25954  current_token(),
25955  "ERR082 - Failed to parse condition of for-loop",
25957 
25958  result = false;
25959  }
25960  else if (!token_is(token_t::e_eof))
25961  {
25962  set_error(make_error(
25964  current_token(),
25965  "ERR083 - Expected ';' after condition section of for-loop",
25967 
25968  result = false;
25969  }
25970  }
25971 
25972  if (!token_is(token_t::e_rbracket))
25973  {
25974  if (0 == (incrementor = parse_expression()))
25975  {
25976  set_error(make_error(
25978  current_token(),
25979  "ERR084 - Failed to parse incrementor of for-loop",
25981 
25982  result = false;
25983  }
25984  else if (!token_is(token_t::e_rbracket))
25985  {
25986  set_error(make_error(
25988  current_token(),
25989  "ERR085 - Expected ')' after incrementor section of for-loop",
25991 
25992  result = false;
25993  }
25994  }
25995 
25996  if (result)
25997  {
25998  brkcnt_list_.push_front(false);
25999 
26000  scoped_inc_dec sid(state_.parsing_loop_stmt_count);
26001 
26002  if (0 == (loop_body = parse_multi_sequence("for-loop", true)))
26003  {
26004  set_error(make_error(
26006  current_token(),
26007  "ERR086 - Failed to parse body of for-loop",
26009 
26010  result = false;
26011  }
26012  }
26013 
26014  if (!result)
26015  {
26016  if (se)
26017  {
26018  se->ref_count--;
26019  }
26020 
26021  free_node(node_allocator_, initialiser);
26022  free_node(node_allocator_, condition );
26023  free_node(node_allocator_, incrementor);
26024  free_node(node_allocator_, loop_body );
26025  return error_node();
26026  }
26027 
26028  expression_node_ptr result_node =
26029  expression_generator_.for_loop(initialiser,
26030  condition,
26031  incrementor,
26032  loop_body,
26033  brkcnt_list_.front());
26034  handle_brkcnt_scope_exit();
26035 
26036  if (result_node && result_node->valid())
26037  {
26038  return result_node;
26039  }
26040 
26041  set_error(make_error(
26043  current_token(),
26044  "ERR087 - Failed to synthesize 'valid' for-loop",
26046 
26047  free_node(node_allocator_, result_node);
26048 
26049  return error_node();
26050  }
26051 
26053  {
26054  std::vector<expression_node_ptr> arg_list;
26055  expression_node_ptr result = error_node();
26056 
26057  if (!details::imatch(current_token().value,"switch"))
26058  {
26059  set_error(make_error(
26061  current_token(),
26062  "ERR088 - Expected keyword 'switch'",
26064 
26065  return error_node();
26066  }
26067 
26068  scoped_vec_delete<expression_node_t> svd((*this),arg_list);
26069 
26070  next_token();
26071 
26072  if (!token_is(token_t::e_lcrlbracket))
26073  {
26074  set_error(make_error(
26076  current_token(),
26077  "ERR089 - Expected '{' for call to switch statement",
26079 
26080  return error_node();
26081  }
26082 
26083  expression_node_ptr default_statement = error_node();
26084 
26085  scoped_expression_delete defstmt_delete((*this), default_statement);
26086 
26087  for ( ; ; )
26088  {
26089  if (details::imatch("case",current_token().value))
26090  {
26091  next_token();
26092 
26093  expression_node_ptr condition = parse_expression();
26094 
26095  if (0 == condition)
26096  return error_node();
26097  else if (!token_is(token_t::e_colon))
26098  {
26099  set_error(make_error(
26101  current_token(),
26102  "ERR090 - Expected ':' for case of switch statement",
26104 
26105  free_node(node_allocator_, condition);
26106 
26107  return error_node();
26108  }
26109 
26110  expression_node_ptr consequent =
26111  (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
26112  parse_multi_sequence("switch-consequent") :
26113  parse_expression();
26114 
26115  if (0 == consequent)
26116  {
26117  free_node(node_allocator_, condition);
26118 
26119  return error_node();
26120  }
26121  else if (!token_is(token_t::e_eof))
26122  {
26123  set_error(make_error(
26125  current_token(),
26126  "ERR091 - Expected ';' at end of case for switch statement",
26128 
26129  free_node(node_allocator_, condition );
26130  free_node(node_allocator_, consequent);
26131 
26132  return error_node();
26133  }
26134 
26135  // Can we optimise away the case statement?
26136  if (is_constant_node(condition) && is_false(condition))
26137  {
26138  free_node(node_allocator_, condition );
26139  free_node(node_allocator_, consequent);
26140  }
26141  else
26142  {
26143  arg_list.push_back(condition );
26144  arg_list.push_back(consequent);
26145  }
26146 
26147  }
26148  else if (details::imatch("default",current_token().value))
26149  {
26150  if (0 != default_statement)
26151  {
26152  set_error(make_error(
26154  current_token(),
26155  "ERR092 - Multiple default cases for switch statement",
26157 
26158  return error_node();
26159  }
26160 
26161  next_token();
26162 
26163  if (!token_is(token_t::e_colon))
26164  {
26165  set_error(make_error(
26167  current_token(),
26168  "ERR093 - Expected ':' for default of switch statement",
26170 
26171  return error_node();
26172  }
26173 
26174  default_statement =
26175  (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
26176  parse_multi_sequence("switch-default"):
26177  parse_expression();
26178 
26179  if (0 == default_statement)
26180  return error_node();
26181  else if (!token_is(token_t::e_eof))
26182  {
26183  set_error(make_error(
26185  current_token(),
26186  "ERR094 - Expected ';' at end of default for switch statement",
26188 
26189  return error_node();
26190  }
26191  }
26192  else if (token_is(token_t::e_rcrlbracket))
26193  break;
26194  else
26195  {
26196  set_error(make_error(
26198  current_token(),
26199  "ERR095 - Expected '}' at end of switch statement",
26201 
26202  return error_node();
26203  }
26204  }
26205 
26206  const bool default_statement_present = (0 != default_statement);
26207 
26208  if (default_statement_present)
26209  {
26210  arg_list.push_back(default_statement);
26211  }
26212  else
26213  {
26214  arg_list.push_back(node_allocator_.allocate_c<literal_node_t>(std::numeric_limits<T>::quiet_NaN()));
26215  }
26216 
26217  result = expression_generator_.switch_statement(arg_list, (0 != default_statement));
26218 
26219  svd.delete_ptr = (0 == result);
26220  defstmt_delete.delete_ptr = (0 == result);
26221 
26222  return result;
26223  }
26224 
26226  {
26227  std::vector<expression_node_ptr> arg_list;
26228 
26229  if (!details::imatch(current_token().value,"[*]"))
26230  {
26231  set_error(make_error(
26233  current_token(),
26234  "ERR096 - Expected token '[*]'",
26236 
26237  return error_node();
26238  }
26239 
26240  scoped_vec_delete<expression_node_t> svd((*this),arg_list);
26241 
26242  next_token();
26243 
26244  if (!token_is(token_t::e_lcrlbracket))
26245  {
26246  set_error(make_error(
26248  current_token(),
26249  "ERR097 - Expected '{' for call to [*] statement",
26251 
26252  return error_node();
26253  }
26254 
26255  for ( ; ; )
26256  {
26257  if (!details::imatch("case",current_token().value))
26258  {
26259  set_error(make_error(
26261  current_token(),
26262  "ERR098 - Expected a 'case' statement for multi-switch",
26264 
26265  return error_node();
26266  }
26267 
26268  next_token();
26269 
26270  expression_node_ptr condition = parse_expression();
26271 
26272  if (0 == condition)
26273  return error_node();
26274 
26275  if (!token_is(token_t::e_colon))
26276  {
26277  set_error(make_error(
26279  current_token(),
26280  "ERR099 - Expected ':' for case of [*] statement",
26282 
26283  return error_node();
26284  }
26285 
26286  expression_node_ptr consequent =
26287  (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ?
26288  parse_multi_sequence("multi-switch-consequent") :
26289  parse_expression();
26290 
26291  if (0 == consequent)
26292  return error_node();
26293 
26294  if (!token_is(token_t::e_eof))
26295  {
26296  set_error(make_error(
26298  current_token(),
26299  "ERR100 - Expected ';' at end of case for [*] statement",
26301 
26302  return error_node();
26303  }
26304 
26305  // Can we optimise away the case statement?
26306  if (is_constant_node(condition) && is_false(condition))
26307  {
26308  free_node(node_allocator_, condition );
26309  free_node(node_allocator_, consequent);
26310  }
26311  else
26312  {
26313  arg_list.push_back(condition );
26314  arg_list.push_back(consequent);
26315  }
26316 
26317  if (token_is(token_t::e_rcrlbracket,prsrhlpr_t::e_hold))
26318  {
26319  break;
26320  }
26321  }
26322 
26323  if (!token_is(token_t::e_rcrlbracket))
26324  {
26325  set_error(make_error(
26327  current_token(),
26328  "ERR101 - Expected '}' at end of [*] statement",
26330 
26331  return error_node();
26332  }
26333 
26334  const expression_node_ptr result = expression_generator_.multi_switch_statement(arg_list);
26335 
26336  svd.delete_ptr = (0 == result);
26337 
26338  return result;
26339  }
26340 
26342  {
26343  std::vector<expression_node_ptr> arg_list;
26344 
26346  const std::string symbol = current_token().value;
26347 
26348  if (details::imatch(symbol,"~"))
26349  {
26350  next_token();
26351  return parse_multi_sequence();
26352  }
26353  else if (details::imatch(symbol,"[*]"))
26354  {
26355  return parse_multi_switch_statement();
26356  }
26357  else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ;
26358  else if (details::imatch(symbol, "mand")) opt_type = details::e_mand;
26359  else if (details::imatch(symbol, "max" )) opt_type = details::e_max ;
26360  else if (details::imatch(symbol, "min" )) opt_type = details::e_min ;
26361  else if (details::imatch(symbol, "mor" )) opt_type = details::e_mor ;
26362  else if (details::imatch(symbol, "mul" )) opt_type = details::e_prod;
26363  else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ;
26364  else
26365  {
26366  set_error(make_error(
26368  current_token(),
26369  "ERR102 - Unsupported built-in vararg function: " + symbol,
26371 
26372  return error_node();
26373  }
26374 
26375  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
26376 
26377  lodge_symbol(symbol, e_st_function);
26378 
26379  next_token();
26380 
26381  if (!token_is(token_t::e_lbracket))
26382  {
26383  set_error(make_error(
26385  current_token(),
26386  "ERR103 - Expected '(' for call to vararg function: " + symbol,
26388 
26389  return error_node();
26390  }
26391 
26392  if (token_is(token_t::e_rbracket))
26393  {
26394  set_error(make_error(
26396  current_token(),
26397  "ERR104 - vararg function: " + symbol +
26398  " requires at least one input parameter",
26400 
26401  return error_node();
26402  }
26403 
26404  for ( ; ; )
26405  {
26406  expression_node_ptr arg = parse_expression();
26407 
26408  if (0 == arg)
26409  return error_node();
26410  else
26411  arg_list.push_back(arg);
26412 
26413  if (token_is(token_t::e_rbracket))
26414  break;
26415  else if (!token_is(token_t::e_comma))
26416  {
26417  set_error(make_error(
26419  current_token(),
26420  "ERR105 - Expected ',' for call to vararg function: " + symbol,
26422 
26423  return error_node();
26424  }
26425  }
26426 
26427  const expression_node_ptr result = expression_generator_.vararg_function(opt_type,arg_list);
26428 
26429  sdd.delete_ptr = (0 == result);
26430  return result;
26431  }
26432 
26433  #ifndef exprtk_disable_string_capabilities
26435  {
26436  if (!token_is(token_t::e_lsqrbracket))
26437  {
26438  set_error(make_error(
26440  current_token(),
26441  "ERR106 - Expected '[' as start of string range definition",
26443 
26444  free_node(node_allocator_,expression);
26445 
26446  return error_node();
26447  }
26448  else if (token_is(token_t::e_rsqrbracket))
26449  {
26450  return node_allocator_.allocate<details::string_size_node<T> >(expression);
26451  }
26452 
26453  range_t rp;
26454 
26455  if (!parse_range(rp,true))
26456  {
26457  free_node(node_allocator_,expression);
26458 
26459  return error_node();
26460  }
26461 
26462  expression_node_ptr result = expression_generator_(expression,rp);
26463 
26464  if (0 == result)
26465  {
26466  set_error(make_error(
26468  current_token(),
26469  "ERR107 - Failed to generate string range node",
26471 
26472  free_node(node_allocator_,expression);
26473  rp.free();
26474  }
26475 
26476  rp.clear();
26477 
26478  if (result && result->valid())
26479  {
26480  return result;
26481  }
26482 
26483  set_error(make_error(
26485  current_token(),
26486  "ERR108 - Failed to synthesize node: string_range_node",
26488 
26489  free_node(node_allocator_, result);
26490  rp.free();
26491  return error_node();
26492  }
26493  #else
26494  inline expression_node_ptr parse_string_range_statement(expression_node_ptr&)
26495  {
26496  return error_node();
26497  }
26498  #endif
26499 
26501  {
26502  // Allow no more than 100 range calls, eg: s[][][]...[][]
26503  const std::size_t max_rangesize_parses = 100;
26504 
26505  std::size_t i = 0;
26506 
26507  while
26508  (
26509  (0 != expression) &&
26510  (i++ < max_rangesize_parses) &&
26511  error_list_.empty() &&
26513  token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)
26514  )
26515  {
26516  expression = parse_string_range_statement(expression);
26517  }
26518 
26519  return (i > 1);
26520  }
26521 
26523  {
26524  if
26525  (
26526  (0 != expression) &&
26527  error_list_.empty() &&
26529  )
26530  {
26531  if (
26532  settings_.commutative_check_enabled() &&
26533  token_is(token_t::e_mul,prsrhlpr_t::e_hold) &&
26534  peek_token_is(token_t::e_lsqrbracket)
26535  )
26536  {
26537  token_is(token_t::e_mul);
26538  token_is(token_t::e_lsqrbracket);
26539  }
26540  else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold))
26541  {
26542  token_is(token_t::e_lsqrbracket);
26543  }
26544  else if (
26545  token_is(token_t::e_rbracket,prsrhlpr_t::e_hold) &&
26546  peek_token_is(token_t::e_lsqrbracket)
26547  )
26548  {
26549  token_is(token_t::e_rbracket );
26550  token_is(token_t::e_lsqrbracket);
26551  }
26552  else
26553  return;
26554 
26556 
26557  if (vi)
26558  {
26559  details::vector_holder<T>& vec = vi->vec()->vec_holder();
26560  const std::string vector_name = sem_.get_vector_name(vec.data());
26561  expression_node_ptr index = parse_vector_index(vector_name);
26562 
26563  if (index)
26564  {
26565  expression = synthesize_vector_element(vector_name, &vec, expression, index);
26566  return;
26567  }
26568  }
26569 
26570  free_node(node_allocator_,expression);
26571  expression = error_node();
26572  }
26573  }
26574 
26575  template <typename Allocator1,
26576  typename Allocator2,
26577  template <typename, typename> class Sequence>
26578  inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator1>& expression_list,
26579  Sequence<bool,Allocator2>& side_effect_list,
26580  const bool specialise_on_final_type = false)
26581  {
26582  if (expression_list.empty())
26583  return error_node();
26584  else if (1 == expression_list.size())
26585  return expression_list[0];
26586 
26587  Sequence<expression_node_ptr,Allocator1> tmp_expression_list;
26588 
26589  bool return_node_present = false;
26590 
26591  for (std::size_t i = 0; i < (expression_list.size() - 1); ++i)
26592  {
26593  if (is_variable_node(expression_list[i]))
26594  continue;
26595  else if (
26596  is_return_node (expression_list[i]) ||
26597  is_break_node (expression_list[i]) ||
26598  is_continue_node(expression_list[i])
26599  )
26600  {
26601  tmp_expression_list.push_back(expression_list[i]);
26602 
26603  // Remove all subexpressions after first short-circuit
26604  // node has been encountered.
26605 
26606  for (std::size_t j = i + 1; j < expression_list.size(); ++j)
26607  {
26608  free_node(node_allocator_,expression_list[j]);
26609  }
26610 
26611  return_node_present = true;
26612 
26613  break;
26614  }
26615  else if (
26616  is_constant_node(expression_list[i]) ||
26617  is_null_node (expression_list[i]) ||
26618  !side_effect_list[i]
26619  )
26620  {
26621  free_node(node_allocator_,expression_list[i]);
26622  continue;
26623  }
26624  else
26625  tmp_expression_list.push_back(expression_list[i]);
26626  }
26627 
26628  if (!return_node_present)
26629  {
26630  tmp_expression_list.push_back(expression_list.back());
26631  }
26632 
26633  expression_list.swap(tmp_expression_list);
26634 
26635  if (tmp_expression_list.size() > expression_list.size())
26636  {
26637  exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n",
26638  static_cast<int>(tmp_expression_list.size()),
26639  static_cast<int>(expression_list .size())));
26640  }
26641 
26642  if (
26643  return_node_present ||
26644  side_effect_list.back() ||
26645  (expression_list.size() > 1)
26646  )
26647  state_.activate_side_effect("simplify()");
26648 
26649  if (1 == expression_list.size())
26650  return expression_list[0];
26651  else if (specialise_on_final_type && is_generally_string_node(expression_list.back()))
26652  return expression_generator_.vararg_function(details::e_smulti,expression_list);
26653  else
26654  return expression_generator_.vararg_function(details::e_multi,expression_list);
26655  }
26656 
26657  inline expression_node_ptr parse_multi_sequence(const std::string& source = "",
26658  const bool enforce_crlbrackets = false)
26659  {
26660  token_t::token_type open_bracket = token_t::e_lcrlbracket;
26661  token_t::token_type close_bracket = token_t::e_rcrlbracket;
26662  token_t::token_type separator = token_t::e_eof;
26663 
26664  if (!token_is(open_bracket))
26665  {
26666  if (!enforce_crlbrackets && token_is(token_t::e_lbracket))
26667  {
26668  open_bracket = token_t::e_lbracket;
26669  close_bracket = token_t::e_rbracket;
26670  separator = token_t::e_comma;
26671  }
26672  else
26673  {
26674  set_error(make_error(
26676  current_token(),
26677  "ERR109 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" +
26678  ((!source.empty()) ? std::string(" section of " + source): ""),
26680 
26681  return error_node();
26682  }
26683  }
26684  else if (token_is(close_bracket))
26685  {
26686  return node_allocator_.allocate<details::null_node<T> >();
26687  }
26688 
26689  std::vector<expression_node_ptr> arg_list;
26690  std::vector<bool> side_effect_list;
26691 
26692  expression_node_ptr result = error_node();
26693 
26694  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
26695 
26696  scope_handler sh(*this);
26697 
26698  scoped_bool_or_restorer sbr(state_.side_effect_present);
26699 
26700  for ( ; ; )
26701  {
26702  state_.side_effect_present = false;
26703 
26704  expression_node_ptr arg = parse_expression();
26705 
26706  if (0 == arg)
26707  return error_node();
26708  else
26709  {
26710  arg_list.push_back(arg);
26711  side_effect_list.push_back(state_.side_effect_present);
26712  }
26713 
26714  if (token_is(close_bracket))
26715  break;
26716 
26717  const bool is_next_close = peek_token_is(close_bracket);
26718 
26719  if (!token_is(separator) && is_next_close)
26720  {
26721  set_error(make_error(
26723  current_token(),
26724  "ERR110 - Expected '" + details::to_str(separator) + "' for call to multi-sequence section of " + source,
26726 
26727  return error_node();
26728  }
26729 
26730  if (token_is(close_bracket))
26731  break;
26732  }
26733 
26734  result = simplify(arg_list, side_effect_list, source.empty());
26735 
26736  sdd.delete_ptr = (0 == result);
26737  return result;
26738  }
26739 
26740  inline bool parse_range(range_t& rp, const bool skip_lsqr = false)
26741  {
26742  // Examples of valid ranges:
26743  // 1. [1:5] -> [1,5)
26744  // 2. [ :5] -> [0,5)
26745  // 3. [1: ] -> [1,end)
26746  // 4. [x:y] -> [x,y) where x <= y
26747  // 5. [x+1:y/2] -> [x+1,y/2) where x+1 <= y/2
26748  // 6. [ :y] -> [0,y) where 0 <= y
26749  // 7. [x: ] -> [x,end) where x <= end
26750 
26751  rp.clear();
26752 
26753  if (!skip_lsqr && !token_is(token_t::e_lsqrbracket))
26754  {
26755  set_error(make_error(
26757  current_token(),
26758  "ERR111 - Expected '[' for start of range",
26760 
26761  return false;
26762  }
26763 
26764  if (token_is(token_t::e_colon))
26765  {
26766  rp.n0_c.first = true;
26767  rp.n0_c.second = 0;
26768  rp.cache.first = 0;
26769  }
26770  else
26771  {
26772  expression_node_ptr r0 = parse_expression();
26773 
26774  if (0 == r0)
26775  {
26776  set_error(make_error(
26778  current_token(),
26779  "ERR112 - Failed parse begin section of range",
26781 
26782  return false;
26783  }
26784  else if (is_constant_node(r0))
26785  {
26786  const T r0_value = r0->value();
26787 
26788  if (r0_value >= T(0))
26789  {
26790  rp.n0_c.first = true;
26791  rp.n0_c.second = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
26792  rp.cache.first = rp.n0_c.second;
26793  }
26794 
26795  free_node(node_allocator_,r0);
26796 
26797  if (r0_value < T(0))
26798  {
26799  set_error(make_error(
26801  current_token(),
26802  "ERR113 - Range lower bound less than zero! Constraint: r0 >= 0",
26804 
26805  return false;
26806  }
26807  }
26808  else
26809  {
26810  rp.n0_e.first = true;
26811  rp.n0_e.second = r0;
26812  }
26813 
26814  if (!token_is(token_t::e_colon))
26815  {
26816  set_error(make_error(
26818  current_token(),
26819  "ERR114 - Expected ':' for break in range",
26821 
26822  rp.free();
26823 
26824  return false;
26825  }
26826  }
26827 
26828  if (token_is(token_t::e_rsqrbracket))
26829  {
26830  rp.n1_c.first = true;
26832  }
26833  else
26834  {
26835  expression_node_ptr r1 = parse_expression();
26836 
26837  if (0 == r1)
26838  {
26839  set_error(make_error(
26841  current_token(),
26842  "ERR115 - Failed parse end section of range",
26844 
26845  rp.free();
26846 
26847  return false;
26848  }
26849  else if (is_constant_node(r1))
26850  {
26851  const T r1_value = r1->value();
26852 
26853  if (r1_value >= T(0))
26854  {
26855  rp.n1_c.first = true;
26856  rp.n1_c.second = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
26857  rp.cache.second = rp.n1_c.second;
26858  }
26859 
26860  free_node(node_allocator_,r1);
26861 
26862  if (r1_value < T(0))
26863  {
26864  set_error(make_error(
26866  current_token(),
26867  "ERR116 - Range upper bound less than zero! Constraint: r1 >= 0",
26869 
26870  rp.free();
26871 
26872  return false;
26873  }
26874  }
26875  else
26876  {
26877  rp.n1_e.first = true;
26878  rp.n1_e.second = r1;
26879  }
26880 
26881  if (!token_is(token_t::e_rsqrbracket))
26882  {
26883  set_error(make_error(
26885  current_token(),
26886  "ERR117 - Expected ']' for start of range",
26888 
26889  rp.free();
26890 
26891  return false;
26892  }
26893  }
26894 
26895  if (rp.const_range())
26896  {
26897  std::size_t r0 = 0;
26898  std::size_t r1 = 0;
26899 
26900  bool rp_result = false;
26901 
26902  try
26903  {
26904  rp_result = rp(r0, r1);
26905  }
26906  catch (std::runtime_error&)
26907  {}
26908 
26909  if (!rp_result || (r0 > r1))
26910  {
26911  set_error(make_error(
26913  current_token(),
26914  "ERR118 - Invalid range, Constraint: r0 <= r1",
26916 
26917  return false;
26918  }
26919  }
26920 
26921  return true;
26922  }
26923 
26924  inline void lodge_symbol(const std::string& symbol,
26925  const symbol_type st)
26926  {
26927  dec_.add_symbol(symbol,st);
26928  }
26929 
26930  #ifndef exprtk_disable_string_capabilities
26932  {
26933  const std::string symbol = current_token().value;
26934 
26935  typedef details::stringvar_node<T>* strvar_node_t;
26936 
26937  expression_node_ptr result = error_node();
26938  strvar_node_t const_str_node = static_cast<strvar_node_t>(0);
26939 
26940  scope_element& se = sem_.get_active_element(symbol);
26941 
26942  if (scope_element::e_string == se.type)
26943  {
26944  se.active = true;
26945  result = se.str_node;
26946  lodge_symbol(symbol, e_st_local_string);
26947  }
26948  else
26949  {
26950  typedef typename symtab_store::string_context str_ctxt_t;
26951  str_ctxt_t str_ctx = symtab_store_.get_string_context(symbol);
26952 
26953  if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol))
26954  {
26955  set_error(make_error(
26957  current_token(),
26958  "ERR119 - Unknown string symbol",
26960 
26961  return error_node();
26962  }
26963 
26964  assert(str_ctx.str_var != 0);
26965  assert(str_ctx.symbol_table != 0);
26966 
26967  result = str_ctx.str_var;
26968 
26969  if (symtab_store_.is_constant_string(symbol))
26970  {
26971  const_str_node = static_cast<strvar_node_t>(result);
26972  result = expression_generator_(const_str_node->str());
26973  }
26974  else if (symbol_table_t::e_immutable == str_ctx.symbol_table->mutability())
26975  {
26976  lodge_immutable_symbol(
26977  current_token(),
26978  make_memory_range(str_ctx.str_var->base(), str_ctx.str_var->size()));
26979  }
26980 
26981  lodge_symbol(symbol, e_st_string);
26982  }
26983 
26984  if (peek_token_is(token_t::e_lsqrbracket))
26985  {
26986  next_token();
26987 
26988  if (peek_token_is(token_t::e_rsqrbracket))
26989  {
26990  next_token();
26991  next_token();
26992 
26993  if (const_str_node)
26994  {
26995  free_node(node_allocator_,result);
26996 
26997  return expression_generator_(T(const_str_node->size()));
26998  }
26999  else
27000  return node_allocator_.allocate<details::stringvar_size_node<T> >
27001  (static_cast<details::stringvar_node<T>*>(result)->ref());
27002  }
27003 
27004  range_t rp;
27005 
27006  if (!parse_range(rp))
27007  {
27008  free_node(node_allocator_,result);
27009 
27010  return error_node();
27011  }
27012  else if (const_str_node)
27013  {
27014  free_node(node_allocator_,result);
27015  result = expression_generator_(const_str_node->ref(),rp);
27016  }
27017  else
27018  result = expression_generator_(static_cast<details::stringvar_node<T>*>
27019  (result)->ref(), rp);
27020 
27021  if (result)
27022  rp.clear();
27023  }
27024  else
27025  next_token();
27026 
27027  return result;
27028  }
27029  #else
27030  inline expression_node_ptr parse_string()
27031  {
27032  return error_node();
27033  }
27034  #endif
27035 
27036  #ifndef exprtk_disable_string_capabilities
27038  {
27039  const std::string const_str = current_token().value;
27040  expression_node_ptr result = expression_generator_(const_str);
27041 
27042  if (peek_token_is(token_t::e_lsqrbracket))
27043  {
27044  next_token();
27045 
27046  if (peek_token_is(token_t::e_rsqrbracket))
27047  {
27048  next_token();
27049  next_token();
27050 
27051  free_node(node_allocator_,result);
27052 
27053  return expression_generator_(T(const_str.size()));
27054  }
27055 
27056  range_t rp;
27057 
27058  if (!parse_range(rp))
27059  {
27060  free_node(node_allocator_,result);
27061  rp.free();
27062 
27063  return error_node();
27064  }
27065 
27066  free_node(node_allocator_,result);
27067 
27068  if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits<std::size_t>::max()))
27069  {
27070  rp.n1_c.second = const_str.size() - 1;
27071  rp.cache.second = rp.n1_c.second;
27072  }
27073 
27074  if (
27075  (rp.n0_c.first && (rp.n0_c.second >= const_str.size())) ||
27076  (rp.n1_c.first && (rp.n1_c.second >= const_str.size()))
27077  )
27078  {
27079  set_error(make_error(
27081  current_token(),
27082  "ERR120 - Overflow in range for string: '" + const_str + "'[" +
27083  (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" +
27084  (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]",
27086 
27087  rp.free();
27088 
27089  return error_node();
27090  }
27091 
27092  result = expression_generator_(const_str,rp);
27093 
27094  if (result)
27095  rp.clear();
27096  }
27097  else
27098  next_token();
27099 
27100  return result;
27101  }
27102  #else
27103  inline expression_node_ptr parse_const_string()
27104  {
27105  return error_node();
27106  }
27107  #endif
27108 
27109  inline expression_node_ptr parse_vector_index(const std::string& vector_name = "")
27110  {
27111  expression_node_ptr index_expr = error_node();
27112 
27113  if (0 == (index_expr = parse_expression()))
27114  {
27115  set_error(make_error(
27117  current_token(),
27118  "ERR121 - Failed to parse index for vector: '" + vector_name + "'",
27120 
27121  return error_node();
27122  }
27123  else if (!token_is(token_t::e_rsqrbracket))
27124  {
27125  set_error(make_error(
27127  current_token(),
27128  "ERR122 - Expected ']' for index of vector: '" + vector_name + "'",
27130 
27131  free_node(node_allocator_,index_expr);
27132 
27133  return error_node();
27134  }
27135 
27136  return index_expr;
27137  }
27138 
27140  {
27141  const std::string vector_name = current_token().value;
27142 
27144 
27145  const scope_element& se = sem_.get_active_element(vector_name);
27146 
27147  if (
27148  !details::imatch(se.name, vector_name) ||
27149  (se.depth > state_.scope_depth) ||
27150  (scope_element::e_vector != se.type)
27151  )
27152  {
27153  typedef typename symtab_store::vector_context vec_ctxt_t;
27154  vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(vector_name);
27155 
27156  if (0 == vec_ctx.vector_holder)
27157  {
27158  set_error(make_error(
27160  current_token(),
27161  "ERR123 - Symbol '" + vector_name + " not a vector",
27163 
27164  return error_node();
27165  }
27166 
27167  assert(0 != vec_ctx.vector_holder);
27168  assert(0 != vec_ctx.symbol_table );
27169 
27170  vec = vec_ctx.vector_holder;
27171 
27172  if (symbol_table_t::e_immutable == vec_ctx.symbol_table->mutability())
27173  {
27174  lodge_immutable_symbol(
27175  current_token(),
27176  make_memory_range(vec->data(), vec->size()));
27177  }
27178  }
27179  else
27180  {
27181  vec = se.vec_node;
27182  }
27183 
27184  assert(0 != vec);
27185 
27186  next_token();
27187 
27188  if (!token_is(token_t::e_lsqrbracket))
27189  {
27190  return node_allocator_.allocate<vector_node_t>(vec);
27191  }
27192  else if (token_is(token_t::e_rsqrbracket))
27193  {
27194  return (vec->rebaseable()) ?
27195  node_allocator_.allocate<vector_size_node_t>(vec) :
27196  expression_generator_(T(vec->size()));
27197  }
27198 
27199  expression_node_ptr index_expr = parse_vector_index(vector_name);
27200 
27201  if (index_expr)
27202  {
27203  expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec);
27204 
27205  return synthesize_vector_element(vector_name, vec, vec_node, index_expr);
27206  }
27207 
27208  return error_node();
27209  }
27210 
27211  inline expression_node_ptr synthesize_vector_element(const std::string& vector_name,
27212  vector_holder_ptr vec,
27213  expression_node_ptr vec_node,
27214  expression_node_ptr index_expr)
27215  {
27216  // Perform compile-time range check
27217  if (details::is_constant_node(index_expr))
27218  {
27219  const std::size_t index = static_cast<std::size_t>(details::numeric::to_int32(index_expr->value()));
27220  const std::size_t vec_size = vec->size();
27221 
27222  if (index >= vec_size)
27223  {
27224  set_error(make_error(
27226  current_token(),
27227  "ERR124 - Index of " + details::to_str(index) + " out of range for "
27228  "vector '" + vector_name + "' of size " + details::to_str(vec_size),
27230 
27231  free_node(node_allocator_, vec_node );
27232  free_node(node_allocator_, index_expr);
27233 
27234  return error_node();
27235  }
27236  }
27237 
27238  return expression_generator_.vector_element(vector_name, vec, vec_node, index_expr);
27239  }
27240 
27241  inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name)
27242  {
27243  std::vector<expression_node_ptr> arg_list;
27244 
27245  expression_node_ptr result = error_node();
27246 
27247  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
27248 
27249  next_token();
27250 
27251  if (token_is(token_t::e_lbracket))
27252  {
27253  if (token_is(token_t::e_rbracket))
27254  {
27255  if (!vararg_function->allow_zero_parameters())
27256  {
27257  set_error(make_error(
27259  current_token(),
27260  "ERR125 - Zero parameter call to vararg function: "
27261  + vararg_function_name + " not allowed",
27263 
27264  return error_node();
27265  }
27266  }
27267  else
27268  {
27269  for ( ; ; )
27270  {
27271  expression_node_ptr arg = parse_expression();
27272 
27273  if (0 == arg)
27274  return error_node();
27275  else
27276  arg_list.push_back(arg);
27277 
27278  if (token_is(token_t::e_rbracket))
27279  break;
27280  else if (!token_is(token_t::e_comma))
27281  {
27282  set_error(make_error(
27284  current_token(),
27285  "ERR126 - Expected ',' for call to vararg function: "
27286  + vararg_function_name,
27288 
27289  return error_node();
27290  }
27291  }
27292  }
27293  }
27294  else if (!vararg_function->allow_zero_parameters())
27295  {
27296  set_error(make_error(
27298  current_token(),
27299  "ERR127 - Zero parameter call to vararg function: "
27300  + vararg_function_name + " not allowed",
27302 
27303  return error_node();
27304  }
27305 
27306  if (arg_list.size() < vararg_function->min_num_args())
27307  {
27308  set_error(make_error(
27310  current_token(),
27311  "ERR128 - Invalid number of parameters to call to vararg function: "
27312  + vararg_function_name + ", require at least "
27313  + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters",
27315 
27316  return error_node();
27317  }
27318  else if (arg_list.size() > vararg_function->max_num_args())
27319  {
27320  set_error(make_error(
27322  current_token(),
27323  "ERR129 - Invalid number of parameters to call to vararg function: "
27324  + vararg_function_name + ", require no more than "
27325  + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters",
27327 
27328  return error_node();
27329  }
27330 
27331  result = expression_generator_.vararg_function_call(vararg_function,arg_list);
27332 
27333  sdd.delete_ptr = (0 == result);
27334 
27335  return result;
27336  }
27337 
27339  {
27340  public:
27341 
27343  {
27344  e_overload = ' ',
27345  e_numeric = 'T',
27346  e_string = 'S'
27347  };
27348 
27350  {
27352  std::string param_seq;
27353  };
27354 
27356  typedef std::vector<function_prototype_t> function_definition_list_t;
27357 
27359  const std::string& func_name,
27360  const std::string& func_prototypes,
27361  const return_type_t default_return_type)
27362  : invalid_state_(true)
27363  , parser_(p)
27364  , function_name_(func_name)
27365  , default_return_type_(default_return_type)
27366  {
27367  parse_function_prototypes(func_prototypes);
27368  }
27369 
27370  bool verify(const std::string& param_seq, std::size_t& pseq_index)
27371  {
27372  if (function_definition_list_.empty())
27373  return true;
27374 
27375  std::vector<std::pair<std::size_t,char> > error_list;
27376 
27377  for (std::size_t i = 0; i < function_definition_list_.size(); ++i)
27378  {
27379  details::char_t diff_value = 0;
27380  std::size_t diff_index = 0;
27381 
27382  const bool result = details::sequence_match(function_definition_list_[i].param_seq,
27383  param_seq,
27384  diff_index, diff_value);
27385 
27386  if (result)
27387  {
27388  pseq_index = i;
27389  return true;
27390  }
27391  else
27392  error_list.push_back(std::make_pair(diff_index, diff_value));
27393  }
27394 
27395  if (1 == error_list.size())
27396  {
27397  parser_.set_error(make_error(
27399  parser_.current_token(),
27400  "ERR130 - Failed parameter type check for function '" + function_name_ + "', "
27401  "Expected '" + function_definition_list_[0].param_seq +
27402  "' call set: '" + param_seq + "'",
27404  }
27405  else
27406  {
27407  // find first with largest diff_index;
27408  std::size_t max_diff_index = 0;
27409 
27410  for (std::size_t i = 1; i < error_list.size(); ++i)
27411  {
27412  if (error_list[i].first > error_list[max_diff_index].first)
27413  {
27414  max_diff_index = i;
27415  }
27416  }
27417 
27418  parser_.set_error(make_error(
27420  parser_.current_token(),
27421  "ERR131 - Failed parameter type check for function '" + function_name_ + "', "
27422  "Best match: '" + function_definition_list_[max_diff_index].param_seq +
27423  "' call set: '" + param_seq + "'",
27425  }
27426 
27427  return false;
27428  }
27429 
27430  std::size_t paramseq_count() const
27431  {
27432  return function_definition_list_.size();
27433  }
27434 
27435  std::string paramseq(const std::size_t& index) const
27436  {
27437  return function_definition_list_[index].param_seq;
27438  }
27439 
27440  return_type_t return_type(const std::size_t& index) const
27441  {
27442  return function_definition_list_[index].return_type;
27443  }
27444 
27445  bool invalid() const
27446  {
27447  return !invalid_state_;
27448  }
27449 
27451  {
27452 
27453  for (std::size_t i = 0; i < function_definition_list_.size(); ++i)
27454  {
27455  if (std::string::npos != function_definition_list_[i].param_seq.find("Z"))
27456  {
27457  return true;
27458  }
27459  }
27460 
27461  return false;
27462  }
27463 
27464  private:
27465 
27466  std::vector<std::string> split_param_seq(const std::string& param_seq, const details::char_t delimiter = '|') const
27467  {
27468  std::string::const_iterator current_begin = param_seq.begin();
27469  std::string::const_iterator iter = param_seq.begin();
27470 
27471  std::vector<std::string> result;
27472 
27473  while (iter != param_seq.end())
27474  {
27475  if (*iter == delimiter)
27476  {
27477  result.push_back(std::string(current_begin, iter));
27478  current_begin = ++iter;
27479  }
27480  else
27481  ++iter;
27482  }
27483 
27484  if (current_begin != iter)
27485  {
27486  result.push_back(std::string(current_begin, iter));
27487  }
27488 
27489  return result;
27490  }
27491 
27492  inline bool is_valid_token(std::string param_seq,
27493  function_prototype_t& funcproto) const
27494  {
27495  // Determine return type
27496  funcproto.return_type = default_return_type_;
27497 
27498  if (param_seq.size() > 2)
27499  {
27500  if (':' == param_seq[1])
27501  {
27502  // Note: Only overloaded igeneric functions can have return
27503  // type definitions.
27504  if (type_checker::e_overload != default_return_type_)
27505  return false;
27506 
27507  switch (param_seq[0])
27508  {
27509  case 'T' : funcproto.return_type = type_checker::e_numeric;
27510  break;
27511 
27512  case 'S' : funcproto.return_type = type_checker::e_string;
27513  break;
27514 
27515  default : return false;
27516  }
27517 
27518  param_seq.erase(0,2);
27519  }
27520  }
27521 
27522  if (
27523  (std::string::npos != param_seq.find("?*")) ||
27524  (std::string::npos != param_seq.find("**"))
27525  )
27526  {
27527  return false;
27528  }
27529  else if (
27530  (std::string::npos == param_seq.find_first_not_of("STV*?|")) ||
27531  ("Z" == param_seq)
27532  )
27533  {
27534  funcproto.param_seq = param_seq;
27535  return true;
27536  }
27537 
27538  return false;
27539  }
27540 
27541  void parse_function_prototypes(const std::string& func_prototypes)
27542  {
27543  if (func_prototypes.empty())
27544  return;
27545 
27546  std::vector<std::string> param_seq_list = split_param_seq(func_prototypes);
27547 
27548  typedef std::map<std::string,std::size_t> param_seq_map_t;
27549  param_seq_map_t param_seq_map;
27550 
27551  for (std::size_t i = 0; i < param_seq_list.size(); ++i)
27552  {
27553  function_prototype_t func_proto;
27554 
27555  if (!is_valid_token(param_seq_list[i], func_proto))
27556  {
27557  invalid_state_ = false;
27558 
27559  parser_.set_error(make_error(
27561  parser_.current_token(),
27562  "ERR132 - Invalid parameter sequence of '" + param_seq_list[i] +
27563  "' for function: " + function_name_,
27565  return;
27566  }
27567 
27568  param_seq_map_t::const_iterator seq_itr = param_seq_map.find(param_seq_list[i]);
27569 
27570  if (param_seq_map.end() != seq_itr)
27571  {
27572  invalid_state_ = false;
27573 
27574  parser_.set_error(make_error(
27576  parser_.current_token(),
27577  "ERR133 - Function '" + function_name_ + "' has a parameter sequence conflict between " +
27578  "pseq_idx[" + details::to_str(seq_itr->second) + "] and" +
27579  "pseq_idx[" + details::to_str(i) + "] " +
27580  "param seq: " + param_seq_list[i],
27582  return;
27583  }
27584 
27585  function_definition_list_.push_back(func_proto);
27586  }
27587  }
27588 
27591 
27594  std::string function_name_;
27597  };
27598 
27599  inline expression_node_ptr parse_generic_function_call(igeneric_function<T>* function, const std::string& function_name)
27600  {
27601  std::vector<expression_node_ptr> arg_list;
27602 
27603  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
27604 
27605  next_token();
27606 
27607  std::string param_type_list;
27608 
27609  type_checker tc(
27610  (*this),
27611  function_name,
27612  function->parameter_sequence,
27613  type_checker::e_string);
27614 
27615  if (tc.invalid())
27616  {
27617  set_error(make_error(
27619  current_token(),
27620  "ERR134 - Type checker instantiation failure for generic function: " + function_name,
27622 
27623  return error_node();
27624  }
27625 
27626  if (token_is(token_t::e_lbracket))
27627  {
27628  if (token_is(token_t::e_rbracket))
27629  {
27630  if (
27631  !function->allow_zero_parameters() &&
27632  !tc .allow_zero_parameters()
27633  )
27634  {
27635  set_error(make_error(
27637  current_token(),
27638  "ERR135 - Zero parameter call to generic function: "
27639  + function_name + " not allowed",
27641 
27642  return error_node();
27643  }
27644  }
27645  else
27646  {
27647  for ( ; ; )
27648  {
27649  expression_node_ptr arg = parse_expression();
27650 
27651  if (0 == arg)
27652  return error_node();
27653 
27654  if (is_ivector_node(arg))
27655  param_type_list += 'V';
27656  else if (is_generally_string_node(arg))
27657  param_type_list += 'S';
27658  else // Everything else is assumed to be a scalar returning expression
27659  param_type_list += 'T';
27660 
27661  arg_list.push_back(arg);
27662 
27663  if (token_is(token_t::e_rbracket))
27664  break;
27665  else if (!token_is(token_t::e_comma))
27666  {
27667  set_error(make_error(
27669  current_token(),
27670  "ERR136 - Expected ',' for call to generic function: " + function_name,
27672 
27673  return error_node();
27674  }
27675  }
27676  }
27677  }
27678  else if (
27679  !function->parameter_sequence.empty() &&
27680  function->allow_zero_parameters () &&
27681  !tc .allow_zero_parameters ()
27682  )
27683  {
27684  set_error(make_error(
27686  current_token(),
27687  "ERR137 - Zero parameter call to generic function: "
27688  + function_name + " not allowed",
27690 
27691  return error_node();
27692  }
27693 
27694  std::size_t param_seq_index = 0;
27695 
27696  if (
27697  state_.type_check_enabled &&
27698  !tc.verify(param_type_list, param_seq_index)
27699  )
27700  {
27701  set_error(make_error(
27703  current_token(),
27704  "ERR138 - Invalid input parameter sequence for call to generic function: " + function_name,
27706 
27707  return error_node();
27708  }
27709 
27710  expression_node_ptr result = error_node();
27711 
27712  result = (tc.paramseq_count() <= 1) ?
27713  expression_generator_
27714  .generic_function_call(function, arg_list) :
27715  expression_generator_
27716  .generic_function_call(function, arg_list, param_seq_index);
27717 
27718  sdd.delete_ptr = (0 == result);
27719 
27720  return result;
27721  }
27722 
27723  inline bool parse_igeneric_function_params(std::string& param_type_list,
27724  std::vector<expression_node_ptr>& arg_list,
27725  const std::string& function_name,
27726  igeneric_function<T>* function,
27727  const type_checker& tc)
27728  {
27729  if (token_is(token_t::e_lbracket))
27730  {
27731  if (token_is(token_t::e_rbracket))
27732  {
27733  if (
27734  !function->allow_zero_parameters() &&
27735  !tc .allow_zero_parameters()
27736  )
27737  {
27738  set_error(make_error(
27740  current_token(),
27741  "ERR139 - Zero parameter call to generic function: "
27742  + function_name + " not allowed",
27744 
27745  return false;
27746  }
27747  }
27748  else
27749  {
27750  for ( ; ; )
27751  {
27752  expression_node_ptr arg = parse_expression();
27753 
27754  if (0 == arg)
27755  return false;
27756 
27757  if (is_ivector_node(arg))
27758  param_type_list += 'V';
27759  else if (is_generally_string_node(arg))
27760  param_type_list += 'S';
27761  else // Everything else is a scalar returning expression
27762  param_type_list += 'T';
27763 
27764  arg_list.push_back(arg);
27765 
27766  if (token_is(token_t::e_rbracket))
27767  break;
27768  else if (!token_is(token_t::e_comma))
27769  {
27770  set_error(make_error(
27772  current_token(),
27773  "ERR140 - Expected ',' for call to string function: " + function_name,
27775 
27776  return false;
27777  }
27778  }
27779  }
27780 
27781  return true;
27782  }
27783  else
27784  return false;
27785  }
27786 
27787  #ifndef exprtk_disable_string_capabilities
27788  inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name)
27789  {
27790  // Move pass the function name
27791  next_token();
27792 
27793  std::string param_type_list;
27794 
27795  type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string);
27796 
27797  if (
27798  (!function->parameter_sequence.empty()) &&
27799  (0 == tc.paramseq_count())
27800  )
27801  {
27802  return error_node();
27803  }
27804 
27805  std::vector<expression_node_ptr> arg_list;
27806  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
27807 
27808  if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc))
27809  {
27810  return error_node();
27811  }
27812 
27813  std::size_t param_seq_index = 0;
27814 
27815  if (!tc.verify(param_type_list, param_seq_index))
27816  {
27817  set_error(make_error(
27819  current_token(),
27820  "ERR141 - Invalid input parameter sequence for call to string function: " + function_name,
27822 
27823  return error_node();
27824  }
27825 
27826  expression_node_ptr result = error_node();
27827 
27828  result = (tc.paramseq_count() <= 1) ?
27829  expression_generator_
27830  .string_function_call(function, arg_list) :
27831  expression_generator_
27832  .string_function_call(function, arg_list, param_seq_index);
27833 
27834  sdd.delete_ptr = (0 == result);
27835 
27836  return result;
27837  }
27838 
27839  inline expression_node_ptr parse_overload_function_call(igeneric_function<T>* function, const std::string& function_name)
27840  {
27841  // Move pass the function name
27842  next_token();
27843 
27844  std::string param_type_list;
27845 
27846  type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_overload);
27847 
27848  if (
27849  (!function->parameter_sequence.empty()) &&
27850  (0 == tc.paramseq_count())
27851  )
27852  {
27853  return error_node();
27854  }
27855 
27856  std::vector<expression_node_ptr> arg_list;
27857  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
27858 
27859  if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc))
27860  {
27861  return error_node();
27862  }
27863 
27864  std::size_t param_seq_index = 0;
27865 
27866  if (!tc.verify(param_type_list, param_seq_index))
27867  {
27868  set_error(make_error(
27870  current_token(),
27871  "ERR142 - Invalid input parameter sequence for call to overloaded function: " + function_name,
27873 
27874  return error_node();
27875  }
27876 
27877  expression_node_ptr result = error_node();
27878 
27879  if (type_checker::e_numeric == tc.return_type(param_seq_index))
27880  {
27881  if (tc.paramseq_count() <= 1)
27882  result = expression_generator_
27883  .generic_function_call(function, arg_list);
27884  else
27885  result = expression_generator_
27886  .generic_function_call(function, arg_list, param_seq_index);
27887  }
27888  else if (type_checker::e_string == tc.return_type(param_seq_index))
27889  {
27890  if (tc.paramseq_count() <= 1)
27891  result = expression_generator_
27892  .string_function_call(function, arg_list);
27893  else
27894  result = expression_generator_
27895  .string_function_call(function, arg_list, param_seq_index);
27896  }
27897  else
27898  {
27899  set_error(make_error(
27901  current_token(),
27902  "ERR143 - Invalid return type for call to overloaded function: " + function_name,
27904  }
27905 
27906  sdd.delete_ptr = (0 == result);
27907  return result;
27908  }
27909  #endif
27910 
27911  template <typename Type, std::size_t NumberOfParameters>
27913  {
27914  static inline expression_node_ptr process(parser<Type>& p, const details::operator_type opt_type, const std::string& sf_name)
27915  {
27916  expression_node_ptr branch[NumberOfParameters];
27917  expression_node_ptr result = error_node();
27918 
27919  std::fill_n(branch, NumberOfParameters, reinterpret_cast<expression_node_ptr>(0));
27920 
27922 
27923  p.next_token();
27924 
27925  if (!p.token_is(token_t::e_lbracket))
27926  {
27929  p.current_token(),
27930  "ERR144 - Expected '(' for special function '" + sf_name + "'",
27932 
27933  return error_node();
27934  }
27935 
27936  for (std::size_t i = 0; i < NumberOfParameters; ++i)
27937  {
27938  branch[i] = p.parse_expression();
27939 
27940  if (0 == branch[i])
27941  {
27942  return p.error_node();
27943  }
27944  else if (i < (NumberOfParameters - 1))
27945  {
27946  if (!p.token_is(token_t::e_comma))
27947  {
27950  p.current_token(),
27951  "ERR145 - Expected ',' before next parameter of special function '" + sf_name + "'",
27953 
27954  return p.error_node();
27955  }
27956  }
27957  }
27958 
27959  if (!p.token_is(token_t::e_rbracket))
27960  {
27963  p.current_token(),
27964  "ERR146 - Invalid number of parameters for special function '" + sf_name + "'",
27966 
27967  return p.error_node();
27968  }
27969  else
27970  result = p.expression_generator_.special_function(opt_type,branch);
27971 
27972  sd.delete_ptr = (0 == result);
27973 
27974  return result;
27975  }
27976  };
27977 
27979  {
27980  const std::string sf_name = current_token().value;
27981 
27982  // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
27983  if (
27984  !details::is_digit(sf_name[2]) ||
27985  !details::is_digit(sf_name[3])
27986  )
27987  {
27988  set_error(make_error(
27990  current_token(),
27991  "ERR147 - Invalid special function[1]: " + sf_name,
27993 
27994  return error_node();
27995  }
27996 
27997  const int id = (sf_name[2] - '0') * 10 +
27998  (sf_name[3] - '0');
27999 
28000  if (id >= details::e_sffinal)
28001  {
28002  set_error(make_error(
28004  current_token(),
28005  "ERR148 - Invalid special function[2]: " + sf_name,
28007 
28008  return error_node();
28009  }
28010 
28011  const int sf_3_to_4 = details::e_sf48;
28012  const details::operator_type opt_type = details::operator_type(id + 1000);
28013  const std::size_t NumberOfParameters = (id < (sf_3_to_4 - 1000)) ? 3U : 4U;
28014 
28015  switch (NumberOfParameters)
28016  {
28017  case 3 : return parse_special_function_impl<T,3>::process((*this), opt_type, sf_name);
28018  case 4 : return parse_special_function_impl<T,4>::process((*this), opt_type, sf_name);
28019  default : return error_node();
28020  }
28021  }
28022 
28024  {
28025  next_token();
28026  return node_allocator_.allocate<details::null_node<T> >();
28027  }
28028 
28029  #ifndef exprtk_disable_break_continue
28031  {
28032  if (state_.parsing_break_stmt)
28033  {
28034  set_error(make_error(
28036  current_token(),
28037  "ERR149 - Invoking 'break' within a break call is not allowed",
28039 
28040  return error_node();
28041  }
28042  else if (0 == state_.parsing_loop_stmt_count)
28043  {
28044  set_error(make_error(
28046  current_token(),
28047  "ERR150 - Invalid use of 'break', allowed only in the scope of a loop",
28049 
28050  return error_node();
28051  }
28052 
28053  scoped_bool_negator sbn(state_.parsing_break_stmt);
28054 
28055  if (!brkcnt_list_.empty())
28056  {
28057  next_token();
28058 
28059  brkcnt_list_.front() = true;
28060 
28061  expression_node_ptr return_expr = error_node();
28062 
28063  if (token_is(token_t::e_lsqrbracket))
28064  {
28065  if (0 == (return_expr = parse_expression()))
28066  {
28067  set_error(make_error(
28069  current_token(),
28070  "ERR151 - Failed to parse return expression for 'break' statement",
28072 
28073  return error_node();
28074  }
28075  else if (!token_is(token_t::e_rsqrbracket))
28076  {
28077  set_error(make_error(
28079  current_token(),
28080  "ERR152 - Expected ']' at the completion of break's return expression",
28082 
28083  free_node(node_allocator_,return_expr);
28084 
28085  return error_node();
28086  }
28087  }
28088 
28089  state_.activate_side_effect("parse_break_statement()");
28090 
28091  return node_allocator_.allocate<details::break_node<T> >(return_expr);
28092  }
28093  else
28094  {
28095  set_error(make_error(
28097  current_token(),
28098  "ERR153 - Invalid use of 'break', allowed only in the scope of a loop",
28100  }
28101 
28102  return error_node();
28103  }
28104 
28106  {
28107  if (0 == state_.parsing_loop_stmt_count)
28108  {
28109  set_error(make_error(
28111  current_token(),
28112  "ERR154 - Invalid use of 'continue', allowed only in the scope of a loop",
28114 
28115  return error_node();
28116  }
28117  else
28118  {
28119  next_token();
28120 
28121  brkcnt_list_.front() = true;
28122  state_.activate_side_effect("parse_continue_statement()");
28123 
28124  return node_allocator_.allocate<details::continue_node<T> >();
28125  }
28126  }
28127  #endif
28128 
28129  inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name)
28130  {
28131  expression_node_ptr size_expression_node = error_node();
28132 
28133  if (!token_is(token_t::e_lsqrbracket))
28134  {
28135  set_error(make_error(
28137  current_token(),
28138  "ERR155 - Expected '[' as part of vector size definition",
28140 
28141  return error_node();
28142  }
28143  else if (0 == (size_expression_node = parse_expression()))
28144  {
28145  set_error(make_error(
28147  current_token(),
28148  "ERR156 - Failed to determine size of vector '" + vec_name + "'",
28150 
28151  return error_node();
28152  }
28153  else if (!is_constant_node(size_expression_node))
28154  {
28155  const bool is_rebaseble_vector =
28156  (size_expression_node->type() == details::expression_node<T>::e_vecsize) &&
28157  static_cast<details::vector_size_node<T>*>(size_expression_node)->vec_holder()->rebaseable();
28158 
28159  free_node(node_allocator_,size_expression_node);
28160 
28161  const std::string error_msg = (is_rebaseble_vector) ?
28162  std::string("Rebasable/Resizable vector cannot be used to define the size of vector") :
28163  std::string("Expected a constant literal number as size of vector");
28164  set_error(make_error(
28166  current_token(),
28167  "ERR157 - " + error_msg + " '" + vec_name + "'",
28169 
28170  return error_node();
28171  }
28172 
28173  const T vector_size = size_expression_node->value();
28174 
28175  free_node(node_allocator_,size_expression_node);
28176 
28177  const std::size_t max_vector_size = settings_.max_local_vector_size();
28178 
28179  if (
28180  (vector_size <= T(0)) ||
28181  std::not_equal_to<T>()
28182  (T(0),vector_size - details::numeric::trunc(vector_size)) ||
28183  (static_cast<std::size_t>(vector_size) > max_vector_size)
28184  )
28185  {
28186  set_error(make_error(
28188  current_token(),
28189  "ERR158 - Invalid vector size. Must be an integer in the "
28190  "range [0," + details::to_str(static_cast<std::size_t>(max_vector_size)) + "], size: " +
28193 
28194  return error_node();
28195  }
28196 
28197  std::vector<expression_node_ptr> vec_initilizer_list;
28198 
28199  scoped_vec_delete<expression_node_t> svd((*this),vec_initilizer_list);
28200 
28201  bool single_value_initialiser = false;
28202  bool vec_to_vec_initialiser = false;
28203  bool null_initialisation = false;
28204 
28205  if (!token_is(token_t::e_rsqrbracket))
28206  {
28207  set_error(make_error(
28209  current_token(),
28210  "ERR159 - Expected ']' as part of vector size definition",
28212 
28213  return error_node();
28214  }
28215  else if (!token_is(token_t::e_eof))
28216  {
28217  if (!token_is(token_t::e_assign))
28218  {
28219  set_error(make_error(
28221  current_token(),
28222  "ERR160 - Expected ':=' as part of vector definition",
28224 
28225  return error_node();
28226  }
28227  else if (token_is(token_t::e_lsqrbracket))
28228  {
28229  expression_node_ptr initialiser = parse_expression();
28230 
28231  if (0 == initialiser)
28232  {
28233  set_error(make_error(
28235  current_token(),
28236  "ERR161 - Failed to parse single vector initialiser",
28238 
28239  return error_node();
28240  }
28241 
28242  vec_initilizer_list.push_back(initialiser);
28243 
28244  if (!token_is(token_t::e_rsqrbracket))
28245  {
28246  set_error(make_error(
28248  current_token(),
28249  "ERR162 - Expected ']' to close single value vector initialiser",
28251 
28252  return error_node();
28253  }
28254 
28255  single_value_initialiser = true;
28256  }
28257  else if (!token_is(token_t::e_lcrlbracket))
28258  {
28259  expression_node_ptr initialiser = error_node();
28260 
28261  // Is this a vector to vector assignment and initialisation?
28262  if (token_t::e_symbol == current_token().type)
28263  {
28264  // Is it a locally defined vector?
28265  const scope_element& se = sem_.get_active_element(current_token().value);
28266 
28267  if (scope_element::e_vector == se.type)
28268  {
28269  if (0 != (initialiser = parse_expression()))
28270  vec_initilizer_list.push_back(initialiser);
28271  else
28272  return error_node();
28273  }
28274  // Are we dealing with a user defined vector?
28275  else if (symtab_store_.is_vector(current_token().value))
28276  {
28277  lodge_symbol(current_token().value, e_st_vector);
28278 
28279  if (0 != (initialiser = parse_expression()))
28280  vec_initilizer_list.push_back(initialiser);
28281  else
28282  return error_node();
28283  }
28284  // Are we dealing with a null initialisation vector definition?
28285  else if (token_is(token_t::e_symbol,"null"))
28286  null_initialisation = true;
28287  }
28288 
28289  if (!null_initialisation)
28290  {
28291  if (0 == initialiser)
28292  {
28293  set_error(make_error(
28295  current_token(),
28296  "ERR163 - Expected '{' as part of vector initialiser list",
28298 
28299  return error_node();
28300  }
28301  else
28302  vec_to_vec_initialiser = true;
28303  }
28304  }
28305  else if (!token_is(token_t::e_rcrlbracket))
28306  {
28307  for ( ; ; )
28308  {
28309  expression_node_ptr initialiser = parse_expression();
28310 
28311  if (0 == initialiser)
28312  {
28313  set_error(make_error(
28315  current_token(),
28316  "ERR164 - Expected '{' as part of vector initialiser list",
28318 
28319  return error_node();
28320  }
28321  else
28322  vec_initilizer_list.push_back(initialiser);
28323 
28324  if (token_is(token_t::e_rcrlbracket))
28325  break;
28326 
28327  const bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
28328 
28329  if (!token_is(token_t::e_comma) && is_next_close)
28330  {
28331  set_error(make_error(
28333  current_token(),
28334  "ERR165 - Expected ',' between vector initialisers",
28336 
28337  return error_node();
28338  }
28339 
28340  if (token_is(token_t::e_rcrlbracket))
28341  break;
28342  }
28343  }
28344 
28345  if (
28346  !token_is(token_t::e_rbracket , prsrhlpr_t::e_hold) &&
28347  !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) &&
28348  !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold)
28349  )
28350  {
28351  if (!token_is(token_t::e_eof))
28352  {
28353  set_error(make_error(
28355  current_token(),
28356  "ERR166 - Expected ';' at end of vector definition",
28358 
28359  return error_node();
28360  }
28361  }
28362 
28363  if (T(vec_initilizer_list.size()) > vector_size)
28364  {
28365  set_error(make_error(
28367  current_token(),
28368  "ERR167 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
28370 
28371  return error_node();
28372  }
28373  }
28374 
28375  typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0);
28376 
28377  const std::size_t vec_size = static_cast<std::size_t>(details::numeric::to_int32(vector_size));
28378 
28379  scope_element& se = sem_.get_element(vec_name);
28380 
28381  if (se.name == vec_name)
28382  {
28383  if (se.active)
28384  {
28385  set_error(make_error(
28387  current_token(),
28388  "ERR168 - Illegal redefinition of local vector: '" + vec_name + "'",
28390 
28391  return error_node();
28392  }
28393  else if (
28394  (se.size == vec_size) &&
28395  (scope_element::e_vector == se.type)
28396  )
28397  {
28398  vec_holder = se.vec_node;
28399  se.active = true;
28400  se.depth = state_.scope_depth;
28401  se.ref_count++;
28402  }
28403  }
28404 
28405  if (0 == vec_holder)
28406  {
28407  scope_element nse;
28408  nse.name = vec_name;
28409  nse.active = true;
28410  nse.ref_count = 1;
28411  nse.type = scope_element::e_vector;
28412  nse.depth = state_.scope_depth;
28413  nse.size = vec_size;
28414  nse.data = new T[vec_size];
28415  nse.vec_node = new typename scope_element::vector_holder_t(reinterpret_cast<T*>(nse.data),nse.size);
28416 
28417  std::memset(nse.data, 0x00, vec_size * sizeof(T));
28418 
28419  if (!sem_.add_element(nse))
28420  {
28421  set_error(make_error(
28423  current_token(),
28424  "ERR169 - Failed to add new local vector '" + vec_name + "' to SEM",
28426 
28427  sem_.free_element(nse);
28428 
28429  return error_node();
28430  }
28431 
28432  vec_holder = nse.vec_node;
28433 
28434  exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n",
28435  nse.name.c_str(),
28436  static_cast<int>(nse.size)));
28437  }
28438 
28439  state_.activate_side_effect("parse_define_vector_statement()");
28440 
28441  lodge_symbol(vec_name, e_st_local_vector);
28442 
28443  expression_node_ptr result = error_node();
28444 
28445  if (!single_value_initialiser && vec_initilizer_list.empty())
28446  {
28447  single_value_initialiser = true;
28448  assert(vec_initilizer_list.size() <= 1);
28449  }
28450 
28451  if (null_initialisation)
28452  result = expression_generator_(T(0.0));
28453  else if (vec_to_vec_initialiser)
28454  {
28455  expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec_holder);
28456 
28457  result = expression_generator_(
28459  vec_node,
28460  vec_initilizer_list[0]);
28461  }
28462  else
28463  result = node_allocator_
28464  .allocate<details::vector_assignment_node<T> >(
28465  (*vec_holder)[0],
28466  vec_size,
28467  vec_initilizer_list,
28468  single_value_initialiser);
28469 
28470  svd.delete_ptr = (0 == result);
28471 
28472  return result;
28473  }
28474 
28475  #ifndef exprtk_disable_string_capabilities
28476  inline expression_node_ptr parse_define_string_statement(const std::string& str_name, expression_node_ptr initialisation_expression)
28477  {
28478  stringvar_node_t* str_node = reinterpret_cast<stringvar_node_t*>(0);
28479 
28480  scope_element& se = sem_.get_element(str_name);
28481 
28482  if (se.name == str_name)
28483  {
28484  if (se.active)
28485  {
28486  set_error(make_error(
28488  current_token(),
28489  "ERR170 - Illegal redefinition of local variable: '" + str_name + "'",
28491 
28492  free_node(node_allocator_,initialisation_expression);
28493 
28494  return error_node();
28495  }
28496  else if (scope_element::e_string == se.type)
28497  {
28498  str_node = se.str_node;
28499  se.active = true;
28500  se.depth = state_.scope_depth;
28501  se.ref_count++;
28502  }
28503  }
28504 
28505  if (0 == str_node)
28506  {
28507  scope_element nse;
28508  nse.name = str_name;
28509  nse.active = true;
28510  nse.ref_count = 1;
28511  nse.type = scope_element::e_string;
28512  nse.depth = state_.scope_depth;
28513  nse.data = new std::string;
28514  nse.str_node = new stringvar_node_t(*reinterpret_cast<std::string*>(nse.data));
28515 
28516  if (!sem_.add_element(nse))
28517  {
28518  set_error(make_error(
28520  current_token(),
28521  "ERR171 - Failed to add new local string variable '" + str_name + "' to SEM",
28523 
28524  free_node(node_allocator_,initialisation_expression);
28525 
28526  sem_.free_element(nse);
28527 
28528  return error_node();
28529  }
28530 
28531  str_node = nse.str_node;
28532 
28533  exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n", nse.name.c_str()));
28534  }
28535 
28536  lodge_symbol(str_name, e_st_local_string);
28537 
28538  state_.activate_side_effect("parse_define_string_statement()");
28539 
28540  expression_node_ptr branch[2] = {0};
28541 
28542  branch[0] = str_node;
28543  branch[1] = initialisation_expression;
28544 
28545  return expression_generator_(details::e_assign,branch);
28546  }
28547  #else
28548  inline expression_node_ptr parse_define_string_statement(const std::string&, expression_node_ptr)
28549  {
28550  return error_node();
28551  }
28552  #endif
28553 
28554  inline bool local_variable_is_shadowed(const std::string& symbol)
28555  {
28556  const scope_element& se = sem_.get_element(symbol);
28557  return (se.name == symbol) && se.active;
28558  }
28559 
28561  {
28562  if (settings_.vardef_disabled())
28563  {
28564  set_error(make_error(
28566  current_token(),
28567  "ERR172 - Illegal variable definition",
28569 
28570  return error_node();
28571  }
28572  else if (!details::imatch(current_token().value,"var"))
28573  {
28574  return error_node();
28575  }
28576  else
28577  next_token();
28578 
28579  const std::string var_name = current_token().value;
28580 
28581  expression_node_ptr initialisation_expression = error_node();
28582 
28583  if (!token_is(token_t::e_symbol))
28584  {
28585  set_error(make_error(
28587  current_token(),
28588  "ERR173 - Expected a symbol for variable definition",
28590 
28591  return error_node();
28592  }
28593  else if (details::is_reserved_symbol(var_name))
28594  {
28595  set_error(make_error(
28597  current_token(),
28598  "ERR174 - Illegal redefinition of reserved keyword: '" + var_name + "'",
28600 
28601  return error_node();
28602  }
28603  else if (symtab_store_.symbol_exists(var_name))
28604  {
28605  set_error(make_error(
28607  current_token(),
28608  "ERR175 - Illegal redefinition of variable '" + var_name + "'",
28610 
28611  return error_node();
28612  }
28613  else if (local_variable_is_shadowed(var_name))
28614  {
28615  set_error(make_error(
28617  current_token(),
28618  "ERR176 - Illegal redefinition of local variable: '" + var_name + "'",
28620 
28621  return error_node();
28622  }
28623  else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold))
28624  {
28625  return parse_define_vector_statement(var_name);
28626  }
28627  else if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
28628  {
28629  return parse_uninitialised_var_statement(var_name);
28630  }
28631  else if (token_is(token_t::e_assign))
28632  {
28633  if (0 == (initialisation_expression = parse_expression()))
28634  {
28635  set_error(make_error(
28637  current_token(),
28638  "ERR177 - Failed to parse initialisation expression",
28640 
28641  return error_node();
28642  }
28643  }
28644 
28645  if (
28646  !token_is(token_t::e_rbracket , prsrhlpr_t::e_hold) &&
28647  !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) &&
28648  !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold)
28649  )
28650  {
28651  if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
28652  {
28653  set_error(make_error(
28655  current_token(),
28656  "ERR178 - Expected ';' after variable definition",
28658 
28659  free_node(node_allocator_,initialisation_expression);
28660 
28661  return error_node();
28662  }
28663  }
28664 
28665  if (
28666  (0 != initialisation_expression) &&
28667  details::is_generally_string_node(initialisation_expression)
28668  )
28669  {
28670  return parse_define_string_statement(var_name,initialisation_expression);
28671  }
28672 
28673  expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
28674 
28675  scope_element& se = sem_.get_element(var_name);
28676 
28677  if (se.name == var_name)
28678  {
28679  if (se.active)
28680  {
28681  set_error(make_error(
28683  current_token(),
28684  "ERR179 - Illegal redefinition of local variable: '" + var_name + "'",
28686 
28687  free_node(node_allocator_, initialisation_expression);
28688 
28689  return error_node();
28690  }
28691  else if (scope_element::e_variable == se.type)
28692  {
28693  var_node = se.var_node;
28694  se.active = true;
28695  se.depth = state_.scope_depth;
28696  se.ref_count++;
28697  }
28698  }
28699 
28700  if (0 == var_node)
28701  {
28702  scope_element nse;
28703  nse.name = var_name;
28704  nse.active = true;
28705  nse.ref_count = 1;
28706  nse.type = scope_element::e_variable;
28707  nse.depth = state_.scope_depth;
28708  nse.data = new T(T(0));
28709  nse.var_node = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data));
28710 
28711  if (!sem_.add_element(nse))
28712  {
28713  set_error(make_error(
28715  current_token(),
28716  "ERR180 - Failed to add new local variable '" + var_name + "' to SEM",
28718 
28719  free_node(node_allocator_, initialisation_expression);
28720 
28721  sem_.free_element(nse);
28722 
28723  return error_node();
28724  }
28725 
28726  var_node = nse.var_node;
28727 
28728  exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n", nse.name.c_str()));
28729  }
28730 
28731  state_.activate_side_effect("parse_define_var_statement()");
28732 
28733  lodge_symbol(var_name, e_st_local_variable);
28734 
28735  expression_node_ptr branch[2] = {0};
28736 
28737  branch[0] = var_node;
28738  branch[1] = initialisation_expression ? initialisation_expression : expression_generator_(T(0));
28739 
28740  return expression_generator_(details::e_assign,branch);
28741  }
28742 
28743  inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name)
28744  {
28745  if (
28746  !token_is(token_t::e_lcrlbracket) ||
28747  !token_is(token_t::e_rcrlbracket)
28748  )
28749  {
28750  set_error(make_error(
28752  current_token(),
28753  "ERR181 - Expected a '{}' for uninitialised var definition",
28755 
28756  return error_node();
28757  }
28758  else if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
28759  {
28760  set_error(make_error(
28762  current_token(),
28763  "ERR182 - Expected ';' after uninitialised variable definition",
28765 
28766  return error_node();
28767  }
28768 
28769  expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
28770 
28771  scope_element& se = sem_.get_element(var_name);
28772 
28773  if (se.name == var_name)
28774  {
28775  if (se.active)
28776  {
28777  set_error(make_error(
28779  current_token(),
28780  "ERR183 - Illegal redefinition of local variable: '" + var_name + "'",
28782 
28783  return error_node();
28784  }
28785  else if (scope_element::e_variable == se.type)
28786  {
28787  var_node = se.var_node;
28788  se.active = true;
28789  se.ref_count++;
28790  }
28791  }
28792 
28793  if (0 == var_node)
28794  {
28795  scope_element nse;
28796  nse.name = var_name;
28797  nse.active = true;
28798  nse.ref_count = 1;
28799  nse.type = scope_element::e_variable;
28800  nse.depth = state_.scope_depth;
28801  nse.ip_index = sem_.next_ip_index();
28802  nse.data = new T(T(0));
28803  nse.var_node = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data));
28804 
28805  if (!sem_.add_element(nse))
28806  {
28807  set_error(make_error(
28809  current_token(),
28810  "ERR184 - Failed to add new local variable '" + var_name + "' to SEM",
28812 
28813  sem_.free_element(nse);
28814 
28815  return error_node();
28816  }
28817 
28818  exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n",
28819  nse.name.c_str()));
28820  }
28821 
28822  lodge_symbol(var_name, e_st_local_variable);
28823 
28824  state_.activate_side_effect("parse_uninitialised_var_statement()");
28825 
28826  return expression_generator_(T(0));
28827  }
28828 
28830  {
28831  if (!details::imatch(current_token().value,"swap"))
28832  {
28833  return error_node();
28834  }
28835  else
28836  next_token();
28837 
28838  if (!token_is(token_t::e_lbracket))
28839  {
28840  set_error(make_error(
28842  current_token(),
28843  "ERR185 - Expected '(' at start of swap statement",
28845 
28846  return error_node();
28847  }
28848 
28849  expression_node_ptr variable0 = error_node();
28850  expression_node_ptr variable1 = error_node();
28851 
28852  bool variable0_generated = false;
28853  bool variable1_generated = false;
28854 
28855  const std::string var0_name = current_token().value;
28856 
28857  if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
28858  {
28859  set_error(make_error(
28861  current_token(),
28862  "ERR186 - Expected a symbol for variable or vector element definition",
28864 
28865  return error_node();
28866  }
28867  else if (peek_token_is(token_t::e_lsqrbracket))
28868  {
28869  if (0 == (variable0 = parse_vector()))
28870  {
28871  set_error(make_error(
28873  current_token(),
28874  "ERR187 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
28876 
28877  return error_node();
28878  }
28879 
28880  variable0_generated = true;
28881  }
28882  else
28883  {
28884  if (symtab_store_.is_variable(var0_name))
28885  {
28886  variable0 = symtab_store_.get_variable(var0_name);
28887  }
28888 
28889  const scope_element& se = sem_.get_element(var0_name);
28890 
28891  if (
28892  (se.active) &&
28893  (se.name == var0_name) &&
28894  (scope_element::e_variable == se.type)
28895  )
28896  {
28897  variable0 = se.var_node;
28898  }
28899 
28900  lodge_symbol(var0_name, e_st_variable);
28901 
28902  if (0 == variable0)
28903  {
28904  set_error(make_error(
28906  current_token(),
28907  "ERR188 - First parameter to swap is an invalid variable: '" + var0_name + "'",
28909 
28910  return error_node();
28911  }
28912  else
28913  next_token();
28914  }
28915 
28916  if (!token_is(token_t::e_comma))
28917  {
28918  set_error(make_error(
28920  current_token(),
28921  "ERR189 - Expected ',' between parameters to swap",
28923 
28924  if (variable0_generated)
28925  {
28926  free_node(node_allocator_,variable0);
28927  }
28928 
28929  return error_node();
28930  }
28931 
28932  const std::string var1_name = current_token().value;
28933 
28934  if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
28935  {
28936  set_error(make_error(
28938  current_token(),
28939  "ERR190 - Expected a symbol for variable or vector element definition",
28941 
28942  if (variable0_generated)
28943  {
28944  free_node(node_allocator_,variable0);
28945  }
28946 
28947  return error_node();
28948  }
28949  else if (peek_token_is(token_t::e_lsqrbracket))
28950  {
28951  if (0 == (variable1 = parse_vector()))
28952  {
28953  set_error(make_error(
28955  current_token(),
28956  "ERR191 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
28958 
28959  if (variable0_generated)
28960  {
28961  free_node(node_allocator_,variable0);
28962  }
28963 
28964  return error_node();
28965  }
28966 
28967  variable1_generated = true;
28968  }
28969  else
28970  {
28971  if (symtab_store_.is_variable(var1_name))
28972  {
28973  variable1 = symtab_store_.get_variable(var1_name);
28974  }
28975 
28976  const scope_element& se = sem_.get_element(var1_name);
28977 
28978  if (
28979  (se.active) &&
28980  (se.name == var1_name) &&
28981  (scope_element::e_variable == se.type)
28982  )
28983  {
28984  variable1 = se.var_node;
28985  }
28986 
28987  lodge_symbol(var1_name, e_st_variable);
28988 
28989  if (0 == variable1)
28990  {
28991  set_error(make_error(
28993  current_token(),
28994  "ERR192 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
28996 
28997  if (variable0_generated)
28998  {
28999  free_node(node_allocator_,variable0);
29000  }
29001 
29002  return error_node();
29003  }
29004  else
29005  next_token();
29006  }
29007 
29008  if (!token_is(token_t::e_rbracket))
29009  {
29010  set_error(make_error(
29012  current_token(),
29013  "ERR193 - Expected ')' at end of swap statement",
29015 
29016  if (variable0_generated)
29017  {
29018  free_node(node_allocator_,variable0);
29019  }
29020 
29021  if (variable1_generated)
29022  {
29023  free_node(node_allocator_,variable1);
29024  }
29025 
29026  return error_node();
29027  }
29028 
29029  typedef details::variable_node<T>* variable_node_ptr;
29030 
29031  variable_node_ptr v0 = variable_node_ptr(0);
29032  variable_node_ptr v1 = variable_node_ptr(0);
29033 
29034  expression_node_ptr result = error_node();
29035 
29036  if (
29037  (0 != (v0 = dynamic_cast<variable_node_ptr>(variable0))) &&
29038  (0 != (v1 = dynamic_cast<variable_node_ptr>(variable1)))
29039  )
29040  {
29041  result = node_allocator_.allocate<details::swap_node<T> >(v0, v1);
29042 
29043  if (variable0_generated)
29044  {
29045  free_node(node_allocator_,variable0);
29046  }
29047 
29048  if (variable1_generated)
29049  {
29050  free_node(node_allocator_,variable1);
29051  }
29052  }
29053  else
29054  result = node_allocator_.allocate<details::swap_generic_node<T> >
29055  (variable0, variable1);
29056 
29057  state_.activate_side_effect("parse_swap_statement()");
29058 
29059  return result;
29060  }
29061 
29062  #ifndef exprtk_disable_return_statement
29064  {
29065  if (state_.parsing_return_stmt)
29066  {
29067  set_error(make_error(
29069  current_token(),
29070  "ERR194 - Return call within a return call is not allowed",
29072 
29073  return error_node();
29074  }
29075 
29076  scoped_bool_negator sbn(state_.parsing_return_stmt);
29077 
29078  std::vector<expression_node_ptr> arg_list;
29079 
29080  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
29081 
29082  if (!details::imatch(current_token().value,"return"))
29083  {
29084  return error_node();
29085  }
29086  else
29087  next_token();
29088 
29089  if (!token_is(token_t::e_lsqrbracket))
29090  {
29091  set_error(make_error(
29093  current_token(),
29094  "ERR195 - Expected '[' at start of return statement",
29096 
29097  return error_node();
29098  }
29099  else if (!token_is(token_t::e_rsqrbracket))
29100  {
29101  for ( ; ; )
29102  {
29103  expression_node_ptr arg = parse_expression();
29104 
29105  if (0 == arg)
29106  return error_node();
29107 
29108  arg_list.push_back(arg);
29109 
29110  if (token_is(token_t::e_rsqrbracket))
29111  break;
29112  else if (!token_is(token_t::e_comma))
29113  {
29114  set_error(make_error(
29116  current_token(),
29117  "ERR196 - Expected ',' between values during call to return",
29119 
29120  return error_node();
29121  }
29122  }
29123  }
29124  else if (settings_.zero_return_disabled())
29125  {
29126  set_error(make_error(
29128  current_token(),
29129  "ERR197 - Zero parameter return statement not allowed",
29131 
29132  return error_node();
29133  }
29134 
29135  const lexer::token prev_token = current_token();
29136 
29137  if (token_is(token_t::e_rsqrbracket))
29138  {
29139  if (!arg_list.empty())
29140  {
29141  set_error(make_error(
29143  prev_token,
29144  "ERR198 - Invalid ']' found during return call",
29146 
29147  return error_node();
29148  }
29149  }
29150 
29151  std::string ret_param_type_list;
29152 
29153  for (std::size_t i = 0; i < arg_list.size(); ++i)
29154  {
29155  if (0 == arg_list[i])
29156  return error_node();
29157  else if (is_ivector_node(arg_list[i]))
29158  ret_param_type_list += 'V';
29159  else if (is_generally_string_node(arg_list[i]))
29160  ret_param_type_list += 'S';
29161  else
29162  ret_param_type_list += 'T';
29163  }
29164 
29165  dec_.retparam_list_.push_back(ret_param_type_list);
29166 
29167  expression_node_ptr result = expression_generator_.return_call(arg_list);
29168 
29169  sdd.delete_ptr = (0 == result);
29170 
29171  state_.return_stmt_present = true;
29172 
29173  state_.activate_side_effect("parse_return_statement()");
29174 
29175  return result;
29176  }
29177  #else
29178  inline expression_node_ptr parse_return_statement()
29179  {
29180  return error_node();
29181  }
29182  #endif
29183 
29184  inline bool post_variable_process(const std::string& symbol)
29185  {
29186  if (
29187  peek_token_is(token_t::e_lbracket ) ||
29188  peek_token_is(token_t::e_lcrlbracket) ||
29189  peek_token_is(token_t::e_lsqrbracket)
29190  )
29191  {
29192  if (!settings_.commutative_check_enabled())
29193  {
29194  set_error(make_error(
29196  current_token(),
29197  "ERR199 - Invalid sequence of variable '" + symbol + "' and bracket",
29199 
29200  return false;
29201  }
29202 
29203  lexer().insert_front(token_t::e_mul);
29204  }
29205 
29206  return true;
29207  }
29208 
29209  inline bool post_bracket_process(const typename token_t::token_type& token, expression_node_ptr& branch)
29210  {
29211  bool implied_mul = false;
29212 
29214  return true;
29215 
29216  const lexer::parser_helper::token_advance_mode hold = prsrhlpr_t::e_hold;
29217 
29218  switch (token)
29219  {
29220  case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket ,hold) ||
29221  token_is(token_t::e_lcrlbracket,hold) ||
29222  token_is(token_t::e_lsqrbracket,hold) ;
29223  break;
29224 
29225  case token_t::e_lbracket : implied_mul = token_is(token_t::e_lbracket ,hold) ||
29226  token_is(token_t::e_lcrlbracket,hold) ||
29227  token_is(token_t::e_lsqrbracket,hold) ;
29228  break;
29229 
29230  case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket ,hold) ||
29231  token_is(token_t::e_lcrlbracket,hold) ||
29232  token_is(token_t::e_lsqrbracket,hold) ;
29233  break;
29234 
29235  default : return true;
29236  }
29237 
29238  if (implied_mul)
29239  {
29240  if (!settings_.commutative_check_enabled())
29241  {
29242  set_error(make_error(
29244  current_token(),
29245  "ERR200 - Invalid sequence of brackets",
29247 
29248  return false;
29249  }
29250  else if (token_t::e_eof != current_token().type)
29251  {
29252  lexer().insert_front(current_token().type);
29253  lexer().insert_front(token_t::e_mul);
29254  next_token();
29255  }
29256  }
29257 
29258  return true;
29259  }
29260 
29263  typedef std::map<interval_t,token_t> immutable_symtok_map_t;
29264 
29265  inline interval_t make_memory_range(const T& t)
29266  {
29267  const T* begin = reinterpret_cast<const T*>(&t);
29268  const T* end = begin + 1;
29269  return interval_t(begin, end);
29270  }
29271 
29272  inline interval_t make_memory_range(const T* begin, const std::size_t size)
29273  {
29274  return interval_t(begin, begin + size);
29275  }
29276 
29277  inline interval_t make_memory_range(details::char_cptr begin, const std::size_t size)
29278  {
29279  return interval_t(begin, begin + size);
29280  }
29281 
29282  void lodge_immutable_symbol(const lexer::token& token, const interval_t interval)
29283  {
29284  immutable_memory_map_.add_interval(interval);
29285  immutable_symtok_map_[interval] = token;
29286  }
29287 
29289  {
29290  const std::string symbol = current_token().value;
29291 
29292  // Are we dealing with a variable or a special constant?
29293  typedef typename symtab_store::variable_context var_ctxt_t;
29294  var_ctxt_t var_ctx = symtab_store_.get_variable_context(symbol);
29295 
29296  if (var_ctx.variable)
29297  {
29298  assert(var_ctx.symbol_table);
29299 
29300  expression_node_ptr result_variable = var_ctx.variable;
29301 
29302  if (symtab_store_.is_constant_node(symbol))
29303  {
29304  result_variable = expression_generator_(var_ctx.variable->value());
29305  }
29306  else if (symbol_table_t::e_immutable == var_ctx.symbol_table->mutability())
29307  {
29308  lodge_immutable_symbol(current_token(), make_memory_range(var_ctx.variable->ref()));
29309  result_variable = var_ctx.variable;
29310  }
29311 
29312  if (!post_variable_process(symbol))
29313  return error_node();
29314 
29315  lodge_symbol(symbol, e_st_variable);
29316 
29317  next_token();
29318 
29319  return result_variable;
29320  }
29321 
29322  // Are we dealing with a locally defined variable, vector or string?
29323  if (!sem_.empty())
29324  {
29325  scope_element& se = sem_.get_active_element(symbol);
29326 
29327  if (se.active && details::imatch(se.name, symbol))
29328  {
29329  if (scope_element::e_variable == se.type)
29330  {
29331  se.active = true;
29332  lodge_symbol(symbol, e_st_local_variable);
29333 
29334  if (!post_variable_process(symbol))
29335  return error_node();
29336 
29337  next_token();
29338 
29339  return se.var_node;
29340  }
29341  else if (scope_element::e_vector == se.type)
29342  {
29343  return parse_vector();
29344  }
29345  #ifndef exprtk_disable_string_capabilities
29346  else if (scope_element::e_string == se.type)
29347  {
29348  return parse_string();
29349  }
29350  #endif
29351  }
29352  }
29353 
29354  #ifndef exprtk_disable_string_capabilities
29355  // Are we dealing with a string variable?
29356  if (symtab_store_.is_stringvar(symbol))
29357  {
29358  return parse_string();
29359  }
29360  #endif
29361 
29362  {
29363  // Are we dealing with a function?
29364  ifunction<T>* function = symtab_store_.get_function(symbol);
29365 
29366  if (function)
29367  {
29368  lodge_symbol(symbol, e_st_function);
29369 
29370  expression_node_ptr func_node =
29371  parse_function_invocation(function,symbol);
29372 
29373  if (func_node)
29374  return func_node;
29375  else
29376  {
29377  set_error(make_error(
29379  current_token(),
29380  "ERR201 - Failed to generate node for function: '" + symbol + "'",
29382 
29383  return error_node();
29384  }
29385  }
29386  }
29387 
29388  {
29389  // Are we dealing with a vararg function?
29390  ivararg_function<T>* vararg_function = symtab_store_.get_vararg_function(symbol);
29391 
29392  if (vararg_function)
29393  {
29394  lodge_symbol(symbol, e_st_function);
29395 
29396  expression_node_ptr vararg_func_node =
29397  parse_vararg_function_call(vararg_function, symbol);
29398 
29399  if (vararg_func_node)
29400  return vararg_func_node;
29401  else
29402  {
29403  set_error(make_error(
29405  current_token(),
29406  "ERR202 - Failed to generate node for vararg function: '" + symbol + "'",
29408 
29409  return error_node();
29410  }
29411  }
29412  }
29413 
29414  {
29415  // Are we dealing with a vararg generic function?
29416  igeneric_function<T>* generic_function = symtab_store_.get_generic_function(symbol);
29417 
29418  if (generic_function)
29419  {
29420  lodge_symbol(symbol, e_st_function);
29421 
29422  expression_node_ptr genericfunc_node =
29423  parse_generic_function_call(generic_function, symbol);
29424 
29425  if (genericfunc_node)
29426  return genericfunc_node;
29427  else
29428  {
29429  set_error(make_error(
29431  current_token(),
29432  "ERR203 - Failed to generate node for generic function: '" + symbol + "'",
29434 
29435  return error_node();
29436  }
29437  }
29438  }
29439 
29440  #ifndef exprtk_disable_string_capabilities
29441  {
29442  // Are we dealing with a vararg string returning function?
29443  igeneric_function<T>* string_function = symtab_store_.get_string_function(symbol);
29444 
29445  if (string_function)
29446  {
29447  lodge_symbol(symbol, e_st_function);
29448 
29449  expression_node_ptr stringfunc_node =
29450  parse_string_function_call(string_function, symbol);
29451 
29452  if (stringfunc_node)
29453  return stringfunc_node;
29454  else
29455  {
29456  set_error(make_error(
29458  current_token(),
29459  "ERR204 - Failed to generate node for string function: '" + symbol + "'",
29461 
29462  return error_node();
29463  }
29464  }
29465  }
29466 
29467  {
29468  // Are we dealing with a vararg overloaded scalar/string returning function?
29469  igeneric_function<T>* overload_function = symtab_store_.get_overload_function(symbol);
29470 
29471  if (overload_function)
29472  {
29473  lodge_symbol(symbol, e_st_function);
29474 
29475  expression_node_ptr overloadfunc_node =
29476  parse_overload_function_call(overload_function, symbol);
29477 
29478  if (overloadfunc_node)
29479  return overloadfunc_node;
29480  else
29481  {
29482  set_error(make_error(
29484  current_token(),
29485  "ERR205 - Failed to generate node for overload function: '" + symbol + "'",
29487 
29488  return error_node();
29489  }
29490  }
29491  }
29492  #endif
29493 
29494  // Are we dealing with a vector?
29495  if (symtab_store_.is_vector(symbol))
29496  {
29497  lodge_symbol(symbol, e_st_vector);
29498  return parse_vector();
29499  }
29500 
29501  if (details::is_reserved_symbol(symbol))
29502  {
29503  if (
29504  settings_.function_enabled(symbol) ||
29505  !details::is_base_function(symbol)
29506  )
29507  {
29508  set_error(make_error(
29510  current_token(),
29511  "ERR206 - Invalid use of reserved symbol '" + symbol + "'",
29513 
29514  return error_node();
29515  }
29516  }
29517 
29518  // Should we handle unknown symbols?
29519  if (resolve_unknown_symbol_ && unknown_symbol_resolver_)
29520  {
29521  if (!(settings_.rsrvd_sym_usr_disabled() && details::is_reserved_symbol(symbol)))
29522  {
29523  symbol_table_t& symtab = symtab_store_.get_symbol_table();
29524 
29525  std::string error_message;
29526 
29527  if (unknown_symbol_resolver::e_usrmode_default == unknown_symbol_resolver_->mode)
29528  {
29529  T default_value = T(0);
29530 
29531  typename unknown_symbol_resolver::usr_symbol_type usr_symbol_type = unknown_symbol_resolver::e_usr_unknown_type;
29532 
29533  if (unknown_symbol_resolver_->process(symbol, usr_symbol_type, default_value, error_message))
29534  {
29535  bool create_result = false;
29536 
29537  switch (usr_symbol_type)
29538  {
29539  case unknown_symbol_resolver::e_usr_variable_type :
29540  create_result = symtab.create_variable(symbol, default_value);
29541  break;
29542 
29543  case unknown_symbol_resolver::e_usr_constant_type :
29544  create_result = symtab.add_constant(symbol, default_value);
29545  break;
29546 
29547  default : create_result = false;
29548  }
29549 
29550  if (create_result)
29551  {
29552  expression_node_ptr var = symtab_store_.get_variable(symbol);
29553 
29554  if (var)
29555  {
29556  if (symtab_store_.is_constant_node(symbol))
29557  {
29558  var = expression_generator_(var->value());
29559  }
29560 
29561  lodge_symbol(symbol, e_st_variable);
29562 
29563  if (!post_variable_process(symbol))
29564  return error_node();
29565 
29566  next_token();
29567 
29568  return var;
29569  }
29570  }
29571  }
29572 
29573  set_error(make_error(
29575  current_token(),
29576  "ERR207 - Failed to create variable: '" + symbol + "'" +
29577  (error_message.empty() ? "" : " - " + error_message),
29579 
29580  }
29581  else if (unknown_symbol_resolver::e_usrmode_extended == unknown_symbol_resolver_->mode)
29582  {
29583  if (unknown_symbol_resolver_->process(symbol, symtab, error_message))
29584  {
29585  expression_node_ptr result = parse_symtab_symbol();
29586 
29587  if (result)
29588  {
29589  return result;
29590  }
29591  }
29592 
29593  set_error(make_error(
29595  current_token(),
29596  "ERR208 - Failed to resolve symbol: '" + symbol + "'" +
29597  (error_message.empty() ? "" : " - " + error_message),
29599  }
29600 
29601  return error_node();
29602  }
29603  }
29604 
29605  set_error(make_error(
29607  current_token(),
29608  "ERR209 - Undefined symbol: '" + symbol + "'",
29610 
29611  return error_node();
29612  }
29613 
29615  {
29616  static const std::string symbol_if = "if" ;
29617  static const std::string symbol_while = "while" ;
29618  static const std::string symbol_repeat = "repeat" ;
29619  static const std::string symbol_for = "for" ;
29620  static const std::string symbol_switch = "switch" ;
29621  static const std::string symbol_null = "null" ;
29622  static const std::string symbol_break = "break" ;
29623  static const std::string symbol_continue = "continue";
29624  static const std::string symbol_var = "var" ;
29625  static const std::string symbol_swap = "swap" ;
29626  static const std::string symbol_return = "return" ;
29627  static const std::string symbol_not = "not" ;
29628 
29629  const std::string symbol = current_token().value;
29630 
29631  if (valid_vararg_operation(symbol))
29632  {
29633  return parse_vararg_function();
29634  }
29635  else if (details::imatch(symbol, symbol_not))
29636  {
29637  return parse_not_statement();
29638  }
29639  else if (valid_base_operation(symbol))
29640  {
29641  return parse_base_operation();
29642  }
29643  else if (
29644  details::imatch(symbol, symbol_if) &&
29645  settings_.control_struct_enabled(symbol)
29646  )
29647  {
29648  return parse_conditional_statement();
29649  }
29650  else if (
29651  details::imatch(symbol, symbol_while) &&
29652  settings_.control_struct_enabled(symbol)
29653  )
29654  {
29655  return parse_while_loop();
29656  }
29657  else if (
29658  details::imatch(symbol, symbol_repeat) &&
29659  settings_.control_struct_enabled(symbol)
29660  )
29661  {
29662  return parse_repeat_until_loop();
29663  }
29664  else if (
29665  details::imatch(symbol, symbol_for) &&
29666  settings_.control_struct_enabled(symbol)
29667  )
29668  {
29669  return parse_for_loop();
29670  }
29671  else if (
29672  details::imatch(symbol, symbol_switch) &&
29673  settings_.control_struct_enabled(symbol)
29674  )
29675  {
29676  return parse_switch_statement();
29677  }
29678  else if (details::is_valid_sf_symbol(symbol))
29679  {
29680  return parse_special_function();
29681  }
29682  else if (details::imatch(symbol, symbol_null))
29683  {
29684  return parse_null_statement();
29685  }
29686  #ifndef exprtk_disable_break_continue
29687  else if (details::imatch(symbol, symbol_break))
29688  {
29689  return parse_break_statement();
29690  }
29691  else if (details::imatch(symbol, symbol_continue))
29692  {
29693  return parse_continue_statement();
29694  }
29695  #endif
29696  else if (details::imatch(symbol, symbol_var))
29697  {
29698  return parse_define_var_statement();
29699  }
29700  else if (details::imatch(symbol, symbol_swap))
29701  {
29702  return parse_swap_statement();
29703  }
29704  #ifndef exprtk_disable_return_statement
29705  else if (
29706  details::imatch(symbol, symbol_return) &&
29707  settings_.control_struct_enabled(symbol)
29708  )
29709  {
29710  return parse_return_statement();
29711  }
29712  #endif
29713  else if (symtab_store_.valid() || !sem_.empty())
29714  {
29715  return parse_symtab_symbol();
29716  }
29717  else
29718  {
29719  set_error(make_error(
29721  current_token(),
29722  "ERR210 - Unknown variable or function encountered. Symbol table(s) "
29723  "is either invalid or does not contain symbol: '" + symbol + "'",
29725 
29726  return error_node();
29727  }
29728  }
29729 
29730  inline expression_node_ptr parse_branch(precedence_level precedence = e_level00)
29731  {
29732  stack_limit_handler slh(*this);
29733 
29734  if (!slh)
29735  {
29736  return error_node();
29737  }
29738 
29739  expression_node_ptr branch = error_node();
29740 
29741  if (token_t::e_number == current_token().type)
29742  {
29743  T numeric_value = T(0);
29744 
29745  if (details::string_to_real(current_token().value, numeric_value))
29746  {
29747  expression_node_ptr literal_exp = expression_generator_(numeric_value);
29748 
29749  if (0 == literal_exp)
29750  {
29751  set_error(make_error(
29753  current_token(),
29754  "ERR211 - Failed generate node for scalar: '" + current_token().value + "'",
29756 
29757  return error_node();
29758  }
29759 
29760  next_token();
29761  branch = literal_exp;
29762  }
29763  else
29764  {
29765  set_error(make_error(
29767  current_token(),
29768  "ERR212 - Failed to convert '" + current_token().value + "' to a number",
29770 
29771  return error_node();
29772  }
29773  }
29774  else if (token_t::e_symbol == current_token().type)
29775  {
29776  branch = parse_symbol();
29777  }
29778  #ifndef exprtk_disable_string_capabilities
29779  else if (token_t::e_string == current_token().type)
29780  {
29781  branch = parse_const_string();
29782  }
29783  #endif
29784  else if (token_t::e_lbracket == current_token().type)
29785  {
29786  next_token();
29787 
29788  if (0 == (branch = parse_expression()))
29789  return error_node();
29790  else if (token_is(token_t::e_eof))
29791  {}
29792  else if (!token_is(token_t::e_rbracket))
29793  {
29794  set_error(make_error(
29796  current_token(),
29797  "ERR213 - Expected ')' instead of: '" + current_token().value + "'",
29799 
29800  details::free_node(node_allocator_,branch);
29801 
29802  return error_node();
29803  }
29804  else if (!post_bracket_process(token_t::e_lbracket,branch))
29805  {
29806  details::free_node(node_allocator_,branch);
29807 
29808  return error_node();
29809  }
29810 
29811  parse_pending_vector_index_operator(branch);
29812  }
29813  else if (token_t::e_lsqrbracket == current_token().type)
29814  {
29815  next_token();
29816 
29817  if (0 == (branch = parse_expression()))
29818  return error_node();
29819  else if (!token_is(token_t::e_rsqrbracket))
29820  {
29821  set_error(make_error(
29823  current_token(),
29824  "ERR214 - Expected ']' instead of: '" + current_token().value + "'",
29826 
29827  details::free_node(node_allocator_,branch);
29828 
29829  return error_node();
29830  }
29831  else if (!post_bracket_process(token_t::e_lsqrbracket,branch))
29832  {
29833  details::free_node(node_allocator_,branch);
29834 
29835  return error_node();
29836  }
29837  }
29838  else if (token_t::e_lcrlbracket == current_token().type)
29839  {
29840  next_token();
29841 
29842  if (0 == (branch = parse_expression()))
29843  return error_node();
29844  else if (!token_is(token_t::e_rcrlbracket))
29845  {
29846  set_error(make_error(
29848  current_token(),
29849  "ERR215 - Expected '}' instead of: '" + current_token().value + "'",
29851 
29852  details::free_node(node_allocator_,branch);
29853 
29854  return error_node();
29855  }
29856  else if (!post_bracket_process(token_t::e_lcrlbracket,branch))
29857  {
29858  details::free_node(node_allocator_,branch);
29859 
29860  return error_node();
29861  }
29862  }
29863  else if (token_t::e_sub == current_token().type)
29864  {
29865  next_token();
29866  branch = parse_expression(e_level11);
29867 
29868  if (
29869  branch &&
29870  !(
29871  details::is_neg_unary_node (branch) &&
29872  simplify_unary_negation_branch(branch)
29873  )
29874  )
29875  {
29876  expression_node_ptr result = expression_generator_(details::e_neg,branch);
29877 
29878  if (0 == result)
29879  {
29880  details::free_node(node_allocator_,branch);
29881 
29882  return error_node();
29883  }
29884  else
29885  branch = result;
29886  }
29887  }
29888  else if (token_t::e_add == current_token().type)
29889  {
29890  next_token();
29891  branch = parse_expression(e_level13);
29892  }
29893  else if (token_t::e_eof == current_token().type)
29894  {
29895  set_error(make_error(
29897  current_token(),
29898  "ERR216 - Premature end of expression[1]",
29900 
29901  return error_node();
29902  }
29903  else
29904  {
29905  set_error(make_error(
29907  current_token(),
29908  "ERR217 - Premature end of expression[2]",
29910 
29911  return error_node();
29912  }
29913 
29914  if (
29915  branch &&
29916  (e_level00 == precedence) &&
29917  token_is(token_t::e_ternary,prsrhlpr_t::e_hold)
29918  )
29919  {
29920  branch = parse_ternary_conditional_statement(branch);
29921  }
29922 
29923  parse_pending_string_rangesize(branch);
29924 
29925  return branch;
29926  }
29927 
29928  template <typename Type>
29930  {
29931  public:
29932 
29934  typedef expression_node_ptr (*synthesize_functor_t)(expression_generator<T>&, const details::operator_type& operation, expression_node_ptr (&branch)[2]);
29935  typedef std::map<std::string,synthesize_functor_t> synthesize_map_t;
29936  typedef typename exprtk::parser<Type> parser_t;
29937  typedef const Type& vtype;
29938  typedef const Type ctype;
29939 
29940  inline void init_synthesize_map()
29941  {
29942  #ifndef exprtk_disable_enhanced_features
29943  synthesize_map_["(v)o(v)"] = synthesize_vov_expression::process;
29944  synthesize_map_["(c)o(v)"] = synthesize_cov_expression::process;
29945  synthesize_map_["(v)o(c)"] = synthesize_voc_expression::process;
29946 
29947  #define register_synthezier(S) \
29948  synthesize_map_[S ::node_type::id()] = S ::process; \
29949 
29962 
29972 
29982 
29991 
30001 
30010 
30011  #undef register_synthezier
30012  #endif
30013  }
30014 
30015  inline void set_parser(parser_t& p)
30016  {
30017  parser_ = &p;
30018  }
30019 
30020  inline void set_uom(unary_op_map_t& unary_op_map)
30021  {
30022  unary_op_map_ = &unary_op_map;
30023  }
30024 
30025  inline void set_bom(binary_op_map_t& binary_op_map)
30026  {
30027  binary_op_map_ = &binary_op_map;
30028  }
30029 
30030  inline void set_ibom(inv_binary_op_map_t& inv_binary_op_map)
30031  {
30032  inv_binary_op_map_ = &inv_binary_op_map;
30033  }
30034 
30035  inline void set_sf3m(sf3_map_t& sf3_map)
30036  {
30037  sf3_map_ = &sf3_map;
30038  }
30039 
30040  inline void set_sf4m(sf4_map_t& sf4_map)
30041  {
30042  sf4_map_ = &sf4_map;
30043  }
30044 
30046  {
30047  node_allocator_ = &na;
30048  }
30049 
30050  inline void set_strength_reduction_state(const bool enabled)
30051  {
30052  strength_reduction_enabled_ = enabled;
30053  }
30054 
30055  inline bool strength_reduction_enabled() const
30056  {
30057  return strength_reduction_enabled_;
30058  }
30059 
30060  inline bool valid_operator(const details::operator_type& operation, binary_functor_t& bop)
30061  {
30062  typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation);
30063 
30064  if (binary_op_map_->end() == bop_itr)
30065  return false;
30066 
30067  bop = bop_itr->second;
30068 
30069  return true;
30070  }
30071 
30072  inline bool valid_operator(const details::operator_type& operation, unary_functor_t& uop)
30073  {
30074  typename unary_op_map_t::iterator uop_itr = unary_op_map_->find(operation);
30075 
30076  if ((*unary_op_map_).end() == uop_itr)
30077  return false;
30078 
30079  uop = uop_itr->second;
30080 
30081  return true;
30082  }
30083 
30085  {
30086  return (*inv_binary_op_map_).find(bop)->second;
30087  }
30088 
30089  inline expression_node_ptr operator() (const Type& v) const
30090  {
30091  return node_allocator_->allocate<literal_node_t>(v);
30092  }
30093 
30094  #ifndef exprtk_disable_string_capabilities
30095  inline expression_node_ptr operator() (const std::string& s) const
30096  {
30097  return node_allocator_->allocate<string_literal_node_t>(s);
30098  }
30099 
30100  inline expression_node_ptr operator() (std::string& s, range_t& rp) const
30101  {
30102  return node_allocator_->allocate_rr<string_range_node_t>(s,rp);
30103  }
30104 
30105  inline expression_node_ptr operator() (const std::string& s, range_t& rp) const
30106  {
30107  return node_allocator_->allocate_tt<const_string_range_node_t>(s,rp);
30108  }
30109 
30110  inline expression_node_ptr operator() (expression_node_ptr branch, range_t& rp) const
30111  {
30112  if (is_generally_string_node(branch))
30113  return node_allocator_->allocate_tt<generic_string_range_node_t>(branch,rp);
30114  else
30115  return error_node();
30116  }
30117  #endif
30118 
30119  inline bool unary_optimisable(const details::operator_type& operation) const
30120  {
30121  return (details::e_abs == operation) || (details::e_acos == operation) ||
30122  (details::e_acosh == operation) || (details::e_asin == operation) ||
30123  (details::e_asinh == operation) || (details::e_atan == operation) ||
30124  (details::e_atanh == operation) || (details::e_ceil == operation) ||
30125  (details::e_cos == operation) || (details::e_cosh == operation) ||
30126  (details::e_exp == operation) || (details::e_expm1 == operation) ||
30127  (details::e_floor == operation) || (details::e_log == operation) ||
30128  (details::e_log10 == operation) || (details::e_log2 == operation) ||
30129  (details::e_log1p == operation) || (details::e_neg == operation) ||
30130  (details::e_pos == operation) || (details::e_round == operation) ||
30131  (details::e_sin == operation) || (details::e_sinc == operation) ||
30132  (details::e_sinh == operation) || (details::e_sqrt == operation) ||
30133  (details::e_tan == operation) || (details::e_tanh == operation) ||
30134  (details::e_cot == operation) || (details::e_sec == operation) ||
30135  (details::e_csc == operation) || (details::e_r2d == operation) ||
30136  (details::e_d2r == operation) || (details::e_d2g == operation) ||
30137  (details::e_g2d == operation) || (details::e_notl == operation) ||
30138  (details::e_sgn == operation) || (details::e_erf == operation) ||
30139  (details::e_erfc == operation) || (details::e_ncdf == operation) ||
30140  (details::e_frac == operation) || (details::e_trunc == operation) ;
30141  }
30142 
30143  inline bool sf3_optimisable(const std::string& sf3id, trinary_functor_t& tfunc) const
30144  {
30145  typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id);
30146 
30147  if (sf3_map_->end() == itr)
30148  return false;
30149  else
30150  tfunc = itr->second.first;
30151 
30152  return true;
30153  }
30154 
30155  inline bool sf4_optimisable(const std::string& sf4id, quaternary_functor_t& qfunc) const
30156  {
30157  typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id);
30158 
30159  if (sf4_map_->end() == itr)
30160  return false;
30161  else
30162  qfunc = itr->second.first;
30163 
30164  return true;
30165  }
30166 
30167  inline bool sf3_optimisable(const std::string& sf3id, details::operator_type& operation) const
30168  {
30169  typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id);
30170 
30171  if (sf3_map_->end() == itr)
30172  return false;
30173  else
30174  operation = itr->second.second;
30175 
30176  return true;
30177  }
30178 
30179  inline bool sf4_optimisable(const std::string& sf4id, details::operator_type& operation) const
30180  {
30181  typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id);
30182 
30183  if (sf4_map_->end() == itr)
30184  return false;
30185  else
30186  operation = itr->second.second;
30187 
30188  return true;
30189  }
30190 
30191  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[1])
30192  {
30193  if (0 == branch[0])
30194  {
30195  return error_node();
30196  }
30197  else if (details::is_null_node(branch[0]))
30198  {
30199  return branch[0];
30200  }
30201  else if (details::is_break_node(branch[0]))
30202  {
30203  return error_node();
30204  }
30205  else if (details::is_continue_node(branch[0]))
30206  {
30207  return error_node();
30208  }
30209  else if (details::is_constant_node(branch[0]))
30210  {
30211  return synthesize_expression<unary_node_t,1>(operation,branch);
30212  }
30213  else if (unary_optimisable(operation) && details::is_variable_node(branch[0]))
30214  {
30215  return synthesize_uv_expression(operation,branch);
30216  }
30217  else if (unary_optimisable(operation) && details::is_ivector_node(branch[0]))
30218  {
30219  return synthesize_uvec_expression(operation,branch);
30220  }
30221  else
30222  return synthesize_unary_expression(operation,branch);
30223  }
30224 
30225  inline bool is_assignment_operation(const details::operator_type& operation) const
30226  {
30227  return (
30228  (details::e_addass == operation) ||
30229  (details::e_subass == operation) ||
30230  (details::e_mulass == operation) ||
30231  (details::e_divass == operation) ||
30232  (details::e_modass == operation)
30233  ) &&
30234  parser_->settings_.assignment_enabled(operation);
30235  }
30236 
30237  #ifndef exprtk_disable_string_capabilities
30238  inline bool valid_string_operation(const details::operator_type& operation) const
30239  {
30240  return (details::e_add == operation) ||
30241  (details::e_lt == operation) ||
30242  (details::e_lte == operation) ||
30243  (details::e_gt == operation) ||
30244  (details::e_gte == operation) ||
30245  (details::e_eq == operation) ||
30246  (details::e_ne == operation) ||
30247  (details::e_in == operation) ||
30248  (details::e_like == operation) ||
30249  (details::e_ilike == operation) ||
30250  (details::e_assign == operation) ||
30251  (details::e_addass == operation) ||
30252  (details::e_swap == operation) ;
30253  }
30254  #else
30255  inline bool valid_string_operation(const details::operator_type&) const
30256  {
30257  return false;
30258  }
30259  #endif
30260 
30261  inline std::string to_str(const details::operator_type& operation) const
30262  {
30263  switch (operation)
30264  {
30265  case details::e_add : return "+" ;
30266  case details::e_sub : return "-" ;
30267  case details::e_mul : return "*" ;
30268  case details::e_div : return "/" ;
30269  case details::e_mod : return "%" ;
30270  case details::e_pow : return "^" ;
30271  case details::e_lt : return "<" ;
30272  case details::e_lte : return "<=" ;
30273  case details::e_gt : return ">" ;
30274  case details::e_gte : return ">=" ;
30275  case details::e_eq : return "==" ;
30276  case details::e_ne : return "!=" ;
30277  case details::e_and : return "and" ;
30278  case details::e_nand : return "nand" ;
30279  case details::e_or : return "or" ;
30280  case details::e_nor : return "nor" ;
30281  case details::e_xor : return "xor" ;
30282  case details::e_xnor : return "xnor" ;
30283  default : return "UNKNOWN";
30284  }
30285  }
30286 
30287  inline bool operation_optimisable(const details::operator_type& operation) const
30288  {
30289  return (details::e_add == operation) ||
30290  (details::e_sub == operation) ||
30291  (details::e_mul == operation) ||
30292  (details::e_div == operation) ||
30293  (details::e_mod == operation) ||
30294  (details::e_pow == operation) ||
30295  (details::e_lt == operation) ||
30296  (details::e_lte == operation) ||
30297  (details::e_gt == operation) ||
30298  (details::e_gte == operation) ||
30299  (details::e_eq == operation) ||
30300  (details::e_ne == operation) ||
30301  (details::e_and == operation) ||
30302  (details::e_nand == operation) ||
30303  (details::e_or == operation) ||
30304  (details::e_nor == operation) ||
30305  (details::e_xor == operation) ||
30306  (details::e_xnor == operation) ;
30307  }
30308 
30309  inline std::string branch_to_id(expression_node_ptr branch) const
30310  {
30311  static const std::string null_str ("(null)" );
30312  static const std::string const_str ("(c)" );
30313  static const std::string var_str ("(v)" );
30314  static const std::string vov_str ("(vov)" );
30315  static const std::string cov_str ("(cov)" );
30316  static const std::string voc_str ("(voc)" );
30317  static const std::string str_str ("(s)" );
30318  static const std::string strrng_str ("(rngs)" );
30319  static const std::string cs_str ("(cs)" );
30320  static const std::string cstrrng_str("(crngs)");
30321 
30322  if (details::is_null_node(branch))
30323  return null_str;
30324  else if (details::is_constant_node(branch))
30325  return const_str;
30326  else if (details::is_variable_node(branch))
30327  return var_str;
30328  else if (details::is_vov_node(branch))
30329  return vov_str;
30330  else if (details::is_cov_node(branch))
30331  return cov_str;
30332  else if (details::is_voc_node(branch))
30333  return voc_str;
30334  else if (details::is_string_node(branch))
30335  return str_str;
30336  else if (details::is_const_string_node(branch))
30337  return cs_str;
30338  else if (details::is_string_range_node(branch))
30339  return strrng_str;
30340  else if (details::is_const_string_range_node(branch))
30341  return cstrrng_str;
30342  else if (details::is_t0ot1ot2_node(branch))
30343  return "(" + dynamic_cast<details::T0oT1oT2_base_node<T>*>(branch)->type_id() + ")";
30344  else if (details::is_t0ot1ot2ot3_node(branch))
30345  return "(" + dynamic_cast<details::T0oT1oT2oT3_base_node<T>*>(branch)->type_id() + ")";
30346  else
30347  return "ERROR";
30348  }
30349 
30350  inline std::string branch_to_id(expression_node_ptr (&branch)[2]) const
30351  {
30352  return branch_to_id(branch[0]) + std::string("o") + branch_to_id(branch[1]);
30353  }
30354 
30355  inline bool cov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30356  {
30357  if (!operation_optimisable(operation))
30358  return false;
30359  else
30360  return details::is_constant_node(branch[0]) &&
30361  details::is_variable_node(branch[1]) ;
30362  }
30363 
30364  inline bool voc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30365  {
30366  if (!operation_optimisable(operation))
30367  return false;
30368  else
30369  return details::is_variable_node(branch[0]) &&
30370  details::is_constant_node(branch[1]) ;
30371  }
30372 
30373  inline bool vov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30374  {
30375  if (!operation_optimisable(operation))
30376  return false;
30377  else
30378  return details::is_variable_node(branch[0]) &&
30379  details::is_variable_node(branch[1]) ;
30380  }
30381 
30382  inline bool cob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30383  {
30384  if (!operation_optimisable(operation))
30385  return false;
30386  else
30387  return details::is_constant_node(branch[0]) &&
30388  !details::is_constant_node(branch[1]) ;
30389  }
30390 
30391  inline bool boc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30392  {
30393  if (!operation_optimisable(operation))
30394  return false;
30395  else
30396  return !details::is_constant_node(branch[0]) &&
30397  details::is_constant_node(branch[1]) ;
30398  }
30399 
30400  inline bool cocob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30401  {
30402  if (
30403  (details::e_add == operation) ||
30404  (details::e_sub == operation) ||
30405  (details::e_mul == operation) ||
30406  (details::e_div == operation)
30407  )
30408  {
30409  return (details::is_constant_node(branch[0]) && details::is_cob_node(branch[1])) ||
30410  (details::is_constant_node(branch[1]) && details::is_cob_node(branch[0])) ;
30411  }
30412  else
30413  return false;
30414  }
30415 
30416  inline bool coboc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30417  {
30418  if (
30419  (details::e_add == operation) ||
30420  (details::e_sub == operation) ||
30421  (details::e_mul == operation) ||
30422  (details::e_div == operation)
30423  )
30424  {
30425  return (details::is_constant_node(branch[0]) && details::is_boc_node(branch[1])) ||
30426  (details::is_constant_node(branch[1]) && details::is_boc_node(branch[0])) ;
30427  }
30428  else
30429  return false;
30430  }
30431 
30432  inline bool uvouv_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30433  {
30434  if (!operation_optimisable(operation))
30435  return false;
30436  else
30437  return details::is_uv_node(branch[0]) &&
30438  details::is_uv_node(branch[1]) ;
30439  }
30440 
30441  inline bool vob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30442  {
30443  if (!operation_optimisable(operation))
30444  return false;
30445  else
30446  return details::is_variable_node(branch[0]) &&
30447  !details::is_variable_node(branch[1]) ;
30448  }
30449 
30450  inline bool bov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30451  {
30452  if (!operation_optimisable(operation))
30453  return false;
30454  else
30455  return !details::is_variable_node(branch[0]) &&
30456  details::is_variable_node(branch[1]) ;
30457  }
30458 
30459  inline bool binext_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30460  {
30461  if (!operation_optimisable(operation))
30462  return false;
30463  else
30464  return !details::is_constant_node(branch[0]) ||
30465  !details::is_constant_node(branch[1]) ;
30466  }
30467 
30468  inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30469  {
30470  if (is_assignment_operation(operation))
30471  {
30472  const bool b1_is_genstring = details::is_generally_string_node(branch[1]);
30473 
30474  if (details::is_string_node(branch[0]))
30475  return !b1_is_genstring;
30476  else
30477  return (
30478  !details::is_variable_node (branch[0]) &&
30479  !details::is_vector_elem_node (branch[0]) &&
30480  !details::is_vector_celem_node (branch[0]) &&
30481  !details::is_vector_elem_rtc_node (branch[0]) &&
30482  !details::is_vector_celem_rtc_node (branch[0]) &&
30483  !details::is_rebasevector_elem_node (branch[0]) &&
30484  !details::is_rebasevector_celem_node (branch[0]) &&
30487  !details::is_vector_node (branch[0])
30488  )
30489  || b1_is_genstring;
30490  }
30491  else
30492  return false;
30493  }
30494 
30495  inline bool is_constpow_operation(const details::operator_type& operation, expression_node_ptr(&branch)[2]) const
30496  {
30497  if (
30498  !details::is_constant_node(branch[1]) ||
30499  details::is_constant_node(branch[0]) ||
30500  details::is_variable_node(branch[0]) ||
30501  details::is_vector_node (branch[0]) ||
30503  )
30504  return false;
30505 
30506  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
30507 
30508  return cardinal_pow_optimisable(operation, c);
30509  }
30510 
30511  inline bool is_invalid_break_continue_op(expression_node_ptr (&branch)[2]) const
30512  {
30513  return (
30514  details::is_break_node (branch[0]) ||
30515  details::is_break_node (branch[1]) ||
30516  details::is_continue_node(branch[0]) ||
30517  details::is_continue_node(branch[1])
30518  );
30519  }
30520 
30521  inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30522  {
30523  const bool b0_string = is_generally_string_node(branch[0]);
30524  const bool b1_string = is_generally_string_node(branch[1]);
30525 
30526  bool result = false;
30527 
30528  if (b0_string != b1_string)
30529  result = true;
30530  else if (!valid_string_operation(operation) && b0_string && b1_string)
30531  result = true;
30532 
30533  if (result)
30534  {
30535  parser_->set_synthesis_error("Invalid string operation");
30536  }
30537 
30538  return result;
30539  }
30540 
30541  inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const
30542  {
30543  const bool b0_string = is_generally_string_node(branch[0]);
30544  const bool b1_string = is_generally_string_node(branch[1]);
30545  const bool b2_string = is_generally_string_node(branch[2]);
30546 
30547  bool result = false;
30548 
30549  if ((b0_string != b1_string) || (b1_string != b2_string))
30550  result = true;
30551  else if ((details::e_inrange != operation) && b0_string && b1_string && b2_string)
30552  result = true;
30553 
30554  if (result)
30555  {
30556  parser_->set_synthesis_error("Invalid string operation");
30557  }
30558 
30559  return result;
30560  }
30561 
30562  inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30563  {
30564  const bool b0_string = is_generally_string_node(branch[0]);
30565  const bool b1_string = is_generally_string_node(branch[1]);
30566 
30567  return (b0_string && b1_string && valid_string_operation(operation));
30568  }
30569 
30570  inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const
30571  {
30572  const bool b0_string = is_generally_string_node(branch[0]);
30573  const bool b1_string = is_generally_string_node(branch[1]);
30574  const bool b2_string = is_generally_string_node(branch[2]);
30575 
30576  return (b0_string && b1_string && b2_string && (details::e_inrange == operation));
30577  }
30578 
30579  #ifndef exprtk_disable_sc_andor
30580  inline bool is_shortcircuit_expression(const details::operator_type& operation) const
30581  {
30582  return (
30583  (details::e_scand == operation) ||
30584  (details::e_scor == operation)
30585  );
30586  }
30587  #else
30588  inline bool is_shortcircuit_expression(const details::operator_type&) const
30589  {
30590  return false;
30591  }
30592  #endif
30593 
30594  inline bool is_null_present(expression_node_ptr (&branch)[2]) const
30595  {
30596  return (
30597  details::is_null_node(branch[0]) ||
30598  details::is_null_node(branch[1])
30599  );
30600  }
30601 
30602  inline bool is_vector_eqineq_logic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30603  {
30604  if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
30605  return false;
30606  else
30607  return (
30608  (details::e_lt == operation) ||
30609  (details::e_lte == operation) ||
30610  (details::e_gt == operation) ||
30611  (details::e_gte == operation) ||
30612  (details::e_eq == operation) ||
30613  (details::e_ne == operation) ||
30614  (details::e_equal == operation) ||
30615  (details::e_and == operation) ||
30616  (details::e_nand == operation) ||
30617  (details::e_or == operation) ||
30618  (details::e_nor == operation) ||
30619  (details::e_xor == operation) ||
30620  (details::e_xnor == operation)
30621  );
30622  }
30623 
30624  inline bool is_vector_arithmetic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
30625  {
30626  if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
30627  return false;
30628  else
30629  return (
30630  (details::e_add == operation) ||
30631  (details::e_sub == operation) ||
30632  (details::e_mul == operation) ||
30633  (details::e_div == operation) ||
30634  (details::e_pow == operation)
30635  );
30636  }
30637 
30638  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[2])
30639  {
30640  if ((0 == branch[0]) || (0 == branch[1]))
30641  {
30642  parser_->set_error(parser_error::make_error(
30644  parser_->current_state().token,
30645  "ERR218 - Invalid branches received for operator '" + details::to_str(operation) + "'",
30647 
30648  return error_node();
30649  }
30650  else if (is_invalid_string_op(operation,branch))
30651  {
30652  parser_->set_error(parser_error::make_error(
30654  parser_->current_state().token,
30655  "ERR219 - Invalid branch pair for string operator '" + details::to_str(operation) + "'",
30657 
30658  return error_node();
30659  }
30660  else if (is_invalid_assignment_op(operation,branch))
30661  {
30662  parser_->set_error(parser_error::make_error(
30664  parser_->current_state().token,
30665  "ERR220 - Invalid branch pair for assignment operator '" + details::to_str(operation) + "'",
30667 
30668  return error_node();
30669  }
30670  else if (is_invalid_break_continue_op(branch))
30671  {
30672  parser_->set_error(parser_error::make_error(
30674  parser_->current_state().token,
30675  "ERR221 - Invalid branch pair for break/continue operator '" + details::to_str(operation) + "'",
30677 
30678  return error_node();
30679  }
30680  else if (details::e_assign == operation)
30681  {
30682  return synthesize_assignment_expression(operation, branch);
30683  }
30684  else if (details::e_swap == operation)
30685  {
30686  return synthesize_swap_expression(branch);
30687  }
30688  else if (is_assignment_operation(operation))
30689  {
30690  return synthesize_assignment_operation_expression(operation, branch);
30691  }
30692  else if (is_vector_eqineq_logic_operation(operation, branch))
30693  {
30694  return synthesize_veceqineqlogic_operation_expression(operation, branch);
30695  }
30696  else if (is_vector_arithmetic_operation(operation, branch))
30697  {
30698  return synthesize_vecarithmetic_operation_expression(operation, branch);
30699  }
30700  else if (is_shortcircuit_expression(operation))
30701  {
30702  return synthesize_shortcircuit_expression(operation, branch);
30703  }
30704  else if (is_string_operation(operation, branch))
30705  {
30706  return synthesize_string_expression(operation, branch);
30707  }
30708  else if (is_null_present(branch))
30709  {
30710  return synthesize_null_expression(operation, branch);
30711  }
30712  #ifndef exprtk_disable_cardinal_pow_optimisation
30713  else if (is_constpow_operation(operation, branch))
30714  {
30715  return cardinal_pow_optimisation(branch);
30716  }
30717  #endif
30718 
30719  expression_node_ptr result = error_node();
30720 
30721  #ifndef exprtk_disable_enhanced_features
30722  if (synthesize_expression(operation, branch, result))
30723  {
30724  return result;
30725  }
30726  else
30727  #endif
30728 
30729  {
30730  /*
30731  Possible reductions:
30732  1. c o cob -> cob
30733  2. cob o c -> cob
30734  3. c o boc -> boc
30735  4. boc o c -> boc
30736  */
30737  result = error_node();
30738 
30739  if (cocob_optimisable(operation, branch))
30740  {
30741  result = synthesize_cocob_expression::process((*this), operation, branch);
30742  }
30743  else if (coboc_optimisable(operation, branch) && (0 == result))
30744  {
30745  result = synthesize_coboc_expression::process((*this), operation, branch);
30746  }
30747 
30748  if (result)
30749  return result;
30750  }
30751 
30752  if (uvouv_optimisable(operation, branch))
30753  {
30754  return synthesize_uvouv_expression(operation, branch);
30755  }
30756  else if (vob_optimisable(operation, branch))
30757  {
30758  return synthesize_vob_expression::process((*this), operation, branch);
30759  }
30760  else if (bov_optimisable(operation, branch))
30761  {
30762  return synthesize_bov_expression::process((*this), operation, branch);
30763  }
30764  else if (cob_optimisable(operation, branch))
30765  {
30766  return synthesize_cob_expression::process((*this), operation, branch);
30767  }
30768  else if (boc_optimisable(operation, branch))
30769  {
30770  return synthesize_boc_expression::process((*this), operation, branch);
30771  }
30772  #ifndef exprtk_disable_enhanced_features
30773  else if (cov_optimisable(operation, branch))
30774  {
30775  return synthesize_cov_expression::process((*this), operation, branch);
30776  }
30777  #endif
30778  else if (binext_optimisable(operation, branch))
30779  {
30780  return synthesize_binary_ext_expression::process((*this), operation, branch);
30781  }
30782  else
30783  return synthesize_expression<binary_node_t,2>(operation, branch);
30784  }
30785 
30786  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[3])
30787  {
30788  if (
30789  (0 == branch[0]) ||
30790  (0 == branch[1]) ||
30791  (0 == branch[2])
30792  )
30793  {
30794  details::free_all_nodes(*node_allocator_,branch);
30795 
30796  parser_->set_error(parser_error::make_error(
30798  parser_->current_state().token,
30799  "ERR222 - Invalid branches operator '" + details::to_str(operation) + "'",
30801 
30802  return error_node();
30803  }
30804  else if (is_invalid_string_op(operation, branch))
30805  {
30806  parser_->set_error(parser_error::make_error(
30808  parser_->current_state().token,
30809  "ERR223 - Invalid branches for string operator '" + details::to_str(operation) + "'",
30811 
30812  return error_node();
30813  }
30814  else if (is_string_operation(operation, branch))
30815  {
30816  return synthesize_string_expression(operation, branch);
30817  }
30818  else
30819  return synthesize_expression<trinary_node_t,3>(operation, branch);
30820  }
30821 
30822  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[4])
30823  {
30824  return synthesize_expression<quaternary_node_t,4>(operation,branch);
30825  }
30826 
30827  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr b0)
30828  {
30829  expression_node_ptr branch[1] = { b0 };
30830  return (*this)(operation,branch);
30831  }
30832 
30834  {
30835  expression_node_ptr result = error_node();
30836 
30837  if ((0 != b0) && (0 != b1))
30838  {
30839  expression_node_ptr branch[2] = { b0, b1 };
30840  result = expression_generator<Type>::operator()(operation, branch);
30841  b0 = branch[0];
30842  b1 = branch[1];
30843  }
30844 
30845  return result;
30846  }
30847 
30849  expression_node_ptr consequent,
30850  expression_node_ptr alternative) const
30851  {
30852  if ((0 == condition) || (0 == consequent))
30853  {
30854  details::free_node(*node_allocator_, condition );
30855  details::free_node(*node_allocator_, consequent );
30856  details::free_node(*node_allocator_, alternative);
30857 
30858  const std::string invalid_branches =
30859  ((0 == condition ) ? std::string("condition ") : "") +
30860  ((0 == consequent) ? std::string("consequent") : "") ;
30861 
30862  parser_->set_error(parser_error::make_error(
30864  parser_->current_state().token,
30865  "ERR224 - Invalid " + invalid_branches + " for conditional statement",
30867 
30868  return error_node();
30869  }
30870  // Can the condition be immediately evaluated? if so optimise.
30871  else if (details::is_constant_node(condition))
30872  {
30873  // True branch
30874  if (details::is_true(condition))
30875  {
30876  details::free_node(*node_allocator_, condition );
30877  details::free_node(*node_allocator_, alternative);
30878 
30879  return consequent;
30880  }
30881  // False branch
30882  else
30883  {
30884  details::free_node(*node_allocator_, condition );
30885  details::free_node(*node_allocator_, consequent);
30886 
30887  if (alternative)
30888  return alternative;
30889  else
30890  return node_allocator_->allocate<details::null_node<T> >();
30891  }
30892  }
30893 
30894  expression_node_ptr result = error_node();
30895  std::string node_name = "Unknown!";
30896 
30897  if ((0 != consequent) && (0 != alternative))
30898  {
30899  result = node_allocator_->allocate<conditional_node_t>(condition, consequent, alternative);
30900  node_name = "conditional_node_t";
30901  }
30902  else
30903  {
30904  result = node_allocator_->allocate<cons_conditional_node_t>(condition, consequent);
30905  node_name = "cons_conditional_node_t";
30906  }
30907 
30908  if (result && result->valid())
30909  {
30910  return result;
30911  }
30912 
30913  parser_->set_error(parser_error::make_error(
30915  token_t(),
30916  "ERR225 - Failed to synthesize node: " + node_name,
30918 
30919  details::free_node(*node_allocator_, result);
30920  return error_node();
30921  }
30922 
30923  #ifndef exprtk_disable_string_capabilities
30925  expression_node_ptr consequent,
30926  expression_node_ptr alternative) const
30927  {
30928  if ((0 == condition) || (0 == consequent))
30929  {
30930  details::free_node(*node_allocator_, condition );
30931  details::free_node(*node_allocator_, consequent );
30932  details::free_node(*node_allocator_, alternative);
30933 
30934  const std::string invalid_branches =
30935  ((0 == condition ) ? std::string("condition ") : "") +
30936  ((0 == consequent) ? std::string("consequent") : "") ;
30937 
30938  parser_->set_error(parser_error::make_error(
30940  parser_->current_state().token,
30941  "ERR226 - Invalid " + invalid_branches + " for string conditional statement",
30943 
30944  return error_node();
30945  }
30946  // Can the condition be immediately evaluated? if so optimise.
30947  else if (details::is_constant_node(condition))
30948  {
30949  // True branch
30950  if (details::is_true(condition))
30951  {
30952  details::free_node(*node_allocator_, condition );
30953  details::free_node(*node_allocator_, alternative);
30954 
30955  return consequent;
30956  }
30957  // False branch
30958  else
30959  {
30960  details::free_node(*node_allocator_, condition );
30961  details::free_node(*node_allocator_, consequent);
30962 
30963  if (alternative)
30964  return alternative;
30965  else
30966  return node_allocator_->
30967  allocate_c<details::string_literal_node<Type> >("");
30968  }
30969  }
30970  else if ((0 != consequent) && (0 != alternative))
30971  {
30972  expression_node_ptr result =
30973  node_allocator_->allocate<conditional_string_node_t>(condition, consequent, alternative);
30974 
30975  if (result && result->valid())
30976  {
30977  return result;
30978  }
30979 
30980  parser_->set_error(parser_error::make_error(
30982  token_t(),
30983  "ERR227 - Failed to synthesize node: conditional_string_node_t",
30985 
30986  details::free_node(*node_allocator_, result);
30987  }
30988 
30989  return error_node();
30990  }
30991  #else
30992  inline expression_node_ptr conditional_string(expression_node_ptr,
30994  expression_node_ptr) const
30995  {
30996  return error_node();
30997  }
30998  #endif
30999 
31001  expression_node_ptr consequent,
31002  expression_node_ptr alternative) const
31003  {
31004  if ((0 == condition) || (0 == consequent))
31005  {
31006  details::free_node(*node_allocator_, condition );
31007  details::free_node(*node_allocator_, consequent );
31008  details::free_node(*node_allocator_, alternative);
31009 
31010  const std::string invalid_branches =
31011  ((0 == condition ) ? std::string("condition ") : "") +
31012  ((0 == consequent) ? std::string("consequent") : "") ;
31013 
31014  parser_->set_error(parser_error::make_error(
31016  parser_->current_state().token,
31017  "ERR228 - Invalid " + invalid_branches + " for vector conditional statement",
31019 
31020  return error_node();
31021  }
31022  // Can the condition be immediately evaluated? if so optimise.
31023  else if (details::is_constant_node(condition))
31024  {
31025  // True branch
31026  if (details::is_true(condition))
31027  {
31028  details::free_node(*node_allocator_, condition );
31029  details::free_node(*node_allocator_, alternative);
31030 
31031  return consequent;
31032  }
31033  // False branch
31034  else
31035  {
31036  details::free_node(*node_allocator_, condition );
31037  details::free_node(*node_allocator_, consequent);
31038 
31039  if (alternative)
31040  return alternative;
31041  else
31042  return node_allocator_->allocate<details::null_node<T> >();
31043 
31044  }
31045  }
31046  else if ((0 != consequent) && (0 != alternative))
31047  {
31048  return node_allocator_->
31049  allocate<conditional_vector_node_t>(condition, consequent, alternative);
31050  }
31051  else
31052  return error_node();
31053  }
31054 
31056  {
31057  if (
31058  parser_->loop_runtime_check_ &&
31059  (loop_type == (parser_->loop_runtime_check_->loop_set & loop_type))
31060  )
31061  {
31062  return parser_->loop_runtime_check_;
31063  }
31064 
31065  return loop_runtime_check_ptr(0);
31066  }
31067 
31069  {
31070  return parser_->vector_access_runtime_check_;
31071  }
31072 
31074  expression_node_ptr& branch,
31075  const bool break_continue_present = false) const
31076  {
31077  if (!break_continue_present && details::is_constant_node(condition))
31078  {
31079  expression_node_ptr result = error_node();
31080  if (details::is_true(condition))
31081  {
31082  // Infinite loops are not allowed.
31083 
31084  parser_->set_error(parser_error::make_error(
31086  parser_->current_state().token,
31087  "ERR229 - Infinite loop condition with 'break' not allowed in while-loops",
31089 
31090  result = error_node();
31091  }
31092  else
31093  result = node_allocator_->allocate<details::null_node<Type> >();
31094 
31095  details::free_node(*node_allocator_, condition);
31096  details::free_node(*node_allocator_, branch );
31097 
31098  return result;
31099  }
31100  else if (details::is_null_node(condition))
31101  {
31102  details::free_node(*node_allocator_,condition);
31103 
31104  return branch;
31105  }
31106 
31107  loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_while_loop);
31108 
31109  if (!break_continue_present)
31110  {
31111  if (rtc)
31112  return node_allocator_->allocate<while_loop_rtc_node_t>
31113  (condition, branch, rtc);
31114  else
31115  return node_allocator_->allocate<while_loop_node_t>
31116  (condition, branch);
31117  }
31118  #ifndef exprtk_disable_break_continue
31119  else
31120  {
31121  if (rtc)
31122  return node_allocator_->allocate<while_loop_bc_rtc_node_t>
31123  (condition, branch, rtc);
31124  else
31125  return node_allocator_->allocate<while_loop_bc_node_t>
31126  (condition, branch);
31127  }
31128  #else
31129  return error_node();
31130  #endif
31131  }
31132 
31134  expression_node_ptr& branch,
31135  const bool break_continue_present = false) const
31136  {
31137  if (!break_continue_present && details::is_constant_node(condition))
31138  {
31139  if (
31140  details::is_true(condition) &&
31142  )
31143  {
31144  free_node(*node_allocator_,condition);
31145 
31146  return branch;
31147  }
31148 
31149  details::free_node(*node_allocator_, condition);
31150  details::free_node(*node_allocator_, branch );
31151 
31152  return error_node();
31153  }
31154  else if (details::is_null_node(condition))
31155  {
31156  details::free_node(*node_allocator_,condition);
31157 
31158  return branch;
31159  }
31160 
31162 
31163  if (!break_continue_present)
31164  {
31165  if (rtc)
31166  return node_allocator_->allocate<repeat_until_loop_rtc_node_t>
31167  (condition, branch, rtc);
31168  else
31169  return node_allocator_->allocate<repeat_until_loop_node_t>
31170  (condition, branch);
31171  }
31172  #ifndef exprtk_disable_break_continue
31173  else
31174  {
31175  if (rtc)
31176  return node_allocator_->allocate<repeat_until_loop_bc_rtc_node_t>
31177  (condition, branch, rtc);
31178  else
31179  return node_allocator_->allocate<repeat_until_loop_bc_node_t>
31180  (condition, branch);
31181  }
31182  #else
31183  return error_node();
31184  #endif
31185  }
31186 
31188  expression_node_ptr& condition,
31189  expression_node_ptr& incrementor,
31190  expression_node_ptr& loop_body,
31191  bool break_continue_present = false) const
31192  {
31193  if (!break_continue_present && details::is_constant_node(condition))
31194  {
31195  expression_node_ptr result = error_node();
31196 
31197  if (details::is_true(condition))
31198  {
31199  // Infinite loops are not allowed.
31200 
31201  parser_->set_error(parser_error::make_error(
31203  parser_->current_state().token,
31204  "ERR230 - Infinite loop condition without 'break' not allowed in for-loop",
31206 
31207  result = error_node();
31208  }
31209  else
31210  result = node_allocator_->allocate<details::null_node<Type> >();
31211 
31212  details::free_node(*node_allocator_, initialiser);
31213  details::free_node(*node_allocator_, condition );
31214  details::free_node(*node_allocator_, incrementor);
31215  details::free_node(*node_allocator_, loop_body );
31216 
31217  return result;
31218  }
31219  else if (details::is_null_node(condition) || (0 == condition))
31220  {
31221  details::free_node(*node_allocator_, initialiser);
31222  details::free_node(*node_allocator_, condition );
31223  details::free_node(*node_allocator_, incrementor);
31224 
31225  return loop_body;
31226  }
31227 
31228  loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_for_loop);
31229 
31230  if (!break_continue_present)
31231  {
31232  if (rtc)
31233  return node_allocator_->allocate<for_loop_rtc_node_t>
31234  (
31235  initialiser,
31236  condition,
31237  incrementor,
31238  loop_body,
31239  rtc
31240  );
31241  else
31242  return node_allocator_->allocate<for_loop_node_t>
31243  (
31244  initialiser,
31245  condition,
31246  incrementor,
31247  loop_body
31248  );
31249  }
31250  #ifndef exprtk_disable_break_continue
31251  else
31252  {
31253  if (rtc)
31254  return node_allocator_->allocate<for_loop_bc_rtc_node_t>
31255  (
31256  initialiser,
31257  condition,
31258  incrementor,
31259  loop_body,
31260  rtc
31261  );
31262  else
31263  return node_allocator_->allocate<for_loop_bc_node_t>
31264  (
31265  initialiser,
31266  condition,
31267  incrementor,
31268  loop_body
31269  );
31270  }
31271  #else
31272  return error_node();
31273  #endif
31274  }
31275 
31276  template <typename Allocator,
31277  template <typename, typename> class Sequence>
31278  inline expression_node_ptr const_optimise_switch(Sequence<expression_node_ptr,Allocator>& arg_list)
31279  {
31280  expression_node_ptr result = error_node();
31281 
31282  for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
31283  {
31284  expression_node_ptr condition = arg_list[(2 * i) ];
31285  expression_node_ptr consequent = arg_list[(2 * i) + 1];
31286 
31287  if ((0 == result) && details::is_true(condition))
31288  {
31289  result = consequent;
31290  break;
31291  }
31292  }
31293 
31294  if (0 == result)
31295  {
31296  result = arg_list.back();
31297  }
31298 
31299  for (std::size_t i = 0; i < arg_list.size(); ++i)
31300  {
31301  expression_node_ptr current_expr = arg_list[i];
31302 
31303  if (current_expr && (current_expr != result))
31304  {
31305  free_node(*node_allocator_,current_expr);
31306  }
31307  }
31308 
31309  return result;
31310  }
31311 
31312  template <typename Allocator,
31313  template <typename, typename> class Sequence>
31314  inline expression_node_ptr const_optimise_mswitch(Sequence<expression_node_ptr,Allocator>& arg_list)
31315  {
31316  expression_node_ptr result = error_node();
31317 
31318  for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
31319  {
31320  expression_node_ptr condition = arg_list[(2 * i) ];
31321  expression_node_ptr consequent = arg_list[(2 * i) + 1];
31322 
31323  if (details::is_true(condition))
31324  {
31325  result = consequent;
31326  }
31327  }
31328 
31329  if (0 == result)
31330  {
31331  const T zero = T(0);
31332  result = node_allocator_->allocate<literal_node_t>(zero);
31333  }
31334 
31335  for (std::size_t i = 0; i < arg_list.size(); ++i)
31336  {
31337  expression_node_ptr& current_expr = arg_list[i];
31338 
31339  if (current_expr && (current_expr != result))
31340  {
31341  details::free_node(*node_allocator_,current_expr);
31342  }
31343  }
31344 
31345  return result;
31346  }
31347 
31349  {
31350  typedef std::vector<std::pair<expression_node_ptr,bool> > arg_list_t;
31351 
31352  #define case_stmt(N) \
31353  if (is_true(arg[(2 * N)].first)) { return arg[(2 * N) + 1].first->value(); } \
31354 
31356  {
31357  static inline T process(const arg_list_t& arg)
31358  {
31359  case_stmt(0)
31360 
31361  assert(arg.size() == ((2 * 1) + 1));
31362 
31363  return arg.back().first->value();
31364  }
31365  };
31366 
31368  {
31369  static inline T process(const arg_list_t& arg)
31370  {
31371  case_stmt(0) case_stmt(1)
31372 
31373  assert(arg.size() == ((2 * 2) + 1));
31374 
31375  return arg.back().first->value();
31376  }
31377  };
31378 
31380  {
31381  static inline T process(const arg_list_t& arg)
31382  {
31383  case_stmt(0) case_stmt(1)
31384  case_stmt(2)
31385 
31386  assert(arg.size() == ((2 * 3) + 1));
31387 
31388  return arg.back().first->value();
31389  }
31390  };
31391 
31393  {
31394  static inline T process(const arg_list_t& arg)
31395  {
31396  case_stmt(0) case_stmt(1)
31397  case_stmt(2) case_stmt(3)
31398 
31399  assert(arg.size() == ((2 * 4) + 1));
31400 
31401  return arg.back().first->value();
31402  }
31403  };
31404 
31406  {
31407  static inline T process(const arg_list_t& arg)
31408  {
31409  case_stmt(0) case_stmt(1)
31410  case_stmt(2) case_stmt(3)
31411  case_stmt(4)
31412 
31413  assert(arg.size() == ((2 * 5) + 1));
31414 
31415  return arg.back().first->value();
31416  }
31417  };
31418 
31420  {
31421  static inline T process(const arg_list_t& arg)
31422  {
31423  case_stmt(0) case_stmt(1)
31424  case_stmt(2) case_stmt(3)
31425  case_stmt(4) case_stmt(5)
31426 
31427  assert(arg.size() == ((2 * 6) + 1));
31428 
31429  return arg.back().first->value();
31430  }
31431  };
31432 
31434  {
31435  static inline T process(const arg_list_t& arg)
31436  {
31437  case_stmt(0) case_stmt(1)
31438  case_stmt(2) case_stmt(3)
31439  case_stmt(4) case_stmt(5)
31440  case_stmt(6)
31441 
31442  assert(arg.size() == ((2 * 7) + 1));
31443 
31444  return arg.back().first->value();
31445  }
31446  };
31447 
31448  #undef case_stmt
31449  };
31450 
31451  template <typename Allocator,
31452  template <typename, typename> class Sequence>
31453  inline expression_node_ptr switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list, const bool default_statement_present)
31454  {
31455  if (arg_list.empty())
31456  return error_node();
31457  else if (
31458  !all_nodes_valid(arg_list) ||
31459  (!default_statement_present && (arg_list.size() < 2))
31460  )
31461  {
31462  details::free_all_nodes(*node_allocator_,arg_list);
31463 
31464  return error_node();
31465  }
31466  else if (is_constant_foldable(arg_list))
31467  return const_optimise_switch(arg_list);
31468 
31469  switch ((arg_list.size() - 1) / 2)
31470  {
31471  #define case_stmt(N) \
31472  case N : \
31473  return node_allocator_-> \
31474  allocate<details::switch_n_node \
31475  <Type,typename switch_nodes::switch_impl_##N > >(arg_list); \
31476 
31477  case_stmt(1)
31478  case_stmt(2)
31479  case_stmt(3)
31480  case_stmt(4)
31481  case_stmt(5)
31482  case_stmt(6)
31483  case_stmt(7)
31484  #undef case_stmt
31485 
31486  default : return node_allocator_->allocate<details::switch_node<Type> >(arg_list);
31487  }
31488  }
31489 
31490  template <typename Allocator,
31491  template <typename, typename> class Sequence>
31492  inline expression_node_ptr multi_switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list)
31493  {
31494  if (!all_nodes_valid(arg_list))
31495  {
31496  details::free_all_nodes(*node_allocator_,arg_list);
31497 
31498  return error_node();
31499  }
31500  else if (is_constant_foldable(arg_list))
31501  return const_optimise_mswitch(arg_list);
31502  else
31503  return node_allocator_->allocate<details::multi_switch_node<Type> >(arg_list);
31504  }
31505 
31506  #define unary_opr_switch_statements \
31507  case_stmt(details::e_abs , details::abs_op ) \
31508  case_stmt(details::e_acos , details::acos_op ) \
31509  case_stmt(details::e_acosh , details::acosh_op) \
31510  case_stmt(details::e_asin , details::asin_op ) \
31511  case_stmt(details::e_asinh , details::asinh_op) \
31512  case_stmt(details::e_atan , details::atan_op ) \
31513  case_stmt(details::e_atanh , details::atanh_op) \
31514  case_stmt(details::e_ceil , details::ceil_op ) \
31515  case_stmt(details::e_cos , details::cos_op ) \
31516  case_stmt(details::e_cosh , details::cosh_op ) \
31517  case_stmt(details::e_exp , details::exp_op ) \
31518  case_stmt(details::e_expm1 , details::expm1_op) \
31519  case_stmt(details::e_floor , details::floor_op) \
31520  case_stmt(details::e_log , details::log_op ) \
31521  case_stmt(details::e_log10 , details::log10_op) \
31522  case_stmt(details::e_log2 , details::log2_op ) \
31523  case_stmt(details::e_log1p , details::log1p_op) \
31524  case_stmt(details::e_neg , details::neg_op ) \
31525  case_stmt(details::e_pos , details::pos_op ) \
31526  case_stmt(details::e_round , details::round_op) \
31527  case_stmt(details::e_sin , details::sin_op ) \
31528  case_stmt(details::e_sinc , details::sinc_op ) \
31529  case_stmt(details::e_sinh , details::sinh_op ) \
31530  case_stmt(details::e_sqrt , details::sqrt_op ) \
31531  case_stmt(details::e_tan , details::tan_op ) \
31532  case_stmt(details::e_tanh , details::tanh_op ) \
31533  case_stmt(details::e_cot , details::cot_op ) \
31534  case_stmt(details::e_sec , details::sec_op ) \
31535  case_stmt(details::e_csc , details::csc_op ) \
31536  case_stmt(details::e_r2d , details::r2d_op ) \
31537  case_stmt(details::e_d2r , details::d2r_op ) \
31538  case_stmt(details::e_d2g , details::d2g_op ) \
31539  case_stmt(details::e_g2d , details::g2d_op ) \
31540  case_stmt(details::e_notl , details::notl_op ) \
31541  case_stmt(details::e_sgn , details::sgn_op ) \
31542  case_stmt(details::e_erf , details::erf_op ) \
31543  case_stmt(details::e_erfc , details::erfc_op ) \
31544  case_stmt(details::e_ncdf , details::ncdf_op ) \
31545  case_stmt(details::e_frac , details::frac_op ) \
31546  case_stmt(details::e_trunc , details::trunc_op) \
31547 
31549  expression_node_ptr (&branch)[1])
31550  {
31551  T& v = static_cast<details::variable_node<T>*>(branch[0])->ref();
31552 
31553  switch (operation)
31554  {
31555  #define case_stmt(op0, op1) \
31556  case op0 : return node_allocator_-> \
31557  allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \
31558 
31560  #undef case_stmt
31561  default : return error_node();
31562  }
31563  }
31564 
31566  expression_node_ptr (&branch)[1])
31567  {
31568  switch (operation)
31569  {
31570  #define case_stmt(op0, op1) \
31571  case op0 : return node_allocator_-> \
31572  allocate<typename details::unary_vector_node<Type,op1<Type> > > \
31573  (operation, branch[0]); \
31574 
31576  #undef case_stmt
31577  default : return error_node();
31578  }
31579  }
31580 
31582  expression_node_ptr (&branch)[1])
31583  {
31584  switch (operation)
31585  {
31586  #define case_stmt(op0, op1) \
31587  case op0 : return node_allocator_-> \
31588  allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \
31589 
31591  #undef case_stmt
31592  default : return error_node();
31593  }
31594  }
31595 
31597  expression_node_ptr (&branch)[3])
31598  {
31599  expression_node_ptr temp_node = error_node();
31600 
31601  switch (operation)
31602  {
31603  #define case_stmt(op) \
31604  case details::e_sf##op : temp_node = node_allocator_-> \
31605  allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
31606  (operation, branch); \
31607  break; \
31608 
31609  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
31610  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
31611  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
31612  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
31613  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
31614  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
31615  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
31616  case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
31617  case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
31618  case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
31619  case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
31620  case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
31621  #undef case_stmt
31622  default : return error_node();
31623  }
31624 
31625  assert(temp_node);
31626 
31627  const T v = temp_node->value();
31628 
31629  details::free_node(*node_allocator_,temp_node);
31630 
31631  return node_allocator_->allocate<literal_node_t>(v);
31632  }
31633 
31635  {
31636  typedef details::variable_node<Type>* variable_ptr;
31637 
31638  const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
31639  const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
31640  const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
31641 
31642  switch (operation)
31643  {
31644  #define case_stmt(op) \
31645  case details::e_sf##op : return node_allocator_-> \
31646  allocate_rrr<details::sf3_var_node<Type,details::sf##op##_op<Type> > > \
31647  (v0, v1, v2); \
31648 
31649  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
31650  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
31651  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
31652  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
31653  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
31654  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
31655  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
31656  case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
31657  case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
31658  case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
31659  case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
31660  case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
31661  #undef case_stmt
31662  default : return error_node();
31663  }
31664  }
31665 
31667  {
31668  if (!all_nodes_valid(branch))
31669  return error_node();
31670  else if (is_constant_foldable(branch))
31671  return const_optimise_sf3(operation,branch);
31672  else if (all_nodes_variables(branch))
31673  return varnode_optimise_sf3(operation,branch);
31674  else
31675  {
31676  switch (operation)
31677  {
31678  #define case_stmt(op) \
31679  case details::e_sf##op : return node_allocator_-> \
31680  allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
31681  (operation, branch); \
31682 
31683  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
31684  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
31685  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
31686  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
31687  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
31688  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
31689  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
31690  case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
31691  case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
31692  case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
31693  case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
31694  case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
31695  #undef case_stmt
31696  default : return error_node();
31697  }
31698  }
31699  }
31700 
31702  {
31703  expression_node_ptr temp_node = error_node();
31704 
31705  switch (operation)
31706  {
31707  #define case_stmt(op) \
31708  case details::e_sf##op : temp_node = node_allocator_-> \
31709  allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
31710  (operation, branch); \
31711  break; \
31712 
31713  case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
31714  case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
31715  case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
31716  case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
31717  case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
31718  case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
31719  case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
31720  case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
31721  case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
31722  case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
31723  case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
31724  case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
31725  case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
31726  #undef case_stmt
31727  default : return error_node();
31728  }
31729 
31730  assert(temp_node);
31731 
31732  const T v = temp_node->value();
31733 
31734  details::free_node(*node_allocator_,temp_node);
31735 
31736  return node_allocator_->allocate<literal_node_t>(v);
31737  }
31738 
31740  {
31741  typedef details::variable_node<Type>* variable_ptr;
31742 
31743  const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
31744  const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
31745  const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
31746  const Type& v3 = static_cast<variable_ptr>(branch[3])->ref();
31747 
31748  switch (operation)
31749  {
31750  #define case_stmt(op) \
31751  case details::e_sf##op : return node_allocator_-> \
31752  allocate_rrrr<details::sf4_var_node<Type,details::sf##op##_op<Type> > > \
31753  (v0, v1, v2, v3); \
31754 
31755  case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
31756  case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
31757  case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
31758  case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
31759  case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
31760  case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
31761  case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
31762  case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
31763  case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
31764  case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
31765  case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
31766  case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
31767  case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
31768  #undef case_stmt
31769  default : return error_node();
31770  }
31771  }
31772 
31774  {
31775  if (!all_nodes_valid(branch))
31776  return error_node();
31777  else if (is_constant_foldable(branch))
31778  return const_optimise_sf4(operation,branch);
31779  else if (all_nodes_variables(branch))
31780  return varnode_optimise_sf4(operation,branch);
31781  switch (operation)
31782  {
31783  #define case_stmt(op) \
31784  case details::e_sf##op : return node_allocator_-> \
31785  allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
31786  (operation, branch); \
31787 
31788  case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
31789  case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
31790  case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
31791  case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
31792  case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
31793  case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
31794  case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
31795  case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
31796  case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
31797  case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
31798  case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
31799  case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
31800  case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
31801  #undef case_stmt
31802  default : return error_node();
31803  }
31804  }
31805 
31806  template <typename Allocator,
31807  template <typename, typename> class Sequence>
31808  inline expression_node_ptr const_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
31809  {
31810  expression_node_ptr temp_node = error_node();
31811 
31812  switch (operation)
31813  {
31814  #define case_stmt(op0, op1) \
31815  case op0 : temp_node = node_allocator_-> \
31816  allocate<details::vararg_node<Type,op1<Type> > > \
31817  (arg_list); \
31818  break; \
31819 
31820  case_stmt(details::e_sum , details::vararg_add_op )
31821  case_stmt(details::e_prod , details::vararg_mul_op )
31822  case_stmt(details::e_avg , details::vararg_avg_op )
31823  case_stmt(details::e_min , details::vararg_min_op )
31824  case_stmt(details::e_max , details::vararg_max_op )
31825  case_stmt(details::e_mand , details::vararg_mand_op )
31826  case_stmt(details::e_mor , details::vararg_mor_op )
31827  case_stmt(details::e_multi , details::vararg_multi_op)
31828  #undef case_stmt
31829  default : return error_node();
31830  }
31831 
31832  const T v = temp_node->value();
31833 
31834  details::free_node(*node_allocator_,temp_node);
31835 
31836  return node_allocator_->allocate<literal_node_t>(v);
31837  }
31838 
31839  inline bool special_one_parameter_vararg(const details::operator_type& operation) const
31840  {
31841  return (
31842  (details::e_sum == operation) ||
31843  (details::e_prod == operation) ||
31844  (details::e_avg == operation) ||
31845  (details::e_min == operation) ||
31846  (details::e_max == operation)
31847  );
31848  }
31849 
31850  template <typename Allocator,
31851  template <typename, typename> class Sequence>
31852  inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
31853  {
31854  switch (operation)
31855  {
31856  #define case_stmt(op0, op1) \
31857  case op0 : return node_allocator_-> \
31858  allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \
31859 
31860  case_stmt(details::e_sum , details::vararg_add_op )
31861  case_stmt(details::e_prod , details::vararg_mul_op )
31862  case_stmt(details::e_avg , details::vararg_avg_op )
31863  case_stmt(details::e_min , details::vararg_min_op )
31864  case_stmt(details::e_max , details::vararg_max_op )
31865  case_stmt(details::e_mand , details::vararg_mand_op )
31866  case_stmt(details::e_mor , details::vararg_mor_op )
31867  case_stmt(details::e_multi , details::vararg_multi_op)
31868  #undef case_stmt
31869  default : return error_node();
31870  }
31871  }
31872 
31873  template <typename Allocator,
31874  template <typename, typename> class Sequence>
31875  inline expression_node_ptr vectorize_func(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
31876  {
31877  if (1 == arg_list.size())
31878  {
31879  switch (operation)
31880  {
31881  #define case_stmt(op0, op1) \
31882  case op0 : return node_allocator_-> \
31883  allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \
31884 
31890  #undef case_stmt
31891  default : return error_node();
31892  }
31893  }
31894  else
31895  return error_node();
31896  }
31897 
31898  template <typename Allocator,
31899  template <typename, typename> class Sequence>
31900  inline expression_node_ptr vararg_function(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
31901  {
31902  if (!all_nodes_valid(arg_list))
31903  {
31904  details::free_all_nodes(*node_allocator_,arg_list);
31905 
31906  return error_node();
31907  }
31908  else if (is_constant_foldable(arg_list))
31909  return const_optimise_varargfunc(operation,arg_list);
31910  else if ((1 == arg_list.size()) && details::is_ivector_node(arg_list[0]))
31911  return vectorize_func(operation,arg_list);
31912  else if ((1 == arg_list.size()) && special_one_parameter_vararg(operation))
31913  return arg_list[0];
31914  else if (all_nodes_variables(arg_list))
31915  return varnode_optimise_varargfunc(operation,arg_list);
31916 
31917  #ifndef exprtk_disable_string_capabilities
31918  if (details::e_smulti == operation)
31919  {
31920  expression_node_ptr result = node_allocator_->
31921  allocate<details::str_vararg_node<Type,details::vararg_multi_op<Type> > >(arg_list);
31922  if (result && result->valid())
31923  {
31924  return result;
31925  }
31926 
31927  parser_->set_error(parser_error::make_error(
31929  token_t(),
31930  "ERR231 - Failed to synthesize node: str_vararg_node<vararg_multi_op>",
31932 
31933  details::free_node(*node_allocator_, result);
31934  }
31935  else
31936  #endif
31937  {
31938  expression_node_ptr result = error_node();
31939 
31940  switch (operation)
31941  {
31942  #define case_stmt(op0, op1) \
31943  case op0 : result = node_allocator_-> \
31944  allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \
31945  break; \
31946 
31947  case_stmt(details::e_sum , details::vararg_add_op )
31948  case_stmt(details::e_prod , details::vararg_mul_op )
31949  case_stmt(details::e_avg , details::vararg_avg_op )
31950  case_stmt(details::e_min , details::vararg_min_op )
31951  case_stmt(details::e_max , details::vararg_max_op )
31952  case_stmt(details::e_mand , details::vararg_mand_op )
31953  case_stmt(details::e_mor , details::vararg_mor_op )
31954  case_stmt(details::e_multi , details::vararg_multi_op)
31955  #undef case_stmt
31956  default : return error_node();
31957  }
31958 
31959  if (result && result->valid())
31960  {
31961  return result;
31962  }
31963 
31964  parser_->set_error(parser_error::make_error(
31966  token_t(),
31967  "ERR232 - Failed to synthesize node: vararg_node",
31969 
31970  details::free_node(*node_allocator_, result);
31971  }
31972 
31973  return error_node();
31974  }
31975 
31976  template <std::size_t N>
31978  {
31979  typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
31980  expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b);
31981 
31982  if (0 == result)
31983  return error_node();
31984  else
31985  {
31986  // Can the function call be completely optimised?
31987  if (details::is_constant_node(result))
31988  return result;
31989  else if (!all_nodes_valid(b))
31990  {
31991  details::free_node(*node_allocator_,result);
31992  std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0));
31993 
31994  return error_node();
31995  }
31996  else if (N != f->param_count)
31997  {
31998  details::free_node(*node_allocator_,result);
31999  std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0));
32000 
32001  return error_node();
32002  }
32003 
32004  function_N_node_t* func_node_ptr = reinterpret_cast<function_N_node_t*>(result);
32005 
32006  if (!func_node_ptr->init_branches(b))
32007  {
32008  details::free_node(*node_allocator_,result);
32009  std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0));
32010 
32011  return error_node();
32012  }
32013 
32014  if (result && result->valid())
32015  {
32016  return result;
32017  }
32018 
32019  parser_->set_error(parser_error::make_error(
32021  token_t(),
32022  "ERR233 - Failed to synthesize node: function_N_node_t",
32024 
32025  details::free_node(*node_allocator_, result);
32026  return error_node();
32027  }
32028  }
32029 
32030  inline expression_node_ptr function(ifunction_t* f)
32031  {
32032  typedef typename details::function_N_node<Type,ifunction_t,0> function_N_node_t;
32033  return node_allocator_->allocate<function_N_node_t>(f);
32034  }
32035 
32037  std::vector<expression_node_ptr>& arg_list)
32038  {
32039  if (!all_nodes_valid(arg_list))
32040  {
32041  details::free_all_nodes(*node_allocator_,arg_list);
32042 
32043  return error_node();
32044  }
32045 
32046  typedef details::vararg_function_node<Type,ivararg_function_t> alloc_type;
32047 
32048  expression_node_ptr result = node_allocator_->allocate<alloc_type>(vaf,arg_list);
32049 
32050  if (
32051  !arg_list.empty() &&
32052  !vaf->has_side_effects() &&
32053  is_constant_foldable(arg_list)
32054  )
32055  {
32056  const Type v = result->value();
32057  details::free_node(*node_allocator_,result);
32058  result = node_allocator_->allocate<literal_node_t>(v);
32059  }
32060 
32061  parser_->state_.activate_side_effect("vararg_function_call()");
32062 
32063  if (result && result->valid())
32064  {
32065  return result;
32066  }
32067 
32068  parser_->set_error(parser_error::make_error(
32070  token_t(),
32071  "ERR234 - Failed to synthesize node: vararg_function_node<ivararg_function_t>",
32073 
32074  details::free_node(*node_allocator_, result);
32075  return error_node();
32076  }
32077 
32079  std::vector<expression_node_ptr>& arg_list,
32080  const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
32081  {
32082  if (!all_nodes_valid(arg_list))
32083  {
32084  details::free_all_nodes(*node_allocator_,arg_list);
32085  return error_node();
32086  }
32087 
32090 
32091  const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
32092 
32093  expression_node_ptr result = error_node();
32094  std::string node_name = "Unknown";
32095 
32096  if (no_psi == param_seq_index)
32097  {
32098  result = node_allocator_->allocate<alloc_type1>(arg_list,gf);
32099  node_name = "generic_function_node<igeneric_function_t>";
32100  }
32101  else
32102  {
32103  result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
32104  node_name = "multimode_genfunction_node<igeneric_function_t>";
32105  }
32106 
32107  alloc_type1* genfunc_node_ptr = static_cast<alloc_type1*>(result);
32108 
32109  assert(genfunc_node_ptr);
32110 
32111  if (
32112  !arg_list.empty() &&
32113  !gf->has_side_effects() &&
32114  parser_->state_.type_check_enabled &&
32115  is_constant_foldable(arg_list)
32116  )
32117  {
32118  genfunc_node_ptr->init_branches();
32119 
32120  const Type v = result->value();
32121 
32122  details::free_node(*node_allocator_,result);
32123 
32124  return node_allocator_->allocate<literal_node_t>(v);
32125  }
32126  else if (genfunc_node_ptr->init_branches())
32127  {
32128  if (result && result->valid())
32129  {
32130  parser_->state_.activate_side_effect("generic_function_call()");
32131  return result;
32132  }
32133 
32134  parser_->set_error(parser_error::make_error(
32136  token_t(),
32137  "ERR235 - Failed to synthesize node: " + node_name,
32139 
32140  details::free_node(*node_allocator_, result);
32141  return error_node();
32142  }
32143  else
32144  {
32145  details::free_node(*node_allocator_, result);
32146  details::free_all_nodes(*node_allocator_, arg_list);
32147 
32148  return error_node();
32149  }
32150  }
32151 
32152  #ifndef exprtk_disable_string_capabilities
32154  std::vector<expression_node_ptr>& arg_list,
32155  const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
32156  {
32157  if (!all_nodes_valid(arg_list))
32158  {
32159  details::free_all_nodes(*node_allocator_,arg_list);
32160  return error_node();
32161  }
32162 
32164  typedef details::multimode_strfunction_node<Type,igeneric_function_t> alloc_type2;
32165 
32166  const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
32167 
32168  expression_node_ptr result = error_node();
32169  std::string node_name = "Unknown";
32170 
32171  if (no_psi == param_seq_index)
32172  {
32173  result = node_allocator_->allocate<alloc_type1>(gf,arg_list);
32174  node_name = "string_function_node<igeneric_function_t>";
32175  }
32176  else
32177  {
32178  result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
32179  node_name = "multimode_strfunction_node<igeneric_function_t>";
32180  }
32181 
32182  alloc_type1* strfunc_node_ptr = static_cast<alloc_type1*>(result);
32183 
32184  assert(strfunc_node_ptr);
32185 
32186  if (
32187  !arg_list.empty() &&
32188  !gf->has_side_effects() &&
32189  is_constant_foldable(arg_list)
32190  )
32191  {
32192  strfunc_node_ptr->init_branches();
32193 
32194  const Type v = result->value();
32195 
32196  details::free_node(*node_allocator_,result);
32197 
32198  return node_allocator_->allocate<literal_node_t>(v);
32199  }
32200  else if (strfunc_node_ptr->init_branches())
32201  {
32202  if (result && result->valid())
32203  {
32204  parser_->state_.activate_side_effect("string_function_call()");
32205  return result;
32206  }
32207 
32208  parser_->set_error(parser_error::make_error(
32210  token_t(),
32211  "ERR236 - Failed to synthesize node: " + node_name,
32213 
32214  details::free_node(*node_allocator_, result);
32215  return error_node();
32216  }
32217  else
32218  {
32219  details::free_node (*node_allocator_,result );
32220  details::free_all_nodes(*node_allocator_,arg_list);
32221 
32222  return error_node();
32223  }
32224  }
32225  #endif
32226 
32227  #ifndef exprtk_disable_return_statement
32228  inline expression_node_ptr return_call(std::vector<expression_node_ptr>& arg_list)
32229  {
32230  if (!all_nodes_valid(arg_list))
32231  {
32232  details::free_all_nodes(*node_allocator_,arg_list);
32233  return error_node();
32234  }
32235 
32236  typedef details::return_node<Type> alloc_type;
32237 
32238  expression_node_ptr result = node_allocator_->
32239  allocate_rr<alloc_type>(arg_list,parser_->results_ctx());
32240 
32241  alloc_type* return_node_ptr = static_cast<alloc_type*>(result);
32242 
32243  assert(return_node_ptr);
32244 
32245  if (return_node_ptr->init_branches())
32246  {
32247  if (result && result->valid())
32248  {
32249  parser_->state_.activate_side_effect("return_call()");
32250  return result;
32251  }
32252 
32253  parser_->set_error(parser_error::make_error(
32255  token_t(),
32256  "ERR237 - Failed to synthesize node: return_node",
32258 
32259  details::free_node(*node_allocator_, result);
32260  return error_node();
32261  }
32262  else
32263  {
32264  details::free_node (*node_allocator_, result );
32265  details::free_all_nodes(*node_allocator_, arg_list);
32266 
32267  return error_node();
32268  }
32269  }
32270 
32272  results_context_t* rc,
32273  bool*& return_invoked)
32274  {
32275  typedef details::return_envelope_node<Type> alloc_type;
32276 
32277  expression_node_ptr result = node_allocator_->
32278  allocate_cr<alloc_type>(body,(*rc));
32279 
32280  return_invoked = static_cast<alloc_type*>(result)->retinvk_ptr();
32281 
32282  return result;
32283  }
32284  #else
32285  inline expression_node_ptr return_call(std::vector<expression_node_ptr>&)
32286  {
32287  return error_node();
32288  }
32289 
32290  inline expression_node_ptr return_envelope(expression_node_ptr,
32291  results_context_t*,
32292  bool*&)
32293  {
32294  return error_node();
32295  }
32296  #endif
32297 
32298  inline expression_node_ptr vector_element(const std::string& symbol,
32299  vector_holder_ptr vector_base,
32300  expression_node_ptr vec_node,
32301  expression_node_ptr index)
32302  {
32303  expression_node_ptr result = error_node();
32304  std::string node_name = "Unknown";
32305 
32306  if (details::is_constant_node(index))
32307  {
32308  std::size_t vec_index = static_cast<std::size_t>(details::numeric::to_int64(index->value()));
32309 
32310  details::free_node(*node_allocator_,index);
32311 
32312  if (vec_index >= vector_base->size())
32313  {
32314  parser_->set_error(parser_error::make_error(
32316  token_t(),
32317  "ERR238 - Index of " + details::to_str(vec_index) + " out of range for "
32318  "vector '" + symbol + "' of size " + details::to_str(vector_base->size()),
32320 
32321  details::free_node(*node_allocator_,vec_node);
32322 
32323  return error_node();
32324  }
32325 
32326  if (vector_base->rebaseable())
32327  {
32328  vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check();
32329 
32330  result = (rtc) ?
32331  node_allocator_->allocate<rebasevector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) :
32332  node_allocator_->allocate<rebasevector_celem_node_t >(vec_node, vec_index, vector_base ) ;
32333 
32334  node_name = (rtc) ?
32335  "rebasevector_elem_rtc_node_t" :
32336  "rebasevector_elem_node_t" ;
32337 
32338  if (result && result->valid())
32339  {
32340  return result;
32341  }
32342 
32343  parser_->set_error(parser_error::make_error(
32345  token_t(),
32346  "ERR239 - Failed to synthesize node: " + node_name + " for vector: " + symbol,
32348 
32349  details::free_node(*node_allocator_, result);
32350  return error_node();
32351  }
32352  else if (details::is_ivector_node(vec_node) && !details::is_vector_node(vec_node))
32353  {
32354  vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check();
32355 
32356  result = (rtc) ?
32357  node_allocator_->allocate<vector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) :
32358  node_allocator_->allocate<vector_celem_node_t >(vec_node, vec_index, vector_base ) ;
32359 
32360  node_name = (rtc) ?
32361  "vector_elem_rtc_node_t" :
32362  "vector_elem_node_t" ;
32363 
32364  if (result && result->valid())
32365  {
32366  return result;
32367  }
32368 
32369  parser_->set_error(parser_error::make_error(
32371  token_t(),
32372  "ERR240 - Failed to synthesize node: " + node_name + " for vector: " + symbol,
32374 
32375  details::free_node(*node_allocator_, result);
32376  return error_node();
32377  }
32378 
32379  const scope_element& se = parser_->sem_.get_element(symbol,vec_index);
32380 
32381  if (se.index == vec_index)
32382  {
32383  result = se.var_node;
32384  details::free_node(*node_allocator_,vec_node);
32385  }
32386  else
32387  {
32388  scope_element nse;
32389  nse.name = symbol;
32390  nse.active = true;
32391  nse.ref_count = 1;
32392  nse.type = scope_element::e_vecelem;
32393  nse.index = vec_index;
32394  nse.depth = parser_->state_.scope_depth;
32395  nse.data = 0;
32396  nse.var_node = node_allocator_->allocate<variable_node_t>((*(*vector_base)[vec_index]));
32397 
32398  if (!parser_->sem_.add_element(nse))
32399  {
32400  parser_->set_synthesis_error("Failed to add new local vector element to SEM [1]");
32401 
32402  parser_->sem_.free_element(nse);
32403 
32404  result = error_node();
32405  }
32406 
32407  details::free_node(*node_allocator_,vec_node);
32408 
32409  exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n", nse.name.c_str()));
32410 
32411  parser_->state_.activate_side_effect("vector_element()");
32412 
32413  result = nse.var_node;
32414  node_name = "variable_node_t";
32415  }
32416  }
32417  else
32418  {
32419  vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check();
32420 
32421  if (vector_base->rebaseable())
32422  {
32423  result = (rtc) ?
32424  node_allocator_->allocate<rebasevector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) :
32425  node_allocator_->allocate<rebasevector_elem_node_t >(vec_node, index, vector_base ) ;
32426 
32427  node_name = (rtc) ?
32428  "rebasevector_elem_rtc_node_t" :
32429  "rebasevector_elem_node_t" ;
32430  }
32431  else
32432  {
32433  result = rtc ?
32434  node_allocator_->allocate<vector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) :
32435  node_allocator_->allocate<vector_elem_node_t >(vec_node, index, vector_base ) ;
32436 
32437  node_name = (rtc) ?
32438  "vector_elem_rtc_node_t" :
32439  "vector_elem_node_t" ;
32440  }
32441  }
32442 
32443  if (result && result->valid())
32444  {
32445  return result;
32446  }
32447 
32448  parser_->set_error(parser_error::make_error(
32450  token_t(),
32451  "ERR241 - Failed to synthesize node: " + node_name,
32453 
32454  details::free_node(*node_allocator_, result);
32455  return error_node();
32456  }
32457 
32458  private:
32459 
32460  template <std::size_t N, typename NodePtr>
32461  inline bool is_constant_foldable(NodePtr (&b)[N]) const
32462  {
32463  for (std::size_t i = 0; i < N; ++i)
32464  {
32465  if (0 == b[i])
32466  return false;
32467  else if (!details::is_constant_node(b[i]))
32468  return false;
32469  }
32470 
32471  return true;
32472  }
32473 
32474  template <typename NodePtr,
32475  typename Allocator,
32476  template <typename, typename> class Sequence>
32477  inline bool is_constant_foldable(const Sequence<NodePtr,Allocator>& b) const
32478  {
32479  for (std::size_t i = 0; i < b.size(); ++i)
32480  {
32481  if (0 == b[i])
32482  return false;
32483  else if (!details::is_constant_node(b[i]))
32484  return false;
32485  }
32486 
32487  return true;
32488  }
32489 
32491  {
32492  parser_->state_.activate_side_effect("lodge_assignment()");
32493 
32494  if (!parser_->dec_.collect_assignments())
32495  return;
32496 
32497  std::string symbol_name;
32498 
32499  switch (cst)
32500  {
32501  case e_st_variable : symbol_name = parser_->symtab_store_
32502  .get_variable_name(node);
32503  break;
32504 
32505  #ifndef exprtk_disable_string_capabilities
32506  case e_st_string : symbol_name = parser_->symtab_store_
32507  .get_stringvar_name(node);
32508  break;
32509  #endif
32510 
32511  case e_st_vector : {
32513 
32514  vector_holder_t& vh = static_cast<vector_node_t*>(node)->vec_holder();
32515 
32516  symbol_name = parser_->symtab_store_.get_vector_name(&vh);
32517  }
32518  break;
32519 
32520  case e_st_vecelem : {
32522 
32523  vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder();
32524 
32525  symbol_name = parser_->symtab_store_.get_vector_name(&vh);
32526 
32527  cst = e_st_vector;
32528  }
32529  break;
32530 
32531  default : return;
32532  }
32533 
32534  if (!symbol_name.empty())
32535  {
32536  parser_->dec_.add_assignment(symbol_name,cst);
32537  }
32538  }
32539 
32540  const void* base_ptr(expression_node_ptr node)
32541  {
32542  if (node)
32543  {
32544  switch(node->type())
32545  {
32547  return reinterpret_cast<const void*>(&static_cast<variable_node_t*>(node)->ref());
32548 
32550  return reinterpret_cast<const void*>(&static_cast<vector_elem_node_t*>(node)->ref());
32551 
32553  return reinterpret_cast<const void*>(&static_cast<vector_celem_node_t*>(node)->ref());
32554 
32556  return reinterpret_cast<const void*>(&static_cast<vector_elem_rtc_node_t*>(node)->ref());
32557 
32559  return reinterpret_cast<const void*>(&static_cast<vector_celem_rtc_node_t*>(node)->ref());
32560 
32562  return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_node_t*>(node)->ref());
32563 
32565  return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_rtc_node_t*>(node)->ref());
32566 
32568  return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_node_t*>(node)->ref());
32569 
32571  return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_rtc_node_t*>(node)->ref());
32572 
32574  return reinterpret_cast<const void*>(static_cast<vector_node_t*>(node)->vec_holder().data());
32575 
32576  #ifndef exprtk_disable_string_capabilities
32578  return reinterpret_cast<const void*>((static_cast<stringvar_node_t*>(node)->base()));
32579 
32581  return reinterpret_cast<const void*>((static_cast<string_range_node_t*>(node)->base()));
32582  #endif
32583  default : return reinterpret_cast<const void*>(0);
32584  }
32585  }
32586 
32587  return reinterpret_cast<const void*>(0);
32588  }
32589 
32591  {
32592  interval_t interval;
32593  const void* baseptr_addr = base_ptr(node);
32594 
32595  exprtk_debug(("assign_immutable_symbol - base ptr addr: %p\n", baseptr_addr));
32596 
32597  if (parser_->immutable_memory_map_.in_interval(baseptr_addr,interval))
32598  {
32599  typename immutable_symtok_map_t::iterator itr = parser_->immutable_symtok_map_.find(interval);
32600 
32601  if (parser_->immutable_symtok_map_.end() != itr)
32602  {
32603  token_t& token = itr->second;
32606  token,
32607  "ERR242 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.",
32609  }
32610  else
32611  parser_->set_synthesis_error("Unable to assign symbol is immutable.");
32612 
32613  return true;
32614  }
32615 
32616  return false;
32617  }
32618 
32620  {
32621  if (assign_immutable_symbol(branch[0]))
32622  {
32623  return error_node();
32624  }
32625  else if (details::is_variable_node(branch[0]))
32626  {
32627  lodge_assignment(e_st_variable,branch[0]);
32628  return synthesize_expression<assignment_node_t,2>(operation,branch);
32629  }
32630  else if (details::is_vector_elem_node(branch[0]) || details::is_vector_celem_node(branch[0]))
32631  {
32632  lodge_assignment(e_st_vecelem,branch[0]);
32633  return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch);
32634  }
32635  else if (details::is_vector_elem_rtc_node(branch[0]) || details::is_vector_celem_rtc_node(branch[0]))
32636  {
32637  lodge_assignment(e_st_vecelem,branch[0]);
32638  return synthesize_expression<assignment_vec_elem_rtc_node_t, 2>(operation, branch);
32639  }
32640  else if (details::is_rebasevector_elem_node(branch[0]))
32641  {
32642  lodge_assignment(e_st_vecelem,branch[0]);
32643  return synthesize_expression<assignment_rebasevec_elem_node_t, 2>(operation, branch);
32644  }
32645  else if (details::is_rebasevector_elem_rtc_node(branch[0]))
32646  {
32647  lodge_assignment(e_st_vecelem,branch[0]);
32648  return synthesize_expression<assignment_rebasevec_elem_rtc_node_t, 2>(operation, branch);
32649  }
32650  else if (details::is_rebasevector_celem_node(branch[0]))
32651  {
32652  lodge_assignment(e_st_vecelem,branch[0]);
32653  return synthesize_expression<assignment_rebasevec_celem_node_t, 2>(operation, branch);
32654  }
32655  #ifndef exprtk_disable_string_capabilities
32656  else if (details::is_string_node(branch[0]))
32657  {
32658  lodge_assignment(e_st_string,branch[0]);
32659  return synthesize_expression<assignment_string_node_t,2>(operation, branch);
32660  }
32661  else if (details::is_string_range_node(branch[0]))
32662  {
32663  lodge_assignment(e_st_string,branch[0]);
32664  return synthesize_expression<assignment_string_range_node_t,2>(operation, branch);
32665  }
32666  #endif
32667  else if (details::is_vector_node(branch[0]))
32668  {
32669  lodge_assignment(e_st_vector,branch[0]);
32670 
32671  if (details::is_ivector_node(branch[1]))
32672  return synthesize_expression<assignment_vecvec_node_t,2>(operation, branch);
32673  else
32674  return synthesize_expression<assignment_vec_node_t,2>(operation, branch);
32675  }
32676  else
32677  {
32678  parser_->set_error(parser_error::make_error(
32680  parser_->current_state().token,
32681  "ERR243 - Invalid branches for assignment operator '" + details::to_str(operation) + "'",
32683 
32684  return error_node();
32685  }
32686  }
32687 
32689  expression_node_ptr (&branch)[2])
32690  {
32691  if (assign_immutable_symbol(branch[0]))
32692  {
32693  return error_node();
32694  }
32695 
32696  expression_node_ptr result = error_node();
32697  std::string node_name = "Unknown";
32698 
32699  if (details::is_variable_node(branch[0]))
32700  {
32701  lodge_assignment(e_st_variable,branch[0]);
32702 
32703  switch (operation)
32704  {
32705  #define case_stmt(op0, op1) \
32706  case op0 : result = node_allocator_-> \
32707  template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \
32708  (operation, branch[0], branch[1]); \
32709  node_name = "assignment_op_node"; \
32710  break; \
32711 
32717  #undef case_stmt
32718  default : return error_node();
32719  }
32720  }
32721  else if (details::is_vector_elem_node(branch[0]))
32722  {
32723  lodge_assignment(e_st_vecelem,branch[0]);
32724 
32725  switch (operation)
32726  {
32727  #define case_stmt(op0, op1) \
32728  case op0 : result = node_allocator_-> \
32729  template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \
32730  (operation, branch[0], branch[1]); \
32731  node_name = "assignment_vec_elem_op_node"; \
32732  break; \
32733 
32739  #undef case_stmt
32740  default : return error_node();
32741  }
32742  }
32743  else if (details::is_vector_elem_rtc_node(branch[0]))
32744  {
32745  lodge_assignment(e_st_vecelem,branch[0]);
32746 
32747  switch (operation)
32748  {
32749  #define case_stmt(op0, op1) \
32750  case op0 : result = node_allocator_-> \
32751  template allocate_rrr<typename details::assignment_vec_elem_op_rtc_node<Type,op1<Type> > > \
32752  (operation, branch[0], branch[1]); \
32753  node_name = "assignment_vec_elem_op_rtc_node"; \
32754  break; \
32755 
32761  #undef case_stmt
32762  default : return error_node();
32763  }
32764  }
32765  else if (details::is_vector_celem_rtc_node(branch[0]))
32766  {
32767  lodge_assignment(e_st_vecelem,branch[0]);
32768 
32769  switch (operation)
32770  {
32771  #define case_stmt(op0, op1) \
32772  case op0 : result = node_allocator_-> \
32773  template allocate_rrr<typename details::assignment_vec_celem_op_rtc_node<Type,op1<Type> > > \
32774  (operation, branch[0], branch[1]); \
32775  node_name = "assignment_vec_celem_op_rtc_node"; \
32776  break; \
32777 
32783  #undef case_stmt
32784  default : return error_node();
32785  }
32786  }
32787  else if (details::is_rebasevector_elem_node(branch[0]))
32788  {
32789  lodge_assignment(e_st_vecelem,branch[0]);
32790 
32791  switch (operation)
32792  {
32793  #define case_stmt(op0, op1) \
32794  case op0 : result = node_allocator_-> \
32795  template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \
32796  (operation, branch[0], branch[1]); \
32797  node_name = "assignment_rebasevec_elem_op_node"; \
32798  break; \
32799 
32805  #undef case_stmt
32806  default : return error_node();
32807  }
32808  }
32809  else if (details::is_rebasevector_celem_node(branch[0]))
32810  {
32811  lodge_assignment(e_st_vecelem,branch[0]);
32812 
32813  switch (operation)
32814  {
32815  #define case_stmt(op0, op1) \
32816  case op0 : result = node_allocator_-> \
32817  template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \
32818  (operation, branch[0], branch[1]); \
32819  node_name = "assignment_rebasevec_celem_op_node"; \
32820  break; \
32821 
32827  #undef case_stmt
32828  default : return error_node();
32829  }
32830  }
32831  else if (details::is_rebasevector_elem_rtc_node(branch[0]))
32832  {
32833  lodge_assignment(e_st_vecelem,branch[0]);
32834 
32835  switch (operation)
32836  {
32837  #define case_stmt(op0, op1) \
32838  case op0 : result = node_allocator_-> \
32839  template allocate_rrr<typename details::assignment_rebasevec_elem_op_rtc_node<Type,op1<Type> > > \
32840  (operation, branch[0], branch[1]); \
32841  node_name = "assignment_rebasevec_elem_op_rtc_node"; \
32842  break; \
32843 
32849  #undef case_stmt
32850  default : return error_node();
32851  }
32852  }
32853  else if (details::is_rebasevector_celem_rtc_node(branch[0]))
32854  {
32855  lodge_assignment(e_st_vecelem,branch[0]);
32856 
32857  switch (operation)
32858  {
32859  #define case_stmt(op0, op1) \
32860  case op0 : result = node_allocator_-> \
32861  template allocate_rrr<typename details::assignment_rebasevec_celem_op_rtc_node<Type,op1<Type> > > \
32862  (operation, branch[0], branch[1]); \
32863  node_name = "assignment_rebasevec_celem_op_rtc_node"; \
32864  break; \
32865 
32871  #undef case_stmt
32872  default : return error_node();
32873  }
32874  }
32875  else if (details::is_vector_node(branch[0]))
32876  {
32877  lodge_assignment(e_st_vector,branch[0]);
32878 
32879  if (details::is_ivector_node(branch[1]))
32880  {
32881  switch (operation)
32882  {
32883  #define case_stmt(op0, op1) \
32884  case op0 : result = node_allocator_-> \
32885  template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \
32886  (operation, branch[0], branch[1]); \
32887  node_name = "assignment_rebasevec_celem_op_node"; \
32888  break; \
32889 
32895  #undef case_stmt
32896  default : return error_node();
32897  }
32898  }
32899  else
32900  {
32901  switch (operation)
32902  {
32903  #define case_stmt(op0, op1) \
32904  case op0 : result = node_allocator_-> \
32905  template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \
32906  (operation, branch[0], branch[1]); \
32907  node_name = "assignment_vec_op_node"; \
32908  break; \
32909 
32915  #undef case_stmt
32916  default : return error_node();
32917  }
32918  }
32919  }
32920  #ifndef exprtk_disable_string_capabilities
32921  else if (
32922  (details::e_addass == operation) &&
32923  details::is_string_node(branch[0])
32924  )
32925  {
32926  typedef details::assignment_string_node<T,details::asn_addassignment> addass_t;
32927 
32928  lodge_assignment(e_st_string,branch[0]);
32929 
32930  result = synthesize_expression<addass_t,2>(operation,branch);
32931  node_name = "assignment_string_node<T,details::asn_addassignment>";
32932  }
32933  #endif
32934  else
32935  {
32936  parser_->set_error(parser_error::make_error(
32938  parser_->current_state().token,
32939  "ERR244 - Invalid branches for assignment operator '" + details::to_str(operation) + "'",
32941 
32942  return error_node();
32943  }
32944 
32945  if (result && result->valid())
32946  {
32947  return result;
32948  }
32949 
32950  parser_->set_error(parser_error::make_error(
32952  token_t(),
32953  "ERR245 - Failed to synthesize node: " + node_name,
32955 
32956  details::free_node(*node_allocator_, result);
32957  return error_node();
32958  }
32959 
32961  expression_node_ptr (&branch)[2])
32962  {
32963  const bool is_b0_ivec = details::is_ivector_node(branch[0]);
32964  const bool is_b1_ivec = details::is_ivector_node(branch[1]);
32965 
32966  #define batch_eqineq_logic_case \
32967  case_stmt(details::e_lt , details::lt_op ) \
32968  case_stmt(details::e_lte , details::lte_op ) \
32969  case_stmt(details::e_gt , details::gt_op ) \
32970  case_stmt(details::e_gte , details::gte_op ) \
32971  case_stmt(details::e_eq , details::eq_op ) \
32972  case_stmt(details::e_ne , details::ne_op ) \
32973  case_stmt(details::e_equal , details::equal_op) \
32974  case_stmt(details::e_and , details::and_op ) \
32975  case_stmt(details::e_nand , details::nand_op ) \
32976  case_stmt(details::e_or , details::or_op ) \
32977  case_stmt(details::e_nor , details::nor_op ) \
32978  case_stmt(details::e_xor , details::xor_op ) \
32979  case_stmt(details::e_xnor , details::xnor_op ) \
32980 
32981  expression_node_ptr result = error_node();
32982  std::string node_name = "Unknown";
32983 
32984  if (is_b0_ivec && is_b1_ivec)
32985  {
32986  switch (operation)
32987  {
32988  #define case_stmt(op0, op1) \
32989  case op0 : result = node_allocator_-> \
32990  template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
32991  (operation, branch[0], branch[1]); \
32992  node_name = "vec_binop_vecvec_node"; \
32993  break; \
32994 
32996  #undef case_stmt
32997  default : return error_node();
32998  }
32999  }
33000  else if (is_b0_ivec && !is_b1_ivec)
33001  {
33002  switch (operation)
33003  {
33004  #define case_stmt(op0, op1) \
33005  case op0 : result = node_allocator_-> \
33006  template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
33007  (operation, branch[0], branch[1]); \
33008  node_name = "vec_binop_vecval_node"; \
33009  break; \
33010 
33012  #undef case_stmt
33013  default : return error_node();
33014  }
33015  }
33016  else if (!is_b0_ivec && is_b1_ivec)
33017  {
33018  switch (operation)
33019  {
33020  #define case_stmt(op0, op1) \
33021  case op0 : result = node_allocator_-> \
33022  template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
33023  (operation, branch[0], branch[1]); \
33024  node_name = "vec_binop_valvec_node"; \
33025  break; \
33026 
33028  #undef case_stmt
33029  default : return error_node();
33030  }
33031  }
33032  else
33033  return error_node();
33034 
33035  if (result && result->valid())
33036  {
33037  return result;
33038  }
33039 
33040  parser_->set_error(parser_error::make_error(
33042  token_t(),
33043  "ERR246 - Failed to synthesize node: " + node_name,
33045 
33046  details::free_node(*node_allocator_, result);
33047  return error_node();
33048 
33049  #undef batch_eqineq_logic_case
33050  }
33051 
33053  expression_node_ptr (&branch)[2])
33054  {
33055  const bool is_b0_ivec = details::is_ivector_node(branch[0]);
33056  const bool is_b1_ivec = details::is_ivector_node(branch[1]);
33057 
33058  #define vector_ops \
33059  case_stmt(details::e_add , details::add_op) \
33060  case_stmt(details::e_sub , details::sub_op) \
33061  case_stmt(details::e_mul , details::mul_op) \
33062  case_stmt(details::e_div , details::div_op) \
33063  case_stmt(details::e_mod , details::mod_op) \
33064 
33065  expression_node_ptr result = error_node();
33066  std::string node_name = "Unknown";
33067 
33068  if (is_b0_ivec && is_b1_ivec)
33069  {
33070  switch (operation)
33071  {
33072  #define case_stmt(op0, op1) \
33073  case op0 : result = node_allocator_-> \
33074  template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
33075  (operation, branch[0], branch[1]); \
33076  node_name = "vec_binop_vecvec_node"; \
33077  break; \
33078 
33079  vector_ops
33081  #undef case_stmt
33082  default : return error_node();
33083  }
33084  }
33085  else if (is_b0_ivec && !is_b1_ivec)
33086  {
33087  switch (operation)
33088  {
33089  #define case_stmt(op0, op1) \
33090  case op0 : result = node_allocator_-> \
33091  template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
33092  (operation, branch[0], branch[1]); \
33093  node_name = "vec_binop_vecval_node(b0ivec,!b1ivec)"; \
33094  break; \
33095 
33096  vector_ops
33098  #undef case_stmt
33099  default : return error_node();
33100  }
33101  }
33102  else if (!is_b0_ivec && is_b1_ivec)
33103  {
33104  switch (operation)
33105  {
33106  #define case_stmt(op0, op1) \
33107  case op0 : result = node_allocator_-> \
33108  template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
33109  (operation, branch[0], branch[1]); \
33110  node_name = "vec_binop_vecval_node(!b0ivec,b1ivec)"; \
33111  break; \
33112 
33113  vector_ops
33114  #undef case_stmt
33115  default : return error_node();
33116  }
33117  }
33118  else
33119  return error_node();
33120 
33121  if (result && result->valid())
33122  {
33123  return result;
33124  }
33125 
33126  parser_->set_error(parser_error::make_error(
33128  token_t(),
33129  "ERR247 - Failed to synthesize node: " + node_name,
33131 
33132  details::free_node(*node_allocator_, result);
33133  return error_node();
33134 
33135  #undef vector_ops
33136  }
33137 
33139  {
33140  const bool v0_is_ivar = details::is_ivariable_node(branch[0]);
33141  const bool v1_is_ivar = details::is_ivariable_node(branch[1]);
33142 
33143  const bool v0_is_ivec = details::is_ivector_node (branch[0]);
33144  const bool v1_is_ivec = details::is_ivector_node (branch[1]);
33145 
33146  #ifndef exprtk_disable_string_capabilities
33147  const bool v0_is_str = details::is_generally_string_node(branch[0]);
33148  const bool v1_is_str = details::is_generally_string_node(branch[1]);
33149  #endif
33150 
33151  expression_node_ptr result = error_node();
33152  std::string node_name = "Unknown";
33153 
33154  if (v0_is_ivar && v1_is_ivar)
33155  {
33156  typedef details::variable_node<T>* variable_node_ptr;
33157 
33158  variable_node_ptr v0 = variable_node_ptr(0);
33159  variable_node_ptr v1 = variable_node_ptr(0);
33160 
33161  if (
33162  (0 != (v0 = dynamic_cast<variable_node_ptr>(branch[0]))) &&
33163  (0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1])))
33164  )
33165  {
33166  result = node_allocator_->allocate<details::swap_node<T> >(v0,v1);
33167  node_name = "swap_node";
33168  }
33169  else
33170  {
33171  result = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
33172  node_name = "swap_generic_node";
33173  }
33174  }
33175  else if (v0_is_ivec && v1_is_ivec)
33176  {
33177  result = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
33178  node_name = "swap_vecvec_node";
33179  }
33180  #ifndef exprtk_disable_string_capabilities
33181  else if (v0_is_str && v1_is_str)
33182  {
33183  if (is_string_node(branch[0]) && is_string_node(branch[1]))
33184  {
33185  result = node_allocator_->allocate<details::swap_string_node<T> >
33186  (branch[0], branch[1]);
33187  node_name = "swap_string_node";
33188  }
33189  else
33190  {
33191  result = node_allocator_->allocate<details::swap_genstrings_node<T> >
33192  (branch[0], branch[1]);
33193  node_name = "swap_genstrings_node";
33194  }
33195  }
33196  #endif
33197  else
33198  {
33199  parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped");
33200  return error_node();
33201  }
33202 
33203  if (result && result->valid())
33204  {
33205  parser_->state_.activate_side_effect("synthesize_swap_expression()");
33206  return result;
33207  }
33208 
33209  parser_->set_error(parser_error::make_error(
33211  token_t(),
33212  "ERR248 - Failed to synthesize node: " + node_name,
33214 
33215  details::free_node(*node_allocator_, result);
33216  return error_node();
33217  }
33218 
33219  #ifndef exprtk_disable_sc_andor
33221  {
33222  expression_node_ptr result = error_node();
33223 
33224  if (details::is_constant_node(branch[0]))
33225  {
33226  if (
33227  (details::e_scand == operation) &&
33228  std::equal_to<T>()(T(0),branch[0]->value())
33229  )
33230  result = node_allocator_->allocate_c<literal_node_t>(T(0));
33231  else if (
33232  (details::e_scor == operation) &&
33233  std::not_equal_to<T>()(T(0),branch[0]->value())
33234  )
33235  result = node_allocator_->allocate_c<literal_node_t>(T(1));
33236  }
33237 
33238  if (details::is_constant_node(branch[1]) && (0 == result))
33239  {
33240  if (
33241  (details::e_scand == operation) &&
33242  std::equal_to<T>()(T(0),branch[1]->value())
33243  )
33244  result = node_allocator_->allocate_c<literal_node_t>(T(0));
33245  else if (
33246  (details::e_scor == operation) &&
33247  std::not_equal_to<T>()(T(0),branch[1]->value())
33248  )
33249  result = node_allocator_->allocate_c<literal_node_t>(T(1));
33250  }
33251 
33252  if (result)
33253  {
33254  details::free_node(*node_allocator_, branch[0]);
33255  details::free_node(*node_allocator_, branch[1]);
33256 
33257  return result;
33258  }
33259  else if (details::e_scand == operation)
33260  {
33261  return synthesize_expression<scand_node_t,2>(operation, branch);
33262  }
33263  else if (details::e_scor == operation)
33264  {
33265  return synthesize_expression<scor_node_t,2>(operation, branch);
33266  }
33267  else
33268  return error_node();
33269  }
33270  #else
33271  inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type&, expression_node_ptr (&)[2])
33272  {
33273  return error_node();
33274  }
33275  #endif
33276 
33277  #define basic_opr_switch_statements \
33278  case_stmt(details::e_add , details::add_op) \
33279  case_stmt(details::e_sub , details::sub_op) \
33280  case_stmt(details::e_mul , details::mul_op) \
33281  case_stmt(details::e_div , details::div_op) \
33282  case_stmt(details::e_mod , details::mod_op) \
33283  case_stmt(details::e_pow , details::pow_op) \
33284 
33285  #define extended_opr_switch_statements \
33286  case_stmt(details::e_lt , details::lt_op ) \
33287  case_stmt(details::e_lte , details::lte_op ) \
33288  case_stmt(details::e_gt , details::gt_op ) \
33289  case_stmt(details::e_gte , details::gte_op ) \
33290  case_stmt(details::e_eq , details::eq_op ) \
33291  case_stmt(details::e_ne , details::ne_op ) \
33292  case_stmt(details::e_and , details::and_op ) \
33293  case_stmt(details::e_nand , details::nand_op) \
33294  case_stmt(details::e_or , details::or_op ) \
33295  case_stmt(details::e_nor , details::nor_op ) \
33296  case_stmt(details::e_xor , details::xor_op ) \
33297  case_stmt(details::e_xnor , details::xnor_op) \
33298 
33299  #ifndef exprtk_disable_cardinal_pow_optimisation
33300  template <typename TType, template <typename, typename> class IPowNode>
33301  inline expression_node_ptr cardinal_pow_optimisation_impl(const TType& v, const unsigned int& p)
33302  {
33303  switch (p)
33304  {
33305  #define case_stmt(cp) \
33306  case cp : return node_allocator_-> \
33307  allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
33308 
33309  case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
33310  case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
33311  case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
33312  case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16)
33313  case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20)
33314  case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24)
33315  case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28)
33316  case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32)
33317  case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36)
33318  case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40)
33319  case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44)
33320  case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48)
33321  case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52)
33322  case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56)
33323  case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60)
33324  #undef case_stmt
33325  default : return error_node();
33326  }
33327  }
33328 
33329  inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c)
33330  {
33331  const bool not_recipricol = (c >= T(0));
33332  const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
33333 
33334  if (0 == p)
33335  return node_allocator_->allocate_c<literal_node_t>(T(1));
33336  else if (std::equal_to<T>()(T(2),c))
33337  {
33338  return node_allocator_->
33339  template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v);
33340  }
33341  else
33342  {
33343  if (not_recipricol)
33344  return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p);
33345  else
33346  return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p);
33347  }
33348  }
33349 
33350  inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const
33351  {
33352  return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
33353  }
33354 
33356  {
33357  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
33358  const bool not_recipricol = (c >= T(0));
33359  const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
33360 
33361  node_allocator_->free(branch[1]);
33362 
33363  if (0 == p)
33364  {
33365  details::free_all_nodes(*node_allocator_, branch);
33366 
33367  return node_allocator_->allocate_c<literal_node_t>(T(1));
33368  }
33369  else if (not_recipricol)
33370  return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p);
33371  else
33372  return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p);
33373  }
33374  #else
33375  inline expression_node_ptr cardinal_pow_optimisation(T&, const T&)
33376  {
33377  return error_node();
33378  }
33379 
33380  inline bool cardinal_pow_optimisable(const details::operator_type&, const T&)
33381  {
33382  return false;
33383  }
33384 
33385  inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&)[2])
33386  {
33387  return error_node();
33388  }
33389  #endif
33390 
33392  {
33394  const details::operator_type& operation,
33395  expression_node_ptr (&branch)[2])
33396  {
33397  const bool left_neg = is_neg_unary_node(branch[0]);
33398  const bool right_neg = is_neg_unary_node(branch[1]);
33399 
33400  if (left_neg && right_neg)
33401  {
33402  if (
33403  (details::e_add == operation) ||
33404  (details::e_sub == operation) ||
33405  (details::e_mul == operation) ||
33406  (details::e_div == operation)
33407  )
33408  {
33409  if (
33410  !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) ||
33411  !expr_gen.parser_->simplify_unary_negation_branch(branch[1])
33412  )
33413  {
33414  details::free_all_nodes(*expr_gen.node_allocator_,branch);
33415 
33416  return error_node();
33417  }
33418  }
33419 
33420  switch (operation)
33421  {
33422  // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1))
33423  case details::e_add : return expr_gen(details::e_neg,
33424  expr_gen.node_allocator_->
33425  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
33426  (branch[0],branch[1]));
33427 
33428  // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1)
33429  case details::e_sub : return expr_gen.node_allocator_->
33430  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
33431  (branch[1],branch[0]);
33432 
33433  default : break;
33434  }
33435  }
33436  else if (left_neg && !right_neg)
33437  {
33438  if (
33439  (details::e_add == operation) ||
33440  (details::e_sub == operation) ||
33441  (details::e_mul == operation) ||
33442  (details::e_div == operation)
33443  )
33444  {
33445  if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0]))
33446  {
33447  details::free_all_nodes(*expr_gen.node_allocator_,branch);
33448 
33449  return error_node();
33450  }
33451 
33452  switch (operation)
33453  {
33454  // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1)
33455  case details::e_add : return expr_gen.node_allocator_->
33456  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
33457  (branch[1], branch[0]);
33458 
33459  // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1))
33460  case details::e_sub : return expr_gen(details::e_neg,
33461  expr_gen.node_allocator_->
33462  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
33463  (branch[0], branch[1]));
33464 
33465  // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1))
33466  case details::e_mul : return expr_gen(details::e_neg,
33467  expr_gen.node_allocator_->
33468  template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
33469  (branch[0], branch[1]));
33470 
33471  // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1))
33472  case details::e_div : return expr_gen(details::e_neg,
33473  expr_gen.node_allocator_->
33474  template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
33475  (branch[0], branch[1]));
33476 
33477  default : return error_node();
33478  }
33479  }
33480  }
33481  else if (!left_neg && right_neg)
33482  {
33483  if (
33484  (details::e_add == operation) ||
33485  (details::e_sub == operation) ||
33486  (details::e_mul == operation) ||
33487  (details::e_div == operation)
33488  )
33489  {
33490  if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1]))
33491  {
33492  details::free_all_nodes(*expr_gen.node_allocator_,branch);
33493 
33494  return error_node();
33495  }
33496 
33497  switch (operation)
33498  {
33499  // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1)
33500  case details::e_add : return expr_gen.node_allocator_->
33501  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
33502  (branch[0], branch[1]);
33503 
33504  // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1)
33505  case details::e_sub : return expr_gen.node_allocator_->
33506  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
33507  (branch[0], branch[1]);
33508 
33509  // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1))
33510  case details::e_mul : return expr_gen(details::e_neg,
33511  expr_gen.node_allocator_->
33512  template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
33513  (branch[0], branch[1]));
33514 
33515  // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1))
33516  case details::e_div : return expr_gen(details::e_neg,
33517  expr_gen.node_allocator_->
33518  template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
33519  (branch[0], branch[1]));
33520 
33521  default : return error_node();
33522  }
33523  }
33524  }
33525 
33526  switch (operation)
33527  {
33528  #define case_stmt(op0, op1) \
33529  case op0 : return expr_gen.node_allocator_-> \
33530  template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
33531  (branch[0], branch[1]); \
33532 
33535  #undef case_stmt
33536  default : return error_node();
33537  }
33538  }
33539  };
33540 
33542  {
33544  const details::operator_type& operation,
33545  expression_node_ptr (&branch)[2])
33546  {
33547  const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
33548 
33549  #ifndef exprtk_disable_enhanced_features
33550  if (details::is_sf3ext_node(branch[1]))
33551  {
33552  expression_node_ptr result = error_node();
33553 
33554  const bool synthesis_result =
33555  synthesize_sf4ext_expression::template compile_right<vtype>
33556  (expr_gen, v, operation, branch[1], result);
33557 
33558  if (synthesis_result)
33559  {
33560  details::free_node(*expr_gen.node_allocator_,branch[1]);
33561  return result;
33562  }
33563  }
33564  #endif
33565 
33566  if (
33567  (details::e_mul == operation) ||
33568  (details::e_div == operation)
33569  )
33570  {
33571  if (details::is_uv_node(branch[1]))
33572  {
33573  typedef details::uv_base_node<Type>* uvbn_ptr_t;
33574 
33575  details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation();
33576 
33577  if (details::e_neg == o)
33578  {
33579  const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v();
33580 
33581  details::free_node(*expr_gen.node_allocator_,branch[1]);
33582 
33583  switch (operation)
33584  {
33585  case details::e_mul : return expr_gen(details::e_neg,
33586  expr_gen.node_allocator_->
33587  template allocate_rr<typename details::
33588  vov_node<Type,details::mul_op<Type> > >(v,v1));
33589 
33590  case details::e_div : return expr_gen(details::e_neg,
33591  expr_gen.node_allocator_->
33592  template allocate_rr<typename details::
33593  vov_node<Type,details::div_op<Type> > >(v,v1));
33594 
33595  default : break;
33596  }
33597  }
33598  }
33599  }
33600 
33601  switch (operation)
33602  {
33603  #define case_stmt(op0, op1) \
33604  case op0 : return expr_gen.node_allocator_-> \
33605  template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
33606  (v, branch[1]); \
33607 
33610  #undef case_stmt
33611  default : return error_node();
33612  }
33613  }
33614  };
33615 
33617  {
33619  const details::operator_type& operation,
33620  expression_node_ptr (&branch)[2])
33621  {
33622  const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33623 
33624  #ifndef exprtk_disable_enhanced_features
33625  if (details::is_sf3ext_node(branch[0]))
33626  {
33627  expression_node_ptr result = error_node();
33628 
33629  const bool synthesis_result =
33630  synthesize_sf4ext_expression::template compile_left<vtype>
33631  (expr_gen, v, operation, branch[0], result);
33632 
33633  if (synthesis_result)
33634  {
33635  details::free_node(*expr_gen.node_allocator_, branch[0]);
33636 
33637  return result;
33638  }
33639  }
33640  #endif
33641 
33642  if (
33643  (details::e_add == operation) ||
33644  (details::e_sub == operation) ||
33645  (details::e_mul == operation) ||
33646  (details::e_div == operation)
33647  )
33648  {
33649  if (details::is_uv_node(branch[0]))
33650  {
33651  typedef details::uv_base_node<Type>* uvbn_ptr_t;
33652 
33653  details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation();
33654 
33655  if (details::e_neg == o)
33656  {
33657  const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v();
33658 
33659  details::free_node(*expr_gen.node_allocator_,branch[0]);
33660 
33661  switch (operation)
33662  {
33663  case details::e_add : return expr_gen.node_allocator_->
33664  template allocate_rr<typename details::
33665  vov_node<Type,details::sub_op<Type> > >(v,v0);
33666 
33667  case details::e_sub : return expr_gen(details::e_neg,
33668  expr_gen.node_allocator_->
33669  template allocate_rr<typename details::
33670  vov_node<Type,details::add_op<Type> > >(v0,v));
33671 
33672  case details::e_mul : return expr_gen(details::e_neg,
33673  expr_gen.node_allocator_->
33674  template allocate_rr<typename details::
33675  vov_node<Type,details::mul_op<Type> > >(v0,v));
33676 
33677  case details::e_div : return expr_gen(details::e_neg,
33678  expr_gen.node_allocator_->
33679  template allocate_rr<typename details::
33680  vov_node<Type,details::div_op<Type> > >(v0,v));
33681  default : break;
33682  }
33683  }
33684  }
33685  }
33686 
33687  switch (operation)
33688  {
33689  #define case_stmt(op0, op1) \
33690  case op0 : return expr_gen.node_allocator_-> \
33691  template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
33692  (branch[0], v); \
33693 
33696  #undef case_stmt
33697  default : return error_node();
33698  }
33699  }
33700  };
33701 
33703  {
33705  const details::operator_type& operation,
33706  expression_node_ptr (&branch)[2])
33707  {
33708  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
33709 
33710  details::free_node(*expr_gen.node_allocator_,branch[0]);
33711 
33712  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
33713  {
33714  details::free_node(*expr_gen.node_allocator_,branch[1]);
33715 
33716  return expr_gen(T(0));
33717  }
33718  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
33719  {
33720  details::free_node(*expr_gen.node_allocator_, branch[1]);
33721 
33722  return expr_gen(T(0));
33723  }
33724  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
33725  return branch[1];
33726  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
33727  return branch[1];
33728 
33729  if (details::is_cob_node(branch[1]))
33730  {
33731  // Simplify expressions of the form:
33732  // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x)
33733  // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x
33734  if (
33735  (details::e_mul == operation) ||
33736  (details::e_add == operation)
33737  )
33738  {
33739  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
33740 
33741  if (operation == cobnode->operation())
33742  {
33743  switch (operation)
33744  {
33745  case details::e_add : cobnode->set_c(c + cobnode->c()); break;
33746  case details::e_mul : cobnode->set_c(c * cobnode->c()); break;
33747  default : return error_node();
33748  }
33749 
33750  return cobnode;
33751  }
33752  }
33753 
33754  if (operation == details::e_mul)
33755  {
33756  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
33757  details::operator_type cob_opr = cobnode->operation();
33758 
33759  if (
33760  (details::e_div == cob_opr) ||
33761  (details::e_mul == cob_opr)
33762  )
33763  {
33764  switch (cob_opr)
33765  {
33766  case details::e_div : cobnode->set_c(c * cobnode->c()); break;
33767  case details::e_mul : cobnode->set_c(cobnode->c() / c); break;
33768  default : return error_node();
33769  }
33770 
33771  return cobnode;
33772  }
33773  }
33774  else if (operation == details::e_div)
33775  {
33776  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
33777  details::operator_type cob_opr = cobnode->operation();
33778 
33779  if (
33780  (details::e_div == cob_opr) ||
33781  (details::e_mul == cob_opr)
33782  )
33783  {
33784  details::expression_node<Type>* new_cobnode = error_node();
33785 
33786  switch (cob_opr)
33787  {
33788  case details::e_div : new_cobnode = expr_gen.node_allocator_->
33789  template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
33790  (c / cobnode->c(), cobnode->move_branch(0));
33791  break;
33792 
33793  case details::e_mul : new_cobnode = expr_gen.node_allocator_->
33794  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
33795  (c / cobnode->c(), cobnode->move_branch(0));
33796  break;
33797 
33798  default : return error_node();
33799  }
33800 
33801  details::free_node(*expr_gen.node_allocator_,branch[1]);
33802 
33803  return new_cobnode;
33804  }
33805  }
33806  }
33807  #ifndef exprtk_disable_enhanced_features
33808  else if (details::is_sf3ext_node(branch[1]))
33809  {
33810  expression_node_ptr result = error_node();
33811 
33812  const bool synthesis_result =
33813  synthesize_sf4ext_expression::template compile_right<ctype>
33814  (expr_gen, c, operation, branch[1], result);
33815 
33816  if (synthesis_result)
33817  {
33818  details::free_node(*expr_gen.node_allocator_,branch[1]);
33819 
33820  return result;
33821  }
33822  }
33823  #endif
33824 
33825  switch (operation)
33826  {
33827  #define case_stmt(op0, op1) \
33828  case op0 : return expr_gen.node_allocator_-> \
33829  template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
33830  (c, branch[1]); \
33831 
33834  #undef case_stmt
33835  default : return error_node();
33836  }
33837  }
33838  };
33839 
33841  {
33843  const details::operator_type& operation,
33844  expression_node_ptr (&branch)[2])
33845  {
33846  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
33847 
33848  details::free_node(*(expr_gen.node_allocator_), branch[1]);
33849 
33850  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
33851  {
33852  details::free_node(*expr_gen.node_allocator_, branch[0]);
33853 
33854  return expr_gen(T(0));
33855  }
33856  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
33857  {
33858  details::free_node(*expr_gen.node_allocator_, branch[0]);
33859 
33860  return expr_gen(std::numeric_limits<T>::quiet_NaN());
33861  }
33862  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
33863  return branch[0];
33864  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
33865  return branch[0];
33866 
33867  if (details::is_boc_node(branch[0]))
33868  {
33869  // Simplify expressions of the form:
33870  // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320
33871  // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45
33872  if (
33873  (details::e_mul == operation) ||
33874  (details::e_add == operation)
33875  )
33876  {
33877  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
33878 
33879  if (operation == bocnode->operation())
33880  {
33881  switch (operation)
33882  {
33883  case details::e_add : bocnode->set_c(c + bocnode->c()); break;
33884  case details::e_mul : bocnode->set_c(c * bocnode->c()); break;
33885  default : return error_node();
33886  }
33887 
33888  return bocnode;
33889  }
33890  }
33891  else if (operation == details::e_div)
33892  {
33893  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
33894  details::operator_type boc_opr = bocnode->operation();
33895 
33896  if (
33897  (details::e_div == boc_opr) ||
33898  (details::e_mul == boc_opr)
33899  )
33900  {
33901  switch (boc_opr)
33902  {
33903  case details::e_div : bocnode->set_c(c * bocnode->c()); break;
33904  case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
33905  default : return error_node();
33906  }
33907 
33908  return bocnode;
33909  }
33910  }
33911  else if (operation == details::e_pow)
33912  {
33913  // (v ^ c0) ^ c1 --> v ^(c0 * c1)
33914  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
33915  details::operator_type boc_opr = bocnode->operation();
33916 
33917  if (details::e_pow == boc_opr)
33918  {
33919  bocnode->set_c(bocnode->c() * c);
33920 
33921  return bocnode;
33922  }
33923  }
33924  }
33925 
33926  #ifndef exprtk_disable_enhanced_features
33927  if (details::is_sf3ext_node(branch[0]))
33928  {
33929  expression_node_ptr result = error_node();
33930 
33931  const bool synthesis_result =
33932  synthesize_sf4ext_expression::template compile_left<ctype>
33933  (expr_gen, c, operation, branch[0], result);
33934 
33935  if (synthesis_result)
33936  {
33937  free_node(*expr_gen.node_allocator_, branch[0]);
33938 
33939  return result;
33940  }
33941  }
33942  #endif
33943 
33944  switch (operation)
33945  {
33946  #define case_stmt(op0, op1) \
33947  case op0 : return expr_gen.node_allocator_-> \
33948  template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
33949  (branch[0], c); \
33950 
33953  #undef case_stmt
33954  default : return error_node();
33955  }
33956  }
33957  };
33958 
33960  {
33962  const details::operator_type& operation,
33963  expression_node_ptr (&branch)[2])
33964  {
33965  expression_node_ptr result = error_node();
33966 
33967  // (cob) o c --> cob
33968  if (details::is_cob_node(branch[0]))
33969  {
33970  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
33971 
33972  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
33973 
33974  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
33975  {
33976  details::free_node(*expr_gen.node_allocator_, branch[0]);
33977  details::free_node(*expr_gen.node_allocator_, branch[1]);
33978 
33979  return expr_gen(T(0));
33980  }
33981  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
33982  {
33983  details::free_node(*expr_gen.node_allocator_, branch[0]);
33984  details::free_node(*expr_gen.node_allocator_, branch[1]);
33985 
33986  return expr_gen(T(std::numeric_limits<T>::quiet_NaN()));
33987  }
33988  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
33989  {
33990  details::free_node(*expr_gen.node_allocator_, branch[1]);
33991 
33992  return branch[0];
33993  }
33994  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
33995  {
33996  details::free_node(*expr_gen.node_allocator_, branch[1]);
33997 
33998  return branch[0];
33999  }
34000  else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
34001  {
34002  details::free_node(*expr_gen.node_allocator_, branch[1]);
34003 
34004  return branch[0];
34005  }
34006 
34007  const bool op_addsub = (details::e_add == cobnode->operation()) ||
34008  (details::e_sub == cobnode->operation()) ;
34009 
34010  if (op_addsub)
34011  {
34012  switch (operation)
34013  {
34014  case details::e_add : cobnode->set_c(cobnode->c() + c); break;
34015  case details::e_sub : cobnode->set_c(cobnode->c() - c); break;
34016  default : return error_node();
34017  }
34018 
34019  result = cobnode;
34020  }
34021  else if (details::e_mul == cobnode->operation())
34022  {
34023  switch (operation)
34024  {
34025  case details::e_mul : cobnode->set_c(cobnode->c() * c); break;
34026  case details::e_div : cobnode->set_c(cobnode->c() / c); break;
34027  default : return error_node();
34028  }
34029 
34030  result = cobnode;
34031  }
34032  else if (details::e_div == cobnode->operation())
34033  {
34034  if (details::e_mul == operation)
34035  {
34036  cobnode->set_c(cobnode->c() * c);
34037  result = cobnode;
34038  }
34039  else if (details::e_div == operation)
34040  {
34041  result = expr_gen.node_allocator_->
34042  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
34043  (cobnode->c() / c, cobnode->move_branch(0));
34044 
34045  details::free_node(*expr_gen.node_allocator_, branch[0]);
34046  }
34047  }
34048 
34049  if (result)
34050  {
34051  details::free_node(*expr_gen.node_allocator_,branch[1]);
34052  }
34053  }
34054 
34055  // c o (cob) --> cob
34056  else if (details::is_cob_node(branch[1]))
34057  {
34058  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
34059 
34060  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
34061 
34062  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
34063  {
34064  details::free_node(*expr_gen.node_allocator_, branch[0]);
34065  details::free_node(*expr_gen.node_allocator_, branch[1]);
34066 
34067  return expr_gen(T(0));
34068  }
34069  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
34070  {
34071  details::free_node(*expr_gen.node_allocator_, branch[0]);
34072  details::free_node(*expr_gen.node_allocator_, branch[1]);
34073 
34074  return expr_gen(T(0));
34075  }
34076  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
34077  {
34078  details::free_node(*expr_gen.node_allocator_, branch[0]);
34079 
34080  return branch[1];
34081  }
34082  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
34083  {
34084  details::free_node(*expr_gen.node_allocator_, branch[0]);
34085 
34086  return branch[1];
34087  }
34088 
34089  if (details::e_add == cobnode->operation())
34090  {
34091  if (details::e_add == operation)
34092  {
34093  cobnode->set_c(c + cobnode->c());
34094  result = cobnode;
34095  }
34096  else if (details::e_sub == operation)
34097  {
34098  result = expr_gen.node_allocator_->
34099  template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
34100  (c - cobnode->c(), cobnode->move_branch(0));
34101 
34102  details::free_node(*expr_gen.node_allocator_,branch[1]);
34103  }
34104  }
34105  else if (details::e_sub == cobnode->operation())
34106  {
34107  if (details::e_add == operation)
34108  {
34109  cobnode->set_c(c + cobnode->c());
34110  result = cobnode;
34111  }
34112  else if (details::e_sub == operation)
34113  {
34114  result = expr_gen.node_allocator_->
34115  template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > >
34116  (c - cobnode->c(), cobnode->move_branch(0));
34117 
34118  details::free_node(*expr_gen.node_allocator_,branch[1]);
34119  }
34120  }
34121  else if (details::e_mul == cobnode->operation())
34122  {
34123  if (details::e_mul == operation)
34124  {
34125  cobnode->set_c(c * cobnode->c());
34126  result = cobnode;
34127  }
34128  else if (details::e_div == operation)
34129  {
34130  result = expr_gen.node_allocator_->
34131  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
34132  (c / cobnode->c(), cobnode->move_branch(0));
34133 
34134  details::free_node(*expr_gen.node_allocator_,branch[1]);
34135  }
34136  }
34137  else if (details::e_div == cobnode->operation())
34138  {
34139  if (details::e_mul == operation)
34140  {
34141  cobnode->set_c(c * cobnode->c());
34142  result = cobnode;
34143  }
34144  else if (details::e_div == operation)
34145  {
34146  result = expr_gen.node_allocator_->
34147  template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
34148  (c / cobnode->c(), cobnode->move_branch(0));
34149 
34150  details::free_node(*expr_gen.node_allocator_,branch[1]);
34151  }
34152  }
34153 
34154  if (result)
34155  {
34156  details::free_node(*expr_gen.node_allocator_,branch[0]);
34157  }
34158  }
34159 
34160  return result;
34161  }
34162  };
34163 
34165  {
34167  const details::operator_type& operation,
34168  expression_node_ptr (&branch)[2])
34169  {
34170  expression_node_ptr result = error_node();
34171 
34172  // (boc) o c --> boc
34173  if (details::is_boc_node(branch[0]))
34174  {
34175  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
34176 
34177  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
34178 
34179  if (details::e_add == bocnode->operation())
34180  {
34181  switch (operation)
34182  {
34183  case details::e_add : bocnode->set_c(bocnode->c() + c); break;
34184  case details::e_sub : bocnode->set_c(bocnode->c() - c); break;
34185  default : return error_node();
34186  }
34187 
34188  result = bocnode;
34189  }
34190  else if (details::e_mul == bocnode->operation())
34191  {
34192  switch (operation)
34193  {
34194  case details::e_mul : bocnode->set_c(bocnode->c() * c); break;
34195  case details::e_div : bocnode->set_c(bocnode->c() / c); break;
34196  default : return error_node();
34197  }
34198 
34199  result = bocnode;
34200  }
34201  else if (details::e_sub == bocnode->operation())
34202  {
34203  if (details::e_add == operation)
34204  {
34205  result = expr_gen.node_allocator_->
34206  template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
34207  (bocnode->move_branch(0), c - bocnode->c());
34208 
34209  details::free_node(*expr_gen.node_allocator_,branch[0]);
34210  }
34211  else if (details::e_sub == operation)
34212  {
34213  bocnode->set_c(bocnode->c() + c);
34214  result = bocnode;
34215  }
34216  }
34217  else if (details::e_div == bocnode->operation())
34218  {
34219  switch (operation)
34220  {
34221  case details::e_div : bocnode->set_c(bocnode->c() * c); break;
34222  case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
34223  default : return error_node();
34224  }
34225 
34226  result = bocnode;
34227  }
34228 
34229  if (result)
34230  {
34231  details::free_node(*expr_gen.node_allocator_, branch[1]);
34232  }
34233  }
34234 
34235  // c o (boc) --> boc
34236  else if (details::is_boc_node(branch[1]))
34237  {
34238  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]);
34239 
34240  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
34241 
34242  if (details::e_add == bocnode->operation())
34243  {
34244  if (details::e_add == operation)
34245  {
34246  bocnode->set_c(c + bocnode->c());
34247  result = bocnode;
34248  }
34249  else if (details::e_sub == operation)
34250  {
34251  result = expr_gen.node_allocator_->
34252  template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
34253  (c - bocnode->c(), bocnode->move_branch(0));
34254 
34255  details::free_node(*expr_gen.node_allocator_,branch[1]);
34256  }
34257  }
34258  else if (details::e_sub == bocnode->operation())
34259  {
34260  if (details::e_add == operation)
34261  {
34262  result = expr_gen.node_allocator_->
34263  template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
34264  (bocnode->move_branch(0), c - bocnode->c());
34265 
34266  details::free_node(*expr_gen.node_allocator_,branch[1]);
34267  }
34268  else if (details::e_sub == operation)
34269  {
34270  result = expr_gen.node_allocator_->
34271  template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
34272  (c + bocnode->c(), bocnode->move_branch(0));
34273 
34274  details::free_node(*expr_gen.node_allocator_,branch[1]);
34275  }
34276  }
34277  else if (details::e_mul == bocnode->operation())
34278  {
34279  if (details::e_mul == operation)
34280  {
34281  bocnode->set_c(c * bocnode->c());
34282  result = bocnode;
34283  }
34284  else if (details::e_div == operation)
34285  {
34286  result = expr_gen.node_allocator_->
34287  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
34288  (c / bocnode->c(), bocnode->move_branch(0));
34289 
34290  details::free_node(*expr_gen.node_allocator_,branch[1]);
34291  }
34292  }
34293  else if (details::e_div == bocnode->operation())
34294  {
34295  if (details::e_mul == operation)
34296  {
34297  bocnode->set_c(bocnode->c() / c);
34298  result = bocnode;
34299  }
34300  else if (details::e_div == operation)
34301  {
34302  result = expr_gen.node_allocator_->
34303  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
34304  (c * bocnode->c(), bocnode->move_branch(0));
34305 
34306  details::free_node(*expr_gen.node_allocator_,branch[1]);
34307  }
34308  }
34309 
34310  if (result)
34311  {
34312  details::free_node(*expr_gen.node_allocator_,branch[0]);
34313  }
34314  }
34315 
34316  return result;
34317  }
34318  };
34319 
34320  #ifndef exprtk_disable_enhanced_features
34321  inline bool synthesize_expression(const details::operator_type& operation,
34322  expression_node_ptr (&branch)[2],
34323  expression_node_ptr& result)
34324  {
34325  result = error_node();
34326 
34327  if (!operation_optimisable(operation))
34328  return false;
34329 
34330  const std::string node_id = branch_to_id(branch);
34331 
34332  const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id);
34333 
34334  if (synthesize_map_.end() != itr)
34335  {
34336  result = itr->second((*this), operation, branch);
34337 
34338  return true;
34339  }
34340  else
34341  return false;
34342  }
34343 
34345  {
34347  const details::operator_type& operation,
34348  expression_node_ptr (&branch)[2])
34349  {
34350  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34351  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
34352 
34353  switch (operation)
34354  {
34355  #define case_stmt(op0, op1) \
34356  case op0 : return expr_gen.node_allocator_-> \
34357  template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
34358  (v1, v2); \
34359 
34362  #undef case_stmt
34363  default : return error_node();
34364  }
34365  }
34366  };
34367 
34369  {
34371  const details::operator_type& operation,
34372  expression_node_ptr (&branch)[2])
34373  {
34374  const Type c = static_cast<details::literal_node<Type>*> (branch[0])->value();
34375  const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref ();
34376 
34377  details::free_node(*(expr_gen.node_allocator_),branch[0]);
34378 
34379  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
34380  return expr_gen(T(0));
34381  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
34382  return expr_gen(T(0));
34383  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
34384  return static_cast<details::variable_node<Type>*>(branch[1]);
34385  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
34386  return static_cast<details::variable_node<Type>*>(branch[1]);
34387 
34388  switch (operation)
34389  {
34390  #define case_stmt(op0, op1) \
34391  case op0 : return expr_gen.node_allocator_-> \
34392  template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
34393  (c, v); \
34394 
34397  #undef case_stmt
34398  default : return error_node();
34399  }
34400  }
34401  };
34402 
34404  {
34406  const details::operator_type& operation,
34407  expression_node_ptr (&branch)[2])
34408  {
34409  const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref ();
34410  const Type c = static_cast<details::literal_node<Type>*> (branch[1])->value();
34411 
34412  details::free_node(*(expr_gen.node_allocator_), branch[1]);
34413 
34414  if (expr_gen.cardinal_pow_optimisable(operation,c))
34415  {
34416  if (std::equal_to<T>()(T(1),c))
34417  return branch[0];
34418  else
34419  return expr_gen.cardinal_pow_optimisation(v,c);
34420  }
34421  else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
34422  return expr_gen(T(0));
34423  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
34424  return expr_gen(std::numeric_limits<T>::quiet_NaN());
34425  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
34426  return static_cast<details::variable_node<Type>*>(branch[0]);
34427  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
34428  return static_cast<details::variable_node<Type>*>(branch[0]);
34429  else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
34430  return static_cast<details::variable_node<Type>*>(branch[0]);
34431 
34432  switch (operation)
34433  {
34434  #define case_stmt(op0, op1) \
34435  case op0 : return expr_gen.node_allocator_-> \
34436  template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
34437  (v, c); \
34438 
34441  #undef case_stmt
34442  default : return error_node();
34443  }
34444  }
34445  };
34446 
34448  {
34449  template <typename T0, typename T1, typename T2>
34451  const details::operator_type& sf3opr,
34452  T0 t0, T1 t1, T2 t2)
34453  {
34454  switch (sf3opr)
34455  {
34456  #define case_stmt(op) \
34457  case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
34458  allocate(*(expr_gen.node_allocator_), t0, t1, t2); \
34459 
34460  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
34461  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
34462  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
34463  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
34464  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
34465  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
34466  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
34467  case_stmt(28) case_stmt(29) case_stmt(30)
34468  #undef case_stmt
34469  default : return error_node();
34470  }
34471  }
34472 
34473  template <typename T0, typename T1, typename T2>
34474  static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
34475  T0 t0, T1 t1, T2 t2,
34476  expression_node_ptr& result)
34477  {
34478  details::operator_type sf3opr;
34479 
34480  if (!expr_gen.sf3_optimisable(id,sf3opr))
34481  return false;
34482  else
34483  result = synthesize_sf3ext_expression::template process<T0, T1, T2>
34484  (expr_gen, sf3opr, t0, t1, t2);
34485 
34486  return true;
34487  }
34488  };
34489 
34491  {
34492  template <typename T0, typename T1, typename T2, typename T3>
34494  const details::operator_type& sf4opr,
34495  T0 t0, T1 t1, T2 t2, T3 t3)
34496  {
34497  switch (sf4opr)
34498  {
34499  #define case_stmt0(op) \
34500  case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
34501  allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
34502 
34503  #define case_stmt1(op) \
34504  case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
34505  allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
34506 
34507  case_stmt0(48) case_stmt0(49) case_stmt0(50) case_stmt0(51)
34508  case_stmt0(52) case_stmt0(53) case_stmt0(54) case_stmt0(55)
34509  case_stmt0(56) case_stmt0(57) case_stmt0(58) case_stmt0(59)
34510  case_stmt0(60) case_stmt0(61) case_stmt0(62) case_stmt0(63)
34511  case_stmt0(64) case_stmt0(65) case_stmt0(66) case_stmt0(67)
34512  case_stmt0(68) case_stmt0(69) case_stmt0(70) case_stmt0(71)
34513  case_stmt0(72) case_stmt0(73) case_stmt0(74) case_stmt0(75)
34514  case_stmt0(76) case_stmt0(77) case_stmt0(78) case_stmt0(79)
34515  case_stmt0(80) case_stmt0(81) case_stmt0(82) case_stmt0(83)
34516 
34517  case_stmt1(00) case_stmt1(01) case_stmt1(02) case_stmt1(03)
34518  case_stmt1(04) case_stmt1(05) case_stmt1(06) case_stmt1(07)
34519  case_stmt1(08) case_stmt1(09) case_stmt1(10) case_stmt1(11)
34520  case_stmt1(12) case_stmt1(13) case_stmt1(14) case_stmt1(15)
34521  case_stmt1(16) case_stmt1(17) case_stmt1(18) case_stmt1(19)
34522  case_stmt1(20) case_stmt1(21) case_stmt1(22) case_stmt1(23)
34523  case_stmt1(24) case_stmt1(25) case_stmt1(26) case_stmt1(27)
34524  case_stmt1(28) case_stmt1(29) case_stmt1(30) case_stmt1(31)
34525  case_stmt1(32) case_stmt1(33) case_stmt1(34) case_stmt1(35)
34526  case_stmt1(36) case_stmt1(37) case_stmt1(38) case_stmt1(39)
34527  case_stmt1(40) case_stmt1(41) case_stmt1(42) case_stmt1(43)
34528  case_stmt1(44) case_stmt1(45) case_stmt1(46) case_stmt1(47)
34529  case_stmt1(48) case_stmt1(49) case_stmt1(50) case_stmt1(51)
34530  case_stmt1(52) case_stmt1(53) case_stmt1(54) case_stmt1(55)
34531  case_stmt1(56) case_stmt1(57) case_stmt1(58) case_stmt1(59)
34532  case_stmt1(60) case_stmt1(61)
34533 
34534  #undef case_stmt0
34535  #undef case_stmt1
34536  default : return error_node();
34537  }
34538  }
34539 
34540  template <typename T0, typename T1, typename T2, typename T3>
34541  static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
34542  T0 t0, T1 t1, T2 t2, T3 t3,
34543  expression_node_ptr& result)
34544  {
34545  details::operator_type sf4opr;
34546 
34547  if (!expr_gen.sf4_optimisable(id,sf4opr))
34548  return false;
34549  else
34550  result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3>
34551  (expr_gen, sf4opr, t0, t1, t2, t3);
34552 
34553  return true;
34554  }
34555 
34556  // T o (sf3ext)
34557  template <typename ExternalType>
34558  static inline bool compile_right(expression_generator<Type>& expr_gen,
34559  ExternalType t,
34560  const details::operator_type& operation,
34561  expression_node_ptr& sf3node,
34562  expression_node_ptr& result)
34563  {
34564  if (!details::is_sf3ext_node(sf3node))
34565  return false;
34566 
34567  typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
34568 
34569  sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
34570  const std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
34571 
34572  switch (n->type())
34573  {
34574  case details::expression_node<Type>::e_covoc : return compile_right_impl
34575  <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
34576  (expr_gen, id, t, sf3node, result);
34577 
34578  case details::expression_node<Type>::e_covov : return compile_right_impl
34579  <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
34580  (expr_gen, id, t, sf3node, result);
34581 
34582  case details::expression_node<Type>::e_vocov : return compile_right_impl
34583  <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
34584  (expr_gen, id, t, sf3node, result);
34585 
34586  case details::expression_node<Type>::e_vovoc : return compile_right_impl
34587  <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
34588  (expr_gen, id, t, sf3node, result);
34589 
34590  case details::expression_node<Type>::e_vovov : return compile_right_impl
34591  <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
34592  (expr_gen, id, t, sf3node, result);
34593 
34594  default : return false;
34595  }
34596  }
34597 
34598  // (sf3ext) o T
34599  template <typename ExternalType>
34600  static inline bool compile_left(expression_generator<Type>& expr_gen,
34601  ExternalType t,
34602  const details::operator_type& operation,
34603  expression_node_ptr& sf3node,
34604  expression_node_ptr& result)
34605  {
34606  if (!details::is_sf3ext_node(sf3node))
34607  return false;
34608 
34609  typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
34610 
34611  sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
34612 
34613  const std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
34614 
34615  switch (n->type())
34616  {
34617  case details::expression_node<Type>::e_covoc : return compile_left_impl
34618  <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype>
34619  (expr_gen, id, t, sf3node, result);
34620 
34621  case details::expression_node<Type>::e_covov : return compile_left_impl
34622  <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype>
34623  (expr_gen, id, t, sf3node, result);
34624 
34625  case details::expression_node<Type>::e_vocov : return compile_left_impl
34626  <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype>
34627  (expr_gen, id, t, sf3node, result);
34628 
34629  case details::expression_node<Type>::e_vovoc : return compile_left_impl
34630  <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype>
34631  (expr_gen, id, t, sf3node, result);
34632 
34633  case details::expression_node<Type>::e_vovov : return compile_left_impl
34634  <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype>
34635  (expr_gen, id, t, sf3node, result);
34636 
34637  default : return false;
34638  }
34639  }
34640 
34641  template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
34642  static inline bool compile_right_impl(expression_generator<Type>& expr_gen,
34643  const std::string& id,
34644  ExternalType t,
34645  expression_node_ptr& node,
34646  expression_node_ptr& result)
34647  {
34648  SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
34649 
34650  if (n)
34651  {
34652  T0 t0 = n->t0();
34653  T1 t1 = n->t1();
34654  T2 t2 = n->t2();
34655 
34656  return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2>
34657  (expr_gen, id, t, t0, t1, t2, result);
34658  }
34659  else
34660  return false;
34661  }
34662 
34663  template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
34664  static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
34665  const std::string& id,
34666  ExternalType t,
34667  expression_node_ptr& node,
34668  expression_node_ptr& result)
34669  {
34670  SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
34671 
34672  if (n)
34673  {
34674  T0 t0 = n->t0();
34675  T1 t1 = n->t1();
34676  T2 t2 = n->t2();
34677 
34678  return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType>
34679  (expr_gen, id, t0, t1, t2, t, result);
34680  }
34681  else
34682  return false;
34683  }
34684  };
34685 
34687  {
34688  typedef typename vovov_t::type0 node_type;
34689  typedef typename vovov_t::sf3_type sf3_type;
34690 
34692  const details::operator_type& operation,
34693  expression_node_ptr (&branch)[2])
34694  {
34695  // (v0 o0 v1) o1 (v2)
34696  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
34697  const Type& v0 = vov->v0();
34698  const Type& v1 = vov->v1();
34699  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
34700  const details::operator_type o0 = vov->operation();
34701  const details::operator_type o1 = operation;
34702 
34703  details::free_node(*(expr_gen.node_allocator_),branch[0]);
34704 
34705  expression_node_ptr result = error_node();
34706 
34708  {
34709  // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)
34710  if ((details::e_div == o0) && (details::e_div == o1))
34711  {
34712  const bool synthesis_result =
34713  synthesize_sf3ext_expression::
34714  template compile<vtype, vtype, vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result);
34715 
34716  exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
34717 
34718  return (synthesis_result) ? result : error_node();
34719  }
34720  }
34721 
34722  const bool synthesis_result =
34723  synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
34724  (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
34725 
34726  if (synthesis_result)
34727  return result;
34728 
34729  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34730  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34731 
34732  if (!expr_gen.valid_operator(o0,f0))
34733  return error_node();
34734  else if (!expr_gen.valid_operator(o1,f1))
34735  return error_node();
34736  else
34737  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
34738  }
34739 
34740  static inline std::string id(expression_generator<Type>& expr_gen,
34741  const details::operator_type o0,
34742  const details::operator_type o1)
34743  {
34744  return details::build_string()
34745  << "(t" << expr_gen.to_str(o0)
34746  << "t)" << expr_gen.to_str(o1)
34747  << "t";
34748  }
34749  };
34750 
34752  {
34753  typedef typename vovov_t::type1 node_type;
34754  typedef typename vovov_t::sf3_type sf3_type;
34755 
34757  const details::operator_type& operation,
34758  expression_node_ptr (&branch)[2])
34759  {
34760  // (v0) o0 (v1 o1 v2)
34761  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
34762  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34763  const Type& v1 = vov->v0();
34764  const Type& v2 = vov->v1();
34765  const details::operator_type o0 = operation;
34766  const details::operator_type o1 = vov->operation();
34767 
34768  details::free_node(*(expr_gen.node_allocator_),branch[1]);
34769 
34770  expression_node_ptr result = error_node();
34771 
34773  {
34774  // v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1
34775  if ((details::e_div == o0) && (details::e_div == o1))
34776  {
34777  const bool synthesis_result =
34778  synthesize_sf3ext_expression::
34779  template compile<vtype, vtype, vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result);
34780 
34781  exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
34782 
34783  return (synthesis_result) ? result : error_node();
34784  }
34785  }
34786 
34787  const bool synthesis_result =
34788  synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
34789  (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
34790 
34791  if (synthesis_result)
34792  return result;
34793 
34794  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34795  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34796 
34797  if (!expr_gen.valid_operator(o0,f0))
34798  return error_node();
34799  else if (!expr_gen.valid_operator(o1,f1))
34800  return error_node();
34801  else
34802  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
34803  }
34804 
34805  static inline std::string id(expression_generator<Type>& expr_gen,
34806  const details::operator_type o0,
34807  const details::operator_type o1)
34808  {
34809  return details::build_string()
34810  << "t" << expr_gen.to_str(o0)
34811  << "(t" << expr_gen.to_str(o1)
34812  << "t)";
34813  }
34814  };
34815 
34817  {
34818  typedef typename vovoc_t::type0 node_type;
34819  typedef typename vovoc_t::sf3_type sf3_type;
34820 
34822  const details::operator_type& operation,
34823  expression_node_ptr (&branch)[2])
34824  {
34825  // (v0 o0 v1) o1 (c)
34826  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
34827  const Type& v0 = vov->v0();
34828  const Type& v1 = vov->v1();
34829  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
34830  const details::operator_type o0 = vov->operation();
34831  const details::operator_type o1 = operation;
34832 
34833  details::free_node(*(expr_gen.node_allocator_),branch[0]);
34834  details::free_node(*(expr_gen.node_allocator_),branch[1]);
34835 
34836  expression_node_ptr result = error_node();
34837 
34839  {
34840  // (v0 / v1) / c --> (vovoc) v0 / (v1 * c)
34841  if ((details::e_div == o0) && (details::e_div == o1))
34842  {
34843  const bool synthesis_result =
34844  synthesize_sf3ext_expression::
34845  template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
34846 
34847  exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
34848 
34849  return (synthesis_result) ? result : error_node();
34850  }
34851  }
34852 
34853  const bool synthesis_result =
34854  synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
34855  (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
34856 
34857  if (synthesis_result)
34858  return result;
34859 
34860  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34861  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34862 
34863  if (!expr_gen.valid_operator(o0,f0))
34864  return error_node();
34865  else if (!expr_gen.valid_operator(o1,f1))
34866  return error_node();
34867  else
34868  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
34869  }
34870 
34871  static inline std::string id(expression_generator<Type>& expr_gen,
34872  const details::operator_type o0,
34873  const details::operator_type o1)
34874  {
34875  return details::build_string()
34876  << "(t" << expr_gen.to_str(o0)
34877  << "t)" << expr_gen.to_str(o1)
34878  << "t";
34879  }
34880  };
34881 
34883  {
34884  typedef typename vovoc_t::type1 node_type;
34885  typedef typename vovoc_t::sf3_type sf3_type;
34886 
34888  const details::operator_type& operation,
34889  expression_node_ptr (&branch)[2])
34890  {
34891  // (v0) o0 (v1 o1 c)
34892  const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]);
34893  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
34894  const Type& v1 = voc->v();
34895  const Type c = voc->c();
34896  const details::operator_type o0 = operation;
34897  const details::operator_type o1 = voc->operation();
34898 
34899  details::free_node(*(expr_gen.node_allocator_),branch[1]);
34900 
34901  expression_node_ptr result = error_node();
34902 
34904  {
34905  // v0 / (v1 / c) --> (vocov) (v0 * c) / v1
34906  if ((details::e_div == o0) && (details::e_div == o1))
34907  {
34908  const bool synthesis_result =
34909  synthesize_sf3ext_expression::
34910  template compile<vtype, ctype, vtype>(expr_gen, "(t*t)/t", v0, c, v1, result);
34911 
34912  exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
34913 
34914  return (synthesis_result) ? result : error_node();
34915  }
34916  }
34917 
34918  const bool synthesis_result =
34919  synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
34920  (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
34921 
34922  if (synthesis_result)
34923  return result;
34924 
34925  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34926  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34927 
34928  if (!expr_gen.valid_operator(o0,f0))
34929  return error_node();
34930  else if (!expr_gen.valid_operator(o1,f1))
34931  return error_node();
34932  else
34933  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
34934  }
34935 
34936  static inline std::string id(expression_generator<Type>& expr_gen,
34937  const details::operator_type o0,
34938  const details::operator_type o1)
34939  {
34940  return details::build_string()
34941  << "t" << expr_gen.to_str(o0)
34942  << "(t" << expr_gen.to_str(o1)
34943  << "t)";
34944  }
34945  };
34946 
34948  {
34949  typedef typename vocov_t::type0 node_type;
34950  typedef typename vocov_t::sf3_type sf3_type;
34951 
34953  const details::operator_type& operation,
34954  expression_node_ptr (&branch)[2])
34955  {
34956  // (v0 o0 c) o1 (v1)
34957  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
34958  const Type& v0 = voc->v();
34959  const Type c = voc->c();
34960  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
34961  const details::operator_type o0 = voc->operation();
34962  const details::operator_type o1 = operation;
34963 
34964  details::free_node(*(expr_gen.node_allocator_),branch[0]);
34965 
34966  expression_node_ptr result = error_node();
34967 
34969  {
34970  // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c)
34971  if ((details::e_div == o0) && (details::e_div == o1))
34972  {
34973  const bool synthesis_result =
34974  synthesize_sf3ext_expression::
34975  template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
34976 
34977  exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
34978 
34979  return (synthesis_result) ? result : error_node();
34980  }
34981  }
34982 
34983  const bool synthesis_result =
34984  synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
34985  (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
34986 
34987  if (synthesis_result)
34988  return result;
34989 
34990  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
34991  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
34992 
34993  if (!expr_gen.valid_operator(o0,f0))
34994  return error_node();
34995  else if (!expr_gen.valid_operator(o1,f1))
34996  return error_node();
34997  else
34998  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
34999  }
35000 
35001  static inline std::string id(expression_generator<Type>& expr_gen,
35002  const details::operator_type o0,
35003  const details::operator_type o1)
35004  {
35005  return details::build_string()
35006  << "(t" << expr_gen.to_str(o0)
35007  << "t)" << expr_gen.to_str(o1)
35008  << "t";
35009  }
35010  };
35011 
35013  {
35014  typedef typename vocov_t::type1 node_type;
35015  typedef typename vocov_t::sf3_type sf3_type;
35016 
35018  const details::operator_type& operation,
35019  expression_node_ptr (&branch)[2])
35020  {
35021  // (v0) o0 (c o1 v1)
35022  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
35023  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
35024  const Type c = cov->c();
35025  const Type& v1 = cov->v();
35026  const details::operator_type o0 = operation;
35027  const details::operator_type o1 = cov->operation();
35028 
35029  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35030 
35031  expression_node_ptr result = error_node();
35032 
35034  {
35035  // v0 / (c / v1) --> (vovoc) (v0 * v1) / c
35036  if ((details::e_div == o0) && (details::e_div == o1))
35037  {
35038  const bool synthesis_result =
35039  synthesize_sf3ext_expression::
35040  template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result);
35041 
35042  exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
35043 
35044  return (synthesis_result) ? result : error_node();
35045  }
35046  }
35047 
35048  const bool synthesis_result =
35049  synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
35050  (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
35051 
35052  if (synthesis_result)
35053  return result;
35054 
35055  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35056  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35057 
35058  if (!expr_gen.valid_operator(o0,f0))
35059  return error_node();
35060  else if (!expr_gen.valid_operator(o1,f1))
35061  return error_node();
35062  else
35063  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
35064  }
35065 
35066  static inline std::string id(expression_generator<Type>& expr_gen,
35067  const details::operator_type o0,
35068  const details::operator_type o1)
35069  {
35070  return details::build_string()
35071  << "t" << expr_gen.to_str(o0)
35072  << "(t" << expr_gen.to_str(o1)
35073  << "t)";
35074  }
35075  };
35076 
35078  {
35079  typedef typename covov_t::type0 node_type;
35080  typedef typename covov_t::sf3_type sf3_type;
35081 
35083  const details::operator_type& operation,
35084  expression_node_ptr (&branch)[2])
35085  {
35086  // (c o0 v0) o1 (v1)
35087  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
35088  const Type c = cov->c();
35089  const Type& v0 = cov->v();
35090  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
35091  const details::operator_type o0 = cov->operation();
35092  const details::operator_type o1 = operation;
35093 
35094  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35095 
35096  expression_node_ptr result = error_node();
35097 
35099  {
35100  // (c / v0) / v1 --> (covov) c / (v0 * v1)
35101  if ((details::e_div == o0) && (details::e_div == o1))
35102  {
35103  const bool synthesis_result =
35104  synthesize_sf3ext_expression::
35105  template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result);
35106 
35107  exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
35108 
35109  return (synthesis_result) ? result : error_node();
35110  }
35111  }
35112 
35113  const bool synthesis_result =
35114  synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
35115  (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
35116 
35117  if (synthesis_result)
35118  return result;
35119 
35120  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35121  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35122 
35123  if (!expr_gen.valid_operator(o0,f0))
35124  return error_node();
35125  else if (!expr_gen.valid_operator(o1,f1))
35126  return error_node();
35127  else
35128  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
35129  }
35130 
35131  static inline std::string id(expression_generator<Type>& expr_gen,
35132  const details::operator_type o0,
35133  const details::operator_type o1)
35134  {
35135  return details::build_string()
35136  << "(t" << expr_gen.to_str(o0)
35137  << "t)" << expr_gen.to_str(o1)
35138  << "t";
35139  }
35140  };
35141 
35143  {
35144  typedef typename covov_t::type1 node_type;
35145  typedef typename covov_t::sf3_type sf3_type;
35146 
35148  const details::operator_type& operation,
35149  expression_node_ptr (&branch)[2])
35150  {
35151  // (c) o0 (v0 o1 v1)
35152  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
35153  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
35154  const Type& v0 = vov->v0();
35155  const Type& v1 = vov->v1();
35156  const details::operator_type o0 = operation;
35157  const details::operator_type o1 = vov->operation();
35158 
35159  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35160  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35161 
35162  expression_node_ptr result = error_node();
35163 
35165  {
35166  // c / (v0 / v1) --> (covov) (c * v1) / v0
35167  if ((details::e_div == o0) && (details::e_div == o1))
35168  {
35169  const bool synthesis_result =
35170  synthesize_sf3ext_expression::
35171  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result);
35172 
35173  exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
35174 
35175  return (synthesis_result) ? result : error_node();
35176  }
35177  }
35178 
35179  const bool synthesis_result =
35180  synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
35181  (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
35182 
35183  if (synthesis_result)
35184  return result;
35185 
35186  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35187  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35188 
35189  if (!expr_gen.valid_operator(o0,f0))
35190  return error_node();
35191  else if (!expr_gen.valid_operator(o1,f1))
35192  return error_node();
35193  else
35194  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
35195  }
35196 
35197  static inline std::string id(expression_generator<Type>& expr_gen,
35198  const details::operator_type o0,
35199  const details::operator_type o1)
35200  {
35201  return details::build_string()
35202  << "t" << expr_gen.to_str(o0)
35203  << "(t" << expr_gen.to_str(o1)
35204  << "t)";
35205  }
35206  };
35207 
35209  {
35210  typedef typename covoc_t::type0 node_type;
35211  typedef typename covoc_t::sf3_type sf3_type;
35212 
35214  const details::operator_type& operation,
35215  expression_node_ptr (&branch)[2])
35216  {
35217  // (c0 o0 v) o1 (c1)
35218  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
35219  const Type c0 = cov->c();
35220  const Type& v = cov->v();
35221  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
35222  const details::operator_type o0 = cov->operation();
35223  const details::operator_type o1 = operation;
35224 
35225  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35226  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35227 
35228  expression_node_ptr result = error_node();
35229 
35231  {
35232  // (c0 + v) + c1 --> (cov) (c0 + c1) + v
35233  if ((details::e_add == o0) && (details::e_add == o1))
35234  {
35235  exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
35236 
35237  return expr_gen.node_allocator_->
35238  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
35239  }
35240  // (c0 + v) - c1 --> (cov) (c0 - c1) + v
35241  else if ((details::e_add == o0) && (details::e_sub == o1))
35242  {
35243  exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
35244 
35245  return expr_gen.node_allocator_->
35246  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
35247  }
35248  // (c0 - v) + c1 --> (cov) (c0 + c1) - v
35249  else if ((details::e_sub == o0) && (details::e_add == o1))
35250  {
35251  exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
35252 
35253  return expr_gen.node_allocator_->
35254  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
35255  }
35256  // (c0 - v) - c1 --> (cov) (c0 - c1) - v
35257  else if ((details::e_sub == o0) && (details::e_sub == o1))
35258  {
35259  exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
35260 
35261  return expr_gen.node_allocator_->
35262  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
35263  }
35264  // (c0 * v) * c1 --> (cov) (c0 * c1) * v
35265  else if ((details::e_mul == o0) && (details::e_mul == o1))
35266  {
35267  exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
35268 
35269  return expr_gen.node_allocator_->
35270  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
35271  }
35272  // (c0 * v) / c1 --> (cov) (c0 / c1) * v
35273  else if ((details::e_mul == o0) && (details::e_div == o1))
35274  {
35275  exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
35276 
35277  return expr_gen.node_allocator_->
35278  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
35279  }
35280  // (c0 / v) * c1 --> (cov) (c0 * c1) / v
35281  else if ((details::e_div == o0) && (details::e_mul == o1))
35282  {
35283  exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
35284 
35285  return expr_gen.node_allocator_->
35286  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
35287  }
35288  // (c0 / v) / c1 --> (cov) (c0 / c1) / v
35289  else if ((details::e_div == o0) && (details::e_div == o1))
35290  {
35291  exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
35292 
35293  return expr_gen.node_allocator_->
35294  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
35295  }
35296  }
35297 
35298  const bool synthesis_result =
35299  synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
35300  (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
35301 
35302  if (synthesis_result)
35303  return result;
35304 
35305  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35306  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35307 
35308  if (!expr_gen.valid_operator(o0,f0))
35309  return error_node();
35310  else if (!expr_gen.valid_operator(o1,f1))
35311  return error_node();
35312  else
35313  return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
35314  }
35315 
35316  static inline std::string id(expression_generator<Type>& expr_gen,
35317  const details::operator_type o0,
35318  const details::operator_type o1)
35319  {
35320  return details::build_string()
35321  << "(t" << expr_gen.to_str(o0)
35322  << "t)" << expr_gen.to_str(o1)
35323  << "t";
35324  }
35325  };
35326 
35328  {
35329  typedef typename covoc_t::type1 node_type;
35330  typedef typename covoc_t::sf3_type sf3_type;
35331 
35333  const details::operator_type& operation,
35334  expression_node_ptr (&branch)[2])
35335  {
35336  // (c0) o0 (v o1 c1)
35337  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
35338  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
35339  const Type& v = voc->v();
35340  const Type c1 = voc->c();
35341  const details::operator_type o0 = operation;
35342  const details::operator_type o1 = voc->operation();
35343 
35344  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35345  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35346 
35347  expression_node_ptr result = error_node();
35348 
35350  {
35351  // (c0) + (v + c1) --> (cov) (c0 + c1) + v
35352  if ((details::e_add == o0) && (details::e_add == o1))
35353  {
35354  exprtk_debug(("(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
35355 
35356  return expr_gen.node_allocator_->
35357  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
35358  }
35359  // (c0) + (v - c1) --> (cov) (c0 - c1) + v
35360  else if ((details::e_add == o0) && (details::e_sub == o1))
35361  {
35362  exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
35363 
35364  return expr_gen.node_allocator_->
35365  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
35366  }
35367  // (c0) - (v + c1) --> (cov) (c0 - c1) - v
35368  else if ((details::e_sub == o0) && (details::e_add == o1))
35369  {
35370  exprtk_debug(("(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
35371 
35372  return expr_gen.node_allocator_->
35373  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
35374  }
35375  // (c0) - (v - c1) --> (cov) (c0 + c1) - v
35376  else if ((details::e_sub == o0) && (details::e_sub == o1))
35377  {
35378  exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
35379 
35380  return expr_gen.node_allocator_->
35381  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
35382  }
35383  // (c0) * (v * c1) --> (voc) v * (c0 * c1)
35384  else if ((details::e_mul == o0) && (details::e_mul == o1))
35385  {
35386  exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
35387 
35388  return expr_gen.node_allocator_->
35389  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
35390  }
35391  // (c0) * (v / c1) --> (cov) (c0 / c1) * v
35392  else if ((details::e_mul == o0) && (details::e_div == o1))
35393  {
35394  exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
35395 
35396  return expr_gen.node_allocator_->
35397  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
35398  }
35399  // (c0) / (v * c1) --> (cov) (c0 / c1) / v
35400  else if ((details::e_div == o0) && (details::e_mul == o1))
35401  {
35402  exprtk_debug(("(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
35403 
35404  return expr_gen.node_allocator_->
35405  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
35406  }
35407  // (c0) / (v / c1) --> (cov) (c0 * c1) / v
35408  else if ((details::e_div == o0) && (details::e_div == o1))
35409  {
35410  exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
35411 
35412  return expr_gen.node_allocator_->
35413  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
35414  }
35415  }
35416 
35417  const bool synthesis_result =
35418  synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
35419  (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
35420 
35421  if (synthesis_result)
35422  return result;
35423 
35424  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35425  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35426 
35427  if (!expr_gen.valid_operator(o0,f0))
35428  return error_node();
35429  else if (!expr_gen.valid_operator(o1,f1))
35430  return error_node();
35431  else
35432  return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
35433  }
35434 
35435  static inline std::string id(expression_generator<Type>& expr_gen,
35436  const details::operator_type o0,
35437  const details::operator_type o1)
35438  {
35439  return details::build_string()
35440  << "t" << expr_gen.to_str(o0)
35441  << "(t" << expr_gen.to_str(o1)
35442  << "t)";
35443  }
35444  };
35445 
35447  {
35448  typedef typename cocov_t::type0 node_type;
35450  const details::operator_type&,
35451  expression_node_ptr (&)[2])
35452  {
35453  // (c0 o0 c1) o1 (v) - Not possible.
35454  return error_node();
35455  }
35456  };
35457 
35459  {
35460  typedef typename cocov_t::type1 node_type;
35461  typedef typename cocov_t::sf3_type sf3_type;
35462 
35464  const details::operator_type& operation,
35465  expression_node_ptr (&branch)[2])
35466  {
35467  // (c0) o0 (c1 o1 v)
35468  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
35469  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
35470  const Type c1 = cov->c();
35471  const Type& v = cov->v();
35472  const details::operator_type o0 = operation;
35473  const details::operator_type o1 = cov->operation();
35474 
35475  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35476  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35477 
35478  expression_node_ptr result = error_node();
35479 
35481  {
35482  // (c0) + (c1 + v) --> (cov) (c0 + c1) + v
35483  if ((details::e_add == o0) && (details::e_add == o1))
35484  {
35485  exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
35486 
35487  return expr_gen.node_allocator_->
35488  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
35489  }
35490  // (c0) + (c1 - v) --> (cov) (c0 + c1) - v
35491  else if ((details::e_add == o0) && (details::e_sub == o1))
35492  {
35493  exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
35494 
35495  return expr_gen.node_allocator_->
35496  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
35497  }
35498  // (c0) - (c1 + v) --> (cov) (c0 - c1) - v
35499  else if ((details::e_sub == o0) && (details::e_add == o1))
35500  {
35501  exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
35502 
35503  return expr_gen.node_allocator_->
35504  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
35505  }
35506  // (c0) - (c1 - v) --> (cov) (c0 - c1) + v
35507  else if ((details::e_sub == o0) && (details::e_sub == o1))
35508  {
35509  exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
35510 
35511  return expr_gen.node_allocator_->
35512  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
35513  }
35514  // (c0) * (c1 * v) --> (cov) (c0 * c1) * v
35515  else if ((details::e_mul == o0) && (details::e_mul == o1))
35516  {
35517  exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
35518 
35519  return expr_gen.node_allocator_->
35520  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
35521  }
35522  // (c0) * (c1 / v) --> (cov) (c0 * c1) / v
35523  else if ((details::e_mul == o0) && (details::e_div == o1))
35524  {
35525  exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
35526 
35527  return expr_gen.node_allocator_->
35528  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
35529  }
35530  // (c0) / (c1 * v) --> (cov) (c0 / c1) / v
35531  else if ((details::e_div == o0) && (details::e_mul == o1))
35532  {
35533  exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
35534 
35535  return expr_gen.node_allocator_->
35536  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
35537  }
35538  // (c0) / (c1 / v) --> (cov) (c0 / c1) * v
35539  else if ((details::e_div == o0) && (details::e_div == o1))
35540  {
35541  exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
35542 
35543  return expr_gen.node_allocator_->
35544  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
35545  }
35546  }
35547 
35548  const bool synthesis_result =
35549  synthesize_sf3ext_expression::template compile<ctype, ctype, vtype>
35550  (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result);
35551 
35552  if (synthesis_result)
35553  return result;
35554 
35555  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35556  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35557 
35558  if (!expr_gen.valid_operator(o0,f0))
35559  return error_node();
35560  else if (!expr_gen.valid_operator(o1,f1))
35561  return error_node();
35562  else
35563  return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1);
35564  }
35565 
35566  static inline std::string id(expression_generator<Type>& expr_gen,
35567  const details::operator_type o0,
35568  const details::operator_type o1)
35569  {
35570  return details::build_string()
35571  << "t" << expr_gen.to_str(o0)
35572  << "(t" << expr_gen.to_str(o1)
35573  << "t)";
35574  }
35575  };
35576 
35578  {
35579  typedef typename vococ_t::type0 node_type;
35580  typedef typename vococ_t::sf3_type sf3_type;
35581 
35583  const details::operator_type& operation,
35584  expression_node_ptr (&branch)[2])
35585  {
35586  // (v o0 c0) o1 (c1)
35587  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
35588  const Type& v = voc->v();
35589  const Type& c0 = voc->c();
35590  const Type& c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
35591  const details::operator_type o0 = voc->operation();
35592  const details::operator_type o1 = operation;
35593 
35594  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35595  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35596 
35597  expression_node_ptr result = error_node();
35598 
35600  {
35601  // (v + c0) + c1 --> (voc) v + (c0 + c1)
35602  if ((details::e_add == o0) && (details::e_add == o1))
35603  {
35604  exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
35605 
35606  return expr_gen.node_allocator_->
35607  template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1);
35608  }
35609  // (v + c0) - c1 --> (voc) v + (c0 - c1)
35610  else if ((details::e_add == o0) && (details::e_sub == o1))
35611  {
35612  exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
35613 
35614  return expr_gen.node_allocator_->
35615  template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1);
35616  }
35617  // (v - c0) + c1 --> (voc) v - (c0 + c1)
35618  else if ((details::e_sub == o0) && (details::e_add == o1))
35619  {
35620  exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
35621 
35622  return expr_gen.node_allocator_->
35623  template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0);
35624  }
35625  // (v - c0) - c1 --> (voc) v - (c0 + c1)
35626  else if ((details::e_sub == o0) && (details::e_sub == o1))
35627  {
35628  exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
35629 
35630  return expr_gen.node_allocator_->
35631  template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1);
35632  }
35633  // (v * c0) * c1 --> (voc) v * (c0 * c1)
35634  else if ((details::e_mul == o0) && (details::e_mul == o1))
35635  {
35636  exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
35637 
35638  return expr_gen.node_allocator_->
35639  template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1);
35640  }
35641  // (v * c0) / c1 --> (voc) v * (c0 / c1)
35642  else if ((details::e_mul == o0) && (details::e_div == o1))
35643  {
35644  exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
35645 
35646  return expr_gen.node_allocator_->
35647  template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1);
35648  }
35649  // (v / c0) * c1 --> (voc) v * (c1 / c0)
35650  else if ((details::e_div == o0) && (details::e_mul == o1))
35651  {
35652  exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
35653 
35654  return expr_gen.node_allocator_->
35655  template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0);
35656  }
35657  // (v / c0) / c1 --> (voc) v / (c0 * c1)
35658  else if ((details::e_div == o0) && (details::e_div == o1))
35659  {
35660  exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
35661 
35662  return expr_gen.node_allocator_->
35663  template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1);
35664  }
35665  // (v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)
35666  else if ((details::e_pow == o0) && (details::e_pow == o1))
35667  {
35668  exprtk_debug(("(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n"));
35669 
35670  return expr_gen.node_allocator_->
35671  template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1);
35672  }
35673  }
35674 
35675  const bool synthesis_result =
35676  synthesize_sf3ext_expression::template compile<vtype, ctype, ctype>
35677  (expr_gen, id(expr_gen, o0, o1), v, c0, c1, result);
35678 
35679  if (synthesis_result)
35680  return result;
35681 
35682  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35683  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35684 
35685  if (!expr_gen.valid_operator(o0,f0))
35686  return error_node();
35687  else if (!expr_gen.valid_operator(o1,f1))
35688  return error_node();
35689  else
35690  return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1);
35691  }
35692 
35693  static inline std::string id(expression_generator<Type>& expr_gen,
35694  const details::operator_type o0,
35695  const details::operator_type o1)
35696  {
35697  return details::build_string()
35698  << "(t" << expr_gen.to_str(o0)
35699  << "t)" << expr_gen.to_str(o1)
35700  << "t";
35701  }
35702  };
35703 
35705  {
35706  typedef typename vococ_t::type0 node_type;
35707 
35709  const details::operator_type&,
35710  expression_node_ptr (&)[2])
35711  {
35712  // (v) o0 (c0 o1 c1) - Not possible.
35713  exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n"));
35714  return error_node();
35715  }
35716  };
35717 
35719  {
35720  typedef typename vovovov_t::type0 node_type;
35721  typedef typename vovovov_t::sf4_type sf4_type;
35722  typedef typename node_type::T0 T0;
35723  typedef typename node_type::T1 T1;
35724  typedef typename node_type::T2 T2;
35725  typedef typename node_type::T3 T3;
35726 
35728  const details::operator_type& operation,
35729  expression_node_ptr (&branch)[2])
35730  {
35731  // (v0 o0 v1) o1 (v2 o2 v3)
35732  const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]);
35733  const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]);
35734  const Type& v0 = vov0->v0();
35735  const Type& v1 = vov0->v1();
35736  const Type& v2 = vov1->v0();
35737  const Type& v3 = vov1->v1();
35738  const details::operator_type o0 = vov0->operation();
35739  const details::operator_type o1 = operation;
35740  const details::operator_type o2 = vov1->operation();
35741 
35742  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35743  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35744 
35745  expression_node_ptr result = error_node();
35746 
35748  {
35749  // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)
35750  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
35751  {
35752  const bool synthesis_result =
35753  synthesize_sf4ext_expression::
35754  template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result);
35755 
35756  exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
35757 
35758  return (synthesis_result) ? result : error_node();
35759  }
35760  // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)
35761  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
35762  {
35763  const bool synthesis_result =
35764  synthesize_sf4ext_expression::
35765  template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result);
35766 
35767  exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
35768 
35769  return (synthesis_result) ? result : error_node();
35770  }
35771  // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
35772  else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2))
35773  {
35774  const bool synthesis_result =
35775  synthesize_sf4ext_expression::
35776  template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result);
35777 
35778  exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
35779 
35780  return (synthesis_result) ? result : error_node();
35781  }
35782  // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
35783  else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2))
35784  {
35785  const bool synthesis_result =
35786  synthesize_sf4ext_expression::
35787  template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result);
35788 
35789  exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
35790 
35791  return (synthesis_result) ? result : error_node();
35792  }
35793  // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2
35794  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
35795  {
35796  const bool synthesis_result =
35797  synthesize_sf4ext_expression::
35798  template compile<vtype, vtype, vtype, vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result);
35799 
35800  exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
35801 
35802  return (synthesis_result) ? result : error_node();
35803  }
35804  }
35805 
35806  const bool synthesis_result =
35807  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
35808  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
35809 
35810  if (synthesis_result)
35811  return result;
35812 
35813  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35814  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35815  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
35816 
35817  if (!expr_gen.valid_operator(o0,f0))
35818  return error_node();
35819  else if (!expr_gen.valid_operator(o1,f1))
35820  return error_node();
35821  else if (!expr_gen.valid_operator(o2,f2))
35822  return error_node();
35823  else
35824  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
35825  }
35826 
35827  static inline std::string id(expression_generator<Type>& expr_gen,
35828  const details::operator_type o0,
35829  const details::operator_type o1,
35830  const details::operator_type o2)
35831  {
35832  return details::build_string()
35833  << "(t" << expr_gen.to_str(o0)
35834  << "t)" << expr_gen.to_str(o1)
35835  << "(t" << expr_gen.to_str(o2)
35836  << "t)";
35837  }
35838  };
35839 
35841  {
35842  typedef typename vovovoc_t::type0 node_type;
35843  typedef typename vovovoc_t::sf4_type sf4_type;
35844  typedef typename node_type::T0 T0;
35845  typedef typename node_type::T1 T1;
35846  typedef typename node_type::T2 T2;
35847  typedef typename node_type::T3 T3;
35848 
35850  const details::operator_type& operation,
35851  expression_node_ptr (&branch)[2])
35852  {
35853  // (v0 o0 v1) o1 (v2 o2 c)
35854  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
35855  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
35856  const Type& v0 = vov->v0();
35857  const Type& v1 = vov->v1();
35858  const Type& v2 = voc->v ();
35859  const Type c = voc->c ();
35860  const details::operator_type o0 = vov->operation();
35861  const details::operator_type o1 = operation;
35862  const details::operator_type o2 = voc->operation();
35863 
35864  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35865  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35866 
35867  expression_node_ptr result = error_node();
35868 
35870  {
35871  // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)
35872  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
35873  {
35874  const bool synthesis_result =
35875  synthesize_sf4ext_expression::
35876  template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
35877 
35878  exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
35879 
35880  return (synthesis_result) ? result : error_node();
35881  }
35882  // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)
35883  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
35884  {
35885  const bool synthesis_result =
35886  synthesize_sf4ext_expression::
35887  template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
35888 
35889  exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
35890 
35891  return (synthesis_result) ? result : error_node();
35892  }
35893  }
35894 
35895  const bool synthesis_result =
35896  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
35897  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
35898 
35899  if (synthesis_result)
35900  return result;
35901 
35902  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35903  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35904  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
35905 
35906  if (!expr_gen.valid_operator(o0,f0))
35907  return error_node();
35908  else if (!expr_gen.valid_operator(o1,f1))
35909  return error_node();
35910  else if (!expr_gen.valid_operator(o2,f2))
35911  return error_node();
35912  else
35913  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
35914  }
35915 
35916  static inline std::string id(expression_generator<Type>& expr_gen,
35917  const details::operator_type o0,
35918  const details::operator_type o1,
35919  const details::operator_type o2)
35920  {
35921  return details::build_string()
35922  << "(t" << expr_gen.to_str(o0)
35923  << "t)" << expr_gen.to_str(o1)
35924  << "(t" << expr_gen.to_str(o2)
35925  << "t)";
35926  }
35927  };
35928 
35930  {
35931  typedef typename vovocov_t::type0 node_type;
35932  typedef typename vovocov_t::sf4_type sf4_type;
35933  typedef typename node_type::T0 T0;
35934  typedef typename node_type::T1 T1;
35935  typedef typename node_type::T2 T2;
35936  typedef typename node_type::T3 T3;
35937 
35939  const details::operator_type& operation,
35940  expression_node_ptr (&branch)[2])
35941  {
35942  // (v0 o0 v1) o1 (c o2 v2)
35943  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
35944  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
35945  const Type& v0 = vov->v0();
35946  const Type& v1 = vov->v1();
35947  const Type& v2 = cov->v ();
35948  const Type c = cov->c ();
35949  const details::operator_type o0 = vov->operation();
35950  const details::operator_type o1 = operation;
35951  const details::operator_type o2 = cov->operation();
35952 
35953  details::free_node(*(expr_gen.node_allocator_),branch[0]);
35954  details::free_node(*(expr_gen.node_allocator_),branch[1]);
35955 
35956  expression_node_ptr result = error_node();
35957 
35959  {
35960  // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)
35961  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
35962  {
35963  const bool synthesis_result =
35964  synthesize_sf4ext_expression::
35965  template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
35966 
35967  exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
35968 
35969  return (synthesis_result) ? result : error_node();
35970  }
35971  // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)
35972  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
35973  {
35974  const bool synthesis_result =
35975  synthesize_sf4ext_expression::
35976  template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
35977 
35978  exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
35979 
35980  return (synthesis_result) ? result : error_node();
35981  }
35982  }
35983 
35984  const bool synthesis_result =
35985  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
35986  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
35987 
35988  if (synthesis_result)
35989  return result;
35990 
35991  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
35992  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
35993  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
35994 
35995  if (!expr_gen.valid_operator(o0,f0))
35996  return error_node();
35997  else if (!expr_gen.valid_operator(o1,f1))
35998  return error_node();
35999  else if (!expr_gen.valid_operator(o2,f2))
36000  return error_node();
36001  else
36002  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
36003  }
36004 
36005  static inline std::string id(expression_generator<Type>& expr_gen,
36006  const details::operator_type o0,
36007  const details::operator_type o1,
36008  const details::operator_type o2)
36009  {
36010  return details::build_string()
36011  << "(t" << expr_gen.to_str(o0)
36012  << "t)" << expr_gen.to_str(o1)
36013  << "(t" << expr_gen.to_str(o2)
36014  << "t)";
36015  }
36016  };
36017 
36019  {
36020  typedef typename vocovov_t::type0 node_type;
36021  typedef typename vocovov_t::sf4_type sf4_type;
36022  typedef typename node_type::T0 T0;
36023  typedef typename node_type::T1 T1;
36024  typedef typename node_type::T2 T2;
36025  typedef typename node_type::T3 T3;
36026 
36028  const details::operator_type& operation,
36029  expression_node_ptr (&branch)[2])
36030  {
36031  // (v0 o0 c) o1 (v1 o2 v2)
36032  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
36033  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36034  const Type c = voc->c ();
36035  const Type& v0 = voc->v ();
36036  const Type& v1 = vov->v0();
36037  const Type& v2 = vov->v1();
36038  const details::operator_type o0 = voc->operation();
36039  const details::operator_type o1 = operation;
36040  const details::operator_type o2 = vov->operation();
36041 
36042  details::free_node(*(expr_gen.node_allocator_),branch[0]);
36043  details::free_node(*(expr_gen.node_allocator_),branch[1]);
36044 
36045  expression_node_ptr result = error_node();
36046 
36048  {
36049  // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)
36050  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36051  {
36052  const bool synthesis_result =
36053  synthesize_sf4ext_expression::
36054  template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result);
36055 
36056  exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
36057 
36058  return (synthesis_result) ? result : error_node();
36059  }
36060  // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)
36061  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36062  {
36063  const bool synthesis_result =
36064  synthesize_sf4ext_expression::
36065  template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result);
36066 
36067  exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
36068 
36069  return (synthesis_result) ? result : error_node();
36070  }
36071  }
36072 
36073  const bool synthesis_result =
36074  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36075  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
36076 
36077  if (synthesis_result)
36078  return result;
36079 
36080  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36081  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36082  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36083 
36084  if (!expr_gen.valid_operator(o0,f0))
36085  return error_node();
36086  else if (!expr_gen.valid_operator(o1,f1))
36087  return error_node();
36088  else if (!expr_gen.valid_operator(o2,f2))
36089  return error_node();
36090  else
36091  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
36092  }
36093 
36094  static inline std::string id(expression_generator<Type>& expr_gen,
36095  const details::operator_type o0,
36096  const details::operator_type o1,
36097  const details::operator_type o2)
36098  {
36099  return details::build_string()
36100  << "(t" << expr_gen.to_str(o0)
36101  << "t)" << expr_gen.to_str(o1)
36102  << "(t" << expr_gen.to_str(o2)
36103  << "t)";
36104  }
36105  };
36106 
36108  {
36109  typedef typename covovov_t::type0 node_type;
36110  typedef typename covovov_t::sf4_type sf4_type;
36111  typedef typename node_type::T0 T0;
36112  typedef typename node_type::T1 T1;
36113  typedef typename node_type::T2 T2;
36114  typedef typename node_type::T3 T3;
36115 
36117  const details::operator_type& operation,
36118  expression_node_ptr (&branch)[2])
36119  {
36120  // (c o0 v0) o1 (v1 o2 v2)
36121  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36122  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
36123  const Type c = cov->c ();
36124  const Type& v0 = cov->v ();
36125  const Type& v1 = vov->v0();
36126  const Type& v2 = vov->v1();
36127  const details::operator_type o0 = cov->operation();
36128  const details::operator_type o1 = operation;
36129  const details::operator_type o2 = vov->operation();
36130 
36131  details::free_node(*(expr_gen.node_allocator_),branch[0]);
36132  details::free_node(*(expr_gen.node_allocator_),branch[1]);
36133 
36134  expression_node_ptr result = error_node();
36135 
36137  {
36138  // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)
36139  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36140  {
36141  const bool synthesis_result =
36142  synthesize_sf4ext_expression::
36143  template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result);
36144 
36145  exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
36146 
36147  return (synthesis_result) ? result : error_node();
36148  }
36149  // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)
36150  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36151  {
36152  const bool synthesis_result =
36153  synthesize_sf4ext_expression::
36154  template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result);
36155 
36156  exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
36157 
36158  return (synthesis_result) ? result : error_node();
36159  }
36160  }
36161 
36162  const bool synthesis_result =
36163  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36164  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
36165 
36166  if (synthesis_result)
36167  return result;
36168 
36169  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36170  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36171  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36172 
36173  if (!expr_gen.valid_operator(o0,f0))
36174  return error_node();
36175  else if (!expr_gen.valid_operator(o1,f1))
36176  return error_node();
36177  else if (!expr_gen.valid_operator(o2,f2))
36178  return error_node();
36179  else
36180  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
36181  }
36182 
36183  static inline std::string id(expression_generator<Type>& expr_gen,
36184  const details::operator_type o0,
36185  const details::operator_type o1,
36186  const details::operator_type o2)
36187  {
36188  return details::build_string()
36189  << "(t" << expr_gen.to_str(o0)
36190  << "t)" << expr_gen.to_str(o1)
36191  << "(t" << expr_gen.to_str(o2)
36192  << "t)";
36193  }
36194  };
36195 
36197  {
36198  typedef typename covocov_t::type0 node_type;
36199  typedef typename covocov_t::sf4_type sf4_type;
36200  typedef typename node_type::T0 T0;
36201  typedef typename node_type::T1 T1;
36202  typedef typename node_type::T2 T2;
36203  typedef typename node_type::T3 T3;
36204 
36206  const details::operator_type& operation,
36207  expression_node_ptr (&branch)[2])
36208  {
36209  // (c0 o0 v0) o1 (c1 o2 v1)
36210  const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]);
36211  const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]);
36212  const Type c0 = cov0->c();
36213  const Type& v0 = cov0->v();
36214  const Type c1 = cov1->c();
36215  const Type& v1 = cov1->v();
36216  const details::operator_type o0 = cov0->operation();
36217  const details::operator_type o1 = operation;
36218  const details::operator_type o2 = cov1->operation();
36219 
36220  details::free_node(*(expr_gen.node_allocator_),branch[0]);
36221  details::free_node(*(expr_gen.node_allocator_),branch[1]);
36222 
36223  expression_node_ptr result = error_node();
36224 
36226  {
36227  // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
36228  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36229  {
36230  const bool synthesis_result =
36231  synthesize_sf3ext_expression::
36232  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36233 
36234  exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
36235 
36236  return (synthesis_result) ? result : error_node();
36237  }
36238  // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
36239  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36240  {
36241  const bool synthesis_result =
36242  synthesize_sf3ext_expression::
36243  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36244 
36245  exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
36246 
36247  return (synthesis_result) ? result : error_node();
36248  }
36249  // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1
36250  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36251  {
36252  const bool synthesis_result =
36253  synthesize_sf3ext_expression::
36254  template compile<ctype, vtype, vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result);
36255 
36256  exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
36257 
36258  return (synthesis_result) ? result : error_node();
36259  }
36260  // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
36261  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36262  {
36263  const bool synthesis_result =
36264  synthesize_sf3ext_expression::
36265  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36266 
36267  exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
36268 
36269  return (synthesis_result) ? result : error_node();
36270  }
36271  // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)
36272  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36273  {
36274  const bool synthesis_result =
36275  synthesize_sf3ext_expression::
36276  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36277 
36278  exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
36279 
36280  return (synthesis_result) ? result : error_node();
36281  }
36282  // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)
36283  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36284  {
36285  const bool synthesis_result =
36286  synthesize_sf3ext_expression::
36287  template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
36288 
36289  exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
36290 
36291  return (synthesis_result) ? result : error_node();
36292  }
36293  // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0
36294  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36295  {
36296  const bool synthesis_result =
36297  synthesize_sf3ext_expression::
36298  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result);
36299 
36300  exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
36301 
36302  return (synthesis_result) ? result : error_node();
36303  }
36304  // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
36305  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36306  {
36307  const bool synthesis_result =
36308  synthesize_sf3ext_expression::
36309  template compile<ctype, vtype, vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result);
36310 
36311  exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
36312 
36313  return (synthesis_result) ? result : error_node();
36314  }
36315  // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)
36316  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36317  {
36318  const bool synthesis_result =
36319  synthesize_sf3ext_expression::
36320  template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
36321 
36322  exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
36323 
36324  return (synthesis_result) ? result : error_node();
36325  }
36326  // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)
36327  else if (
36328  (std::equal_to<T>()(c0,c1)) &&
36329  (details::e_mul == o0) &&
36330  (details::e_mul == o2) &&
36331  (
36332  (details::e_add == o1) ||
36333  (details::e_sub == o1)
36334  )
36335  )
36336  {
36337  std::string specfunc;
36338 
36339  switch (o1)
36340  {
36341  case details::e_add : specfunc = "t*(t+t)"; break;
36342  case details::e_sub : specfunc = "t*(t-t)"; break;
36343  default : return error_node();
36344  }
36345 
36346  const bool synthesis_result =
36347  synthesize_sf3ext_expression::
36348  template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36349 
36350  exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
36351 
36352  return (synthesis_result) ? result : error_node();
36353  }
36354  }
36355 
36356  const bool synthesis_result =
36357  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36358  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
36359 
36360  if (synthesis_result)
36361  return result;
36362 
36363  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36364  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36365  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36366 
36367  if (!expr_gen.valid_operator(o0,f0))
36368  return error_node();
36369  else if (!expr_gen.valid_operator(o1,f1))
36370  return error_node();
36371  else if (!expr_gen.valid_operator(o2,f2))
36372  return error_node();
36373  else
36374  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
36375  }
36376 
36377  static inline std::string id(expression_generator<Type>& expr_gen,
36378  const details::operator_type o0,
36379  const details::operator_type o1,
36380  const details::operator_type o2)
36381  {
36382  return details::build_string()
36383  << "(t" << expr_gen.to_str(o0)
36384  << "t)" << expr_gen.to_str(o1)
36385  << "(t" << expr_gen.to_str(o2)
36386  << "t)";
36387  }
36388  };
36389 
36391  {
36392  typedef typename vocovoc_t::type0 node_type;
36393  typedef typename vocovoc_t::sf4_type sf4_type;
36394  typedef typename node_type::T0 T0;
36395  typedef typename node_type::T1 T1;
36396  typedef typename node_type::T2 T2;
36397  typedef typename node_type::T3 T3;
36398 
36400  const details::operator_type& operation,
36401  expression_node_ptr (&branch)[2])
36402  {
36403  // (v0 o0 c0) o1 (v1 o2 c1)
36404  const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]);
36405  const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]);
36406  const Type c0 = voc0->c();
36407  const Type& v0 = voc0->v();
36408  const Type c1 = voc1->c();
36409  const Type& v1 = voc1->v();
36410  const details::operator_type o0 = voc0->operation();
36411  const details::operator_type o1 = operation;
36412  const details::operator_type o2 = voc1->operation();
36413 
36414  details::free_node(*(expr_gen.node_allocator_),branch[0]);
36415  details::free_node(*(expr_gen.node_allocator_),branch[1]);
36416 
36417  expression_node_ptr result = error_node();
36418 
36420  {
36421  // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
36422  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36423  {
36424  const bool synthesis_result =
36425  synthesize_sf3ext_expression::
36426  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36427 
36428  exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
36429 
36430  return (synthesis_result) ? result : error_node();
36431  }
36432  // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
36433  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36434  {
36435  const bool synthesis_result =
36436  synthesize_sf3ext_expression::
36437  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36438 
36439  exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
36440 
36441  return (synthesis_result) ? result : error_node();
36442  }
36443  // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1
36444  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36445  {
36446  const bool synthesis_result =
36447  synthesize_sf3ext_expression::
36448  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result);
36449 
36450  exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
36451 
36452  return (synthesis_result) ? result : error_node();
36453  }
36454  // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
36455  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36456  {
36457  const bool synthesis_result =
36458  synthesize_sf3ext_expression::
36459  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36460 
36461  exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
36462 
36463  return (synthesis_result) ? result : error_node();
36464  }
36465  // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
36466  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36467  {
36468  const bool synthesis_result =
36469  synthesize_sf3ext_expression::
36470  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36471 
36472  exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
36473 
36474  return (synthesis_result) ? result : error_node();
36475  }
36476  // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1
36477  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36478  {
36479  const bool synthesis_result =
36480  synthesize_sf3ext_expression::
36481  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result);
36482 
36483  exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
36484 
36485  return (synthesis_result) ? result : error_node();
36486  }
36487  // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1
36488  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36489  {
36490  const bool synthesis_result =
36491  synthesize_sf3ext_expression::
36492  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
36493 
36494  exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
36495 
36496  return (synthesis_result) ? result : error_node();
36497  }
36498  // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
36499  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36500  {
36501  const bool synthesis_result =
36502  synthesize_sf3ext_expression::
36503  template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result);
36504 
36505  exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
36506 
36507  return (synthesis_result) ? result : error_node();
36508  }
36509  // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1
36510  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36511  {
36512  const bool synthesis_result =
36513  synthesize_sf3ext_expression::
36514  template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result);
36515 
36516  exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
36517 
36518  return (synthesis_result) ? result : error_node();
36519  }
36520  // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)
36521  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2))
36522  {
36523  const bool synthesis_result =
36524  synthesize_sf4ext_expression::
36525  template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result);
36526 
36527  exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
36528 
36529  return (synthesis_result) ? result : error_node();
36530  }
36531  // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)
36532  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2))
36533  {
36534  const bool synthesis_result =
36535  synthesize_sf4ext_expression::
36536  template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result);
36537 
36538  exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
36539 
36540  return (synthesis_result) ? result : error_node();
36541  }
36542  // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
36543  else if (
36544  (std::equal_to<T>()(c0,c1)) &&
36545  (details::e_mul == o0) &&
36546  (details::e_mul == o2) &&
36547  (
36548  (details::e_add == o1) ||
36549  (details::e_sub == o1)
36550  )
36551  )
36552  {
36553  std::string specfunc;
36554 
36555  switch (o1)
36556  {
36557  case details::e_add : specfunc = "t*(t+t)"; break;
36558  case details::e_sub : specfunc = "t*(t-t)"; break;
36559  default : return error_node();
36560  }
36561 
36562  const bool synthesis_result =
36563  synthesize_sf3ext_expression::
36564  template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36565 
36566  exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
36567 
36568  return (synthesis_result) ? result : error_node();
36569  }
36570  // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c
36571  else if (
36572  (std::equal_to<T>()(c0,c1)) &&
36573  (details::e_div == o0) &&
36574  (details::e_div == o2) &&
36575  (
36576  (details::e_add == o1) ||
36577  (details::e_sub == o1)
36578  )
36579  )
36580  {
36581  std::string specfunc;
36582 
36583  switch (o1)
36584  {
36585  case details::e_add : specfunc = "(t+t)/t"; break;
36586  case details::e_sub : specfunc = "(t-t)/t"; break;
36587  default : return error_node();
36588  }
36589 
36590  const bool synthesis_result =
36591  synthesize_sf3ext_expression::
36592  template compile<vtype, vtype, ctype>(expr_gen, specfunc, v0, v1, c0, result);
36593 
36594  exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
36595 
36596  return (synthesis_result) ? result : error_node();
36597  }
36598  }
36599 
36600  const bool synthesis_result =
36601  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36602  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
36603 
36604  if (synthesis_result)
36605  return result;
36606 
36607  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36608  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36609  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36610 
36611  if (!expr_gen.valid_operator(o0,f0))
36612  return error_node();
36613  else if (!expr_gen.valid_operator(o1,f1))
36614  return error_node();
36615  else if (!expr_gen.valid_operator(o2,f2))
36616  return error_node();
36617  else
36618  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
36619  }
36620 
36621  static inline std::string id(expression_generator<Type>& expr_gen,
36622  const details::operator_type o0,
36623  const details::operator_type o1,
36624  const details::operator_type o2)
36625  {
36626  return details::build_string()
36627  << "(t" << expr_gen.to_str(o0)
36628  << "t)" << expr_gen.to_str(o1)
36629  << "(t" << expr_gen.to_str(o2)
36630  << "t)";
36631  }
36632  };
36633 
36635  {
36636  typedef typename covovoc_t::type0 node_type;
36637  typedef typename covovoc_t::sf4_type sf4_type;
36638  typedef typename node_type::T0 T0;
36639  typedef typename node_type::T1 T1;
36640  typedef typename node_type::T2 T2;
36641  typedef typename node_type::T3 T3;
36642 
36644  const details::operator_type& operation,
36645  expression_node_ptr (&branch)[2])
36646  {
36647  // (c0 o0 v0) o1 (v1 o2 c1)
36648  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
36649  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
36650  const Type c0 = cov->c();
36651  const Type& v0 = cov->v();
36652  const Type c1 = voc->c();
36653  const Type& v1 = voc->v();
36654  const details::operator_type o0 = cov->operation();
36655  const details::operator_type o1 = operation;
36656  const details::operator_type o2 = voc->operation();
36657 
36658  details::free_node(*(expr_gen.node_allocator_),branch[0]);
36659  details::free_node(*(expr_gen.node_allocator_),branch[1]);
36660 
36661  expression_node_ptr result = error_node();
36662 
36664  {
36665  // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
36666  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36667  {
36668  const bool synthesis_result =
36669  synthesize_sf3ext_expression::
36670  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36671 
36672  exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
36673 
36674  return (synthesis_result) ? result : error_node();
36675  }
36676  // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
36677  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36678  {
36679  const bool synthesis_result =
36680  synthesize_sf3ext_expression::
36681  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36682 
36683  exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
36684 
36685  return (synthesis_result) ? result : error_node();
36686  }
36687  // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1
36688  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36689  {
36690  const bool synthesis_result =
36691  synthesize_sf3ext_expression::
36692  template compile<ctype, vtype, vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result);
36693 
36694  exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
36695 
36696  return (synthesis_result) ? result : error_node();
36697  }
36698  // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
36699  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36700  {
36701  const bool synthesis_result =
36702  synthesize_sf3ext_expression::
36703  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36704 
36705  exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
36706 
36707  return (synthesis_result) ? result : error_node();
36708  }
36709  // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
36710  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36711  {
36712  const bool synthesis_result =
36713  synthesize_sf3ext_expression::
36714  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36715 
36716  exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
36717 
36718  return (synthesis_result) ? result : error_node();
36719  }
36720  // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)
36721  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36722  {
36723  const bool synthesis_result =
36724  synthesize_sf3ext_expression::
36725  template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result);
36726 
36727  exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
36728 
36729  return (synthesis_result) ? result : error_node();
36730  }
36731  // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)
36732  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36733  {
36734  const bool synthesis_result =
36735  synthesize_sf3ext_expression::
36736  template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
36737 
36738  exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
36739 
36740  return (synthesis_result) ? result : error_node();
36741  }
36742  // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
36743  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36744  {
36745  const bool synthesis_result =
36746  synthesize_sf3ext_expression::
36747  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result);
36748 
36749  exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
36750 
36751  return (synthesis_result) ? result : error_node();
36752  }
36753  // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)
36754  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36755  {
36756  const bool synthesis_result =
36757  synthesize_sf3ext_expression::
36758  template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
36759 
36760  exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
36761 
36762  return (synthesis_result) ? result : error_node();
36763  }
36764  // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
36765  else if (
36766  (std::equal_to<T>()(c0,c1)) &&
36767  (details::e_mul == o0) &&
36768  (details::e_mul == o2) &&
36769  (
36770  (details::e_add == o1) ||
36771  (details::e_sub == o1)
36772  )
36773  )
36774  {
36775  std::string specfunc;
36776 
36777  switch (o1)
36778  {
36779  case details::e_add : specfunc = "t*(t+t)"; break;
36780  case details::e_sub : specfunc = "t*(t-t)"; break;
36781  default : return error_node();
36782  }
36783 
36784  const bool synthesis_result =
36785  synthesize_sf3ext_expression::
36786  template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36787 
36788  exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
36789 
36790  return (synthesis_result) ? result : error_node();
36791  }
36792  }
36793 
36794  const bool synthesis_result =
36795  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36796  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
36797 
36798  if (synthesis_result)
36799  return result;
36800 
36801  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36802  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36803  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36804 
36805  if (!expr_gen.valid_operator(o0,f0))
36806  return error_node();
36807  else if (!expr_gen.valid_operator(o1,f1))
36808  return error_node();
36809  else if (!expr_gen.valid_operator(o2,f2))
36810  return error_node();
36811  else
36812  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
36813  }
36814 
36815  static inline std::string id(expression_generator<Type>& expr_gen,
36816  const details::operator_type o0,
36817  const details::operator_type o1,
36818  const details::operator_type o2)
36819  {
36820  return details::build_string()
36821  << "(t" << expr_gen.to_str(o0)
36822  << "t)" << expr_gen.to_str(o1)
36823  << "(t" << expr_gen.to_str(o2)
36824  << "t)";
36825  }
36826  };
36827 
36829  {
36830  typedef typename vococov_t::type0 node_type;
36831  typedef typename vococov_t::sf4_type sf4_type;
36832  typedef typename node_type::T0 T0;
36833  typedef typename node_type::T1 T1;
36834  typedef typename node_type::T2 T2;
36835  typedef typename node_type::T3 T3;
36836 
36838  const details::operator_type& operation,
36839  expression_node_ptr (&branch)[2])
36840  {
36841  // (v0 o0 c0) o1 (c1 o2 v1)
36842  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
36843  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
36844  const Type c0 = voc->c();
36845  const Type& v0 = voc->v();
36846  const Type c1 = cov->c();
36847  const Type& v1 = cov->v();
36848  const details::operator_type o0 = voc->operation();
36849  const details::operator_type o1 = operation;
36850  const details::operator_type o2 = cov->operation();
36851 
36852  details::free_node(*(expr_gen.node_allocator_),branch[0]);
36853  details::free_node(*(expr_gen.node_allocator_),branch[1]);
36854 
36855  expression_node_ptr result = error_node();
36856 
36858  {
36859  // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
36860  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
36861  {
36862  const bool synthesis_result =
36863  synthesize_sf3ext_expression::
36864  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
36865 
36866  exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
36867 
36868  return (synthesis_result) ? result : error_node();
36869  }
36870  // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
36871  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
36872  {
36873  const bool synthesis_result =
36874  synthesize_sf3ext_expression::
36875  template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
36876 
36877  exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
36878 
36879  return (synthesis_result) ? result : error_node();
36880  }
36881  // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)
36882  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
36883  {
36884  const bool synthesis_result =
36885  synthesize_sf3ext_expression::
36886  template compile<vtype, vtype, ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result);
36887 
36888  exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
36889 
36890  return (synthesis_result) ? result : error_node();
36891  }
36892  // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
36893  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
36894  {
36895  const bool synthesis_result =
36896  synthesize_sf3ext_expression::
36897  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
36898 
36899  exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
36900 
36901  return (synthesis_result) ? result : error_node();
36902  }
36903  // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)
36904  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
36905  {
36906  const bool synthesis_result =
36907  synthesize_sf3ext_expression::
36908  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
36909 
36910  exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
36911 
36912  return (synthesis_result) ? result : error_node();
36913  }
36914  // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)
36915  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
36916  {
36917  const bool synthesis_result =
36918  synthesize_sf3ext_expression::
36919  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
36920 
36921  exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
36922 
36923  return (synthesis_result) ? result : error_node();
36924  }
36925  // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
36926  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
36927  {
36928  const bool synthesis_result =
36929  synthesize_sf3ext_expression::
36930  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result);
36931 
36932  exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
36933 
36934  return (synthesis_result) ? result : error_node();
36935  }
36936  // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)
36937  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
36938  {
36939  const bool synthesis_result =
36940  synthesize_sf3ext_expression::
36941  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result);
36942 
36943  exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
36944 
36945  return (synthesis_result) ? result : error_node();
36946  }
36947  // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))
36948  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
36949  {
36950  const bool synthesis_result =
36951  synthesize_sf3ext_expression::
36952  template compile<vtype, vtype, ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result);
36953 
36954  exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
36955 
36956  return (synthesis_result) ? result : error_node();
36957  }
36958  // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)
36959  else if (
36960  (std::equal_to<T>()(c0,c1)) &&
36961  (details::e_mul == o0) &&
36962  (details::e_mul == o2) &&
36963  (
36964  (details::e_add == o1) || (details::e_sub == o1)
36965  )
36966  )
36967  {
36968  std::string specfunc;
36969 
36970  switch (o1)
36971  {
36972  case details::e_add : specfunc = "t*(t+t)"; break;
36973  case details::e_sub : specfunc = "t*(t-t)"; break;
36974  default : return error_node();
36975  }
36976 
36977  const bool synthesis_result =
36978  synthesize_sf3ext_expression::
36979  template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
36980 
36981  exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
36982 
36983  return (synthesis_result) ? result : error_node();
36984  }
36985  }
36986 
36987  const bool synthesis_result =
36988  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
36989  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
36990 
36991  if (synthesis_result)
36992  return result;
36993 
36994  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
36995  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
36996  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
36997 
36998  if (!expr_gen.valid_operator(o0,f0))
36999  return error_node();
37000  else if (!expr_gen.valid_operator(o1,f1))
37001  return error_node();
37002  else if (!expr_gen.valid_operator(o2,f2))
37003  return error_node();
37004  else
37005  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
37006  }
37007 
37008  static inline std::string id(expression_generator<Type>& expr_gen,
37009  const details::operator_type o0,
37010  const details::operator_type o1,
37011  const details::operator_type o2)
37012  {
37013  return details::build_string()
37014  << "(t" << expr_gen.to_str(o0)
37015  << "t)" << expr_gen.to_str(o1)
37016  << "(t" << expr_gen.to_str(o2)
37017  << "t)";
37018  }
37019  };
37020 
37022  {
37023  typedef typename vovovov_t::type1 node_type;
37024  typedef typename vovovov_t::sf4_type sf4_type;
37025  typedef typename node_type::T0 T0;
37026  typedef typename node_type::T1 T1;
37027  typedef typename node_type::T2 T2;
37028  typedef typename node_type::T3 T3;
37029 
37031  const details::operator_type& operation,
37032  expression_node_ptr (&branch)[2])
37033  {
37034  // v0 o0 (v1 o1 (v2 o2 v3))
37035  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
37036 
37037  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
37038  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37039  const Type& v1 = vovov->t0();
37040  const Type& v2 = vovov->t1();
37041  const Type& v3 = vovov->t2();
37042  const details::operator_type o0 = operation;
37043  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
37044  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
37045 
37046  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37047  binary_functor_t f1 = vovov->f0();
37048  binary_functor_t f2 = vovov->f1();
37049 
37050  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37051 
37052  expression_node_ptr result = error_node();
37053 
37054  const bool synthesis_result =
37055  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37056  (expr_gen,id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
37057 
37058  if (synthesis_result)
37059  return result;
37060  else if (!expr_gen.valid_operator(o0,f0))
37061  return error_node();
37062 
37063  exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n"));
37064 
37065  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
37066  }
37067 
37068  static inline std::string id(expression_generator<Type>& expr_gen,
37069  const details::operator_type o0,
37070  const details::operator_type o1,
37071  const details::operator_type o2)
37072  {
37073  return details::build_string()
37074  << "t" << expr_gen.to_str(o0)
37075  << "(t" << expr_gen.to_str(o1)
37076  << "(t" << expr_gen.to_str(o2)
37077  << "t))";
37078  }
37079  };
37080 
37082  {
37083  typedef typename vovovoc_t::type1 node_type;
37084  typedef typename vovovoc_t::sf4_type sf4_type;
37085  typedef typename node_type::T0 T0;
37086  typedef typename node_type::T1 T1;
37087  typedef typename node_type::T2 T2;
37088  typedef typename node_type::T3 T3;
37089 
37091  const details::operator_type& operation,
37092  expression_node_ptr (&branch)[2])
37093  {
37094  // v0 o0 (v1 o1 (v2 o2 c))
37095  typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
37096 
37097  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
37098  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37099  const Type& v1 = vovoc->t0();
37100  const Type& v2 = vovoc->t1();
37101  const Type c = vovoc->t2();
37102  const details::operator_type o0 = operation;
37103  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
37104  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
37105 
37106  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37107  binary_functor_t f1 = vovoc->f0();
37108  binary_functor_t f2 = vovoc->f1();
37109 
37110  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37111 
37112  expression_node_ptr result = error_node();
37113 
37114  const bool synthesis_result =
37115  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37116  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
37117 
37118  if (synthesis_result)
37119  return result;
37120  else if (!expr_gen.valid_operator(o0,f0))
37121  return error_node();
37122 
37123  exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n"));
37124 
37125  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
37126  }
37127 
37128  static inline std::string id(expression_generator<Type>& expr_gen,
37129  const details::operator_type o0,
37130  const details::operator_type o1,
37131  const details::operator_type o2)
37132  {
37133  return details::build_string()
37134  << "t" << expr_gen.to_str(o0)
37135  << "(t" << expr_gen.to_str(o1)
37136  << "(t" << expr_gen.to_str(o2)
37137  << "t))";
37138  }
37139  };
37140 
37142  {
37143  typedef typename vovocov_t::type1 node_type;
37144  typedef typename vovocov_t::sf4_type sf4_type;
37145  typedef typename node_type::T0 T0;
37146  typedef typename node_type::T1 T1;
37147  typedef typename node_type::T2 T2;
37148  typedef typename node_type::T3 T3;
37149 
37151  const details::operator_type& operation,
37152  expression_node_ptr (&branch)[2])
37153  {
37154  // v0 o0 (v1 o1 (c o2 v2))
37155  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
37156 
37157  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37158  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37159  const Type& v1 = vocov->t0();
37160  const Type c = vocov->t1();
37161  const Type& v2 = vocov->t2();
37162  const details::operator_type o0 = operation;
37163  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37164  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37165 
37166  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37167  binary_functor_t f1 = vocov->f0();
37168  binary_functor_t f2 = vocov->f1();
37169 
37170  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37171 
37172  expression_node_ptr result = error_node();
37173 
37174  const bool synthesis_result =
37175  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37176  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
37177 
37178  if (synthesis_result)
37179  return result;
37180  if (!expr_gen.valid_operator(o0,f0))
37181  return error_node();
37182 
37183  exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n"));
37184 
37185  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
37186  }
37187 
37188  static inline std::string id(expression_generator<Type>& expr_gen,
37189  const details::operator_type o0,
37190  const details::operator_type o1,
37191  const details::operator_type o2)
37192  {
37193  return details::build_string()
37194  << "t" << expr_gen.to_str(o0)
37195  << "(t" << expr_gen.to_str(o1)
37196  << "(t" << expr_gen.to_str(o2)
37197  << "t))";
37198  }
37199  };
37200 
37202  {
37203  typedef typename vocovov_t::type1 node_type;
37204  typedef typename vocovov_t::sf4_type sf4_type;
37205  typedef typename node_type::T0 T0;
37206  typedef typename node_type::T1 T1;
37207  typedef typename node_type::T2 T2;
37208  typedef typename node_type::T3 T3;
37209 
37211  const details::operator_type& operation,
37212  expression_node_ptr (&branch)[2])
37213  {
37214  // v0 o0 (c o1 (v1 o2 v2))
37215  typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
37216 
37217  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
37218  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37219  const Type c = covov->t0();
37220  const Type& v1 = covov->t1();
37221  const Type& v2 = covov->t2();
37222  const details::operator_type o0 = operation;
37223  const details::operator_type o1 = expr_gen.get_operator(covov->f0());
37224  const details::operator_type o2 = expr_gen.get_operator(covov->f1());
37225 
37226  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37227  binary_functor_t f1 = covov->f0();
37228  binary_functor_t f2 = covov->f1();
37229 
37230  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37231 
37232  expression_node_ptr result = error_node();
37233 
37234  const bool synthesis_result =
37235  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37236  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
37237 
37238  if (synthesis_result)
37239  return result;
37240  else if (!expr_gen.valid_operator(o0,f0))
37241  return error_node();
37242 
37243  exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n"));
37244 
37245  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
37246  }
37247 
37248  static inline std::string id(expression_generator<Type>& expr_gen,
37249  const details::operator_type o0,
37250  const details::operator_type o1,
37251  const details::operator_type o2)
37252  {
37253  return details::build_string()
37254  << "t" << expr_gen.to_str(o0)
37255  << "(t" << expr_gen.to_str(o1)
37256  << "(t" << expr_gen.to_str(o2)
37257  << "t))";
37258  }
37259  };
37260 
37262  {
37263  typedef typename covovov_t::type1 node_type;
37264  typedef typename covovov_t::sf4_type sf4_type;
37265  typedef typename node_type::T0 T0;
37266  typedef typename node_type::T1 T1;
37267  typedef typename node_type::T2 T2;
37268  typedef typename node_type::T3 T3;
37269 
37271  const details::operator_type& operation,
37272  expression_node_ptr (&branch)[2])
37273  {
37274  // c o0 (v0 o1 (v1 o2 v2))
37275  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
37276 
37277  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
37278  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
37279  const Type& v0 = vovov->t0();
37280  const Type& v1 = vovov->t1();
37281  const Type& v2 = vovov->t2();
37282  const details::operator_type o0 = operation;
37283  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
37284  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
37285 
37286  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37287  binary_functor_t f1 = vovov->f0();
37288  binary_functor_t f2 = vovov->f1();
37289 
37290  details::free_node(*(expr_gen.node_allocator_),branch[0]);
37291  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37292 
37293  expression_node_ptr result = error_node();
37294 
37295  const bool synthesis_result =
37296  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37297  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
37298 
37299  if (synthesis_result)
37300  return result;
37301  if (!expr_gen.valid_operator(o0,f0))
37302  return error_node();
37303 
37304  exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n"));
37305 
37306  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
37307  }
37308 
37309  static inline std::string id(expression_generator<Type>& expr_gen,
37310  const details::operator_type o0,
37311  const details::operator_type o1,
37312  const details::operator_type o2)
37313  {
37314  return details::build_string()
37315  << "t" << expr_gen.to_str(o0)
37316  << "(t" << expr_gen.to_str(o1)
37317  << "(t" << expr_gen.to_str(o2)
37318  << "t))";
37319  }
37320  };
37321 
37323  {
37324  typedef typename covocov_t::type1 node_type;
37325  typedef typename covocov_t::sf4_type sf4_type;
37326  typedef typename node_type::T0 T0;
37327  typedef typename node_type::T1 T1;
37328  typedef typename node_type::T2 T2;
37329  typedef typename node_type::T3 T3;
37330 
37332  const details::operator_type& operation,
37333  expression_node_ptr (&branch)[2])
37334  {
37335  // c0 o0 (v0 o1 (c1 o2 v1))
37336  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
37337 
37338  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37339  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
37340  const Type& v0 = vocov->t0();
37341  const Type c1 = vocov->t1();
37342  const Type& v1 = vocov->t2();
37343  const details::operator_type o0 = operation;
37344  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37345  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37346 
37347  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37348  binary_functor_t f1 = vocov->f0();
37349  binary_functor_t f2 = vocov->f1();
37350 
37351  details::free_node(*(expr_gen.node_allocator_),branch[0]);
37352  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37353 
37354  expression_node_ptr result = error_node();
37355 
37356  const bool synthesis_result =
37357  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37358  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
37359 
37360  if (synthesis_result)
37361  return result;
37362  else if (!expr_gen.valid_operator(o0,f0))
37363  return error_node();
37364 
37365  exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n"));
37366 
37367  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
37368  }
37369 
37370  static inline std::string id(expression_generator<Type>& expr_gen,
37371  const details::operator_type o0,
37372  const details::operator_type o1,
37373  const details::operator_type o2)
37374  {
37375  return details::build_string()
37376  << "t" << expr_gen.to_str(o0)
37377  << "(t" << expr_gen.to_str(o1)
37378  << "(t" << expr_gen.to_str(o2)
37379  << "t))";
37380  }
37381  };
37382 
37384  {
37385  typedef typename vocovoc_t::type1 node_type;
37386  typedef typename vocovoc_t::sf4_type sf4_type;
37387  typedef typename node_type::T0 T0;
37388  typedef typename node_type::T1 T1;
37389  typedef typename node_type::T2 T2;
37390  typedef typename node_type::T3 T3;
37391 
37393  const details::operator_type& operation,
37394  expression_node_ptr (&branch)[2])
37395  {
37396  // v0 o0 (c0 o1 (v1 o2 c2))
37397  typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
37398 
37399  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
37400  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37401  const Type c0 = covoc->t0();
37402  const Type& v1 = covoc->t1();
37403  const Type c1 = covoc->t2();
37404  const details::operator_type o0 = operation;
37405  const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
37406  const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
37407 
37408  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37409  binary_functor_t f1 = covoc->f0();
37410  binary_functor_t f2 = covoc->f1();
37411 
37412  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37413 
37414  expression_node_ptr result = error_node();
37415 
37416  const bool synthesis_result =
37417  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37418  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
37419 
37420  if (synthesis_result)
37421  return result;
37422  else if (!expr_gen.valid_operator(o0,f0))
37423  return error_node();
37424 
37425  exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n"));
37426 
37427  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
37428  }
37429 
37430  static inline std::string id(expression_generator<Type>& expr_gen,
37431  const details::operator_type o0,
37432  const details::operator_type o1,
37433  const details::operator_type o2)
37434  {
37435  return details::build_string()
37436  << "t" << expr_gen.to_str(o0)
37437  << "(t" << expr_gen.to_str(o1)
37438  << "(t" << expr_gen.to_str(o2)
37439  << "t))";
37440  }
37441  };
37442 
37444  {
37445  typedef typename covovoc_t::type1 node_type;
37446  typedef typename covovoc_t::sf4_type sf4_type;
37447  typedef typename node_type::T0 T0;
37448  typedef typename node_type::T1 T1;
37449  typedef typename node_type::T2 T2;
37450  typedef typename node_type::T3 T3;
37452  const details::operator_type& operation,
37453  expression_node_ptr (&branch)[2])
37454  {
37455  // c0 o0 (v0 o1 (v1 o2 c1))
37456  typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
37457 
37458  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
37459  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
37460  const Type& v0 = vovoc->t0();
37461  const Type& v1 = vovoc->t1();
37462  const Type c1 = vovoc->t2();
37463  const details::operator_type o0 = operation;
37464  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
37465  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
37466 
37467  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37468  binary_functor_t f1 = vovoc->f0();
37469  binary_functor_t f2 = vovoc->f1();
37470 
37471  details::free_node(*(expr_gen.node_allocator_),branch[0]);
37472  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37473 
37474  expression_node_ptr result = error_node();
37475 
37476  const bool synthesis_result =
37477  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37478  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
37479 
37480  if (synthesis_result)
37481  return result;
37482  else if (!expr_gen.valid_operator(o0,f0))
37483  return error_node();
37484 
37485  exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n"));
37486 
37487  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
37488  }
37489 
37490  static inline std::string id(expression_generator<Type>& expr_gen,
37491  const details::operator_type o0,
37492  const details::operator_type o1,
37493  const details::operator_type o2)
37494  {
37495  return details::build_string()
37496  << "t" << expr_gen.to_str(o0)
37497  << "(t" << expr_gen.to_str(o1)
37498  << "(t" << expr_gen.to_str(o2)
37499  << "t))";
37500  }
37501  };
37502 
37504  {
37505  typedef typename vococov_t::type1 node_type;
37506  typedef typename vococov_t::sf4_type sf4_type;
37507  typedef typename node_type::T0 T0;
37508  typedef typename node_type::T1 T1;
37509  typedef typename node_type::T2 T2;
37510  typedef typename node_type::T3 T3;
37511 
37513  const details::operator_type& operation,
37514  expression_node_ptr (&branch)[2])
37515  {
37516  // v0 o0 (c0 o1 (c1 o2 v1))
37517  typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t;
37518 
37519  const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]);
37520  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37521  const Type c0 = cocov->t0();
37522  const Type c1 = cocov->t1();
37523  const Type& v1 = cocov->t2();
37524  const details::operator_type o0 = operation;
37525  const details::operator_type o1 = expr_gen.get_operator(cocov->f0());
37526  const details::operator_type o2 = expr_gen.get_operator(cocov->f1());
37527 
37528  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37529  binary_functor_t f1 = cocov->f0();
37530  binary_functor_t f2 = cocov->f1();
37531 
37532  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37533 
37534  expression_node_ptr result = error_node();
37535 
37536  const bool synthesis_result =
37537  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37538  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
37539 
37540  if (synthesis_result)
37541  return result;
37542  else if (!expr_gen.valid_operator(o0,f0))
37543  return error_node();
37544 
37545  exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n"));
37546 
37547  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
37548  }
37549 
37550  static inline std::string id(expression_generator<Type>& expr_gen,
37551  const details::operator_type o0,
37552  const details::operator_type o1,
37553  const details::operator_type o2)
37554  {
37555  return details::build_string()
37556  << "t" << expr_gen.to_str(o0)
37557  << "(t" << expr_gen.to_str(o1)
37558  << "(t" << expr_gen.to_str(o2)
37559  << "t))";
37560  }
37561  };
37562 
37564  {
37565  typedef typename vovovov_t::type2 node_type;
37566  typedef typename vovovov_t::sf4_type sf4_type;
37567  typedef typename node_type::T0 T0;
37568  typedef typename node_type::T1 T1;
37569  typedef typename node_type::T2 T2;
37570  typedef typename node_type::T3 T3;
37571 
37573  const details::operator_type& operation,
37574  expression_node_ptr (&branch)[2])
37575  {
37576  // v0 o0 ((v1 o1 v2) o2 v3)
37577  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
37578 
37579  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
37580  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37581  const Type& v1 = vovov->t0();
37582  const Type& v2 = vovov->t1();
37583  const Type& v3 = vovov->t2();
37584  const details::operator_type o0 = operation;
37585  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
37586  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
37587 
37588  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37589  binary_functor_t f1 = vovov->f0();
37590  binary_functor_t f2 = vovov->f1();
37591 
37592  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37593 
37594  expression_node_ptr result = error_node();
37595 
37596  const bool synthesis_result =
37597  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37598  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
37599 
37600  if (synthesis_result)
37601  return result;
37602  else if (!expr_gen.valid_operator(o0,f0))
37603  return error_node();
37604 
37605  exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n"));
37606 
37607  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
37608  }
37609 
37610  static inline std::string id(expression_generator<Type>& expr_gen,
37611  const details::operator_type o0,
37612  const details::operator_type o1,
37613  const details::operator_type o2)
37614  {
37615  return details::build_string()
37616  << "t" << expr_gen.to_str(o0)
37617  << "((t" << expr_gen.to_str(o1)
37618  << "t)" << expr_gen.to_str(o2)
37619  << "t)";
37620  }
37621  };
37622 
37624  {
37625  typedef typename vovovoc_t::type2 node_type;
37626  typedef typename vovovoc_t::sf4_type sf4_type;
37627  typedef typename node_type::T0 T0;
37628  typedef typename node_type::T1 T1;
37629  typedef typename node_type::T2 T2;
37630  typedef typename node_type::T3 T3;
37631 
37633  const details::operator_type& operation,
37634  expression_node_ptr (&branch)[2])
37635  {
37636  // v0 o0 ((v1 o1 v2) o2 c)
37637  typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
37638 
37639  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
37640  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37641  const Type& v1 = vovoc->t0();
37642  const Type& v2 = vovoc->t1();
37643  const Type c = vovoc->t2();
37644  const details::operator_type o0 = operation;
37645  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
37646  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
37647 
37648  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37649  binary_functor_t f1 = vovoc->f0();
37650  binary_functor_t f2 = vovoc->f1();
37651 
37652  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37653 
37654  expression_node_ptr result = error_node();
37655 
37656  const bool synthesis_result =
37657  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37658  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
37659 
37660  if (synthesis_result)
37661  return result;
37662  else if (!expr_gen.valid_operator(o0,f0))
37663  return error_node();
37664 
37665  exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n"));
37666 
37667  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
37668  }
37669 
37670  static inline std::string id(expression_generator<Type>& expr_gen,
37671  const details::operator_type o0,
37672  const details::operator_type o1,
37673  const details::operator_type o2)
37674  {
37675  return details::build_string()
37676  << "t" << expr_gen.to_str(o0)
37677  << "((t" << expr_gen.to_str(o1)
37678  << "t)" << expr_gen.to_str(o2)
37679  << "t)";
37680  }
37681  };
37682 
37684  {
37685  typedef typename vovocov_t::type2 node_type;
37686  typedef typename vovocov_t::sf4_type sf4_type;
37687  typedef typename node_type::T0 T0;
37688  typedef typename node_type::T1 T1;
37689  typedef typename node_type::T2 T2;
37690  typedef typename node_type::T3 T3;
37691 
37693  const details::operator_type& operation,
37694  expression_node_ptr (&branch)[2])
37695  {
37696  // v0 o0 ((v1 o1 c) o2 v2)
37697  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
37698 
37699  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37700  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37701  const Type& v1 = vocov->t0();
37702  const Type c = vocov->t1();
37703  const Type& v2 = vocov->t2();
37704  const details::operator_type o0 = operation;
37705  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37706  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37707 
37708  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37709  binary_functor_t f1 = vocov->f0();
37710  binary_functor_t f2 = vocov->f1();
37711 
37712  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37713 
37714  expression_node_ptr result = error_node();
37715 
37716  const bool synthesis_result =
37717  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37718  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
37719 
37720  if (synthesis_result)
37721  return result;
37722  else if (!expr_gen.valid_operator(o0,f0))
37723  return error_node();
37724 
37725  exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n"));
37726 
37727  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
37728  }
37729 
37730  static inline std::string id(expression_generator<Type>& expr_gen,
37731  const details::operator_type o0,
37732  const details::operator_type o1,
37733  const details::operator_type o2)
37734  {
37735  return details::build_string()
37736  << "t" << expr_gen.to_str(o0)
37737  << "((t" << expr_gen.to_str(o1)
37738  << "t)" << expr_gen.to_str(o2)
37739  << "t)";
37740  }
37741  };
37742 
37744  {
37745  typedef typename vocovov_t::type2 node_type;
37746  typedef typename vocovov_t::sf4_type sf4_type;
37747  typedef typename node_type::T0 T0;
37748  typedef typename node_type::T1 T1;
37749  typedef typename node_type::T2 T2;
37750  typedef typename node_type::T3 T3;
37751 
37753  const details::operator_type& operation,
37754  expression_node_ptr (&branch)[2])
37755  {
37756  // v0 o0 ((c o1 v1) o2 v2)
37757  typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
37758 
37759  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
37760  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37761  const Type c = covov->t0();
37762  const Type& v1 = covov->t1();
37763  const Type& v2 = covov->t2();
37764  const details::operator_type o0 = operation;
37765  const details::operator_type o1 = expr_gen.get_operator(covov->f0());
37766  const details::operator_type o2 = expr_gen.get_operator(covov->f1());
37767 
37768  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37769  binary_functor_t f1 = covov->f0();
37770  binary_functor_t f2 = covov->f1();
37771 
37772  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37773 
37774  expression_node_ptr result = error_node();
37775 
37776  const bool synthesis_result =
37777  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37778  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
37779 
37780  if (synthesis_result)
37781  return result;
37782  else if (!expr_gen.valid_operator(o0,f0))
37783  return error_node();
37784 
37785  exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n"));
37786 
37787  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
37788  }
37789 
37790  static inline std::string id(expression_generator<Type>& expr_gen,
37791  const details::operator_type o0,
37792  const details::operator_type o1,
37793  const details::operator_type o2)
37794  {
37795  return details::build_string()
37796  << "t" << expr_gen.to_str(o0)
37797  << "((t" << expr_gen.to_str(o1)
37798  << "t)" << expr_gen.to_str(o2)
37799  << "t)";
37800  }
37801  };
37802 
37804  {
37805  typedef typename covovov_t::type2 node_type;
37806  typedef typename covovov_t::sf4_type sf4_type;
37807  typedef typename node_type::T0 T0;
37808  typedef typename node_type::T1 T1;
37809  typedef typename node_type::T2 T2;
37810  typedef typename node_type::T3 T3;
37811 
37813  const details::operator_type& operation,
37814  expression_node_ptr (&branch)[2])
37815  {
37816  // c o0 ((v1 o1 v2) o2 v3)
37817  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
37818 
37819  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
37820  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
37821  const Type& v0 = vovov->t0();
37822  const Type& v1 = vovov->t1();
37823  const Type& v2 = vovov->t2();
37824  const details::operator_type o0 = operation;
37825  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
37826  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
37827 
37828  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37829  binary_functor_t f1 = vovov->f0();
37830  binary_functor_t f2 = vovov->f1();
37831 
37832  details::free_node(*(expr_gen.node_allocator_),branch[0]);
37833  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37834 
37835  expression_node_ptr result = error_node();
37836 
37837  const bool synthesis_result =
37838  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37839  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
37840 
37841  if (synthesis_result)
37842  return result;
37843  else if (!expr_gen.valid_operator(o0,f0))
37844  return error_node();
37845 
37846  exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n"));
37847 
37848  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
37849  }
37850 
37851  static inline std::string id(expression_generator<Type>& expr_gen,
37852  const details::operator_type o0,
37853  const details::operator_type o1,
37854  const details::operator_type o2)
37855  {
37856  return details::build_string()
37857  << "t" << expr_gen.to_str(o0)
37858  << "((t" << expr_gen.to_str(o1)
37859  << "t)" << expr_gen.to_str(o2)
37860  << "t)";
37861  }
37862  };
37863 
37865  {
37866  typedef typename covocov_t::type2 node_type;
37867  typedef typename covocov_t::sf4_type sf4_type;
37868  typedef typename node_type::T0 T0;
37869  typedef typename node_type::T1 T1;
37870  typedef typename node_type::T2 T2;
37871  typedef typename node_type::T3 T3;
37872 
37874  const details::operator_type& operation,
37875  expression_node_ptr (&branch)[2])
37876  {
37877  // c0 o0 ((v0 o1 c1) o2 v1)
37878  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
37879 
37880  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
37881  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
37882  const Type& v0 = vocov->t0();
37883  const Type c1 = vocov->t1();
37884  const Type& v1 = vocov->t2();
37885  const details::operator_type o0 = operation;
37886  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
37887  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
37888 
37889  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37890  binary_functor_t f1 = vocov->f0();
37891  binary_functor_t f2 = vocov->f1();
37892 
37893  details::free_node(*(expr_gen.node_allocator_),branch[0]);
37894  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37895 
37896  expression_node_ptr result = error_node();
37897 
37898  const bool synthesis_result =
37899  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37900  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
37901 
37902  if (synthesis_result)
37903  return result;
37904  else if (!expr_gen.valid_operator(o0,f0))
37905  return error_node();
37906 
37907  exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n"));
37908 
37909  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
37910  }
37911 
37912  static inline std::string id(expression_generator<Type>& expr_gen,
37913  const details::operator_type o0,
37914  const details::operator_type o1,
37915  const details::operator_type o2)
37916  {
37917  return details::build_string()
37918  << "t" << expr_gen.to_str(o0)
37919  << "((t" << expr_gen.to_str(o1)
37920  << "t)" << expr_gen.to_str(o2)
37921  << "t)";
37922  }
37923  };
37924 
37926  {
37927  typedef typename vocovoc_t::type2 node_type;
37928  typedef typename vocovoc_t::sf4_type sf4_type;
37929  typedef typename node_type::T0 T0;
37930  typedef typename node_type::T1 T1;
37931  typedef typename node_type::T2 T2;
37932  typedef typename node_type::T3 T3;
37933 
37935  const details::operator_type& operation,
37936  expression_node_ptr (&branch)[2])
37937  {
37938  // v0 o0 ((c0 o1 v1) o2 c1)
37939  typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
37940 
37941  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
37942  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
37943  const Type c0 = covoc->t0();
37944  const Type& v1 = covoc->t1();
37945  const Type c1 = covoc->t2();
37946  const details::operator_type o0 = operation;
37947  const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
37948  const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
37949 
37950  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
37951  binary_functor_t f1 = covoc->f0();
37952  binary_functor_t f2 = covoc->f1();
37953 
37954  details::free_node(*(expr_gen.node_allocator_),branch[1]);
37955 
37956  expression_node_ptr result = error_node();
37957 
37958  const bool synthesis_result =
37959  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
37960  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
37961 
37962  if (synthesis_result)
37963  return result;
37964  else if (!expr_gen.valid_operator(o0,f0))
37965  return error_node();
37966 
37967  exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n"));
37968 
37969  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
37970  }
37971 
37972  static inline std::string id(expression_generator<Type>& expr_gen,
37973  const details::operator_type o0,
37974  const details::operator_type o1,
37975  const details::operator_type o2)
37976  {
37977  return details::build_string()
37978  << "t" << expr_gen.to_str(o0)
37979  << "((t" << expr_gen.to_str(o1)
37980  << "t)" << expr_gen.to_str(o2)
37981  << "t)";
37982  }
37983  };
37984 
37986  {
37987  typedef typename covovoc_t::type2 node_type;
37988  typedef typename covovoc_t::sf4_type sf4_type;
37989  typedef typename node_type::T0 T0;
37990  typedef typename node_type::T1 T1;
37991  typedef typename node_type::T2 T2;
37992  typedef typename node_type::T3 T3;
37993 
37995  const details::operator_type& operation,
37996  expression_node_ptr (&branch)[2])
37997  {
37998  // c0 o0 ((v0 o1 v1) o2 c1)
37999  typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
38000 
38001  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
38002  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
38003  const Type& v0 = vovoc->t0();
38004  const Type& v1 = vovoc->t1();
38005  const Type c1 = vovoc->t2();
38006  const details::operator_type o0 = operation;
38007  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
38008  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
38009 
38010  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
38011  binary_functor_t f1 = vovoc->f0();
38012  binary_functor_t f2 = vovoc->f1();
38013 
38014  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38015  details::free_node(*(expr_gen.node_allocator_),branch[1]);
38016 
38017  expression_node_ptr result = error_node();
38018 
38019  const bool synthesis_result =
38020  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38021  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38022 
38023  if (synthesis_result)
38024  return result;
38025  else if (!expr_gen.valid_operator(o0,f0))
38026  return error_node();
38027 
38028  exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n"));
38029 
38030  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38031  }
38032 
38033  static inline std::string id(expression_generator<Type>& expr_gen,
38034  const details::operator_type o0,
38035  const details::operator_type o1,
38036  const details::operator_type o2)
38037  {
38038  return details::build_string()
38039  << "t" << expr_gen.to_str(o0)
38040  << "((t" << expr_gen.to_str(o1)
38041  << "t)" << expr_gen.to_str(o2)
38042  << "t)";
38043  }
38044  };
38045 
38047  {
38048  typedef typename vococov_t::type2 node_type;
38050  const details::operator_type&,
38051  expression_node_ptr (&)[2])
38052  {
38053  // v0 o0 ((c0 o1 c1) o2 v1) - Not possible
38054  exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
38055  return error_node();
38056  }
38057 
38058  static inline std::string id(expression_generator<Type>&,
38059  const details::operator_type,
38060  const details::operator_type,
38061  const details::operator_type)
38062  {
38063  return "INVALID";
38064  }
38065  };
38066 
38068  {
38069  typedef typename vovovov_t::type3 node_type;
38070  typedef typename vovovov_t::sf4_type sf4_type;
38071  typedef typename node_type::T0 T0;
38072  typedef typename node_type::T1 T1;
38073  typedef typename node_type::T2 T2;
38074  typedef typename node_type::T3 T3;
38075 
38077  const details::operator_type& operation,
38078  expression_node_ptr (&branch)[2])
38079  {
38080  // ((v0 o0 v1) o1 v2) o2 v3
38081  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
38082 
38083  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38084  const Type& v0 = vovov->t0();
38085  const Type& v1 = vovov->t1();
38086  const Type& v2 = vovov->t2();
38087  const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38088  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38089  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38090  const details::operator_type o2 = operation;
38091 
38092  binary_functor_t f0 = vovov->f0();
38093  binary_functor_t f1 = vovov->f1();
38094  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38095 
38096  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38097 
38098  expression_node_ptr result = error_node();
38099 
38100  const bool synthesis_result =
38101  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38102  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
38103 
38104  if (synthesis_result)
38105  return result;
38106  else if (!expr_gen.valid_operator(o2,f2))
38107  return error_node();
38108 
38109  exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n"));
38110 
38111  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
38112  }
38113 
38114  static inline std::string id(expression_generator<Type>& expr_gen,
38115  const details::operator_type o0,
38116  const details::operator_type o1,
38117  const details::operator_type o2)
38118  {
38119  return details::build_string()
38120  << "((t" << expr_gen.to_str(o0)
38121  << "t)" << expr_gen.to_str(o1)
38122  << "t)" << expr_gen.to_str(o2)
38123  << "t";
38124  }
38125  };
38126 
38128  {
38129  typedef typename vovovoc_t::type3 node_type;
38130  typedef typename vovovoc_t::sf4_type sf4_type;
38131  typedef typename node_type::T0 T0;
38132  typedef typename node_type::T1 T1;
38133  typedef typename node_type::T2 T2;
38134  typedef typename node_type::T3 T3;
38135 
38137  const details::operator_type& operation,
38138  expression_node_ptr (&branch)[2])
38139  {
38140  // ((v0 o0 v1) o1 v2) o2 c
38141  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
38142 
38143  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38144  const Type& v0 = vovov->t0();
38145  const Type& v1 = vovov->t1();
38146  const Type& v2 = vovov->t2();
38147  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
38148  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38149  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38150  const details::operator_type o2 = operation;
38151 
38152  binary_functor_t f0 = vovov->f0();
38153  binary_functor_t f1 = vovov->f1();
38154  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38155 
38156  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38157  details::free_node(*(expr_gen.node_allocator_),branch[1]);
38158 
38159  expression_node_ptr result = error_node();
38160 
38161  const bool synthesis_result =
38162  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38163  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
38164 
38165  if (synthesis_result)
38166  return result;
38167  else if (!expr_gen.valid_operator(o2,f2))
38168  return error_node();
38169 
38170  exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n"));
38171 
38172  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
38173  }
38174 
38175  static inline std::string id(expression_generator<Type>& expr_gen,
38176  const details::operator_type o0,
38177  const details::operator_type o1,
38178  const details::operator_type o2)
38179  {
38180  return details::build_string()
38181  << "((t" << expr_gen.to_str(o0)
38182  << "t)" << expr_gen.to_str(o1)
38183  << "t)" << expr_gen.to_str(o2)
38184  << "t";
38185  }
38186  };
38187 
38189  {
38190  typedef typename vovocov_t::type3 node_type;
38191  typedef typename vovocov_t::sf4_type sf4_type;
38192  typedef typename node_type::T0 T0;
38193  typedef typename node_type::T1 T1;
38194  typedef typename node_type::T2 T2;
38195  typedef typename node_type::T3 T3;
38196 
38198  const details::operator_type& operation,
38199  expression_node_ptr (&branch)[2])
38200  {
38201  // ((v0 o0 v1) o1 c) o2 v2
38202  typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
38203 
38204  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
38205  const Type& v0 = vovoc->t0();
38206  const Type& v1 = vovoc->t1();
38207  const Type c = vovoc->t2();
38208  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38209  const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
38210  const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
38211  const details::operator_type o2 = operation;
38212 
38213  binary_functor_t f0 = vovoc->f0();
38214  binary_functor_t f1 = vovoc->f1();
38215  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38216 
38217  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38218 
38219  expression_node_ptr result = error_node();
38220 
38221  const bool synthesis_result =
38222  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38223  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
38224 
38225  if (synthesis_result)
38226  return result;
38227  else if (!expr_gen.valid_operator(o2,f2))
38228  return error_node();
38229 
38230  exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n"));
38231 
38232  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
38233  }
38234 
38235  static inline std::string id(expression_generator<Type>& expr_gen,
38236  const details::operator_type o0,
38237  const details::operator_type o1,
38238  const details::operator_type o2)
38239  {
38240  return details::build_string()
38241  << "((t" << expr_gen.to_str(o0)
38242  << "t)" << expr_gen.to_str(o1)
38243  << "t)" << expr_gen.to_str(o2)
38244  << "t";
38245  }
38246  };
38247 
38249  {
38250  typedef typename vocovov_t::type3 node_type;
38251  typedef typename vocovov_t::sf4_type sf4_type;
38252  typedef typename node_type::T0 T0;
38253  typedef typename node_type::T1 T1;
38254  typedef typename node_type::T2 T2;
38255  typedef typename node_type::T3 T3;
38256 
38258  const details::operator_type& operation,
38259  expression_node_ptr (&branch)[2])
38260  {
38261  // ((v0 o0 c) o1 v1) o2 v2
38262  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
38263 
38264  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38265  const Type& v0 = vocov->t0();
38266  const Type c = vocov->t1();
38267  const Type& v1 = vocov->t2();
38268  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38269  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38270  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38271  const details::operator_type o2 = operation;
38272 
38273  binary_functor_t f0 = vocov->f0();
38274  binary_functor_t f1 = vocov->f1();
38275  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38276 
38277  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38278 
38279  expression_node_ptr result = error_node();
38280 
38281  const bool synthesis_result =
38282  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38283  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
38284 
38285  if (synthesis_result)
38286  return result;
38287  else if (!expr_gen.valid_operator(o2,f2))
38288  return error_node();
38289 
38290  exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n"));
38291 
38292  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
38293  }
38294 
38295  static inline std::string id(expression_generator<Type>& expr_gen,
38296  const details::operator_type o0,
38297  const details::operator_type o1,
38298  const details::operator_type o2)
38299  {
38300  return details::build_string()
38301  << "((t" << expr_gen.to_str(o0)
38302  << "t)" << expr_gen.to_str(o1)
38303  << "t)" << expr_gen.to_str(o2)
38304  << "t";
38305  }
38306  };
38307 
38309  {
38310  typedef typename covovov_t::type3 node_type;
38311  typedef typename covovov_t::sf4_type sf4_type;
38312  typedef typename node_type::T0 T0;
38313  typedef typename node_type::T1 T1;
38314  typedef typename node_type::T2 T2;
38315  typedef typename node_type::T3 T3;
38316 
38318  const details::operator_type& operation,
38319  expression_node_ptr (&branch)[2])
38320  {
38321  // ((c o0 v0) o1 v1) o2 v2
38322  typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
38323 
38324  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
38325  const Type c = covov->t0();
38326  const Type& v0 = covov->t1();
38327  const Type& v1 = covov->t2();
38328  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38329  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
38330  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
38331  const details::operator_type o2 = operation;
38332 
38333  binary_functor_t f0 = covov->f0();
38334  binary_functor_t f1 = covov->f1();
38335  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38336 
38337  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38338 
38339  expression_node_ptr result = error_node();
38340 
38341  const bool synthesis_result =
38342  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38343  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
38344 
38345  if (synthesis_result)
38346  return result;
38347  else if (!expr_gen.valid_operator(o2,f2))
38348  return error_node();
38349 
38350  exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n"));
38351 
38352  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
38353  }
38354 
38355  static inline std::string id(expression_generator<Type>& expr_gen,
38356  const details::operator_type o0,
38357  const details::operator_type o1,
38358  const details::operator_type o2)
38359  {
38360  return details::build_string()
38361  << "((t" << expr_gen.to_str(o0)
38362  << "t)" << expr_gen.to_str(o1)
38363  << "t)" << expr_gen.to_str(o2)
38364  << "t";
38365  }
38366  };
38367 
38369  {
38370  typedef typename covocov_t::type3 node_type;
38371  typedef typename covocov_t::sf4_type sf4_type;
38372  typedef typename node_type::T0 T0;
38373  typedef typename node_type::T1 T1;
38374  typedef typename node_type::T2 T2;
38375  typedef typename node_type::T3 T3;
38376 
38378  const details::operator_type& operation,
38379  expression_node_ptr (&branch)[2])
38380  {
38381  // ((c0 o0 v0) o1 c1) o2 v1
38382  typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
38383 
38384  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
38385  const Type c0 = covoc->t0();
38386  const Type& v0 = covoc->t1();
38387  const Type c1 = covoc->t2();
38388  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38389  const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
38390  const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
38391  const details::operator_type o2 = operation;
38392 
38393  binary_functor_t f0 = covoc->f0();
38394  binary_functor_t f1 = covoc->f1();
38395  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38396 
38397  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38398 
38399  expression_node_ptr result = error_node();
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), c0, v0, c1, v1, result);
38404 
38405  if (synthesis_result)
38406  return result;
38407  else if (!expr_gen.valid_operator(o2,f2))
38408  return error_node();
38409 
38410  exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n"));
38411 
38412  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
38413  }
38414 
38415  static inline std::string id(expression_generator<Type>& expr_gen,
38416  const details::operator_type o0,
38417  const details::operator_type o1,
38418  const details::operator_type o2)
38419  {
38420  return details::build_string()
38421  << "((t" << expr_gen.to_str(o0)
38422  << "t)" << expr_gen.to_str(o1)
38423  << "t)" << expr_gen.to_str(o2)
38424  << "t";
38425  }
38426  };
38427 
38429  {
38430  typedef typename vocovoc_t::type3 node_type;
38431  typedef typename vocovoc_t::sf4_type sf4_type;
38432  typedef typename node_type::T0 T0;
38433  typedef typename node_type::T1 T1;
38434  typedef typename node_type::T2 T2;
38435  typedef typename node_type::T3 T3;
38436 
38438  const details::operator_type& operation,
38439  expression_node_ptr (&branch)[2])
38440  {
38441  // ((v0 o0 c0) o1 v1) o2 c1
38442  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
38443 
38444  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38445  const Type& v0 = vocov->t0();
38446  const Type c0 = vocov->t1();
38447  const Type& v1 = vocov->t2();
38448  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
38449  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38450  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38451  const details::operator_type o2 = operation;
38452 
38453  binary_functor_t f0 = vocov->f0();
38454  binary_functor_t f1 = vocov->f1();
38455  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38456 
38457  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38458  details::free_node(*(expr_gen.node_allocator_),branch[1]);
38459 
38460  expression_node_ptr result = error_node();
38461 
38462  const bool synthesis_result =
38463  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38464  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
38465 
38466  if (synthesis_result)
38467  return result;
38468  else if (!expr_gen.valid_operator(o2,f2))
38469  return error_node();
38470 
38471  exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n"));
38472 
38473  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
38474  }
38475 
38476  static inline std::string id(expression_generator<Type>& expr_gen,
38477  const details::operator_type o0,
38478  const details::operator_type o1,
38479  const details::operator_type o2)
38480  {
38481  return details::build_string()
38482  << "((t" << expr_gen.to_str(o0)
38483  << "t)" << expr_gen.to_str(o1)
38484  << "t)" << expr_gen.to_str(o2)
38485  << "t";
38486  }
38487  };
38488 
38490  {
38491  typedef typename covovoc_t::type3 node_type;
38492  typedef typename covovoc_t::sf4_type sf4_type;
38493  typedef typename node_type::T0 T0;
38494  typedef typename node_type::T1 T1;
38495  typedef typename node_type::T2 T2;
38496  typedef typename node_type::T3 T3;
38497 
38499  const details::operator_type& operation,
38500  expression_node_ptr (&branch)[2])
38501  {
38502  // ((c0 o0 v0) o1 v1) o2 c1
38503  typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
38504 
38505  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
38506  const Type c0 = covov->t0();
38507  const Type& v0 = covov->t1();
38508  const Type& v1 = covov->t2();
38509  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
38510  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
38511  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
38512  const details::operator_type o2 = operation;
38513 
38514  binary_functor_t f0 = covov->f0();
38515  binary_functor_t f1 = covov->f1();
38516  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38517 
38518  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38519  details::free_node(*(expr_gen.node_allocator_),branch[1]);
38520 
38521  expression_node_ptr result = error_node();
38522 
38523  const bool synthesis_result =
38524  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38525  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
38526 
38527  if (synthesis_result)
38528  return result;
38529  else if (!expr_gen.valid_operator(o2,f2))
38530  return error_node();
38531 
38532  exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n"));
38533 
38534  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
38535  }
38536 
38537  static inline std::string id(expression_generator<Type>& expr_gen,
38538  const details::operator_type o0,
38539  const details::operator_type o1,
38540  const details::operator_type o2)
38541  {
38542  return details::build_string()
38543  << "((t" << expr_gen.to_str(o0)
38544  << "t)" << expr_gen.to_str(o1)
38545  << "t)" << expr_gen.to_str(o2)
38546  << "t";
38547  }
38548  };
38549 
38551  {
38552  typedef typename vococov_t::type3 node_type;
38553  typedef typename vococov_t::sf4_type sf4_type;
38554  typedef typename node_type::T0 T0;
38555  typedef typename node_type::T1 T1;
38556  typedef typename node_type::T2 T2;
38557  typedef typename node_type::T3 T3;
38558 
38560  const details::operator_type& operation,
38561  expression_node_ptr (&branch)[2])
38562  {
38563  // ((v0 o0 c0) o1 c1) o2 v1
38564  typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t;
38565 
38566  const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]);
38567  const Type& v0 = vococ->t0();
38568  const Type c0 = vococ->t1();
38569  const Type c1 = vococ->t2();
38570  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38571  const details::operator_type o0 = expr_gen.get_operator(vococ->f0());
38572  const details::operator_type o1 = expr_gen.get_operator(vococ->f1());
38573  const details::operator_type o2 = operation;
38574 
38575  binary_functor_t f0 = vococ->f0();
38576  binary_functor_t f1 = vococ->f1();
38577  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38578 
38579  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38580 
38581  expression_node_ptr result = error_node();
38582 
38583  const bool synthesis_result =
38584  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38585  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
38586 
38587  if (synthesis_result)
38588  return result;
38589  else if (!expr_gen.valid_operator(o2,f2))
38590  return error_node();
38591 
38592  exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n"));
38593 
38594  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
38595  }
38596 
38597  static inline std::string id(expression_generator<Type>& expr_gen,
38598  const details::operator_type o0,
38599  const details::operator_type o1,
38600  const details::operator_type o2)
38601  {
38602  return details::build_string()
38603  << "((t" << expr_gen.to_str(o0)
38604  << "t)" << expr_gen.to_str(o1)
38605  << "t)" << expr_gen.to_str(o2)
38606  << "t";
38607  }
38608  };
38609 
38611  {
38612  typedef typename vovovov_t::type4 node_type;
38613  typedef typename vovovov_t::sf4_type sf4_type;
38614  typedef typename node_type::T0 T0;
38615  typedef typename node_type::T1 T1;
38616  typedef typename node_type::T2 T2;
38617  typedef typename node_type::T3 T3;
38618 
38620  const details::operator_type& operation,
38621  expression_node_ptr (&branch)[2])
38622  {
38623  // (v0 o0 (v1 o1 v2)) o2 v3
38624  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38625 
38626  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38627  const Type& v0 = vovov->t0();
38628  const Type& v1 = vovov->t1();
38629  const Type& v2 = vovov->t2();
38630  const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38631  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38632  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38633  const details::operator_type o2 = operation;
38634 
38635  binary_functor_t f0 = vovov->f0();
38636  binary_functor_t f1 = vovov->f1();
38637  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38638 
38639  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38640 
38641  expression_node_ptr result = error_node();
38642 
38643  const bool synthesis_result =
38644  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38645  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
38646 
38647  if (synthesis_result)
38648  return result;
38649  else if (!expr_gen.valid_operator(o2,f2))
38650  return error_node();
38651 
38652  exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n"));
38653 
38654  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
38655  }
38656 
38657  static inline std::string id(expression_generator<Type>& expr_gen,
38658  const details::operator_type o0,
38659  const details::operator_type o1,
38660  const details::operator_type o2)
38661  {
38662  return details::build_string()
38663  << "(t" << expr_gen.to_str(o0)
38664  << "(t" << expr_gen.to_str(o1)
38665  << "t)" << expr_gen.to_str(o2)
38666  << "t";
38667  }
38668  };
38669 
38671  {
38672  typedef typename vovovoc_t::type4 node_type;
38673  typedef typename vovovoc_t::sf4_type sf4_type;
38674  typedef typename node_type::T0 T0;
38675  typedef typename node_type::T1 T1;
38676  typedef typename node_type::T2 T2;
38677  typedef typename node_type::T3 T3;
38678 
38680  const details::operator_type& operation,
38681  expression_node_ptr (&branch)[2])
38682  {
38683  // ((v0 o0 (v1 o1 v2)) o2 c)
38684  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
38685 
38686  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
38687  const Type& v0 = vovov->t0();
38688  const Type& v1 = vovov->t1();
38689  const Type& v2 = vovov->t2();
38690  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
38691  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
38692  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
38693  const details::operator_type o2 = operation;
38694 
38695  binary_functor_t f0 = vovov->f0();
38696  binary_functor_t f1 = vovov->f1();
38697  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38698 
38699  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38700  details::free_node(*(expr_gen.node_allocator_),branch[1]);
38701 
38702  expression_node_ptr result = error_node();
38703 
38704  const bool synthesis_result =
38705  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38706  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
38707 
38708  if (synthesis_result)
38709  return result;
38710  else if (!expr_gen.valid_operator(o2,f2))
38711  return error_node();
38712 
38713  exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n"));
38714 
38715  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
38716  }
38717 
38718  static inline std::string id(expression_generator<Type>& expr_gen,
38719  const details::operator_type o0,
38720  const details::operator_type o1,
38721  const details::operator_type o2)
38722  {
38723  return details::build_string()
38724  << "(t" << expr_gen.to_str(o0)
38725  << "(t" << expr_gen.to_str(o1)
38726  << "t)" << expr_gen.to_str(o2)
38727  << "t";
38728  }
38729  };
38730 
38732  {
38733  typedef typename vovocov_t::type4 node_type;
38734  typedef typename vovocov_t::sf4_type sf4_type;
38735  typedef typename node_type::T0 T0;
38736  typedef typename node_type::T1 T1;
38737  typedef typename node_type::T2 T2;
38738  typedef typename node_type::T3 T3;
38739 
38741  const details::operator_type& operation,
38742  expression_node_ptr (&branch)[2])
38743  {
38744  // ((v0 o0 (v1 o1 c)) o2 v1)
38745  typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
38746 
38747  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
38748  const Type& v0 = vovoc->t0();
38749  const Type& v1 = vovoc->t1();
38750  const Type c = vovoc->t2();
38751  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38752  const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
38753  const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
38754  const details::operator_type o2 = operation;
38755 
38756  binary_functor_t f0 = vovoc->f0();
38757  binary_functor_t f1 = vovoc->f1();
38758  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38759 
38760  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38761 
38762  expression_node_ptr result = error_node();
38763 
38764  const bool synthesis_result =
38765  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38766  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
38767 
38768  if (synthesis_result)
38769  return result;
38770  else if (!expr_gen.valid_operator(o2,f2))
38771  return error_node();
38772 
38773  exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n"));
38774 
38775  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
38776  }
38777 
38778  static inline std::string id(expression_generator<Type>& expr_gen,
38779  const details::operator_type o0,
38780  const details::operator_type o1,
38781  const details::operator_type o2)
38782  {
38783  return details::build_string()
38784  << "(t" << expr_gen.to_str(o0)
38785  << "(t" << expr_gen.to_str(o1)
38786  << "t)" << expr_gen.to_str(o2)
38787  << "t";
38788  }
38789  };
38790 
38792  {
38793  typedef typename vocovov_t::type4 node_type;
38794  typedef typename vocovov_t::sf4_type sf4_type;
38795  typedef typename node_type::T0 T0;
38796  typedef typename node_type::T1 T1;
38797  typedef typename node_type::T2 T2;
38798  typedef typename node_type::T3 T3;
38799 
38801  const details::operator_type& operation,
38802  expression_node_ptr (&branch)[2])
38803  {
38804  // ((v0 o0 (c o1 v1)) o2 v2)
38805  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38806 
38807  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38808  const Type& v0 = vocov->t0();
38809  const Type c = vocov->t1();
38810  const Type& v1 = vocov->t2();
38811  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38812  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38813  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38814  const details::operator_type o2 = operation;
38815 
38816  binary_functor_t f0 = vocov->f0();
38817  binary_functor_t f1 = vocov->f1();
38818  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38819 
38820  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38821  expression_node_ptr result = error_node();
38822 
38823  const bool synthesis_result =
38824  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38825  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
38826 
38827  if (synthesis_result)
38828  return result;
38829  else if (!expr_gen.valid_operator(o2,f2))
38830  return error_node();
38831 
38832  exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n"));
38833 
38834  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
38835  }
38836 
38837  static inline std::string id(expression_generator<Type>& expr_gen,
38838  const details::operator_type o0,
38839  const details::operator_type o1,
38840  const details::operator_type o2)
38841  {
38842  return details::build_string()
38843  << "(t" << expr_gen.to_str(o0)
38844  << "(t" << expr_gen.to_str(o1)
38845  << "t)" << expr_gen.to_str(o2)
38846  << "t";
38847  }
38848  };
38849 
38851  {
38852  typedef typename covovov_t::type4 node_type;
38853  typedef typename covovov_t::sf4_type sf4_type;
38854  typedef typename node_type::T0 T0;
38855  typedef typename node_type::T1 T1;
38856  typedef typename node_type::T2 T2;
38857  typedef typename node_type::T3 T3;
38858 
38860  const details::operator_type& operation,
38861  expression_node_ptr (&branch)[2])
38862  {
38863  // ((c o0 (v0 o1 v1)) o2 v2)
38864  typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
38865 
38866  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
38867  const Type c = covov->t0();
38868  const Type& v0 = covov->t1();
38869  const Type& v1 = covov->t2();
38870  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38871  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
38872  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
38873  const details::operator_type o2 = operation;
38874 
38875  binary_functor_t f0 = covov->f0();
38876  binary_functor_t f1 = covov->f1();
38877  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38878 
38879  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38880 
38881  expression_node_ptr result = error_node();
38882 
38883  const bool synthesis_result =
38884  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38885  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
38886 
38887  if (synthesis_result)
38888  return result;
38889  else if (!expr_gen.valid_operator(o2,f2))
38890  return error_node();
38891 
38892  exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n"));
38893 
38894  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
38895  }
38896 
38897  static inline std::string id(expression_generator<Type>& expr_gen,
38898  const details::operator_type o0,
38899  const details::operator_type o1,
38900  const details::operator_type o2)
38901  {
38902  return details::build_string()
38903  << "(t" << expr_gen.to_str(o0)
38904  << "(t" << expr_gen.to_str(o1)
38905  << "t)" << expr_gen.to_str(o2)
38906  << "t";
38907  }
38908  };
38909 
38911  {
38912  typedef typename covocov_t::type4 node_type;
38913  typedef typename covocov_t::sf4_type sf4_type;
38914  typedef typename node_type::T0 T0;
38915  typedef typename node_type::T1 T1;
38916  typedef typename node_type::T2 T2;
38917  typedef typename node_type::T3 T3;
38918 
38920  const details::operator_type& operation,
38921  expression_node_ptr (&branch)[2])
38922  {
38923  // ((c0 o0 (v0 o1 c1)) o2 v1)
38924  typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
38925 
38926  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
38927  const Type c0 = covoc->t0();
38928  const Type& v0 = covoc->t1();
38929  const Type c1 = covoc->t2();
38930  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
38931  const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
38932  const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
38933  const details::operator_type o2 = operation;
38934 
38935  binary_functor_t f0 = covoc->f0();
38936  binary_functor_t f1 = covoc->f1();
38937  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38938 
38939  details::free_node(*(expr_gen.node_allocator_),branch[0]);
38940 
38941  expression_node_ptr result = error_node();
38942 
38943  const bool synthesis_result =
38944  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
38945  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
38946 
38947  if (synthesis_result)
38948  return result;
38949  else if (!expr_gen.valid_operator(o2,f2))
38950  return error_node();
38951 
38952  exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n"));
38953 
38954  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
38955  }
38956 
38957  static inline std::string id(expression_generator<Type>& expr_gen,
38958  const details::operator_type o0,
38959  const details::operator_type o1,
38960  const details::operator_type o2)
38961  {
38962  return details::build_string()
38963  << "(t" << expr_gen.to_str(o0)
38964  << "(t" << expr_gen.to_str(o1)
38965  << "t)" << expr_gen.to_str(o2)
38966  << "t";
38967  }
38968  };
38969 
38971  {
38972  typedef typename vocovoc_t::type4 node_type;
38973  typedef typename vocovoc_t::sf4_type sf4_type;
38974  typedef typename node_type::T0 T0;
38975  typedef typename node_type::T1 T1;
38976  typedef typename node_type::T2 T2;
38977  typedef typename node_type::T3 T3;
38978 
38980  const details::operator_type& operation,
38981  expression_node_ptr (&branch)[2])
38982  {
38983  // ((v0 o0 (c0 o1 v1)) o2 c1)
38984  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
38985 
38986  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
38987  const Type& v0 = vocov->t0();
38988  const Type c0 = vocov->t1();
38989  const Type& v1 = vocov->t2();
38990  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
38991  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
38992  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
38993  const details::operator_type o2 = operation;
38994 
38995  binary_functor_t f0 = vocov->f0();
38996  binary_functor_t f1 = vocov->f1();
38997  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
38998 
38999  details::free_node(*(expr_gen.node_allocator_),branch[0]);
39000  details::free_node(*(expr_gen.node_allocator_),branch[1]);
39001 
39002  expression_node_ptr result = error_node();
39003 
39004  const bool synthesis_result =
39005  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39006  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
39007 
39008  if (synthesis_result)
39009  return result;
39010  else if (!expr_gen.valid_operator(o2,f2))
39011  return error_node();
39012 
39013  exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n"));
39014 
39015  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
39016  }
39017 
39018  static inline std::string id(expression_generator<Type>& expr_gen,
39019  const details::operator_type o0,
39020  const details::operator_type o1,
39021  const details::operator_type o2)
39022  {
39023  return details::build_string()
39024  << "(t" << expr_gen.to_str(o0)
39025  << "(t" << expr_gen.to_str(o1)
39026  << "t)" << expr_gen.to_str(o2)
39027  << "t";
39028  }
39029  };
39030 
39032  {
39033  typedef typename covovoc_t::type4 node_type;
39034  typedef typename covovoc_t::sf4_type sf4_type;
39035  typedef typename node_type::T0 T0;
39036  typedef typename node_type::T1 T1;
39037  typedef typename node_type::T2 T2;
39038  typedef typename node_type::T3 T3;
39039 
39041  const details::operator_type& operation,
39042  expression_node_ptr (&branch)[2])
39043  {
39044  // ((c0 o0 (v0 o1 v1)) o2 c1)
39045  typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
39046 
39047  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
39048  const Type c0 = covov->t0();
39049  const Type& v0 = covov->t1();
39050  const Type& v1 = covov->t2();
39051  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
39052  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
39053  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
39054  const details::operator_type o2 = operation;
39055 
39056  binary_functor_t f0 = covov->f0();
39057  binary_functor_t f1 = covov->f1();
39058  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
39059 
39060  details::free_node(*(expr_gen.node_allocator_),branch[0]);
39061  details::free_node(*(expr_gen.node_allocator_),branch[1]);
39062 
39063  expression_node_ptr result = error_node();
39064 
39065  const bool synthesis_result =
39066  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
39067  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
39068 
39069  if (synthesis_result)
39070  return result;
39071  else if (!expr_gen.valid_operator(o2,f2))
39072  return error_node();
39073 
39074  exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n"));
39075 
39076  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
39077  }
39078 
39079  static inline std::string id(expression_generator<Type>& expr_gen,
39080  const details::operator_type o0,
39081  const details::operator_type o1,
39082  const details::operator_type o2)
39083  {
39084  return details::build_string()
39085  << "(t" << expr_gen.to_str(o0)
39086  << "(t" << expr_gen.to_str(o1)
39087  << "t)" << expr_gen.to_str(o2)
39088  << "t";
39089  }
39090  };
39091 
39093  {
39094  typedef typename vococov_t::type4 node_type;
39096  const details::operator_type&,
39097  expression_node_ptr (&)[2])
39098  {
39099  // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible
39100  exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
39101  return error_node();
39102  }
39103 
39104  static inline std::string id(expression_generator<Type>&,
39105  const details::operator_type,
39106  const details::operator_type,
39107  const details::operator_type)
39108  {
39109  return "INVALID";
39110  }
39111  };
39112  #endif
39113 
39115  {
39116  // Definition: uv o uv
39117  details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
39118  details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
39119  const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
39120  const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
39121  unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0);
39122  unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0);
39123  binary_functor_t f = reinterpret_cast<binary_functor_t>(0);
39124 
39125  if (!valid_operator(o0,u0))
39126  return error_node();
39127  else if (!valid_operator(o1,u1))
39128  return error_node();
39129  else if (!valid_operator(operation,f))
39130  return error_node();
39131 
39132  expression_node_ptr result = error_node();
39133 
39134  if (
39135  (details::e_neg == o0) &&
39136  (details::e_neg == o1)
39137  )
39138  {
39139  switch (operation)
39140  {
39141  // (-v0 + -v1) --> -(v0 + v1)
39142  case details::e_add : result = (*this)(details::e_neg,
39143  node_allocator_->
39144  allocate_rr<typename details::
39145  vov_node<Type,details::add_op<Type> > >(v0, v1));
39146  exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n"));
39147  break;
39148 
39149  // (-v0 - -v1) --> (v1 - v0)
39150  case details::e_sub : result = node_allocator_->
39151  allocate_rr<typename details::
39152  vov_node<Type,details::sub_op<Type> > >(v1, v0);
39153  exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n"));
39154  break;
39155 
39156  // (-v0 * -v1) --> (v0 * v1)
39157  case details::e_mul : result = node_allocator_->
39158  allocate_rr<typename details::
39159  vov_node<Type,details::mul_op<Type> > >(v0, v1);
39160  exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n"));
39161  break;
39162 
39163  // (-v0 / -v1) --> (v0 / v1)
39164  case details::e_div : result = node_allocator_->
39165  allocate_rr<typename details::
39166  vov_node<Type,details::div_op<Type> > >(v0, v1);
39167  exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n"));
39168  break;
39169 
39170  default : break;
39171  }
39172  }
39173 
39174  if (0 == result)
39175  {
39176  result = node_allocator_->
39177  allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f);
39178  }
39179 
39180  details::free_all_nodes(*node_allocator_,branch);
39181  return result;
39182  }
39183 
39184  #undef basic_opr_switch_statements
39185  #undef extended_opr_switch_statements
39186  #undef unary_opr_switch_statements
39187 
39188  #ifndef exprtk_disable_string_capabilities
39189 
39190  #define string_opr_switch_statements \
39191  case_stmt(details::e_lt , details::lt_op ) \
39192  case_stmt(details::e_lte , details::lte_op ) \
39193  case_stmt(details::e_gt , details::gt_op ) \
39194  case_stmt(details::e_gte , details::gte_op ) \
39195  case_stmt(details::e_eq , details::eq_op ) \
39196  case_stmt(details::e_ne , details::ne_op ) \
39197  case_stmt(details::e_in , details::in_op ) \
39198  case_stmt(details::e_like , details::like_op ) \
39199  case_stmt(details::e_ilike , details::ilike_op) \
39200 
39201  template <typename T0, typename T1>
39203  T0 s0, T1 s1,
39204  range_t rp0)
39205  {
39206  switch (opr)
39207  {
39208  #define case_stmt(op0, op1) \
39209  case op0 : return node_allocator_-> \
39210  allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
39211  (s0, s1, rp0); \
39212 
39214  #undef case_stmt
39215  default : return error_node();
39216  }
39217  }
39218 
39219  template <typename T0, typename T1>
39221  T0 s0, T1 s1,
39222  range_t rp1)
39223  {
39224  switch (opr)
39225  {
39226  #define case_stmt(op0, op1) \
39227  case op0 : return node_allocator_-> \
39228  allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
39229  (s0, s1, rp1); \
39230 
39232  #undef case_stmt
39233  default : return error_node();
39234  }
39235  }
39236 
39237  template <typename T0, typename T1>
39239  T0 s0, T1 s1,
39240  range_t rp0, range_t rp1)
39241  {
39242  switch (opr)
39243  {
39244  #define case_stmt(op0, op1) \
39245  case op0 : return node_allocator_-> \
39246  allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
39247  (s0, s1, rp0, rp1); \
39248 
39250  #undef case_stmt
39251  default : return error_node();
39252  }
39253  }
39254 
39255  template <typename T0, typename T1>
39257  {
39258  switch (opr)
39259  {
39260  #define case_stmt(op0, op1) \
39261  case op0 : return node_allocator_-> \
39262  allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \
39263 
39265  #undef case_stmt
39266  default : return error_node();
39267  }
39268  }
39269 
39271  {
39272  std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
39273  std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
39274 
39275  return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1);
39276  }
39277 
39279  {
39280  std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
39281  std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
39282  range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
39283 
39284  static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
39285 
39286  details::free_node(*node_allocator_,branch[0]);
39287 
39288  return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0);
39289  }
39290 
39292  {
39293  std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
39294  std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
39295  range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
39296 
39297  static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
39298 
39299  details::free_node(*node_allocator_,branch[1]);
39300 
39301  return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1);
39302  }
39303 
39305  {
39306  std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
39307  std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39308  range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39309 
39310  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39311 
39312  details::free_node(*node_allocator_,branch[1]);
39313 
39314  return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1);
39315  }
39316 
39318  {
39319  std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
39320  std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
39321  range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
39322  range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
39323 
39324  static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
39325  static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
39326 
39327  details::free_node(*node_allocator_,branch[0]);
39328  details::free_node(*node_allocator_,branch[1]);
39329 
39330  return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1);
39331  }
39332 
39334  {
39335  std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
39336  std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39337 
39338  details::free_node(*node_allocator_,branch[1]);
39339 
39340  return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1);
39341  }
39342 
39344  {
39345  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39346  std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39347 
39348  details::free_node(*node_allocator_,branch[0]);
39349 
39350  return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1);
39351  }
39352 
39354  {
39355  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str ();
39356  std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
39357  range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
39358 
39359  static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
39360 
39361  details::free_node(*node_allocator_,branch[0]);
39362  details::free_node(*node_allocator_,branch[1]);
39363 
39364  return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1);
39365  }
39366 
39368  {
39369  std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
39370  std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str ();
39371  range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
39372 
39373  static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
39374 
39375  details::free_node(*node_allocator_,branch[0]);
39376  details::free_node(*node_allocator_,branch[1]);
39377 
39378  return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0);
39379  }
39380 
39382  {
39383  std::string& s0 = static_cast<details::string_range_node<Type>* >(branch[0])->ref ();
39384  std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39385  range_t rp0 = static_cast<details::string_range_node<Type>* >(branch[0])->range();
39386  range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39387 
39388  static_cast<details::string_range_node<Type>*> (branch[0])->range_ref().clear();
39389  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39390 
39391  details::free_node(*node_allocator_,branch[0]);
39392  details::free_node(*node_allocator_,branch[1]);
39393 
39394  return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1);
39395  }
39396 
39398  {
39399  const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39400  const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39401 
39402  expression_node_ptr result = error_node();
39403 
39404  if (details::e_add == opr)
39405  result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1);
39406  else if (details::e_in == opr)
39407  result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op <Type>::process(s0,s1));
39408  else if (details::e_like == opr)
39409  result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op <Type>::process(s0,s1));
39410  else if (details::e_ilike == opr)
39411  result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1));
39412  else
39413  {
39414  expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1);
39415 
39416  const Type v = temp->value();
39417 
39418  details::free_node(*node_allocator_,temp);
39419 
39420  result = node_allocator_->allocate<literal_node_t>(v);
39421  }
39422 
39423  details::free_all_nodes(*node_allocator_,branch);
39424 
39425  return result;
39426  }
39427 
39429  {
39430  const std::string s0 = static_cast<details::string_literal_node<Type>* >(branch[0])->str ();
39431  std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39432  range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39433 
39434  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39435 
39436  details::free_node(*node_allocator_,branch[0]);
39437  details::free_node(*node_allocator_,branch[1]);
39438 
39439  return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1);
39440  }
39441 
39443  {
39444  std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39445  std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref ();
39446  range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39447 
39448  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39449 
39450  details::free_node(*node_allocator_,branch[0]);
39451 
39452  return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0);
39453  }
39454 
39456  {
39457  const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39458  std::string& s1 = static_cast<details::string_range_node<Type>* >(branch[1])->ref ();
39459  const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39460  const range_t rp1 = static_cast<details::string_range_node<Type>* >(branch[1])->range();
39461 
39462  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39463  static_cast<details::string_range_node<Type>*> (branch[1])->range_ref().clear();
39464 
39465  details::free_node(*node_allocator_,branch[0]);
39466  details::free_node(*node_allocator_,branch[1]);
39467 
39468  return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1);
39469  }
39470 
39472  {
39473  const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39474  const std::string s1 = static_cast<details::string_literal_node<Type>* >(branch[1])->str ();
39475  const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39476 
39477  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39478 
39479  details::free_all_nodes(*node_allocator_,branch);
39480 
39481  return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0);
39482  }
39483 
39485  {
39486  const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
39487  const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
39488  const range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
39489  const range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
39490 
39491  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
39492  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
39493 
39494  details::free_all_nodes(*node_allocator_,branch);
39495 
39496  return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1);
39497  }
39498 
39500  {
39501  switch (opr)
39502  {
39503  #define case_stmt(op0, op1) \
39504  case op0 : return node_allocator_-> \
39505  allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
39506  (opr, branch[0], branch[1]); \
39507 
39509  #undef case_stmt
39510  default : return error_node();
39511  }
39512  }
39513 
39514  #undef string_opr_switch_statements
39515  #endif
39516 
39517  #ifndef exprtk_disable_string_capabilities
39519  {
39520  if ((0 == branch[0]) || (0 == branch[1]))
39521  {
39522  details::free_all_nodes(*node_allocator_,branch);
39523 
39524  return error_node();
39525  }
39526 
39527  const bool b0_is_s = details::is_string_node (branch[0]);
39528  const bool b0_is_cs = details::is_const_string_node (branch[0]);
39529  const bool b0_is_sr = details::is_string_range_node (branch[0]);
39530  const bool b0_is_csr = details::is_const_string_range_node(branch[0]);
39531 
39532  const bool b1_is_s = details::is_string_node (branch[1]);
39533  const bool b1_is_cs = details::is_const_string_node (branch[1]);
39534  const bool b1_is_sr = details::is_string_range_node (branch[1]);
39535  const bool b1_is_csr = details::is_const_string_range_node(branch[1]);
39536 
39537  const bool b0_is_gen = details::is_string_assignment_node (branch[0]) ||
39539  details::is_string_concat_node (branch[0]) ||
39540  details::is_string_function_node (branch[0]) ||
39541  details::is_string_condition_node (branch[0]) ||
39542  details::is_string_ccondition_node (branch[0]) ||
39543  details::is_string_vararg_node (branch[0]) ;
39544 
39545  const bool b1_is_gen = details::is_string_assignment_node (branch[1]) ||
39547  details::is_string_concat_node (branch[1]) ||
39548  details::is_string_function_node (branch[1]) ||
39549  details::is_string_condition_node (branch[1]) ||
39550  details::is_string_ccondition_node (branch[1]) ||
39551  details::is_string_vararg_node (branch[1]) ;
39552 
39553  if (details::e_add == opr)
39554  {
39555  if (!b0_is_cs || !b1_is_cs)
39556  {
39557  return synthesize_expression<string_concat_node_t,2>(opr,branch);
39558  }
39559  }
39560 
39561  if (b0_is_gen || b1_is_gen)
39562  {
39563  return synthesize_strogen_expression(opr,branch);
39564  }
39565  else if (b0_is_s)
39566  {
39567  if (b1_is_s ) return synthesize_sos_expression (opr,branch);
39568  else if (b1_is_cs ) return synthesize_socs_expression (opr,branch);
39569  else if (b1_is_sr ) return synthesize_sosr_expression (opr,branch);
39570  else if (b1_is_csr) return synthesize_socsr_expression (opr,branch);
39571  }
39572  else if (b0_is_cs)
39573  {
39574  if (b1_is_s ) return synthesize_csos_expression (opr,branch);
39575  else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch);
39576  else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch);
39577  else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch);
39578  }
39579  else if (b0_is_sr)
39580  {
39581  if (b1_is_s ) return synthesize_sros_expression (opr,branch);
39582  else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch);
39583  else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch);
39584  else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch);
39585  }
39586  else if (b0_is_csr)
39587  {
39588  if (b1_is_s ) return synthesize_csros_expression (opr,branch);
39589  else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch);
39590  else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch);
39591  else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch);
39592  }
39593 
39594  return error_node();
39595  }
39596  #else
39597  inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2])
39598  {
39599  details::free_all_nodes(*node_allocator_,branch);
39600  return error_node();
39601  }
39602  #endif
39603 
39604  #ifndef exprtk_disable_string_capabilities
39606  {
39607  if (details::e_inrange != opr)
39608  return error_node();
39609  else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
39610  {
39611  details::free_all_nodes(*node_allocator_,branch);
39612 
39613  return error_node();
39614  }
39615  else if (
39616  details::is_const_string_node(branch[0]) &&
39617  details::is_const_string_node(branch[1]) &&
39619  )
39620  {
39621  const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39622  const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39623  const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
39624 
39625  const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
39626 
39627  details::free_all_nodes(*node_allocator_,branch);
39628 
39629  return node_allocator_->allocate_c<details::literal_node<Type> >(v);
39630  }
39631  else if (
39632  details::is_string_node(branch[0]) &&
39633  details::is_string_node(branch[1]) &&
39634  details::is_string_node(branch[2])
39635  )
39636  {
39637  std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
39638  std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
39639  std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
39640 
39641  typedef typename details::sosos_node<Type, std::string&, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
39642 
39643  return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2);
39644  }
39645  else if (
39646  details::is_const_string_node(branch[0]) &&
39647  details::is_string_node(branch[1]) &&
39649  )
39650  {
39651  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39652  std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39653  std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
39654 
39655  typedef typename details::sosos_node<Type, std::string, std::string&, std::string, details::inrange_op<Type> > inrange_t;
39656 
39657  details::free_node(*node_allocator_,branch[0]);
39658  details::free_node(*node_allocator_,branch[2]);
39659 
39660  return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2);
39661  }
39662  else if (
39663  details::is_string_node(branch[0]) &&
39664  details::is_const_string_node(branch[1]) &&
39665  details::is_string_node(branch[2])
39666  )
39667  {
39668  std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
39669  std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
39670  std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
39671 
39672  typedef typename details::sosos_node<Type, std::string&, std::string, std::string&, details::inrange_op<Type> > inrange_t;
39673 
39674  details::free_node(*node_allocator_,branch[1]);
39675 
39676  return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2);
39677  }
39678  else if (
39679  details::is_string_node(branch[0]) &&
39680  details::is_string_node(branch[1]) &&
39682  )
39683  {
39684  std::string& s0 = static_cast<details::stringvar_node<Type>* >(branch[0])->ref();
39685  std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39686  std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
39687 
39688  typedef typename details::sosos_node<Type, std::string&, std::string&, std::string, details::inrange_op<Type> > inrange_t;
39689 
39690  details::free_node(*node_allocator_,branch[2]);
39691 
39692  return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2);
39693  }
39694  else if (
39695  details::is_const_string_node(branch[0]) &&
39696  details:: is_string_node(branch[1]) &&
39697  details:: is_string_node(branch[2])
39698  )
39699  {
39700  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
39701  std::string& s1 = static_cast<details::stringvar_node<Type>* >(branch[1])->ref();
39702  std::string& s2 = static_cast<details::stringvar_node<Type>* >(branch[2])->ref();
39703 
39704  typedef typename details::sosos_node<Type, std::string, std::string&, std::string&, details::inrange_op<Type> > inrange_t;
39705 
39706  details::free_node(*node_allocator_,branch[0]);
39707 
39708  return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2);
39709  }
39710  else
39711  return error_node();
39712  }
39713  #else
39714  inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3])
39715  {
39716  details::free_all_nodes(*node_allocator_,branch);
39717  return error_node();
39718  }
39719  #endif
39720 
39722  {
39723  /*
39724  Note: The following are the type promotion rules
39725  that relate to operations that include 'null':
39726  0. null ==/!= null --> true false
39727  1. null operation null --> null
39728  2. x ==/!= null --> true/false
39729  3. null ==/!= x --> true/false
39730  4. x operation null --> x
39731  5. null operation x --> x
39732  */
39733 
39734  typedef typename details::null_eq_node<T> nulleq_node_t;
39735 
39736  const bool b0_null = details::is_null_node(branch[0]);
39737  const bool b1_null = details::is_null_node(branch[1]);
39738 
39739  if (b0_null && b1_null)
39740  {
39741  expression_node_ptr result = error_node();
39742 
39743  if (details::e_eq == operation)
39744  result = node_allocator_->allocate_c<literal_node_t>(T(1));
39745  else if (details::e_ne == operation)
39746  result = node_allocator_->allocate_c<literal_node_t>(T(0));
39747 
39748  if (result)
39749  {
39750  details::free_node(*node_allocator_,branch[0]);
39751  details::free_node(*node_allocator_,branch[1]);
39752 
39753  return result;
39754  }
39755 
39756  details::free_node(*node_allocator_,branch[1]);
39757 
39758  return branch[0];
39759  }
39760  else if (details::e_eq == operation)
39761  {
39762  expression_node_ptr result = node_allocator_->
39763  allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true);
39764 
39765  details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
39766 
39767  return result;
39768  }
39769  else if (details::e_ne == operation)
39770  {
39771  expression_node_ptr result = node_allocator_->
39772  allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false);
39773 
39774  details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
39775 
39776  return result;
39777  }
39778  else if (b0_null)
39779  {
39780  details::free_node(*node_allocator_,branch[0]);
39781  branch[0] = branch[1];
39782  branch[1] = error_node();
39783  }
39784  else if (b1_null)
39785  {
39786  details::free_node(*node_allocator_,branch[1]);
39787  branch[1] = error_node();
39788  }
39789 
39790  if (
39791  (details::e_add == operation) || (details::e_sub == operation) ||
39792  (details::e_mul == operation) || (details::e_div == operation) ||
39793  (details::e_mod == operation) || (details::e_pow == operation)
39794  )
39795  {
39796  return branch[0];
39797  }
39798 
39799  details::free_node(*node_allocator_, branch[0]);
39800 
39801  if (
39802  (details::e_lt == operation) || (details::e_lte == operation) ||
39803  (details::e_gt == operation) || (details::e_gte == operation) ||
39804  (details::e_and == operation) || (details::e_nand == operation) ||
39805  (details::e_or == operation) || (details::e_nor == operation) ||
39806  (details::e_xor == operation) || (details::e_xnor == operation) ||
39807  (details::e_in == operation) || (details::e_like == operation) ||
39808  (details::e_ilike == operation)
39809  )
39810  {
39811  return node_allocator_->allocate_c<literal_node_t>(T(0));
39812  }
39813 
39814  return node_allocator_->allocate<details::null_node<Type> >();
39815  }
39816 
39817  template <typename NodeType, std::size_t N>
39819  {
39820  if (
39821  (details::e_in == operation) ||
39822  (details::e_like == operation) ||
39823  (details::e_ilike == operation)
39824  )
39825  {
39826  free_all_nodes(*node_allocator_,branch);
39827 
39828  return error_node();
39829  }
39830  else if (!details::all_nodes_valid<N>(branch))
39831  {
39832  free_all_nodes(*node_allocator_,branch);
39833 
39834  return error_node();
39835  }
39836  else if ((details::e_default != operation))
39837  {
39838  // Attempt simple constant folding optimisation.
39839  expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
39840 
39841  if (is_constant_foldable<N>(branch))
39842  {
39843  const Type v = expression_point->value();
39844  details::free_node(*node_allocator_,expression_point);
39845 
39846  return node_allocator_->allocate<literal_node_t>(v);
39847  }
39848 
39849  if (expression_point && expression_point->valid())
39850  {
39851  return expression_point;
39852  }
39853 
39854  parser_->set_error(parser_error::make_error(
39856  token_t(),
39857  "ERR249 - Failed to synthesize node: NodeType",
39859 
39860  details::free_node(*node_allocator_, expression_point);
39861  }
39862 
39863  return error_node();
39864  }
39865 
39866  template <typename NodeType, std::size_t N>
39868  {
39869  if (!details::all_nodes_valid<N>(branch))
39870  {
39871  free_all_nodes(*node_allocator_,branch);
39872 
39873  return error_node();
39874  }
39875 
39876  typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
39877 
39878  // Attempt simple constant folding optimisation.
39879 
39880  expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
39881  function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point);
39882 
39883  if (0 == func_node_ptr)
39884  {
39885  free_all_nodes(*node_allocator_,branch);
39886 
39887  return error_node();
39888  }
39889  else
39890  func_node_ptr->init_branches(branch);
39891 
39892  if (is_constant_foldable<N>(branch) && !f->has_side_effects())
39893  {
39894  Type v = expression_point->value();
39895  details::free_node(*node_allocator_,expression_point);
39896 
39897  return node_allocator_->allocate<literal_node_t>(v);
39898  }
39899 
39900  parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)");
39901 
39902  return expression_point;
39903  }
39904 
39914  }; // class expression_generator
39915 
39916  inline void set_error(const parser_error::type& error_type)
39917  {
39918  error_list_.push_back(error_type);
39919  }
39920 
39921  inline void remove_last_error()
39922  {
39923  if (!error_list_.empty())
39924  {
39925  error_list_.pop_back();
39926  }
39927  }
39928 
39929  inline void set_synthesis_error(const std::string& synthesis_error_message)
39930  {
39931  if (synthesis_error_.empty())
39932  {
39933  synthesis_error_ = synthesis_error_message;
39934  }
39935  }
39936 
39938  {
39939  for (std::size_t i = 0; i < sem_.size(); ++i)
39940  {
39941  scope_element& se = sem_.get_element(i);
39942 
39943  if (
39944  (scope_element::e_variable == se.type) ||
39945  (scope_element::e_vecelem == se.type)
39946  )
39947  {
39948  if (se.var_node)
39949  {
39950  e.register_local_var(se.var_node);
39951  }
39952 
39953  if (se.data)
39954  {
39955  e.register_local_data(se.data, 1, 0);
39956  }
39957  }
39958  else if (scope_element::e_vector == se.type)
39959  {
39960  if (se.vec_node)
39961  {
39962  e.register_local_var(se.vec_node);
39963  }
39964 
39965  if (se.data)
39966  {
39967  e.register_local_data(se.data, se.size, 1);
39968  }
39969  }
39970  #ifndef exprtk_disable_string_capabilities
39971  else if (scope_element::e_string == se.type)
39972  {
39973  if (se.str_node)
39974  {
39975  e.register_local_var(se.str_node);
39976  }
39977 
39978  if (se.data)
39979  {
39980  e.register_local_data(se.data, se.size, 2);
39981  }
39982  }
39983  #endif
39984 
39985  se.var_node = 0;
39986  se.vec_node = 0;
39987  #ifndef exprtk_disable_string_capabilities
39988  se.str_node = 0;
39989  #endif
39990  se.data = 0;
39991  se.ref_count = 0;
39992  se.active = false;
39993  }
39994  }
39995 
39997  {
39998  e.register_return_results(results_context_);
39999  results_context_ = 0;
40000  }
40001 
40003  {
40004  #define register_unary_op(Op, UnaryFunctor) \
40005  m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
40006 
40007  register_unary_op(details::e_abs , details::abs_op )
40008  register_unary_op(details::e_acos , details::acos_op )
40009  register_unary_op(details::e_acosh , details::acosh_op)
40010  register_unary_op(details::e_asin , details::asin_op )
40011  register_unary_op(details::e_asinh , details::asinh_op)
40012  register_unary_op(details::e_atanh , details::atanh_op)
40013  register_unary_op(details::e_ceil , details::ceil_op )
40014  register_unary_op(details::e_cos , details::cos_op )
40015  register_unary_op(details::e_cosh , details::cosh_op )
40016  register_unary_op(details::e_exp , details::exp_op )
40017  register_unary_op(details::e_expm1 , details::expm1_op)
40018  register_unary_op(details::e_floor , details::floor_op)
40019  register_unary_op(details::e_log , details::log_op )
40020  register_unary_op(details::e_log10 , details::log10_op)
40021  register_unary_op(details::e_log2 , details::log2_op )
40022  register_unary_op(details::e_log1p , details::log1p_op)
40023  register_unary_op(details::e_neg , details::neg_op )
40024  register_unary_op(details::e_pos , details::pos_op )
40025  register_unary_op(details::e_round , details::round_op)
40026  register_unary_op(details::e_sin , details::sin_op )
40027  register_unary_op(details::e_sinc , details::sinc_op )
40028  register_unary_op(details::e_sinh , details::sinh_op )
40029  register_unary_op(details::e_sqrt , details::sqrt_op )
40030  register_unary_op(details::e_tan , details::tan_op )
40031  register_unary_op(details::e_tanh , details::tanh_op )
40032  register_unary_op(details::e_cot , details::cot_op )
40033  register_unary_op(details::e_sec , details::sec_op )
40034  register_unary_op(details::e_csc , details::csc_op )
40035  register_unary_op(details::e_r2d , details::r2d_op )
40036  register_unary_op(details::e_d2r , details::d2r_op )
40037  register_unary_op(details::e_d2g , details::d2g_op )
40038  register_unary_op(details::e_g2d , details::g2d_op )
40039  register_unary_op(details::e_notl , details::notl_op )
40040  register_unary_op(details::e_sgn , details::sgn_op )
40041  register_unary_op(details::e_erf , details::erf_op )
40042  register_unary_op(details::e_erfc , details::erfc_op )
40043  register_unary_op(details::e_ncdf , details::ncdf_op )
40044  register_unary_op(details::e_frac , details::frac_op )
40045  register_unary_op(details::e_trunc , details::trunc_op)
40046  #undef register_unary_op
40047  }
40048 
40050  {
40051  typedef typename binary_op_map_t::value_type value_type;
40052 
40053  #define register_binary_op(Op, BinaryFunctor) \
40054  m.insert(value_type(Op,BinaryFunctor<T>::process)); \
40055 
40074  #undef register_binary_op
40075  }
40076 
40078  {
40079  typedef typename inv_binary_op_map_t::value_type value_type;
40080 
40081  #define register_binary_op(Op, BinaryFunctor) \
40082  m.insert(value_type(BinaryFunctor<T>::process,Op)); \
40083 
40102  #undef register_binary_op
40103  }
40104 
40105  inline void load_sf3_map(sf3_map_t& sf3_map)
40106  {
40107  typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
40108 
40109  #define register_sf3(Op) \
40110  sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
40111 
40120  #undef register_sf3
40121 
40122  #define register_sf3_extid(Id, Op) \
40123  sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
40124 
40125  register_sf3_extid("(t-t)-t",23) // (t-t)-t --> t-(t+t)
40126  #undef register_sf3_extid
40127  }
40128 
40129  inline void load_sf4_map(sf4_map_t& sf4_map)
40130  {
40131  typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
40132 
40133  #define register_sf4(Op) \
40134  sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
40135 
40145  #undef register_sf4
40146 
40147  #define register_sf4ext(Op) \
40148  sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
40149 
40166  #undef register_sf4ext
40167  }
40168 
40170  {
40171  if (0 == results_context_)
40172  {
40173  results_context_ = new results_context_t();
40174  }
40175 
40176  return (*results_context_);
40177  }
40178 
40179  inline void return_cleanup()
40180  {
40181  #ifndef exprtk_disable_return_statement
40182  if (results_context_)
40183  {
40184  delete results_context_;
40185  results_context_ = 0;
40186  }
40187 
40188  state_.return_stmt_present = false;
40189  #endif
40190  }
40191 
40192  private:
40193 
40196 
40202  std::deque<parser_error::type> error_list_;
40203  std::deque<bool> brkcnt_list_;
40215  std::string synthesis_error_;
40217  std::vector<state_t> current_state_stack_;
40218 
40221 
40223 
40225  lexer::helper::operator_joiner operator_joiner_2_;
40226  lexer::helper::operator_joiner operator_joiner_3_;
40227  lexer::helper::symbol_replacer symbol_replacer_;
40228  lexer::helper::bracket_checker bracket_checker_;
40229  lexer::helper::numeric_checker<T> numeric_checker_;
40230  lexer::helper::sequence_validator sequence_validator_;
40231  lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_;
40232 
40236 
40237  template <typename ParserType>
40238  friend void details::disable_type_checking(ParserType& p);
40239  }; // class parser
40240 
40241  namespace details
40242  {
40243  template <typename T>
40245  {
40249  typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
40251 
40253  {
40255 
40257  : usr_t(usr_t::e_usrmode_extended)
40258  {}
40259 
40260  virtual bool process(const std::string& unknown_symbol,
40262  std::string&) exprtk_override
40263  {
40264  static T v[1];
40265  symbol_table.add_vector(unknown_symbol,v);
40266  return true;
40267  }
40268  };
40269 
40270  static inline bool collection_pass(const std::string& expression_string,
40271  std::set<std::string>& symbol_set,
40272  const bool collect_variables,
40273  const bool collect_functions,
40274  const bool vector_pass,
40275  symbol_table_t& ext_symbol_table)
40276  {
40279  parser_t parser;
40280 
40281  resolve_as_vector vect_resolver;
40282 
40284  expression.register_symbol_table(ext_symbol_table);
40285 
40286  if (vector_pass)
40287  parser.enable_unknown_symbol_resolver(&vect_resolver);
40288  else
40290 
40291  if (collect_variables)
40292  parser.dec().collect_variables() = true;
40293 
40294  if (collect_functions)
40295  parser.dec().collect_functions() = true;
40296 
40297  bool pass_result = false;
40298 
40300 
40301  if (parser.compile(expression_string, expression))
40302  {
40303  pass_result = true;
40304 
40305  std::deque<symbol_t> symb_list;
40306  parser.dec().symbols(symb_list);
40307 
40308  for (std::size_t i = 0; i < symb_list.size(); ++i)
40309  {
40310  symbol_set.insert(symb_list[i].first);
40311  }
40312  }
40313 
40314  return pass_result;
40315  }
40316  };
40317  }
40318 
40319  template <typename Allocator,
40320  template <typename, typename> class Sequence>
40321  inline bool collect_variables(const std::string& expression,
40322  Sequence<std::string, Allocator>& symbol_list)
40323  {
40324  typedef double T;
40325  typedef details::collector_helper<T> collect_t;
40326 
40327  collect_t::symbol_table_t null_symbol_table;
40328 
40329  std::set<std::string> symbol_set;
40330 
40331  const bool variable_pass = collect_t::collection_pass
40332  (expression, symbol_set, true, false, false, null_symbol_table);
40333  const bool vector_pass = collect_t::collection_pass
40334  (expression, symbol_set, true, false, true, null_symbol_table);
40335 
40336  if (!variable_pass && !vector_pass)
40337  return false;
40338 
40339  std::set<std::string>::iterator itr = symbol_set.begin();
40340 
40341  while (symbol_set.end() != itr)
40342  {
40343  symbol_list.push_back(*itr);
40344  ++itr;
40345  }
40346 
40347  return true;
40348  }
40349 
40350  template <typename T,
40351  typename Allocator,
40352  template <typename, typename> class Sequence>
40353  inline bool collect_variables(const std::string& expression,
40354  exprtk::symbol_table<T>& extrnl_symbol_table,
40355  Sequence<std::string, Allocator>& symbol_list)
40356  {
40357  typedef details::collector_helper<T> collect_t;
40358 
40359  std::set<std::string> symbol_set;
40360 
40361  const bool variable_pass = collect_t::collection_pass
40362  (expression, symbol_set, true, false, false, extrnl_symbol_table);
40363  const bool vector_pass = collect_t::collection_pass
40364  (expression, symbol_set, true, false, true, extrnl_symbol_table);
40365 
40366  if (!variable_pass && !vector_pass)
40367  return false;
40368 
40369  std::set<std::string>::iterator itr = symbol_set.begin();
40370 
40371  while (symbol_set.end() != itr)
40372  {
40373  symbol_list.push_back(*itr);
40374  ++itr;
40375  }
40376 
40377  return true;
40378  }
40379 
40380  template <typename Allocator,
40381  template <typename, typename> class Sequence>
40382  inline bool collect_functions(const std::string& expression,
40383  Sequence<std::string, Allocator>& symbol_list)
40384  {
40385  typedef double T;
40386  typedef details::collector_helper<T> collect_t;
40387 
40388  collect_t::symbol_table_t null_symbol_table;
40389 
40390  std::set<std::string> symbol_set;
40391 
40392  const bool variable_pass = collect_t::collection_pass
40393  (expression, symbol_set, false, true, false, null_symbol_table);
40394  const bool vector_pass = collect_t::collection_pass
40395  (expression, symbol_set, false, true, true, null_symbol_table);
40396 
40397  if (!variable_pass && !vector_pass)
40398  return false;
40399 
40400  std::set<std::string>::iterator itr = symbol_set.begin();
40401 
40402  while (symbol_set.end() != itr)
40403  {
40404  symbol_list.push_back(*itr);
40405  ++itr;
40406  }
40407 
40408  return true;
40409  }
40410 
40411  template <typename T,
40412  typename Allocator,
40413  template <typename, typename> class Sequence>
40414  inline bool collect_functions(const std::string& expression,
40415  exprtk::symbol_table<T>& extrnl_symbol_table,
40416  Sequence<std::string, Allocator>& symbol_list)
40417  {
40418  typedef details::collector_helper<T> collect_t;
40419 
40420  std::set<std::string> symbol_set;
40421 
40422  const bool variable_pass = collect_t::collection_pass
40423  (expression, symbol_set, false, true, false, extrnl_symbol_table);
40424  const bool vector_pass = collect_t::collection_pass
40425  (expression, symbol_set, false, true, true, extrnl_symbol_table);
40426 
40427  if (!variable_pass && !vector_pass)
40428  return false;
40429 
40430  std::set<std::string>::iterator itr = symbol_set.begin();
40431 
40432  while (symbol_set.end() != itr)
40433  {
40434  symbol_list.push_back(*itr);
40435  ++itr;
40436  }
40437 
40438  return true;
40439  }
40440 
40441  template <typename T>
40442  inline T integrate(const expression<T>& e,
40443  T& x,
40444  const T& r0, const T& r1,
40445  const std::size_t number_of_intervals = 1000000)
40446  {
40447  if (r0 > r1)
40448  return T(0);
40449 
40450  const T h = (r1 - r0) / (T(2) * number_of_intervals);
40451  T total_area = T(0);
40452 
40453  for (std::size_t i = 0; i < number_of_intervals; ++i)
40454  {
40455  x = r0 + T(2) * i * h;
40456  const T y0 = e.value(); x += h;
40457  const T y1 = e.value(); x += h;
40458  const T y2 = e.value(); x += h;
40459  total_area += h * (y0 + T(4) * y1 + y2) / T(3);
40460  }
40461 
40462  return total_area;
40463  }
40464 
40465  template <typename T>
40466  inline T integrate(const expression<T>& e,
40467  const std::string& variable_name,
40468  const T& r0, const T& r1,
40469  const std::size_t number_of_intervals = 1000000)
40470  {
40471  const symbol_table<T>& sym_table = e.get_symbol_table();
40472 
40473  if (!sym_table.valid())
40474  {
40475  return std::numeric_limits<T>::quiet_NaN();
40476  }
40477 
40478  details::variable_node<T>* var = sym_table.get_variable(variable_name);
40479 
40480  if (var)
40481  {
40482  T& x = var->ref();
40483  const T x_original = x;
40484  const T result = integrate(e, x, r0, r1, number_of_intervals);
40485  x = x_original;
40486 
40487  return result;
40488  }
40489 
40490  return std::numeric_limits<T>::quiet_NaN();
40491  }
40492 
40493  template <typename T>
40494  inline T derivative(const expression<T>& e,
40495  T& x,
40496  const T& h = T(0.00000001))
40497  {
40498  const T x_init = x;
40499  const T _2h = T(2) * h;
40500 
40501  x = x_init + _2h;
40502  const T y0 = e.value();
40503  x = x_init + h;
40504  const T y1 = e.value();
40505  x = x_init - h;
40506  const T y2 = e.value();
40507  x = x_init - _2h;
40508  const T y3 = e.value();
40509  x = x_init;
40510 
40511  return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h);
40512  }
40513 
40514  template <typename T>
40516  T& x,
40517  const T& h = T(0.00001))
40518  {
40519  const T x_init = x;
40520  const T _2h = T(2) * h;
40521 
40522  const T y = e.value();
40523  x = x_init + _2h;
40524  const T y0 = e.value();
40525  x = x_init + h;
40526  const T y1 = e.value();
40527  x = x_init - h;
40528  const T y2 = e.value();
40529  x = x_init - _2h;
40530  const T y3 = e.value();
40531  x = x_init;
40532 
40533  return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h);
40534  }
40535 
40536  template <typename T>
40538  T& x,
40539  const T& h = T(0.0001))
40540  {
40541  const T x_init = x;
40542  const T _2h = T(2) * h;
40543 
40544  x = x_init + _2h;
40545  const T y0 = e.value();
40546  x = x_init + h;
40547  const T y1 = e.value();
40548  x = x_init - h;
40549  const T y2 = e.value();
40550  x = x_init - _2h;
40551  const T y3 = e.value();
40552  x = x_init;
40553 
40554  return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h);
40555  }
40556 
40557  template <typename T>
40558  inline T derivative(const expression<T>& e,
40559  const std::string& variable_name,
40560  const T& h = T(0.00000001))
40561  {
40562  const symbol_table<T>& sym_table = e.get_symbol_table();
40563 
40564  if (!sym_table.valid())
40565  {
40566  return std::numeric_limits<T>::quiet_NaN();
40567  }
40568 
40569  details::variable_node<T>* var = sym_table.get_variable(variable_name);
40570 
40571  if (var)
40572  {
40573  T& x = var->ref();
40574  const T x_original = x;
40575  const T result = derivative(e, x, h);
40576  x = x_original;
40577 
40578  return result;
40579  }
40580 
40581  return std::numeric_limits<T>::quiet_NaN();
40582  }
40583 
40584  template <typename T>
40586  const std::string& variable_name,
40587  const T& h = T(0.00001))
40588  {
40589  const symbol_table<T>& sym_table = e.get_symbol_table();
40590 
40591  if (!sym_table.valid())
40592  {
40593  return std::numeric_limits<T>::quiet_NaN();
40594  }
40595 
40596  details::variable_node<T>* var = sym_table.get_variable(variable_name);
40597 
40598  if (var)
40599  {
40600  T& x = var->ref();
40601  const T x_original = x;
40602  const T result = second_derivative(e, x, h);
40603  x = x_original;
40604 
40605  return result;
40606  }
40607 
40608  return std::numeric_limits<T>::quiet_NaN();
40609  }
40610 
40611  template <typename T>
40613  const std::string& variable_name,
40614  const T& h = T(0.0001))
40615  {
40616  const symbol_table<T>& sym_table = e.get_symbol_table();
40617 
40618  if (!sym_table.valid())
40619  {
40620  return std::numeric_limits<T>::quiet_NaN();
40621  }
40622 
40623  details::variable_node<T>* var = sym_table.get_variable(variable_name);
40624 
40625  if (var)
40626  {
40627  T& x = var->ref();
40628  const T x_original = x;
40629  const T result = third_derivative(e, x, h);
40630  x = x_original;
40631 
40632  return result;
40633  }
40634 
40635  return std::numeric_limits<T>::quiet_NaN();
40636  }
40637 
40638  /*
40639  Note: The following 'compute' routines are simple helpers,
40640  for quickly setting up the required pieces of code in order
40641  to evaluate an expression. By virtue of how they operate
40642  there will be an overhead with regards to their setup and
40643  teardown and hence should not be used in time critical
40644  sections of code.
40645  Furthermore they only assume a small sub set of variables,
40646  no string variables or user defined functions.
40647  */
40648  template <typename T>
40649  inline bool compute(const std::string& expression_string, T& result)
40650  {
40651  // No variables
40654 
40657 
40658  parser<T> parser;
40659 
40660  if (parser.compile(expression_string,expression))
40661  {
40662  result = expression.value();
40663 
40664  return true;
40665  }
40666  else
40667  return false;
40668  }
40669 
40670  template <typename T>
40671  inline bool compute(const std::string& expression_string,
40672  const T& x,
40673  T& result)
40674  {
40675  // Only 'x'
40676  static const std::string x_var("x");
40677 
40680  symbol_table.add_constant(x_var,x);
40681 
40684 
40685  parser<T> parser;
40686 
40687  if (parser.compile(expression_string,expression))
40688  {
40689  result = expression.value();
40690 
40691  return true;
40692  }
40693  else
40694  return false;
40695  }
40696 
40697  template <typename T>
40698  inline bool compute(const std::string& expression_string,
40699  const T&x, const T& y,
40700  T& result)
40701  {
40702  // Only 'x' and 'y'
40703  static const std::string x_var("x");
40704  static const std::string y_var("y");
40705 
40708  symbol_table.add_constant(x_var,x);
40709  symbol_table.add_constant(y_var,y);
40710 
40713 
40714  parser<T> parser;
40715 
40716  if (parser.compile(expression_string,expression))
40717  {
40718  result = expression.value();
40719 
40720  return true;
40721  }
40722  else
40723  return false;
40724  }
40725 
40726  template <typename T>
40727  inline bool compute(const std::string& expression_string,
40728  const T& x, const T& y, const T& z,
40729  T& result)
40730  {
40731  // Only 'x', 'y' or 'z'
40732  static const std::string x_var("x");
40733  static const std::string y_var("y");
40734  static const std::string z_var("z");
40735 
40738  symbol_table.add_constant(x_var,x);
40739  symbol_table.add_constant(y_var,y);
40740  symbol_table.add_constant(z_var,z);
40741 
40744 
40745  parser<T> parser;
40746 
40747  if (parser.compile(expression_string,expression))
40748  {
40749  result = expression.value();
40750 
40751  return true;
40752  }
40753  else
40754  return false;
40755  }
40756 
40757  template <typename T, std::size_t N>
40758  class polynomial : public ifunction<T>
40759  {
40760  private:
40761 
40762  template <typename Type, std::size_t NumberOfCoefficients>
40763  struct poly_impl { };
40764 
40765  template <typename Type>
40766  struct poly_impl <Type,12>
40767  {
40768  static inline T evaluate(const Type x,
40769  const Type c12, const Type c11, const Type c10, const Type c9, const Type c8,
40770  const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
40771  const Type c2, const Type c1, const Type c0)
40772  {
40773  // 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
40774  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);
40775  }
40776  };
40777 
40778  template <typename Type>
40779  struct poly_impl <Type,11>
40780  {
40781  static inline T evaluate(const Type x,
40782  const Type c11, const Type c10, const Type c9, const Type c8, const Type c7,
40783  const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
40784  const Type c1, const Type c0)
40785  {
40786  // 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
40787  return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40788  }
40789  };
40790 
40791  template <typename Type>
40792  struct poly_impl <Type,10>
40793  {
40794  static inline T evaluate(const Type x,
40795  const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
40796  const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
40797  const Type c0)
40798  {
40799  // 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
40800  return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40801  }
40802  };
40803 
40804  template <typename Type>
40805  struct poly_impl <Type,9>
40806  {
40807  static inline T evaluate(const Type x,
40808  const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
40809  const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
40810  {
40811  // 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
40812  return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40813  }
40814  };
40815 
40816  template <typename Type>
40817  struct poly_impl <Type,8>
40818  {
40819  static inline T evaluate(const Type x,
40820  const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
40821  const Type c3, const Type c2, const Type c1, const Type c0)
40822  {
40823  // 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
40824  return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40825  }
40826  };
40827 
40828  template <typename Type>
40829  struct poly_impl <Type,7>
40830  {
40831  static inline T evaluate(const Type x,
40832  const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
40833  const Type c2, const Type c1, const Type c0)
40834  {
40835  // 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
40836  return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40837  }
40838  };
40839 
40840  template <typename Type>
40841  struct poly_impl <Type,6>
40842  {
40843  static inline T evaluate(const Type x,
40844  const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
40845  const Type c1, const Type c0)
40846  {
40847  // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
40848  return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40849  }
40850  };
40851 
40852  template <typename Type>
40853  struct poly_impl <Type,5>
40854  {
40855  static inline T evaluate(const Type x,
40856  const Type c5, const Type c4, const Type c3, const Type c2,
40857  const Type c1, const Type c0)
40858  {
40859  // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
40860  return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
40861  }
40862  };
40863 
40864  template <typename Type>
40865  struct poly_impl <Type,4>
40866  {
40867  static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
40868  {
40869  // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
40870  return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
40871  }
40872  };
40873 
40874  template <typename Type>
40875  struct poly_impl <Type,3>
40876  {
40877  static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
40878  {
40879  // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
40880  return (((c3 * x + c2) * x + c1) * x + c0);
40881  }
40882  };
40883 
40884  template <typename Type>
40885  struct poly_impl <Type,2>
40886  {
40887  static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
40888  {
40889  // p(x) = c_2x^2 + c_1x^1 + c_0x^0
40890  return ((c2 * x + c1) * x + c0);
40891  }
40892  };
40893 
40894  template <typename Type>
40895  struct poly_impl <Type,1>
40896  {
40897  static inline T evaluate(const Type x, const Type c1, const Type c0)
40898  {
40899  // p(x) = c_1x^1 + c_0x^0
40900  return (c1 * x + c0);
40901  }
40902  };
40903 
40904  public:
40905 
40906  using ifunction<T>::operator();
40907 
40909  : ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max())
40910  {
40911  disable_has_side_effects(*this);
40912  }
40913 
40914  virtual ~polynomial()
40915  {}
40916 
40917  #define poly_rtrn(NN) \
40918  return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
40919 
40920  inline virtual T operator() (const T& x, const T& c1, const T& c0) exprtk_override
40921  {
40922  poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0));
40923  }
40924 
40925  inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) exprtk_override
40926  {
40927  poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0));
40928  }
40929 
40930  inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
40931  {
40932  poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0));
40933  }
40934 
40935  inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1,
40936  const T& c0) exprtk_override
40937  {
40938  poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0));
40939  }
40940 
40941  inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2,
40942  const T& c1, const T& c0) exprtk_override
40943  {
40944  poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0));
40945  }
40946 
40947  inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3,
40948  const T& c2, const T& c1, const T& c0) exprtk_override
40949  {
40950  poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0));
40951  }
40952 
40953  inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4,
40954  const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
40955  {
40956  poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0));
40957  }
40958 
40959  inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5,
40960  const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
40961  {
40962  poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40963  }
40964 
40965  inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6,
40966  const T& c5, const T& c4, const T& c3, const T& c2, const T& c1,
40967  const T& c0) exprtk_override
40968  {
40969  poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40970  }
40971 
40972  inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7,
40973  const T& c6, const T& c5, const T& c4, const T& c3, const T& c2,
40974  const T& c1, const T& c0) exprtk_override
40975  {
40976  poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40977  }
40978 
40979  inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8,
40980  const T& c7, const T& c6, const T& c5, const T& c4, const T& c3,
40981  const T& c2, const T& c1, const T& c0) exprtk_override
40982  {
40983  poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40984  }
40985 
40986  inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9,
40987  const T& c8, const T& c7, const T& c6, const T& c5, const T& c4,
40988  const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override
40989  {
40990  poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0));
40991  }
40992 
40993  #undef poly_rtrn
40994 
40995  inline virtual T operator() () exprtk_override
40996  {
40997  return std::numeric_limits<T>::quiet_NaN();
40998  }
40999 
41000  inline virtual T operator() (const T&) exprtk_override
41001  {
41002  return std::numeric_limits<T>::quiet_NaN();
41003  }
41004 
41005  inline virtual T operator() (const T&, const T&) exprtk_override
41006  {
41007  return std::numeric_limits<T>::quiet_NaN();
41008  }
41009  };
41010 
41011  template <typename T>
41013  {
41014  public:
41015 
41020 
41021  struct function
41022  {
41023  function()
41024  {}
41025 
41026  function(const std::string& n)
41027  : name_(n)
41028  {}
41029 
41030  function(const std::string& name,
41031  const std::string& expression)
41032  : name_(name)
41033  , expression_(expression)
41034  {}
41035 
41036  function(const std::string& name,
41037  const std::string& expression,
41038  const std::string& v0)
41039  : name_(name)
41040  , expression_(expression)
41041  {
41042  v_.push_back(v0);
41043  }
41044 
41045  function(const std::string& name,
41046  const std::string& expression,
41047  const std::string& v0, const std::string& v1)
41048  : name_(name)
41049  , expression_(expression)
41050  {
41051  v_.push_back(v0); v_.push_back(v1);
41052  }
41053 
41054  function(const std::string& name,
41055  const std::string& expression,
41056  const std::string& v0, const std::string& v1,
41057  const std::string& v2)
41058  : name_(name)
41059  , expression_(expression)
41060  {
41061  v_.push_back(v0); v_.push_back(v1);
41062  v_.push_back(v2);
41063  }
41064 
41065  function(const std::string& name,
41066  const std::string& expression,
41067  const std::string& v0, const std::string& v1,
41068  const std::string& v2, const std::string& v3)
41069  : name_(name)
41070  , expression_(expression)
41071  {
41072  v_.push_back(v0); v_.push_back(v1);
41073  v_.push_back(v2); v_.push_back(v3);
41074  }
41075 
41076  function(const std::string& name,
41077  const std::string& expression,
41078  const std::string& v0, const std::string& v1,
41079  const std::string& v2, const std::string& v3,
41080  const std::string& v4)
41081  : name_(name)
41082  , expression_(expression)
41083  {
41084  v_.push_back(v0); v_.push_back(v1);
41085  v_.push_back(v2); v_.push_back(v3);
41086  v_.push_back(v4);
41087  }
41088 
41089  inline function& name(const std::string& n)
41090  {
41091  name_ = n;
41092  return (*this);
41093  }
41094 
41095  inline function& expression(const std::string& e)
41096  {
41097  expression_ = e;
41098  return (*this);
41099  }
41100 
41101  inline function& var(const std::string& v)
41102  {
41103  v_.push_back(v);
41104  return (*this);
41105  }
41106 
41107  inline function& vars(const std::string& v0,
41108  const std::string& v1)
41109  {
41110  v_.push_back(v0);
41111  v_.push_back(v1);
41112  return (*this);
41113  }
41114 
41115  inline function& vars(const std::string& v0,
41116  const std::string& v1,
41117  const std::string& v2)
41118  {
41119  v_.push_back(v0);
41120  v_.push_back(v1);
41121  v_.push_back(v2);
41122  return (*this);
41123  }
41124 
41125  inline function& vars(const std::string& v0,
41126  const std::string& v1,
41127  const std::string& v2,
41128  const std::string& v3)
41129  {
41130  v_.push_back(v0);
41131  v_.push_back(v1);
41132  v_.push_back(v2);
41133  v_.push_back(v3);
41134  return (*this);
41135  }
41136 
41137  inline function& vars(const std::string& v0,
41138  const std::string& v1,
41139  const std::string& v2,
41140  const std::string& v3,
41141  const std::string& v4)
41142  {
41143  v_.push_back(v0);
41144  v_.push_back(v1);
41145  v_.push_back(v2);
41146  v_.push_back(v3);
41147  v_.push_back(v4);
41148  return (*this);
41149  }
41150 
41151  std::string name_;
41152  std::string expression_;
41153  std::deque<std::string> v_;
41154  };
41155 
41156  private:
41157 
41158  struct base_func : public exprtk::ifunction<T>
41159  {
41160  typedef const T& type;
41162  typedef std::vector<T*> varref_t;
41163  typedef std::vector<T> var_t;
41164  typedef std::pair<T*,std::size_t> lvarref_t;
41165  typedef std::vector<lvarref_t> lvr_vec_t;
41166 
41168 
41169  base_func(const std::size_t& pc = 0)
41170  : exprtk::ifunction<T>(pc)
41171  , local_var_stack_size(0)
41172  , stack_depth(0)
41173  {
41174  v.resize(pc);
41175  }
41176 
41177  virtual ~base_func()
41178  {}
41179 
41180  #define exprtk_assign(Index) \
41181  (*v[Index]) = v##Index; \
41182 
41183  inline void update(const T& v0)
41184  {
41185  exprtk_assign(0)
41186  }
41187 
41188  inline void update(const T& v0, const T& v1)
41189  {
41191  }
41192 
41193  inline void update(const T& v0, const T& v1, const T& v2)
41194  {
41196  exprtk_assign(2)
41197  }
41198 
41199  inline void update(const T& v0, const T& v1, const T& v2, const T& v3)
41200  {
41203  }
41204 
41205  inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
41206  {
41209  exprtk_assign(4)
41210  }
41211 
41212  inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
41213  {
41217  }
41218 
41219  #ifdef exprtk_assign
41220  #undef exprtk_assign
41221  #endif
41222 
41224  {
41225  expression = expr;
41226 
41227  typedef typename expression_t::control_block::local_data_list_t ldl_t;
41228 
41229  const ldl_t ldl = expr.local_data_list();
41230 
41231  std::vector<std::size_t> index_list;
41232 
41233  for (std::size_t i = 0; i < ldl.size(); ++i)
41234  {
41235  if (ldl[i].size)
41236  {
41237  index_list.push_back(i);
41238  }
41239  }
41240 
41241  std::size_t input_param_count = 0;
41242 
41243  for (std::size_t i = 0; i < index_list.size(); ++i)
41244  {
41245  const std::size_t index = index_list[i];
41246 
41247  if (i < (index_list.size() - v.size()))
41248  {
41249  lv.push_back(
41250  std::make_pair(
41251  reinterpret_cast<T*>(ldl[index].pointer),
41252  ldl[index].size));
41253 
41254  local_var_stack_size += ldl[index].size;
41255  }
41256  else
41257  v[input_param_count++] = reinterpret_cast<T*>(ldl[index].pointer);
41258  }
41259 
41260  clear_stack();
41261 
41262  return (*this);
41263  }
41264 
41265  inline void pre()
41266  {
41267  if (stack_depth++)
41268  {
41269  if (!v.empty())
41270  {
41271  var_t var_stack(v.size(),T(0));
41272  copy(v,var_stack);
41273  param_stack.push_back(var_stack);
41274  }
41275 
41276  if (!lv.empty())
41277  {
41278  var_t local_var_stack(local_var_stack_size,T(0));
41279  copy(lv,local_var_stack);
41280  local_stack.push_back(local_var_stack);
41281  }
41282  }
41283  }
41284 
41285  inline void post()
41286  {
41287  if (--stack_depth)
41288  {
41289  if (!v.empty())
41290  {
41291  copy(param_stack.back(),v);
41292  param_stack.pop_back();
41293  }
41294 
41295  if (!lv.empty())
41296  {
41297  copy(local_stack.back(),lv);
41298  local_stack.pop_back();
41299  }
41300  }
41301  }
41302 
41303  void copy(const varref_t& src_v, var_t& dest_v)
41304  {
41305  for (std::size_t i = 0; i < src_v.size(); ++i)
41306  {
41307  dest_v[i] = (*src_v[i]);
41308  }
41309  }
41310 
41311  void copy(const var_t& src_v, varref_t& dest_v)
41312  {
41313  for (std::size_t i = 0; i < src_v.size(); ++i)
41314  {
41315  (*dest_v[i]) = src_v[i];
41316  }
41317  }
41318 
41319  void copy(const lvr_vec_t& src_v, var_t& dest_v)
41320  {
41321  typename var_t::iterator itr = dest_v.begin();
41322  typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
41323 
41324  for (std::size_t i = 0; i < src_v.size(); ++i)
41325  {
41326  lvarref_t vr = src_v[i];
41327 
41328  if (1 == vr.second)
41329  *itr++ = (*vr.first);
41330  else
41331  {
41332  std::copy(vr.first, vr.first + vr.second, itr);
41333  itr += static_cast<diff_t>(vr.second);
41334  }
41335  }
41336  }
41337 
41338  void copy(const var_t& src_v, lvr_vec_t& dest_v)
41339  {
41340  typename var_t::const_iterator itr = src_v.begin();
41341  typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
41342 
41343  for (std::size_t i = 0; i < src_v.size(); ++i)
41344  {
41345  lvarref_t vr = dest_v[i];
41346 
41347  if (1 == vr.second)
41348  (*vr.first) = *itr++;
41349  else
41350  {
41351  std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first);
41352  itr += static_cast<diff_t>(vr.second);
41353  }
41354  }
41355  }
41356 
41357  inline void clear_stack()
41358  {
41359  for (std::size_t i = 0; i < v.size(); ++i)
41360  {
41361  (*v[i]) = 0;
41362  }
41363  }
41364 
41365  inline virtual T value(expression_t& e)
41366  {
41367  return e.value();
41368  }
41369 
41374  std::size_t stack_depth;
41375  std::deque<var_t> param_stack;
41376  std::deque<var_t> local_stack;
41377  };
41378 
41379  typedef std::map<std::string,base_func*> funcparam_t;
41380 
41381  struct func_0param : public base_func
41382  {
41384 
41386 
41387  inline T operator() () exprtk_override
41388  {
41389  return this->value(base_func::expression);
41390  }
41391  };
41392 
41393  typedef const T& type;
41394 
41395  template <typename BaseFuncType>
41396  struct scoped_bft
41397  {
41398  explicit scoped_bft(BaseFuncType& bft)
41399  : bft_(bft)
41400  {
41401  bft_.pre ();
41402  }
41403 
41405  {
41406  bft_.post();
41407  }
41408 
41409  BaseFuncType& bft_;
41410 
41411  private:
41412 
41415  };
41416 
41417  struct func_1param : public base_func
41418  {
41420 
41422 
41423  inline T operator() (type v0) exprtk_override
41424  {
41425  scoped_bft<func_1param> sb(*this);
41426  base_func::update(v0);
41427  return this->value(base_func::expression);
41428  }
41429  };
41430 
41431  struct func_2param : public base_func
41432  {
41434 
41436 
41437  inline T operator() (type v0, type v1) exprtk_override
41438  {
41439  scoped_bft<func_2param> sb(*this);
41440  base_func::update(v0, v1);
41441  return this->value(base_func::expression);
41442  }
41443  };
41444 
41445  struct func_3param : public base_func
41446  {
41448 
41450 
41451  inline T operator() (type v0, type v1, type v2) exprtk_override
41452  {
41453  scoped_bft<func_3param> sb(*this);
41454  base_func::update(v0, v1, v2);
41455  return this->value(base_func::expression);
41456  }
41457  };
41458 
41459  struct func_4param : public base_func
41460  {
41462 
41464 
41465  inline T operator() (type v0, type v1, type v2, type v3) exprtk_override
41466  {
41467  scoped_bft<func_4param> sb(*this);
41468  base_func::update(v0, v1, v2, v3);
41469  return this->value(base_func::expression);
41470  }
41471  };
41472 
41473  struct func_5param : public base_func
41474  {
41476 
41478 
41479  inline T operator() (type v0, type v1, type v2, type v3, type v4) exprtk_override
41480  {
41481  scoped_bft<func_5param> sb(*this);
41482  base_func::update(v0, v1, v2, v3, v4);
41483  return this->value(base_func::expression);
41484  }
41485  };
41486 
41487  struct func_6param : public base_func
41488  {
41490 
41492 
41493  inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) exprtk_override
41494  {
41495  scoped_bft<func_6param> sb(*this);
41496  base_func::update(v0, v1, v2, v3, v4, v5);
41497  return this->value(base_func::expression);
41498  }
41499  };
41500 
41502  {
41503  typedef exprtk::results_context<T> results_context_t;
41504  typedef typename results_context_t::type_store_t type_t;
41505  typedef typename type_t::scalar_view scalar_t;
41506 
41507  const T result = e.value();
41508 
41509  if (e.return_invoked())
41510  {
41511  // Due to the post compilation checks, it can be safely
41512  // assumed that there will be at least one parameter
41513  // and that the first parameter will always be scalar.
41514  return scalar_t(e.results()[0])();
41515  }
41516 
41517  return result;
41518  }
41519 
41520  #define def_fp_retval(N) \
41521  struct func_##N##param_retval exprtk_final : public func_##N##param \
41522  { \
41523  inline T value(expression_t& e) exprtk_override \
41524  { \
41525  return return_value(e); \
41526  } \
41527  }; \
41528 
41530  def_fp_retval(1)
41531  def_fp_retval(2)
41532  def_fp_retval(3)
41533  def_fp_retval(4)
41534  def_fp_retval(5)
41535  def_fp_retval(6)
41536 
41537  #undef def_fp_retval
41538 
41539  template <typename Allocator,
41540  template <typename, typename> class Sequence>
41541  inline bool add(const std::string& name,
41542  const std::string& expression,
41543  const Sequence<std::string,Allocator>& var_list,
41544  const bool override = false)
41545  {
41546  const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name);
41547 
41548  if (expr_map_.end() != itr)
41549  {
41550  if (!override)
41551  {
41552  exprtk_debug(("Compositor error(add): function '%s' already defined\n",
41553  name.c_str()));
41554 
41555  return false;
41556  }
41557 
41558  remove(name, var_list.size());
41559  }
41560 
41561  if (compile_expression(name, expression, var_list))
41562  {
41563  const std::size_t n = var_list.size();
41564 
41565  fp_map_[n][name]->setup(expr_map_[name]);
41566 
41567  return true;
41568  }
41569  else
41570  {
41571  exprtk_debug(("Compositor error(add): Failed to compile function '%s'\n",
41572  name.c_str()));
41573 
41574  return false;
41575  }
41576  }
41577 
41578  public:
41579 
41581  : parser_(settings_t::default_compile_all_opts +
41582  settings_t::e_disable_zero_return)
41583  , fp_map_(7)
41584  , load_variables_(false)
41585  , load_vectors_(false)
41586  {}
41587 
41589  : symbol_table_(st)
41590  , parser_(settings_t::default_compile_all_opts +
41591  settings_t::e_disable_zero_return)
41592  , fp_map_(7)
41593  , load_variables_(false)
41594  , load_vectors_(false)
41595  {}
41596 
41598  {
41599  clear();
41600  }
41601 
41603  {
41604  return symbol_table_;
41605  }
41606 
41607  inline const symbol_table_t& symbol_table() const
41608  {
41609  return symbol_table_;
41610  }
41611 
41613  {
41614  auxiliary_symtab_list_.push_back(&symtab);
41615  }
41616 
41617  void load_variables(const bool load = true)
41618  {
41619  load_variables_ = load;
41620  }
41621 
41622  void load_vectors(const bool load = true)
41623  {
41624  load_vectors_ = load;
41625  }
41626 
41627  void clear()
41628  {
41629  symbol_table_.clear();
41630  expr_map_ .clear();
41631 
41632  for (std::size_t i = 0; i < fp_map_.size(); ++i)
41633  {
41634  typename funcparam_t::iterator itr = fp_map_[i].begin();
41635  typename funcparam_t::iterator end = fp_map_[i].end ();
41636 
41637  while (itr != end)
41638  {
41639  delete itr->second;
41640  ++itr;
41641  }
41642 
41643  fp_map_[i].clear();
41644  }
41645  }
41646 
41647  inline bool add(const function& f, const bool override = false)
41648  {
41649  return add(f.name_, f.expression_, f.v_,override);
41650  }
41651 
41652  inline std::string error() const
41653  {
41654  if (!error_list_.empty())
41655  {
41656  return error_list_[0].diagnostic;
41657  }
41658  else
41659  return std::string("No Error");
41660  }
41661 
41662  inline std::size_t error_count() const
41663  {
41664  return error_list_.size();
41665  }
41666 
41667  inline parser_error::type get_error(const std::size_t& index) const
41668  {
41669  if (index < error_list_.size())
41670  return error_list_[index];
41671  else
41672  throw std::invalid_argument("compositor::get_error() - Invalid error index specified");
41673  }
41674 
41675  private:
41676 
41677  template <typename Allocator,
41678  template <typename, typename> class Sequence>
41679  bool compile_expression(const std::string& name,
41680  const std::string& expression,
41681  const Sequence<std::string,Allocator>& input_var_list,
41682  bool return_present = false)
41683  {
41684  expression_t compiled_expression;
41685  symbol_table_t local_symbol_table;
41686 
41687  local_symbol_table.load_from(symbol_table_);
41688  local_symbol_table.add_constants();
41689 
41690  if (load_variables_)
41691  {
41692  local_symbol_table.load_variables_from(symbol_table_);
41693  }
41694 
41695  if (load_vectors_)
41696  {
41697  local_symbol_table.load_vectors_from(symbol_table_);
41698  }
41699 
41700  error_list_.clear();
41701 
41702  if (!valid(name,input_var_list.size()))
41703  {
41704  parser_error::type error =
41707  lexer::token(),
41708  "ERR250 - Function '" + name + "' is an invalid overload",
41710 
41711  error_list_.push_back(error);
41712  return false;
41713  }
41714 
41715  if (!forward(name,
41716  input_var_list.size(),
41717  local_symbol_table,
41718  return_present))
41719  return false;
41720 
41721  compiled_expression.register_symbol_table(local_symbol_table);
41722 
41723  for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i)
41724  {
41725  compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i]));
41726  }
41727 
41728  std::string mod_expression;
41729 
41730  for (std::size_t i = 0; i < input_var_list.size(); ++i)
41731  {
41732  mod_expression += " var " + input_var_list[i] + "{};\n";
41733  }
41734 
41735  if (
41736  ('{' == details::front(expression)) &&
41737  ('}' == details::back (expression))
41738  )
41739  mod_expression += "~" + expression + ";";
41740  else
41741  mod_expression += "~{" + expression + "};";
41742 
41743  if (!parser_.compile(mod_expression,compiled_expression))
41744  {
41745  exprtk_debug(("Compositor Error: %s\n", parser_.error().c_str()));
41746  exprtk_debug(("Compositor modified expression: \n%s\n", mod_expression.c_str()));
41747 
41748  remove(name,input_var_list.size());
41749 
41750  for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index)
41751  {
41752  error_list_.push_back(parser_.get_error(err_index));
41753  }
41754 
41755  return false;
41756  }
41757 
41758  if (!return_present && parser_.dec().return_present())
41759  {
41760  remove(name,input_var_list.size());
41761  return compile_expression(name, expression, input_var_list, true);
41762  }
41763 
41764  // Make sure every return point has a scalar as its first parameter
41765  if (parser_.dec().return_present())
41766  {
41767  typedef std::vector<std::string> str_list_t;
41768 
41769  str_list_t ret_param_list = parser_.dec().return_param_type_list();
41770 
41771  for (std::size_t i = 0; i < ret_param_list.size(); ++i)
41772  {
41773  const std::string& params = ret_param_list[i];
41774 
41775  if (params.empty() || ('T' != params[0]))
41776  {
41777  exprtk_debug(("Compositor Error: Return statement in function '%s' is invalid\n",
41778  name.c_str()));
41779 
41780  remove(name,input_var_list.size());
41781 
41782  return false;
41783  }
41784  }
41785  }
41786 
41787  expr_map_[name] = compiled_expression;
41788 
41789  exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]);
41790 
41791  if (symbol_table_.add_function(name,ifunc))
41792  return true;
41793  else
41794  {
41795  exprtk_debug(("Compositor Error: Failed to add function '%s' to symbol table\n",
41796  name.c_str()));
41797  return false;
41798  }
41799  }
41800 
41801  inline bool symbol_used(const std::string& symbol) const
41802  {
41803  return (
41804  symbol_table_.is_variable (symbol) ||
41805  symbol_table_.is_stringvar (symbol) ||
41806  symbol_table_.is_function (symbol) ||
41807  symbol_table_.is_vector (symbol) ||
41808  symbol_table_.is_vararg_function(symbol)
41809  );
41810  }
41811 
41812  inline bool valid(const std::string& name,
41813  const std::size_t& arg_count) const
41814  {
41815  if (arg_count > 6)
41816  return false;
41817  else if (symbol_used(name))
41818  return false;
41819  else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
41820  return false;
41821  else
41822  return true;
41823  }
41824 
41825  inline bool forward(const std::string& name,
41826  const std::size_t& arg_count,
41827  symbol_table_t& sym_table,
41828  const bool ret_present = false)
41829  {
41830  switch (arg_count)
41831  {
41832  #define case_stmt(N) \
41833  case N : (fp_map_[arg_count])[name] = \
41834  (!ret_present) ? static_cast<base_func*> \
41835  (new func_##N##param) : \
41836  static_cast<base_func*> \
41837  (new func_##N##param_retval) ; \
41838  break; \
41839 
41840  case_stmt(0) case_stmt(1) case_stmt(2)
41841  case_stmt(3) case_stmt(4) case_stmt(5)
41842  case_stmt(6)
41843  #undef case_stmt
41844  }
41845 
41846  exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]);
41847 
41848  return sym_table.add_function(name,ifunc);
41849  }
41850 
41851  inline void remove(const std::string& name, const std::size_t& arg_count)
41852  {
41853  if (arg_count > 6)
41854  return;
41855 
41856  const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name);
41857 
41858  if (expr_map_.end() != em_itr)
41859  {
41860  expr_map_.erase(em_itr);
41861  }
41862 
41863  const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
41864 
41865  if (fp_map_[arg_count].end() != fp_itr)
41866  {
41867  delete fp_itr->second;
41868  fp_map_[arg_count].erase(fp_itr);
41869  }
41870 
41871  symbol_table_.remove_function(name);
41872  }
41873 
41874  private:
41875 
41878  std::map<std::string,expression_t> expr_map_;
41879  std::vector<funcparam_t> fp_map_;
41880  std::vector<symbol_table_t*> auxiliary_symtab_list_;
41881  std::deque<parser_error::type> error_list_;
41884  }; // class function_compositor
41885 
41886 } // namespace exprtk
41887 
41888 #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
41889 # ifndef NOMINMAX
41890 # define NOMINMAX
41891 # endif
41892 # ifndef WIN32_LEAN_AND_MEAN
41893 # define WIN32_LEAN_AND_MEAN
41894 # endif
41895 # include <windows.h>
41896 # include <ctime>
41897 #else
41898 # include <ctime>
41899 # include <sys/time.h>
41900 # include <sys/types.h>
41901 #endif
41902 
41903 namespace exprtk
41904 {
41905  class timer
41906  {
41907  public:
41908 
41909  #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
41910  timer()
41911  : in_use_(false)
41912  , start_time_{ 0 }
41913  , stop_time_ { 0 }
41914  {
41915  QueryPerformanceFrequency(&clock_frequency_);
41916  }
41917 
41918  inline void start()
41919  {
41920  in_use_ = true;
41921  QueryPerformanceCounter(&start_time_);
41922  }
41923 
41924  inline void stop()
41925  {
41926  QueryPerformanceCounter(&stop_time_);
41927  in_use_ = false;
41928  }
41929 
41930  inline double time() const
41931  {
41932  return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
41933  }
41934 
41935  #else
41936 
41938  : in_use_(false)
41939  {
41940  start_time_.tv_sec = 0;
41941  start_time_.tv_usec = 0;
41942 
41943  stop_time_.tv_sec = 0;
41944  stop_time_.tv_usec = 0;
41945  }
41946 
41947  inline void start()
41948  {
41949  in_use_ = true;
41950  gettimeofday(&start_time_,0);
41951  }
41952 
41953  inline void stop()
41954  {
41955  gettimeofday(&stop_time_, 0);
41956  in_use_ = false;
41957  }
41958 
41959  inline unsigned long long int usec_time() const
41960  {
41961  if (!in_use_)
41962  {
41963  if (stop_time_.tv_sec >= start_time_.tv_sec)
41964  {
41965  return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec - start_time_.tv_sec ) +
41966  static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ;
41967  }
41968  else
41970  }
41971  else
41973  }
41974 
41975  inline double time() const
41976  {
41977  return usec_time() * 0.000001;
41978  }
41979 
41980  #endif
41981 
41982  inline bool in_use() const
41983  {
41984  return in_use_;
41985  }
41986 
41987  private:
41988 
41989  bool in_use_;
41990 
41991  #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
41992  LARGE_INTEGER start_time_;
41993  LARGE_INTEGER stop_time_;
41994  LARGE_INTEGER clock_frequency_;
41995  #else
41996  struct timeval start_time_;
41997  struct timeval stop_time_;
41998  #endif
41999  };
42000 
42001  template <typename T>
42002  struct type_defs
42003  {
42010  };
42011 
42012 } // namespace exprtk
42013 
42014 #ifndef exprtk_disable_rtl_io
42015 namespace exprtk
42016 {
42017  namespace rtl { namespace io { namespace details
42018  {
42019  template <typename T>
42020  inline void print_type(const std::string& fmt,
42021  const T v,
42023  {
42024  #if defined(__clang__)
42025  #pragma clang diagnostic push
42026  #pragma clang diagnostic ignored "-Wformat-nonliteral"
42027  #elif defined(__GNUC__) || defined(__GNUG__)
42028  #pragma GCC diagnostic push
42029  #pragma GCC diagnostic ignored "-Wformat-nonliteral"
42030  #elif defined(_MSC_VER)
42031  #endif
42032 
42033  printf(fmt.c_str(), v);
42034 
42035  #if defined(__clang__)
42036  #pragma clang diagnostic pop
42037  #elif defined(__GNUC__) || defined(__GNUG__)
42038  #pragma GCC diagnostic pop
42039  #elif defined(_MSC_VER)
42040  #endif
42041  }
42042 
42043  template <typename T>
42044  struct print_impl
42045  {
42052 
42053  static void process(const std::string& scalar_format, parameter_list_t parameters)
42054  {
42055  for (std::size_t i = 0; i < parameters.size(); ++i)
42056  {
42057  generic_type& gt = parameters[i];
42058 
42059  switch (gt.type)
42060  {
42061  case generic_type::e_scalar : print(scalar_format,scalar_t(gt));
42062  break;
42063 
42064  case generic_type::e_vector : print(scalar_format,vector_t(gt));
42065  break;
42066 
42068  break;
42069 
42070  default : continue;
42071  }
42072  }
42073  }
42074 
42075  static inline void print(const std::string& scalar_format, const scalar_t& s)
42076  {
42077  print_type(scalar_format,s(),num_type());
42078  }
42079 
42080  static inline void print(const std::string& scalar_format, const vector_t& v)
42081  {
42082  for (std::size_t i = 0; i < v.size(); ++i)
42083  {
42084  print_type(scalar_format,v[i],num_type());
42085 
42086  if ((i + 1) < v.size())
42087  printf(" ");
42088  }
42089  }
42090 
42091  static inline void print(const string_t& s)
42092  {
42093  printf("%s",to_str(s).c_str());
42094  }
42095  };
42096 
42097  } // namespace exprtk::rtl::io::details
42098 
42099  template <typename T>
42100  struct print exprtk_final : public exprtk::igeneric_function<T>
42101  {
42103 
42105 
42106  explicit print(const std::string& scalar_format = "%10.5f")
42107  : scalar_format_(scalar_format)
42108  {
42110  }
42111 
42112  inline T operator() (parameter_list_t parameters) exprtk_override
42113  {
42114  details::print_impl<T>::process(scalar_format_,parameters);
42115  return T(0);
42116  }
42117 
42118  std::string scalar_format_;
42119  };
42120 
42121  template <typename T>
42122  struct println exprtk_final : public exprtk::igeneric_function<T>
42123  {
42125 
42127 
42128  explicit println(const std::string& scalar_format = "%10.5f")
42129  : scalar_format_(scalar_format)
42130  {
42132  }
42133 
42134  inline T operator() (parameter_list_t parameters) exprtk_override
42135  {
42136  details::print_impl<T>::process(scalar_format_,parameters);
42137  printf("\n");
42138  return T(0);
42139  }
42140 
42141  std::string scalar_format_;
42142  };
42143 
42144  template <typename T>
42145  struct package
42146  {
42147  print <T> p;
42148  println<T> pl;
42149 
42151  {
42152  #define exprtk_register_function(FunctionName, FunctionType) \
42153  if (!symtab.add_function(FunctionName,FunctionType)) \
42154  { \
42155  exprtk_debug(( \
42156  "exprtk::rtl::io::register_package - Failed to add function: %s\n", \
42157  FunctionName)); \
42158  return false; \
42159  } \
42160 
42161  exprtk_register_function("print" , p )
42162  exprtk_register_function("println", pl)
42163  #undef exprtk_register_function
42164 
42165  return true;
42166  }
42167  };
42168 
42169  } // namespace exprtk::rtl::io
42170  } // namespace exprtk::rtl
42171 } // namespace exprtk
42172 #endif
42173 
42174 #ifndef exprtk_disable_rtl_io_file
42175 #include <fstream>
42176 namespace exprtk
42177 {
42178  namespace rtl { namespace io { namespace file { namespace details
42179  {
42182 
42184  {
42185  e_error = 0,
42186  e_read = 1,
42187  e_write = 2,
42188  e_rdwrt = 4
42189  };
42190 
42192  {
42193  file_descriptor(const std::string& fname, const std::string& access)
42194  : stream_ptr(0)
42195  , mode(get_file_mode(access))
42196  , file_name(fname)
42197  {}
42198 
42199  void* stream_ptr;
42201  std::string file_name;
42202 
42203  bool open()
42204  {
42205  if (e_read == mode)
42206  {
42207  std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary);
42208 
42209  if (!(*stream))
42210  {
42211  file_name.clear();
42212  delete stream;
42213 
42214  return false;
42215  }
42216 
42217  stream_ptr = stream;
42218 
42219  return true;
42220  }
42221  else if (e_write == mode)
42222  {
42223  std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary);
42224 
42225  if (!(*stream))
42226  {
42227  file_name.clear();
42228  delete stream;
42229 
42230  return false;
42231  }
42232 
42233  stream_ptr = stream;
42234 
42235  return true;
42236  }
42237  else if (e_rdwrt == mode)
42238  {
42239  std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary);
42240 
42241  if (!(*stream))
42242  {
42243  file_name.clear();
42244  delete stream;
42245 
42246  return false;
42247  }
42248 
42249  stream_ptr = stream;
42250 
42251  return true;
42252  }
42253 
42254  return false;
42255  }
42256 
42257  template <typename Stream, typename Ptr>
42258  void close(Ptr& p)
42259  {
42260  Stream* stream = reinterpret_cast<Stream*>(p);
42261  stream->close();
42262  delete stream;
42263  p = reinterpret_cast<Ptr>(0);
42264  }
42265 
42266  bool close()
42267  {
42268  switch (mode)
42269  {
42270  case e_read : close<std::ifstream>(stream_ptr);
42271  break;
42272 
42273  case e_write : close<std::ofstream>(stream_ptr);
42274  break;
42275 
42276  case e_rdwrt : close<std::fstream> (stream_ptr);
42277  break;
42278 
42279  default : return false;
42280  }
42281 
42282  return true;
42283  }
42284 
42285  template <typename View>
42286  bool write(const View& view, const std::size_t amount, const std::size_t offset = 0)
42287  {
42288  switch (mode)
42289  {
42290  case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)->
42291  write(reinterpret_cast<char_cptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
42292  break;
42293 
42294  case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
42295  write(reinterpret_cast<char_cptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
42296  break;
42297 
42298  default : return false;
42299  }
42300 
42301  return true;
42302  }
42303 
42304  template <typename View>
42305  bool read(View& view, const std::size_t amount, const std::size_t offset = 0)
42306  {
42307  switch (mode)
42308  {
42309  case e_read : reinterpret_cast<std::ifstream*>(stream_ptr)->
42310  read(reinterpret_cast<char_ptr>(view.begin() + offset), amount * sizeof(typename View::value_t));
42311  break;
42312 
42313  case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
42314  read(reinterpret_cast<char_ptr>(view.begin() + offset) , amount * sizeof(typename View::value_t));
42315  break;
42316 
42317  default : return false;
42318  }
42319 
42320  return true;
42321  }
42322 
42323  bool getline(std::string& s)
42324  {
42325  switch (mode)
42326  {
42327  case e_read : return (!!std::getline(*reinterpret_cast<std::ifstream*>(stream_ptr),s));
42328  case e_rdwrt : return (!!std::getline(*reinterpret_cast<std::fstream* >(stream_ptr),s));
42329  default : return false;
42330  }
42331  }
42332 
42333  bool eof() const
42334  {
42335  switch (mode)
42336  {
42337  case e_read : return reinterpret_cast<std::ifstream*>(stream_ptr)->eof();
42338  case e_write : return reinterpret_cast<std::ofstream*>(stream_ptr)->eof();
42339  case e_rdwrt : return reinterpret_cast<std::fstream* >(stream_ptr)->eof();
42340  default : return true;
42341  }
42342  }
42343 
42344  file_mode get_file_mode(const std::string& access) const
42345  {
42346  if (access.empty() || access.size() > 2)
42347  return e_error;
42348 
42349  std::size_t w_cnt = 0;
42350  std::size_t r_cnt = 0;
42351 
42352  for (std::size_t i = 0; i < access.size(); ++i)
42353  {
42354  switch (std::tolower(access[i]))
42355  {
42356  case 'r' : r_cnt++; break;
42357  case 'w' : w_cnt++; break;
42358  default : return e_error;
42359  }
42360  }
42361 
42362  if ((0 == r_cnt) && (0 == w_cnt))
42363  return e_error;
42364  else if ((r_cnt > 1) || (w_cnt > 1))
42365  return e_error;
42366  else if ((1 == r_cnt) && (1 == w_cnt))
42367  return e_rdwrt;
42368  else if (1 == r_cnt)
42369  return e_read;
42370  else
42371  return e_write;
42372  }
42373  };
42374 
42375  template <typename T>
42377  {
42378  const std::size_t fd_size = sizeof(details::file_descriptor*);
42379  details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0);
42380 
42381  std::memcpy(reinterpret_cast<char_ptr >(&fd),
42382  reinterpret_cast<char_cptr>(&v ),
42383  fd_size);
42384  return fd;
42385  }
42386 
42387  template <typename T>
42389  {
42390  #ifdef _MSC_VER
42391  #pragma warning(push)
42392  #pragma warning(disable: 4127)
42393  #endif
42394  if (sizeof(T) < sizeof(void*))
42395  {
42396  throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder.");
42397  }
42398  #ifdef _MSC_VER
42399  #pragma warning(pop)
42400  #endif
42401  assert(sizeof(T) <= sizeof(void*));
42402  }
42403 
42404  } // namespace exprtk::rtl::io::file::details
42405 
42406  template <typename T>
42408  {
42409  public:
42410 
42415 
42416  using igfun_t::operator();
42417 
42419  : exprtk::igeneric_function<T>("S|SS")
42420  { details::perform_check<T>(); }
42421 
42422  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42423  {
42424  const std::string file_name = to_str(string_t(parameters[0]));
42425 
42426  if (file_name.empty())
42427  return T(0);
42428 
42429  if ((1 == ps_index) && (0 == string_t(parameters[1]).size()))
42430  {
42431  return T(0);
42432  }
42433 
42434  const std::string access =
42435  (0 == ps_index) ? "r" : to_str(string_t(parameters[1]));
42436 
42437  details::file_descriptor* fd = new details::file_descriptor(file_name,access);
42438 
42439  if (fd->open())
42440  {
42441  T t = T(0);
42442 
42443  const std::size_t fd_size = sizeof(details::file_descriptor*);
42444 
42445  std::memcpy(reinterpret_cast<char*>(&t ),
42446  reinterpret_cast<char*>(&fd),
42447  fd_size);
42448  return t;
42449  }
42450  else
42451  {
42452  delete fd;
42453  return T(0);
42454  }
42455  }
42456  };
42457 
42458  template <typename T>
42459  struct close exprtk_final : public exprtk::ifunction<T>
42460  {
42462 
42464  : exprtk::ifunction<T>(1)
42465  { details::perform_check<T>(); }
42466 
42467  inline T operator() (const T& v) exprtk_override
42468  {
42470 
42471  if (!fd->close())
42472  return T(0);
42473 
42474  delete fd;
42475 
42476  return T(1);
42477  }
42478  };
42479 
42480  template <typename T>
42481  class write exprtk_final : public exprtk::igeneric_function<T>
42482  {
42483  public:
42484 
42491 
42492  using igfun_t::operator();
42493 
42495  : igfun_t("TS|TST|TV|TVT")
42496  { details::perform_check<T>(); }
42497 
42498  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42499  {
42500  details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
42501 
42502  switch (ps_index)
42503  {
42504  case 0 : {
42505  const string_t buffer(parameters[1]);
42506  const std::size_t amount = buffer.size();
42507  return T(fd->write(buffer, amount) ? 1 : 0);
42508  }
42509 
42510  case 1 : {
42511  const string_t buffer(parameters[1]);
42512  const std::size_t amount =
42513  std::min(buffer.size(),
42514  static_cast<std::size_t>(scalar_t(parameters[2])()));
42515  return T(fd->write(buffer, amount) ? 1 : 0);
42516  }
42517 
42518  case 2 : {
42519  const vector_t vec(parameters[1]);
42520  const std::size_t amount = vec.size();
42521  return T(fd->write(vec, amount) ? 1 : 0);
42522  }
42523 
42524  case 3 : {
42525  const vector_t vec(parameters[1]);
42526  const std::size_t amount =
42527  std::min(vec.size(),
42528  static_cast<std::size_t>(scalar_t(parameters[2])()));
42529  return T(fd->write(vec, amount) ? 1 : 0);
42530  }
42531  }
42532 
42533  return T(0);
42534  }
42535  };
42536 
42537  template <typename T>
42538  class read exprtk_final : public exprtk::igeneric_function<T>
42539  {
42540  public:
42541 
42548 
42549  using igfun_t::operator();
42550 
42552  : igfun_t("TS|TST|TV|TVT")
42553  { details::perform_check<T>(); }
42554 
42555  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42556  {
42557  details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
42558 
42559  switch (ps_index)
42560  {
42561  case 0 : {
42562  string_t buffer(parameters[1]);
42563  const std::size_t amount = buffer.size();
42564  return T(fd->read(buffer,amount) ? 1 : 0);
42565  }
42566 
42567  case 1 : {
42568  string_t buffer(parameters[1]);
42569  const std::size_t amount =
42570  std::min(buffer.size(),
42571  static_cast<std::size_t>(scalar_t(parameters[2])()));
42572  return T(fd->read(buffer,amount) ? 1 : 0);
42573  }
42574 
42575  case 2 : {
42576  vector_t vec(parameters[1]);
42577  const std::size_t amount = vec.size();
42578  return T(fd->read(vec,amount) ? 1 : 0);
42579  }
42580 
42581  case 3 : {
42582  vector_t vec(parameters[1]);
42583  const std::size_t amount =
42584  std::min(vec.size(),
42585  static_cast<std::size_t>(scalar_t(parameters[2])()));
42586  return T(fd->read(vec,amount) ? 1 : 0);
42587  }
42588  }
42589 
42590  return T(0);
42591  }
42592  };
42593 
42594  template <typename T>
42595  class getline exprtk_final : public exprtk::igeneric_function<T>
42596  {
42597  public:
42598 
42604 
42605  using igfun_t::operator();
42606 
42608  : igfun_t("T",igfun_t::e_rtrn_string)
42609  { details::perform_check<T>(); }
42610 
42611  inline T operator() (std::string& result, parameter_list_t parameters) exprtk_override
42612  {
42613  details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
42614  return T(fd->getline(result) ? 1 : 0);
42615  }
42616  };
42617 
42618  template <typename T>
42619  struct eof exprtk_final : public exprtk::ifunction<T>
42620  {
42622 
42624  : exprtk::ifunction<T>(1)
42625  { details::perform_check<T>(); }
42626 
42627  inline T operator() (const T& v) exprtk_override
42628  {
42630 
42631  return (fd->eof() ? T(1) : T(0));
42632  }
42633  };
42634 
42635  template <typename T>
42636  struct package
42637  {
42638  open <T> o;
42639  close <T> c;
42640  write <T> w;
42641  read <T> r;
42642  getline<T> g;
42643  eof <T> e;
42644 
42646  {
42647  #define exprtk_register_function(FunctionName, FunctionType) \
42648  if (!symtab.add_function(FunctionName,FunctionType)) \
42649  { \
42650  exprtk_debug(( \
42651  "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
42652  FunctionName)); \
42653  return false; \
42654  } \
42655 
42656  exprtk_register_function("open" , o)
42657  exprtk_register_function("close" , c)
42658  exprtk_register_function("write" , w)
42659  exprtk_register_function("read" , r)
42660  exprtk_register_function("getline" , g)
42661  exprtk_register_function("eof" , e)
42662  #undef exprtk_register_function
42663 
42664  return true;
42665  }
42666  };
42667 
42668  } // namespace exprtk::rtl::io::file
42669  } // namespace exprtk::rtl::io
42670  } // namespace exprtk::rtl
42671 } // namespace exprtk
42672 #endif
42673 
42674 #ifndef exprtk_disable_rtl_vecops
42675 namespace exprtk
42676 {
42677  namespace rtl { namespace vecops {
42678 
42679  namespace helper
42680  {
42681  template <typename Vector>
42682  inline bool invalid_range(const Vector& v, const std::size_t r0, const std::size_t r1)
42683  {
42684  if (r0 > (v.size() - 1))
42685  return true;
42686  else if (r1 > (v.size() - 1))
42687  return true;
42688  else if (r1 < r0)
42689  return true;
42690  else
42691  return false;
42692  }
42693 
42694  template <typename T>
42696  {
42702 
42703  static inline bool process(parameter_list_t& parameters,
42704  std::size_t& r0, std::size_t& r1,
42705  const std::size_t& r0_prmidx,
42706  const std::size_t& r1_prmidx,
42707  const std::size_t vec_idx = 0)
42708  {
42709  if (r0_prmidx >= parameters.size())
42710  return false;
42711 
42712  if (r1_prmidx >= parameters.size())
42713  return false;
42714 
42715  if (!scalar_t(parameters[r0_prmidx]).to_uint(r0))
42716  return false;
42717 
42718  if (!scalar_t(parameters[r1_prmidx]).to_uint(r1))
42719  return false;
42720 
42721  return !invalid_range(vector_t(parameters[vec_idx]), r0, r1);
42722  }
42723  };
42724  }
42725 
42726  namespace details
42727  {
42728  template <typename T>
42729  inline void kahan_sum(T& sum, T& error, const T v)
42730  {
42731  const T x = v - error;
42732  const T y = sum + x;
42733  error = (y - sum) - x;
42734  sum = y;
42735  }
42736 
42737  } // namespace exprtk::rtl::details
42738 
42739  template <typename T>
42740  class all_true exprtk_final : public exprtk::igeneric_function<T>
42741  {
42742  public:
42743 
42748 
42749  using igfun_t::operator();
42750 
42752  : exprtk::igeneric_function<T>("V|VTT")
42753  /*
42754  Overloads:
42755  0. V - vector
42756  1. VTT - vector, r0, r1
42757  */
42758  {}
42759 
42760  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42761  {
42762  const vector_t vec(parameters[0]);
42763 
42764  std::size_t r0 = 0;
42765  std::size_t r1 = vec.size() - 1;
42766 
42767  if (
42768  (1 == ps_index) &&
42769  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42770  )
42771  {
42772  return std::numeric_limits<T>::quiet_NaN();
42773  }
42774 
42775  for (std::size_t i = r0; i <= r1; ++i)
42776  {
42777  if (vec[i] == T(0))
42778  {
42779  return T(0);
42780  }
42781  }
42782 
42783  return T(1);
42784  }
42785  };
42786 
42787  template <typename T>
42788  class all_false exprtk_final : public exprtk::igeneric_function<T>
42789  {
42790  public:
42791 
42796 
42797  using igfun_t::operator();
42798 
42800  : exprtk::igeneric_function<T>("V|VTT")
42801  /*
42802  Overloads:
42803  0. V - vector
42804  1. VTT - vector, r0, r1
42805  */
42806  {}
42807 
42808  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42809  {
42810  const vector_t vec(parameters[0]);
42811 
42812  std::size_t r0 = 0;
42813  std::size_t r1 = vec.size() - 1;
42814 
42815  if (
42816  (1 == ps_index) &&
42817  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42818  )
42819  {
42820  return std::numeric_limits<T>::quiet_NaN();
42821  }
42822 
42823  for (std::size_t i = r0; i <= r1; ++i)
42824  {
42825  if (vec[i] != T(0))
42826  {
42827  return T(0);
42828  }
42829  }
42830 
42831  return T(1);
42832  }
42833  };
42834 
42835  template <typename T>
42836  class any_true exprtk_final : public exprtk::igeneric_function<T>
42837  {
42838  public:
42839 
42844 
42845  using igfun_t::operator();
42846 
42848  : exprtk::igeneric_function<T>("V|VTT")
42849  /*
42850  Overloads:
42851  0. V - vector
42852  1. VTT - vector, r0, r1
42853  */
42854  {}
42855 
42856  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42857  {
42858  const vector_t vec(parameters[0]);
42859 
42860  std::size_t r0 = 0;
42861  std::size_t r1 = vec.size() - 1;
42862 
42863  if (
42864  (1 == ps_index) &&
42865  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42866  )
42867  {
42868  return std::numeric_limits<T>::quiet_NaN();
42869  }
42870 
42871  for (std::size_t i = r0; i <= r1; ++i)
42872  {
42873  if (vec[i] != T(0))
42874  {
42875  return T(1);
42876  }
42877  }
42878 
42879  return T(0);
42880  }
42881  };
42882 
42883  template <typename T>
42884  class any_false exprtk_final : public exprtk::igeneric_function<T>
42885  {
42886  public:
42887 
42892 
42893  using igfun_t::operator();
42894 
42896  : exprtk::igeneric_function<T>("V|VTT")
42897  /*
42898  Overloads:
42899  0. V - vector
42900  1. VTT - vector, r0, r1
42901  */
42902  {}
42903 
42904  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42905  {
42906  const vector_t vec(parameters[0]);
42907 
42908  std::size_t r0 = 0;
42909  std::size_t r1 = vec.size() - 1;
42910 
42911  if (
42912  (1 == ps_index) &&
42913  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42914  )
42915  {
42916  return std::numeric_limits<T>::quiet_NaN();
42917  }
42918 
42919  for (std::size_t i = r0; i <= r1; ++i)
42920  {
42921  if (vec[i] == T(0))
42922  {
42923  return T(1);
42924  }
42925  }
42926 
42927  return T(0);
42928  }
42929  };
42930 
42931  template <typename T>
42932  class count exprtk_final : public exprtk::igeneric_function<T>
42933  {
42934  public:
42935 
42940 
42941  using igfun_t::operator();
42942 
42944  : exprtk::igeneric_function<T>("V|VTT")
42945  /*
42946  Overloads:
42947  0. V - vector
42948  1. VTT - vector, r0, r1
42949  */
42950  {}
42951 
42952  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
42953  {
42954  const vector_t vec(parameters[0]);
42955 
42956  std::size_t r0 = 0;
42957  std::size_t r1 = vec.size() - 1;
42958 
42959  if (
42960  (1 == ps_index) &&
42961  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
42962  )
42963  {
42964  return std::numeric_limits<T>::quiet_NaN();
42965  }
42966 
42967  std::size_t cnt = 0;
42968 
42969  for (std::size_t i = r0; i <= r1; ++i)
42970  {
42971  if (vec[i] != T(0)) ++cnt;
42972  }
42973 
42974  return T(cnt);
42975  }
42976  };
42977 
42978  template <typename T>
42979  class copy exprtk_final : public exprtk::igeneric_function<T>
42980  {
42981  public:
42982 
42988 
42989  using igfun_t::operator();
42990 
42992  : exprtk::igeneric_function<T>("VV|VTTVTT")
42993  /*
42994  Overloads:
42995  0. VV - x(vector), y(vector)
42996  1. VTTVTT - x(vector), xr0, xr1, y(vector), yr0, yr1,
42997  */
42998  {}
42999 
43000  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43001  {
43002  const vector_t x(parameters[0]);
43003  vector_t y(parameters[(0 == ps_index) ? 1 : 3]);
43004 
43005  std::size_t xr0 = 0;
43006  std::size_t xr1 = x.size() - 1;
43007 
43008  std::size_t yr0 = 0;
43009  std::size_t yr1 = y.size() - 1;
43010 
43011  if (1 == ps_index)
43012  {
43013  if (
43014  !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) ||
43015  !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3)
43016  )
43017  return T(0);
43018  }
43019 
43020  const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1);
43021 
43022  std::copy(
43023  x.begin() + xr0,
43024  x.begin() + xr0 + n,
43025  y.begin() + yr0);
43026 
43027  return T(n);
43028  }
43029  };
43030 
43031  template <typename T>
43032  class rol exprtk_final : public exprtk::igeneric_function<T>
43033  {
43034  public:
43035 
43041 
43042  using igfun_t::operator();
43043 
43045  : exprtk::igeneric_function<T>("VT|VTTT")
43046  /*
43047  Overloads:
43048  0. VT - vector, N
43049  1. VTTT - vector, N, r0, r1
43050  */
43051  {}
43052 
43053  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43054  {
43055  vector_t vec(parameters[0]);
43056 
43057  std::size_t n = 0;
43058  std::size_t r0 = 0;
43059  std::size_t r1 = vec.size() - 1;
43060 
43061  if (!scalar_t(parameters[1]).to_uint(n))
43062  return T(0);
43063 
43064  if (
43065  (1 == ps_index) &&
43066  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43067  )
43068  return T(0);
43069 
43070  const std::size_t dist = r1 - r0 + 1;
43071  const std::size_t shift = n % dist;
43072 
43073  std::rotate(
43074  vec.begin() + r0,
43075  vec.begin() + r0 + shift,
43076  vec.begin() + r1 + 1);
43077 
43078  return T(1);
43079  }
43080  };
43081 
43082  template <typename T>
43083  class ror exprtk_final : public exprtk::igeneric_function<T>
43084  {
43085  public:
43086 
43092 
43093  using igfun_t::operator();
43094 
43096  : exprtk::igeneric_function<T>("VT|VTTT")
43097  /*
43098  Overloads:
43099  0. VT - vector, N
43100  1. VTTT - vector, N, r0, r1
43101  */
43102  {}
43103 
43104  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43105  {
43106  vector_t vec(parameters[0]);
43107 
43108  std::size_t n = 0;
43109  std::size_t r0 = 0;
43110  std::size_t r1 = vec.size() - 1;
43111 
43112  if (!scalar_t(parameters[1]).to_uint(n))
43113  return T(0);
43114 
43115  if (
43116  (1 == ps_index) &&
43117  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43118  )
43119  return T(0);
43120 
43121  const std::size_t dist = r1 - r0 + 1;
43122  const std::size_t shift = (dist - (n % dist)) % dist;
43123 
43124  std::rotate(
43125  vec.begin() + r0,
43126  vec.begin() + r0 + shift,
43127  vec.begin() + r1 + 1);
43128 
43129  return T(1);
43130  }
43131  };
43132 
43133  template <typename T>
43134  class shift_left exprtk_final : public exprtk::igeneric_function<T>
43135  {
43136  public:
43137 
43143 
43144  using igfun_t::operator();
43145 
43147  : exprtk::igeneric_function<T>("VT|VTTT")
43148  /*
43149  Overloads:
43150  0. VT - vector, N
43151  1. VTTT - vector, N, r0, r1
43152  */
43153  {}
43154 
43155  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43156  {
43157  vector_t vec(parameters[0]);
43158 
43159  std::size_t n = 0;
43160  std::size_t r0 = 0;
43161  std::size_t r1 = vec.size() - 1;
43162 
43163  if (!scalar_t(parameters[1]).to_uint(n))
43164  return T(0);
43165 
43166  if (
43167  (1 == ps_index) &&
43168  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43169  )
43170  return T(0);
43171 
43172  const std::size_t dist = r1 - r0 + 1;
43173 
43174  if (n > dist)
43175  return T(0);
43176 
43177  std::rotate(
43178  vec.begin() + r0,
43179  vec.begin() + r0 + n,
43180  vec.begin() + r1 + 1);
43181 
43182  for (std::size_t i = r1 - n + 1; i <= r1; ++i)
43183  {
43184  vec[i] = T(0);
43185  }
43186 
43187  return T(1);
43188  }
43189  };
43190 
43191  template <typename T>
43192  class shift_right exprtk_final : public exprtk::igeneric_function<T>
43193  {
43194  public:
43195 
43201 
43202  using igfun_t::operator();
43203 
43205  : exprtk::igeneric_function<T>("VT|VTTT")
43206  /*
43207  Overloads:
43208  0. VT - vector, N
43209  1. VTTT - vector, N, r0, r1
43210  */
43211  {}
43212 
43213  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43214  {
43215  vector_t vec(parameters[0]);
43216 
43217  std::size_t n = 0;
43218  std::size_t r0 = 0;
43219  std::size_t r1 = vec.size() - 1;
43220 
43221  if (!scalar_t(parameters[1]).to_uint(n))
43222  return T(0);
43223 
43224  if (
43225  (1 == ps_index) &&
43226  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43227  )
43228  return T(0);
43229 
43230  const std::size_t dist = r1 - r0 + 1;
43231 
43232  if (n > dist)
43233  return T(0);
43234 
43235  const std::size_t shift = (dist - (n % dist)) % dist;
43236 
43237  std::rotate(
43238  vec.begin() + r0,
43239  vec.begin() + r0 + shift,
43240  vec.begin() + r1 + 1);
43241 
43242  for (std::size_t i = r0; i < r0 + n; ++i)
43243  {
43244  vec[i] = T(0);
43245  }
43246 
43247  return T(1);
43248  }
43249  };
43250 
43251  template <typename T>
43252  class sort exprtk_final : public exprtk::igeneric_function<T>
43253  {
43254  public:
43255 
43261 
43262  using igfun_t::operator();
43263 
43265  : exprtk::igeneric_function<T>("V|VTT|VS|VSTT")
43266  /*
43267  Overloads:
43268  0. V - vector
43269  1. VTT - vector, r0, r1
43270  2. VS - vector, string
43271  3. VSTT - vector, string, r0, r1
43272  */
43273  {}
43274 
43275  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43276  {
43277  vector_t vec(parameters[0]);
43278 
43279  std::size_t r0 = 0;
43280  std::size_t r1 = vec.size() - 1;
43281 
43282  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
43283  return T(0);
43284  if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43285  return T(0);
43286 
43287  bool ascending = true;
43288 
43289  if ((2 == ps_index) || (3 == ps_index))
43290  {
43291  if (exprtk::details::imatch(to_str(string_t(parameters[1])),"ascending"))
43292  ascending = true;
43293  else if (exprtk::details::imatch(to_str(string_t(parameters[1])),"descending"))
43294  ascending = false;
43295  else
43296  return T(0);
43297  }
43298 
43299  if (ascending)
43300  std::sort(
43301  vec.begin() + r0,
43302  vec.begin() + r1 + 1,
43303  std::less<T>());
43304  else
43305  std::sort(
43306  vec.begin() + r0,
43307  vec.begin() + r1 + 1,
43308  std::greater<T>());
43309 
43310  return T(1);
43311  }
43312  };
43313 
43314  template <typename T>
43315  class nthelement exprtk_final : public exprtk::igeneric_function<T>
43316  {
43317  public:
43318 
43324 
43325  using igfun_t::operator();
43326 
43328  : exprtk::igeneric_function<T>("VT|VTTT")
43329  /*
43330  Overloads:
43331  0. VT - vector, nth-element
43332  1. VTTT - vector, nth-element, r0, r1
43333  */
43334  {}
43335 
43336  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43337  {
43338  vector_t vec(parameters[0]);
43339 
43340  std::size_t n = 0;
43341  std::size_t r0 = 0;
43342  std::size_t r1 = vec.size() - 1;
43343 
43344  if (!scalar_t(parameters[1]).to_uint(n))
43345  return T(0);
43346 
43347  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43348  {
43349  return std::numeric_limits<T>::quiet_NaN();
43350  }
43351 
43352  std::nth_element(
43353  vec.begin() + r0,
43354  vec.begin() + r0 + n ,
43355  vec.begin() + r1 + 1);
43356 
43357  return T(1);
43358  }
43359  };
43360 
43361  template <typename T>
43362  class assign exprtk_final : public exprtk::igeneric_function<T>
43363  {
43364  public:
43365 
43371 
43372  using igfun_t::operator();
43373 
43375  : exprtk::igeneric_function<T>("VT|VTTT|VTTTT")
43376  /*
43377  Overloads:
43378  0. VT - vector, V
43379  1. VTTT - vector, V, r0, r1
43380  2. VTTTT - vector, V, r0, r1, SS
43381  */
43382  {}
43383 
43384  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43385  {
43386  vector_t vec(parameters[0]);
43387 
43388  const T assign_value = scalar_t(parameters[1]);
43389 
43390  const std::size_t step_size = (2 != ps_index) ? 1 :
43391  static_cast<std::size_t>(scalar_t(parameters.back())());
43392 
43393  std::size_t r0 = 0;
43394  std::size_t r1 = vec.size() - 1;
43395 
43396  if (
43397  ((ps_index == 1) || (ps_index == 2)) &&
43398  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
43399  )
43400  {
43401  return T(0);
43402  }
43403 
43404  for (std::size_t i = r0; i <= r1; i += step_size)
43405  {
43406  vec[i] = assign_value;
43407  }
43408 
43409  return T(1);
43410  }
43411  };
43412 
43413  template <typename T>
43414  class iota exprtk_final : public exprtk::igeneric_function<T>
43415  {
43416  public:
43417 
43423 
43424  using igfun_t::operator();
43425 
43427  : exprtk::igeneric_function<T>("VTT|VT|VTTTT|VTTT")
43428  /*
43429  Overloads:
43430  0. VTT - vector, SV, SS
43431  1. VT - vector, SV, SS (+1)
43432  2. VTTT - vector, r0, r1, SV, SS
43433  3. VTT - vector, r0, r1, SV, SS (+1)
43434 
43435  Where:
43436  1. SV - Start value
43437  2. SS - Step size
43438  */
43439  {}
43440 
43441  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43442  {
43443  vector_t vec(parameters[0]);
43444 
43445  const T start_value = (ps_index <= 1) ?
43446  scalar_t(parameters[1]) :
43447  scalar_t(parameters[3]) ;
43448 
43449  const T step_size = ((0 == ps_index) || (2 == ps_index)) ?
43450  scalar_t(parameters.back())() :
43451  T(1) ;
43452 
43453  std::size_t r0 = 0;
43454  std::size_t r1 = vec.size() - 1;
43455 
43456  if (
43457  ((ps_index == 2) || (ps_index == 3)) &&
43458  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
43459  )
43460  {
43461  return T(0);
43462  }
43463 
43464  for (std::size_t i = r0; i <= r1; ++i)
43465  {
43466  vec[i] = start_value + ((i - r0) * step_size);
43467  }
43468 
43469  return T(1);
43470  }
43471  };
43472 
43473  template <typename T>
43474  class sumk exprtk_final : public exprtk::igeneric_function<T>
43475  {
43476  public:
43477 
43483 
43484  using igfun_t::operator();
43485 
43487  : exprtk::igeneric_function<T>("V|VTT|VTTT")
43488  /*
43489  Overloads:
43490  0. V - vector
43491  1. VTT - vector, r0, r1
43492  2. VTTT - vector, r0, r1, stride
43493  */
43494  {}
43495 
43496  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43497  {
43498  const vector_t vec(parameters[0]);
43499 
43500  const std::size_t stride = (2 != ps_index) ? 1 :
43501  static_cast<std::size_t>(scalar_t(parameters[3])());
43502 
43503  std::size_t r0 = 0;
43504  std::size_t r1 = vec.size() - 1;
43505 
43506  if (
43507  ((1 == ps_index) || (2 == ps_index)) &&
43508  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
43509  )
43510  {
43511  return std::numeric_limits<T>::quiet_NaN();
43512  }
43513 
43514  T result = T(0);
43515  T error = T(0);
43516 
43517  for (std::size_t i = r0; i <= r1; i += stride)
43518  {
43519  details::kahan_sum(result, error, vec[i]);
43520  }
43521 
43522  return result;
43523  }
43524  };
43525 
43526  template <typename T>
43527  class axpy exprtk_final : public exprtk::igeneric_function<T>
43528  {
43529  public:
43530 
43536 
43537  using igfun_t::operator();
43538 
43540  : exprtk::igeneric_function<T>("TVV|TVVTT")
43541  /*
43542  y <- ax + y
43543  Overloads:
43544  0. TVV - a, x(vector), y(vector)
43545  1. TVVTT - a, x(vector), y(vector), r0, r1
43546  */
43547  {}
43548 
43549  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43550  {
43551  const vector_t x(parameters[1]);
43552  vector_t y(parameters[2]);
43553 
43554  std::size_t r0 = 0;
43555  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43556 
43557  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
43558  return std::numeric_limits<T>::quiet_NaN();
43559  else if (helper::invalid_range(y, r0, r1))
43560  return std::numeric_limits<T>::quiet_NaN();
43561 
43562  const T a = scalar_t(parameters[0])();
43563 
43564  for (std::size_t i = r0; i <= r1; ++i)
43565  {
43566  y[i] = (a * x[i]) + y[i];
43567  }
43568 
43569  return T(1);
43570  }
43571  };
43572 
43573  template <typename T>
43574  class axpby exprtk_final : public exprtk::igeneric_function<T>
43575  {
43576  public:
43577 
43583 
43584  using igfun_t::operator();
43585 
43587  : exprtk::igeneric_function<T>("TVTV|TVTVTT")
43588  /*
43589  y <- ax + by
43590  Overloads:
43591  0. TVTV - a, x(vector), b, y(vector)
43592  1. TVTVTT - a, x(vector), b, y(vector), r0, r1
43593  */
43594  {}
43595 
43596  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43597  {
43598  const vector_t x(parameters[1]);
43599  vector_t y(parameters[3]);
43600 
43601  std::size_t r0 = 0;
43602  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43603 
43604  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
43605  return std::numeric_limits<T>::quiet_NaN();
43606  else if (helper::invalid_range(y, r0, r1))
43607  return std::numeric_limits<T>::quiet_NaN();
43608 
43609  const T a = scalar_t(parameters[0])();
43610  const T b = scalar_t(parameters[2])();
43611 
43612  for (std::size_t i = r0; i <= r1; ++i)
43613  {
43614  y[i] = (a * x[i]) + (b * y[i]);
43615  }
43616 
43617  return T(1);
43618  }
43619  };
43620 
43621  template <typename T>
43622  class axpyz exprtk_final : public exprtk::igeneric_function<T>
43623  {
43624  public:
43625 
43631 
43632  using igfun_t::operator();
43633 
43635  : exprtk::igeneric_function<T>("TVVV|TVVVTT")
43636  /*
43637  z <- ax + y
43638  Overloads:
43639  0. TVVV - a, x(vector), y(vector), z(vector)
43640  1. TVVVTT - a, x(vector), y(vector), z(vector), r0, r1
43641  */
43642  {}
43643 
43644  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43645  {
43646  const vector_t x(parameters[1]);
43647  const vector_t y(parameters[2]);
43648  vector_t z(parameters[3]);
43649 
43650  std::size_t r0 = 0;
43651  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43652 
43653  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
43654  return std::numeric_limits<T>::quiet_NaN();
43655  else if (helper::invalid_range(y, r0, r1))
43656  return std::numeric_limits<T>::quiet_NaN();
43657  else if (helper::invalid_range(z, r0, r1))
43658  return std::numeric_limits<T>::quiet_NaN();
43659 
43660  const T a = scalar_t(parameters[0])();
43661 
43662  for (std::size_t i = r0; i <= r1; ++i)
43663  {
43664  z[i] = (a * x[i]) + y[i];
43665  }
43666 
43667  return T(1);
43668  }
43669  };
43670 
43671  template <typename T>
43672  class axpbyz exprtk_final : public exprtk::igeneric_function<T>
43673  {
43674  public:
43675 
43681 
43682  using igfun_t::operator();
43683 
43685  : exprtk::igeneric_function<T>("TVTVV|TVTVVTT")
43686  /*
43687  z <- ax + by
43688  Overloads:
43689  0. TVTVV - a, x(vector), b, y(vector), z(vector)
43690  1. TVTVVTT - a, x(vector), b, y(vector), z(vector), r0, r1
43691  */
43692  {}
43693 
43694  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43695  {
43696  const vector_t x(parameters[1]);
43697  const vector_t y(parameters[3]);
43698  vector_t z(parameters[4]);
43699 
43700  std::size_t r0 = 0;
43701  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43702 
43703  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
43704  return std::numeric_limits<T>::quiet_NaN();
43705  else if (helper::invalid_range(y, r0, r1))
43706  return std::numeric_limits<T>::quiet_NaN();
43707  else if (helper::invalid_range(z, r0, r1))
43708  return std::numeric_limits<T>::quiet_NaN();
43709 
43710  const T a = scalar_t(parameters[0])();
43711  const T b = scalar_t(parameters[2])();
43712 
43713  for (std::size_t i = r0; i <= r1; ++i)
43714  {
43715  z[i] = (a * x[i]) + (b * y[i]);
43716  }
43717 
43718  return T(1);
43719  }
43720  };
43721 
43722  template <typename T>
43723  class axpbsy exprtk_final : public exprtk::igeneric_function<T>
43724  {
43725  public:
43726 
43732 
43733  using igfun_t::operator();
43734 
43736  : exprtk::igeneric_function<T>("TVTTV|TVTTVTT")
43737  /*
43738  y <- ax + by
43739  Overloads:
43740  0. TVTVV - a, x(vector), b, shift, y(vector), z(vector)
43741  1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
43742  */
43743  {}
43744 
43745  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43746  {
43747  const vector_t x(parameters[1]);
43748  vector_t y(parameters[4]);
43749 
43750  std::size_t r0 = 0;
43751  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43752 
43753  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1))
43754  return std::numeric_limits<T>::quiet_NaN();
43755  else if (helper::invalid_range(y, r0, r1))
43756  return std::numeric_limits<T>::quiet_NaN();
43757 
43758  const T a = scalar_t(parameters[0])();
43759  const T b = scalar_t(parameters[2])();
43760 
43761  const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
43762 
43763  for (std::size_t i = r0; i <= r1; ++i)
43764  {
43765  y[i] = (a * x[i]) + (b * y[i + s]);
43766  }
43767 
43768  return T(1);
43769  }
43770  };
43771 
43772  template <typename T>
43773  class axpbsyz exprtk_final : public exprtk::igeneric_function<T>
43774  {
43775  public:
43776 
43782 
43783  using igfun_t::operator();
43784 
43786  : exprtk::igeneric_function<T>("TVTTVV|TVTTVVTT")
43787  /*
43788  z <- ax + by
43789  Overloads:
43790  0. TVTVV - a, x(vector), b, shift, y(vector), z(vector)
43791  1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1
43792  */
43793  {}
43794 
43795  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43796  {
43797  const vector_t x(parameters[1]);
43798  const vector_t y(parameters[4]);
43799  vector_t z(parameters[5]);
43800 
43801  std::size_t r0 = 0;
43802  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43803 
43804  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1))
43805  return std::numeric_limits<T>::quiet_NaN();
43806  else if (helper::invalid_range(y, r0, r1))
43807  return std::numeric_limits<T>::quiet_NaN();
43808  else if (helper::invalid_range(z, r0, r1))
43809  return std::numeric_limits<T>::quiet_NaN();
43810 
43811  const T a = scalar_t(parameters[0])();
43812  const T b = scalar_t(parameters[2])();
43813 
43814  const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])());
43815 
43816  for (std::size_t i = r0; i <= r1; ++i)
43817  {
43818  z[i] = (a * x[i]) + (b * y[i + s]);
43819  }
43820 
43821  return T(1);
43822  }
43823  };
43824 
43825  template <typename T>
43826  class axpbz exprtk_final : public exprtk::igeneric_function<T>
43827  {
43828  public:
43829 
43835 
43836  using igfun_t::operator();
43837 
43839  : exprtk::igeneric_function<T>("TVTV|TVTVTT")
43840  /*
43841  z <- ax + b
43842  Overloads:
43843  0. TVTV - a, x(vector), b, z(vector)
43844  1. TVTVTT - a, x(vector), b, z(vector), r0, r1
43845  */
43846  {}
43847 
43848  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43849  {
43850  const vector_t x(parameters[1]);
43851  vector_t z(parameters[3]);
43852 
43853  std::size_t r0 = 0;
43854  std::size_t r1 = x.size() - 1;
43855 
43856  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
43857  return std::numeric_limits<T>::quiet_NaN();
43858  else if (helper::invalid_range(z, r0, r1))
43859  return std::numeric_limits<T>::quiet_NaN();
43860 
43861  const T a = scalar_t(parameters[0])();
43862  const T b = scalar_t(parameters[2])();
43863 
43864  for (std::size_t i = r0; i <= r1; ++i)
43865  {
43866  z[i] = (a * x[i]) + b;
43867  }
43868 
43869  return T(1);
43870  }
43871  };
43872 
43873  template <typename T>
43874  class diff exprtk_final : public exprtk::igeneric_function<T>
43875  {
43876  public:
43877 
43883 
43884  using igfun_t::operator();
43885 
43887  : exprtk::igeneric_function<T>("VV|VVT")
43888  /*
43889  x_(i - stride) - x_i
43890  Overloads:
43891  0. VV - x(vector), y(vector)
43892  1. VVT - x(vector), y(vector), stride
43893  */
43894  {}
43895 
43896  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43897  {
43898  const vector_t x(parameters[0]);
43899  vector_t y(parameters[1]);
43900 
43901  const std::size_t r0 = 0;
43902  const std::size_t r1 = std::min(x.size(),y.size()) - 1;
43903 
43904  const std::size_t stride = (1 != ps_index) ? 1 :
43905  std::min(r1,static_cast<std::size_t>(scalar_t(parameters[2])()));
43906 
43907  for (std::size_t i = 0; i < stride; ++i)
43908  {
43909  y[i] = std::numeric_limits<T>::quiet_NaN();
43910  }
43911 
43912  for (std::size_t i = (r0 + stride); i <= r1; ++i)
43913  {
43914  y[i] = x[i] - x[i - stride];
43915  }
43916 
43917  return T(1);
43918  }
43919  };
43920 
43921  template <typename T>
43922  class dot exprtk_final : public exprtk::igeneric_function<T>
43923  {
43924  public:
43925 
43931 
43932  using igfun_t::operator();
43933 
43935  : exprtk::igeneric_function<T>("VV|VVTT")
43936  /*
43937  Overloads:
43938  0. VV - x(vector), y(vector)
43939  1. VVTT - x(vector), y(vector), r0, r1
43940  */
43941  {}
43942 
43943  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43944  {
43945  const vector_t x(parameters[0]);
43946  const vector_t y(parameters[1]);
43947 
43948  std::size_t r0 = 0;
43949  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43950 
43951  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43952  return std::numeric_limits<T>::quiet_NaN();
43953  else if (helper::invalid_range(y, r0, r1))
43954  return std::numeric_limits<T>::quiet_NaN();
43955 
43956  T result = T(0);
43957 
43958  for (std::size_t i = r0; i <= r1; ++i)
43959  {
43960  result += (x[i] * y[i]);
43961  }
43962 
43963  return result;
43964  }
43965  };
43966 
43967  template <typename T>
43968  class dotk exprtk_final : public exprtk::igeneric_function<T>
43969  {
43970  public:
43971 
43977 
43978  using igfun_t::operator();
43979 
43981  : exprtk::igeneric_function<T>("VV|VVTT")
43982  /*
43983  Overloads:
43984  0. VV - x(vector), y(vector)
43985  1. VVTT - x(vector), y(vector), r0, r1
43986  */
43987  {}
43988 
43989  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
43990  {
43991  const vector_t x(parameters[0]);
43992  const vector_t y(parameters[1]);
43993 
43994  std::size_t r0 = 0;
43995  std::size_t r1 = std::min(x.size(),y.size()) - 1;
43996 
43997  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
43998  return std::numeric_limits<T>::quiet_NaN();
43999  else if (helper::invalid_range(y, r0, r1))
44000  return std::numeric_limits<T>::quiet_NaN();
44001 
44002  T result = T(0);
44003  T error = T(0);
44004 
44005  for (std::size_t i = r0; i <= r1; ++i)
44006  {
44007  details::kahan_sum(result, error, (x[i] * y[i]));
44008  }
44009 
44010  return result;
44011  }
44012  };
44013 
44014  template <typename T>
44015  class threshold_below exprtk_final : public exprtk::igeneric_function<T>
44016  {
44017  public:
44018 
44024 
44025  using igfun_t::operator();
44026 
44028  : exprtk::igeneric_function<T>("VTT|VTTTT")
44029  /*
44030  Overloads:
44031  0. VTT - vector, TV, SV
44032  1. VTTTT - vector, r0, r1, TV, SV
44033 
44034  Where:
44035  TV - Threshold value
44036  SV - Snap-to value
44037  */
44038  {}
44039 
44040  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44041  {
44042  vector_t vec(parameters[0]);
44043 
44044  const T threshold_value = (0 == ps_index) ?
44045  scalar_t(parameters[1]) :
44046  scalar_t(parameters[3]) ;
44047 
44048  const T snap_value = scalar_t(parameters.back());
44049 
44050  std::size_t r0 = 0;
44051  std::size_t r1 = vec.size() - 1;
44052 
44053  if (
44054  (1 == ps_index) &&
44055  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44056  )
44057  {
44058  return T(0);
44059  }
44060 
44061  for (std::size_t i = r0; i <= r1; ++i)
44062  {
44063  if (vec[i] < threshold_value)
44064  {
44065  vec[i] = snap_value;
44066  }
44067  }
44068 
44069  return T(1);
44070  }
44071  };
44072 
44073  template <typename T>
44074  class threshold_above exprtk_final : public exprtk::igeneric_function<T>
44075  {
44076  public:
44077 
44083 
44084  using igfun_t::operator();
44085 
44087  : exprtk::igeneric_function<T>("VTT|VTTTT")
44088  /*
44089  Overloads:
44090  0. VTT - vector, TV, SV
44091  1. VTTTT - vector, r0, r1, TV, SV
44092 
44093  Where:
44094  TV - Threshold value
44095  SV - Snap-to value
44096  */
44097  {}
44098 
44099  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override
44100  {
44101  vector_t vec(parameters[0]);
44102 
44103  const T threshold_value = (0 == ps_index) ?
44104  scalar_t(parameters[1]) :
44105  scalar_t(parameters[3]) ;
44106 
44107  const T snap_value = scalar_t(parameters.back());
44108 
44109  std::size_t r0 = 0;
44110  std::size_t r1 = vec.size() - 1;
44111 
44112  if (
44113  (1 == ps_index) &&
44114  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
44115  )
44116  {
44117  return T(0);
44118  }
44119 
44120  for (std::size_t i = r0; i <= r1; ++i)
44121  {
44122  if (vec[i] > threshold_value)
44123  {
44124  vec[i] = snap_value;
44125  }
44126  }
44127 
44128  return T(1);
44129  }
44130  };
44131 
44132  template <typename T>
44133  struct package
44134  {
44135  all_true <T> at;
44136  all_false <T> af;
44137  any_true <T> nt;
44138  any_false <T> nf;
44139  count <T> c;
44140  copy <T> cp;
44141  rol <T> rl;
44142  ror <T> rr;
44143  shift_left <T> sl;
44144  shift_right <T> sr;
44145  sort <T> st;
44146  nthelement <T> ne;
44147  assign <T> an;
44148  iota <T> ia;
44149  sumk <T> sk;
44150  axpy <T> b1_axpy;
44151  axpby <T> b1_axpby;
44152  axpyz <T> b1_axpyz;
44153  axpbyz <T> b1_axpbyz;
44154  axpbsy <T> b1_axpbsy;
44155  axpbsyz <T> b1_axpbsyz;
44156  axpbz <T> b1_axpbz;
44157  diff <T> df;
44158  dot <T> dt;
44159  dotk <T> dtk;
44160  threshold_above<T> ta;
44161  threshold_below<T> tb;
44162 
44164  {
44165  #define exprtk_register_function(FunctionName, FunctionType) \
44166  if (!symtab.add_function(FunctionName,FunctionType)) \
44167  { \
44168  exprtk_debug(( \
44169  "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
44170  FunctionName)); \
44171  return false; \
44172  } \
44173 
44174  exprtk_register_function("all_true" , at )
44175  exprtk_register_function("all_false" , af )
44176  exprtk_register_function("any_true" , nt )
44177  exprtk_register_function("any_false" , nf )
44178  exprtk_register_function("count" , c )
44179  exprtk_register_function("copy" , cp )
44180  exprtk_register_function("rotate_left" , rl )
44181  exprtk_register_function("rol" , rl )
44182  exprtk_register_function("rotate_right" , rr )
44183  exprtk_register_function("ror" , rr )
44184  exprtk_register_function("shftl" , sl )
44185  exprtk_register_function("shftr" , sr )
44186  exprtk_register_function("sort" , st )
44187  exprtk_register_function("nth_element" , ne )
44188  exprtk_register_function("assign" , an )
44189  exprtk_register_function("iota" , ia )
44190  exprtk_register_function("sumk" , sk )
44194  exprtk_register_function("axpbyz" , b1_axpbyz )
44195  exprtk_register_function("axpbsy" , b1_axpbsy )
44198  exprtk_register_function("diff" , df )
44199  exprtk_register_function("dot" , dt )
44200  exprtk_register_function("dotk" , dtk )
44201  exprtk_register_function("threshold_above" , ta )
44202  exprtk_register_function("threshold_below" , tb )
44203  #undef exprtk_register_function
44204 
44205  return true;
44206  }
44207  };
44208 
44209  } // namespace exprtk::rtl::vecops
44210  } // namespace exprtk::rtl
44211 } // namespace exprtk
44212 #endif
44213 
44214 namespace exprtk
44215 {
44216  namespace information
44217  {
44219 
44220  static char_cptr library = "Mathematical Expression Toolkit";
44221  static char_cptr version = "2.718281828459045235360287471352662"
44222  "49775724709369995957496696762772407"
44223  "66303535475945713821785251664274274"
44224  "66391932003059921817413596629043572";
44225  static char_cptr date = "20240101";
44226  static char_cptr min_cpp = "199711L";
44227 
44228  static inline std::string data()
44229  {
44230  static const std::string info_str = std::string(library) +
44231  std::string(" v") + std::string(version) +
44232  std::string(" (") + date + std::string(")") +
44233  std::string(" (") + min_cpp + std::string(")");
44234  return info_str;
44235  }
44236 
44237  } // namespace information
44238 
44239  #ifdef exprtk_debug
44240  #undef exprtk_debug
44241  #endif
44242 
44243  #ifdef exprtk_error_location
44244  #undef exprtk_error_location
44245  #endif
44246 
44247  #ifdef exprtk_fallthrough
44248  #undef exprtk_fallthrough
44249  #endif
44250 
44251  #ifdef exprtk_override
44252  #undef exprtk_override
44253  #endif
44254 
44255  #ifdef exprtk_final
44256  #undef exprtk_final
44257  #endif
44258 
44259  #ifdef exprtk_delete
44260  #undef exprtk_delete
44261  #endif
44262 
44263 } // namespace exprtk
44264 
44265 #endif
#define register_sf4(Op)
#define basic_opr_switch_statements
Definition: Exprtk.hpp:33277
#define register_binary_op(Op, BinaryFunctor)
#define define_sfop4(NN, OP0, OP1)
#define exprtk_final
Definition: Exprtk.hpp:78
#define case_stmt(N)
Definition: Exprtk.hpp:31352
#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:1631
#define register_synthezier(S)
#define exprtk_define_process(Type)
Definition: Exprtk.hpp:19299
#define empty_method_body(N)
Definition: Exprtk.hpp:18873
#define exprtk_crtype(Type)
Definition: Exprtk.hpp:16318
#define case_stmt0(op)
#define parse_digit_1(d)
#define poly_rtrn(NN)
Definition: Exprtk.hpp:40917
#define parse_digit_2(d)
#define igeneric_function_empty_body(N)
Definition: Exprtk.hpp:18996
#define register_sf4ext(Op)
#define vector_ops
#define exprtk_register_int_type_tag(T)
Definition: Exprtk.hpp:837
#define def_fp_retval(N)
Definition: Exprtk.hpp:41520
#define extended_opr_switch_statements
Definition: Exprtk.hpp:33285
#define exprtk_override
Definition: Exprtk.hpp:77
#define exprtk_debug(params)
Definition: Exprtk.hpp:66
#define exprtk_error_location
Definition: Exprtk.hpp:69
#define string_opr_switch_statements
Definition: Exprtk.hpp:39190
#define register_op(Symbol, Type, Args)
#define exprtk_assign(Index)
Definition: Exprtk.hpp:41180
#define exprtk_define_freefunction(NN)
Definition: Exprtk.hpp:20185
#define unary_opr_switch_statements
Definition: Exprtk.hpp:31506
#define register_sf3_extid(Id, Op)
#define exprtk_fallthrough
Definition: Exprtk.hpp:85
#define token_inserter_empty_body
Definition: Exprtk.hpp:3249
#define register_sf3(Op)
#define exprtk_loop(N)
#define batch_eqineq_logic_case
#define exprtk_delete
Definition: Exprtk.hpp:79
Definition: Exprtk.hpp:16115
virtual std::string type_id() const =0
virtual ~T0oT1oT2_base_node()
Definition: Exprtk.hpp:16118
Definition: Exprtk.hpp:16126
virtual std::string type_id() const =0
virtual ~T0oT1oT2oT3_base_node()
Definition: Exprtk.hpp:16129
Definition: Exprtk.hpp:6831
operator_type operation_
Definition: Exprtk.hpp:6891
T value() const exprtk_override
Definition: Exprtk.hpp:6846
binary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:6837
bool valid() const exprtk_override
Definition: Exprtk.hpp:6872
std::size_t node_depth() const exprtk_final
Definition: Exprtk.hpp:6884
expression_node< T > * branch(const std::size_t &index=0) const exprtk_override
Definition: Exprtk.hpp:6866
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:6856
operator_type operation()
Definition: Exprtk.hpp:6861
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:6834
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:6879
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:6835
Definition: Exprtk.hpp:16051
virtual ~boc_base_node()
Definition: Exprtk.hpp:16054
virtual operator_type operation() const
Definition: Exprtk.hpp:16057
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
Definition: Exprtk.hpp:16020
virtual const T & v() const =0
virtual ~bov_base_node()
Definition: Exprtk.hpp:16023
Definition: Exprtk.hpp:7193
T value
Definition: Exprtk.hpp:7200
break_exception(const T &v)
Definition: Exprtk.hpp:7196
Definition: Exprtk.hpp:394
build_string & operator<<(const std::string &s)
Definition: Exprtk.hpp:402
build_string(const std::size_t &initial_size=64)
Definition: Exprtk.hpp:397
std::string as_string() const
Definition: Exprtk.hpp:419
std::string data_
Definition: Exprtk.hpp:426
Definition: Exprtk.hpp:16031
virtual const T c() const =0
virtual expression_node< T > * move_branch(const std::size_t &index)=0
virtual ~cob_base_node()
Definition: Exprtk.hpp:16034
virtual operator_type operation() const
Definition: Exprtk.hpp:16037
virtual void set_c(const T)=0
Definition: Exprtk.hpp:7203
Definition: Exprtk.hpp:15973
virtual const T c() const =0
virtual const T & v() const =0
virtual operator_type operation() const
Definition: Exprtk.hpp:15979
virtual ~cov_base_node()
Definition: Exprtk.hpp:15976
Definition: Exprtk.hpp:5465
virtual T value() const
Definition: Exprtk.hpp:5519
virtual node_type type() const
Definition: Exprtk.hpp:5529
nci_t::noderef_list_t noderef_list_t
Definition: Exprtk.hpp:5513
node_type
Definition: Exprtk.hpp:5469
@ e_bov
Definition: Exprtk.hpp:5495
@ e_constant
Definition: Exprtk.hpp:5470
@ e_cstringvarrng
Definition: Exprtk.hpp:5475
@ e_rbvecelem
Definition: Exprtk.hpp:5502
@ e_cot
Definition: Exprtk.hpp:5491
@ e_exp
Definition: Exprtk.hpp:5487
@ e_nor
Definition: Exprtk.hpp:5482
@ e_covocov
Definition: Exprtk.hpp:5499
@ e_veccelem
Definition: Exprtk.hpp:5501
@ e_frac
Definition: Exprtk.hpp:5494
@ e_abs
Definition: Exprtk.hpp:5484
@ e_for
Definition: Exprtk.hpp:5473
@ e_log10
Definition: Exprtk.hpp:5488
@ e_ilike
Definition: Exprtk.hpp:5483
@ e_rbveccelem
Definition: Exprtk.hpp:5503
@ e_erf
Definition: Exprtk.hpp:5493
@ e_function
Definition: Exprtk.hpp:5477
@ e_vecfunc
Definition: Exprtk.hpp:5504
@ e_covoc
Definition: Exprtk.hpp:5497
@ e_binary
Definition: Exprtk.hpp:5471
@ e_d2g
Definition: Exprtk.hpp:5492
@ e_valvecineq
Definition: Exprtk.hpp:5505
@ e_pos
Definition: Exprtk.hpp:5489
@ e_boc
Definition: Exprtk.hpp:5496
@ e_add
Definition: Exprtk.hpp:5478
@ e_gt
Definition: Exprtk.hpp:5480
@ e_and
Definition: Exprtk.hpp:5481
@ e_acosh
Definition: Exprtk.hpp:5485
@ e_atanh
Definition: Exprtk.hpp:5486
@ e_conditional
Definition: Exprtk.hpp:5472
@ e_stringsize
Definition: Exprtk.hpp:5476
@ e_retenv
Definition: Exprtk.hpp:5474
@ e_covovov
Definition: Exprtk.hpp:5498
@ e_sinh
Definition: Exprtk.hpp:5490
@ e_div
Definition: Exprtk.hpp:5479
@ e_break
Definition: Exprtk.hpp:5507
@ e_valvecarith
Definition: Exprtk.hpp:5506
@ e_nulleq
Definition: Exprtk.hpp:5500
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:5511
node_depth_base< expression_node< T > > ndb_t
Definition: Exprtk.hpp:5514
node_collector_interface< expression_node< T > > nci_t
Definition: Exprtk.hpp:5512
virtual bool valid() const
Definition: Exprtk.hpp:5534
virtual expression_node< T > * branch(const std::size_t &index=0) const
Definition: Exprtk.hpp:5524
T value_type
Definition: Exprtk.hpp:5510
virtual ~expression_node()
Definition: Exprtk.hpp:5516
Definition: Exprtk.hpp:6511
std::size_t base_size() const exprtk_override
Definition: Exprtk.hpp:8414
assignment_string_range_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:10545
swap_generic_node(expression_ptr var0, expression_ptr var1)
Definition: Exprtk.hpp:9377
while_loop_node< T > parent_t
Definition: Exprtk.hpp:7377
ufunc_t u0()
Definition: Exprtk.hpp:16215
ProcessMode process_mode_t
Definition: Exprtk.hpp:16626
functor_t::ufunc_t ufunc_t
Definition: Exprtk.hpp:16183
~conditional_vector_node()
Definition: Exprtk.hpp:13584
const std::size_t max_vector_index_
Definition: Exprtk.hpp:8756
const T & v_
Definition: Exprtk.hpp:16172
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2)
Definition: Exprtk.hpp:16959
results_context_t * results_context_
Definition: Exprtk.hpp:14663
std::string & s1()
Definition: Exprtk.hpp:17634
static T process_3(const Sequence &arg_list)
Definition: Exprtk.hpp:15138
ipow_node< T, PowOp > & operator=(const ipow_node< T, PowOp > &) exprtk_delete
assignment_vecvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11987
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:8665
range_t & range_ref()
Definition: Exprtk.hpp:10925
bool initialised_
Definition: Exprtk.hpp:9516
const T & v0() const exprtk_override
Definition: Exprtk.hpp:17227
variable_node< T > * variable_node_ptr
Definition: Exprtk.hpp:9345
unary_branch_node(expression_ptr branch)
Definition: Exprtk.hpp:16251
bov_node< T, Operation > & operator=(const bov_node< T, Operation > &) exprtk_delete
T0oT1oT2oT3(const node_type &) exprtk_delete
generic_string_range_node(expression_ptr str_branch, const range_t &brange)
Definition: Exprtk.hpp:9789
std::vector< branch_t > arg_list_
Definition: Exprtk.hpp:8092
range_t * range_ptr
Definition: Exprtk.hpp:9784
repeat_until_loop_bc_node< T > parent_t
Definition: Exprtk.hpp:7752
memory_context_t< T > memory_context
Definition: Exprtk.hpp:12837
bfunc_t f() const
Definition: Exprtk.hpp:16592
vec_binop_valvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:13208
str_vararg_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:10978
ivariable_ptr var1_
Definition: Exprtk.hpp:9397
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:7586
const T c() const exprtk_override
Definition: Exprtk.hpp:17277
variable_node_ptr var0_
Definition: Exprtk.hpp:9365
bool * retinvk_ptr()
Definition: Exprtk.hpp:14710
RangePack rp1_
Definition: Exprtk.hpp:17776
T0oT1oT2oT3_sf4(const node_type &) exprtk_delete
bipow_node< T, PowOp > & operator=(const bipow_node< T, PowOp > &) exprtk_delete
ipowinv_node< T, PowOp > & operator=(const ipowinv_node< T, PowOp > &) exprtk_delete
rebasevector_celem_node(expression_ptr vec_node, const std::size_t index, vector_holder_ptr vec_holder)
Definition: Exprtk.hpp:8955
assignment_rebasevec_elem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11733
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:6519
T0oT1oT2< T, T0, T1, T2, ProcessMode > node_type
Definition: Exprtk.hpp:16625
cov_node< T, Operation > & operator=(const cov_node< T, Operation > &) exprtk_delete
const T & v1()
Definition: Exprtk.hpp:16210
static T process_7(const Sequence &arg_list)
Definition: Exprtk.hpp:15669
for_loop_node< T > parent_t
Definition: Exprtk.hpp:7583
T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
Definition: Exprtk.hpp:16722
bfunc_t f2() const
Definition: Exprtk.hpp:16767
~vec_binop_vecval_node()
Definition: Exprtk.hpp:13080
ivariable< T > * ivariable_ptr
Definition: Exprtk.hpp:9375
T0 t0() const exprtk_override
Definition: Exprtk.hpp:16933
T0oT1(const T0oT1< T, T0, T1 > &) exprtk_delete
cob_node(const cob_node< T, Operation > &) exprtk_delete
virtual const std::string & ref() const
Definition: Exprtk.hpp:9674
bool init_branches(expression_ptr(&b)[NumBranches])
Definition: Exprtk.hpp:13762
stringvar_size_node(std::string &v)
Definition: Exprtk.hpp:10316
uvouv_node(const T &var0, const T &var1, ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
Definition: Exprtk.hpp:16186
swap_string_node(expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:10073
vector_node_ptr vec() exprtk_override
Definition: Exprtk.hpp:8394
results_context< T > results_context_t
Definition: Exprtk.hpp:14622
rebasevector_elem_node< T > * rbvec_node_ptr_
Definition: Exprtk.hpp:11762
unary_variable_node< T, Operation > & operator=(const unary_variable_node< T, Operation > &) exprtk_delete
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
Definition: Exprtk.hpp:16870
string_size_node(expression_ptr branch)
Definition: Exprtk.hpp:10347
vov_node(const vov_node< T, Operation > &) exprtk_delete
std::vector< T > value_list_
Definition: Exprtk.hpp:14170
vector_holder_t & vec_holder()
Definition: Exprtk.hpp:8429
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3)
Definition: Exprtk.hpp:17136
branch_t branch_
Definition: Exprtk.hpp:6624
sf4_var_node(const T &v0, const T &v1, const T &v2, const T &v3)
Definition: Exprtk.hpp:11412
irange_ptr str0_range_ptr_
Definition: Exprtk.hpp:10049
assignment_rebasevec_elem_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11773
ifunction * function_
Definition: Exprtk.hpp:14060
~str_xroxr_node()
Definition: Exprtk.hpp:17801
ufunc_t f()
Definition: Exprtk.hpp:16225
voc_node(const T &var, const T &const_var)
Definition: Exprtk.hpp:17307
T0oT1(T0 p0, T1 p1, const bfunc_t p2)
Definition: Exprtk.hpp:16560
sos_node(SType0 p0, SType1 p1)
Definition: Exprtk.hpp:17609
vector_node(vector_holder_t *vh)
Definition: Exprtk.hpp:8366
multi_switch_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:8027
opr_base< T >::Type Type
Definition: Exprtk.hpp:15096
vararg_function_node(VarArgFunction *func, const std::vector< expression_ptr > &arg_list)
Definition: Exprtk.hpp:14112
ivariable_ptr var0_
Definition: Exprtk.hpp:9396
assignment_rebasevec_celem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11813
assignment_vec_elem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11653
T2 t2() const exprtk_override
Definition: Exprtk.hpp:16943
T * vector_base_
Definition: Exprtk.hpp:8568
char_cptr base() const
Definition: Exprtk.hpp:10915
const T & v() const exprtk_override
Definition: Exprtk.hpp:16162
T single_initialiser_value_
Definition: Exprtk.hpp:9336
T0 t0_
Definition: Exprtk.hpp:16612
operator_type operation() const exprtk_override
Definition: Exprtk.hpp:16157
std::string str() const
Definition: Exprtk.hpp:10910
boc_node(const expression_ptr branch, const T const_var)
Definition: Exprtk.hpp:17537
swap_vecvec_node(expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:9413
sos_node< T, SType0, SType1, Operation > & operator=(const sos_node< T, SType0, SType1, Operation > &) exprtk_delete
std::string str() const exprtk_override
Definition: Exprtk.hpp:6732
sf4_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3)
Definition: Exprtk.hpp:11353
str_base_ptr str0_base_ptr_
Definition: Exprtk.hpp:10047
assignment_rebasevec_elem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12313
rebasevector_elem_rtc_node< T > * rbvec_node_ptr_
Definition: Exprtk.hpp:11802
static T process_6(const Sequence &arg_list)
Definition: Exprtk.hpp:15658
bool valid() const exprtk_override
Definition: Exprtk.hpp:6606
std::string & s0()
Definition: Exprtk.hpp:17629
details::functor_t< T > functor_t
Definition: Exprtk.hpp:16181
IFunction ifunction
Definition: Exprtk.hpp:13753
unary_vector_node(const operator_type &opr, expression_ptr branch0)
Definition: Exprtk.hpp:13373
T0oT1oT2oT3_sf4< T, T0, T1, T2, T3 > node_type
Definition: Exprtk.hpp:16998
branch_t index_
Definition: Exprtk.hpp:8570
vector_holder_t & vec_holder() const
Definition: Exprtk.hpp:8434
static std::string id()
Definition: Exprtk.hpp:16682
std::vector< const T * > arg_list_
Definition: Exprtk.hpp:11552
vec_data_store< T > vds_t
Definition: Exprtk.hpp:8364
static T process_5(const Sequence &arg_list)
Definition: Exprtk.hpp:15152
node_type & operator=(const node_type &) exprtk_delete
vector_node_ptr vec() const exprtk_override
Definition: Exprtk.hpp:8389
std::size_t result_vec_size_
Definition: Exprtk.hpp:13686
cov_node(const T &const_var, const T &var)
Definition: Exprtk.hpp:17257
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:6575
vector_assignment_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list, const bool single_value_initialse)
Definition: Exprtk.hpp:9224
const bool single_value_initialse_
Definition: Exprtk.hpp:9333
vectorize_node(const expression_ptr v)
Definition: Exprtk.hpp:11564
T3 t3() const
Definition: Exprtk.hpp:16752
repeat_until_loop_node< T > parent_t
Definition: Exprtk.hpp:7470
branch_t return_
Definition: Exprtk.hpp:7248
T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
Definition: Exprtk.hpp:17000
VarArgFunction * function_
Definition: Exprtk.hpp:14168
expression_ptr alternative_
Definition: Exprtk.hpp:10831
expression_node< T > * branch(const std::size_t &) const exprtk_override
Definition: Exprtk.hpp:6601
stringvar_node()
Definition: Exprtk.hpp:9533
rebasevector_celem_rtc_node< T > * rbvec_node_ptr_
Definition: Exprtk.hpp:12462
memory_context memory_context_
Definition: Exprtk.hpp:13025
static T null_value
Definition: Exprtk.hpp:8114
swap_genstrings_node(expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:10159
string_range_node(std::string &v, const range_t &rp)
Definition: Exprtk.hpp:9629
T2 t2() const
Definition: Exprtk.hpp:16662
std::string * value_
Definition: Exprtk.hpp:9610
function_N_node(ifunction *func)
Definition: Exprtk.hpp:13755
~generic_string_range_node()
Definition: Exprtk.hpp:9819
static T process_8(const Sequence &arg_list)
Definition: Exprtk.hpp:15681
ipowinv_node(const ipowinv_node< T, PowOp > &) exprtk_delete
static T process_4(const Sequence &arg_list)
Definition: Exprtk.hpp:15145
functor_t::tfunc_t tfunc_t
Definition: Exprtk.hpp:16812
assignment_vec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11858
variable_node()
Definition: Exprtk.hpp:8116
T0oT1oT2_sf3ext(const node_type &) exprtk_delete
Operation operation_t
Definition: Exprtk.hpp:16141
T0_ T0
Definition: Exprtk.hpp:16715
T0oT1< T, T0, T1 > node_type
Definition: Exprtk.hpp:16558
~vec_binop_vecvec_node()
Definition: Exprtk.hpp:12910
T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
Definition: Exprtk.hpp:16628
vob_node< T, Operation > & operator=(const vob_node< T, Operation > &) exprtk_delete
static const std::string null_value
Definition: Exprtk.hpp:10310
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, bfunc_t p2)
Definition: Exprtk.hpp:16598
vec_binop_vecvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12841
literal_node< T > & operator=(const literal_node< T > &) exprtk_delete
bov_node(const bov_node< T, Operation > &) exprtk_delete
T0oT1oT2(const node_type &) exprtk_delete
T2_ T2
Definition: Exprtk.hpp:16717
assignment_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11615
return_envelope_node(expression_ptr body, results_context_t &rc)
Definition: Exprtk.hpp:14675
char_cptr base() const exprtk_override
Definition: Exprtk.hpp:6737
bipowinv_node< T, PowOp > & operator=(const bipowinv_node< T, PowOp > &) exprtk_delete
bool return_invoked_
Definition: Exprtk.hpp:14728
std::size_t size() const exprtk_override
Definition: Exprtk.hpp:6742
range_t range_
Definition: Exprtk.hpp:9906
T0 t0() const
Definition: Exprtk.hpp:16582
str_xoxr_node(const node_type &) exprtk_delete
literal_node(const literal_node< T > &) exprtk_delete
str_xrox_node< T, SType0, SType1, RangePack, Operation > node_type
Definition: Exprtk.hpp:17657
strvar_node_ptr str0_node_ptr_
Definition: Exprtk.hpp:10141
~const_string_range_node()
Definition: Exprtk.hpp:9718
bipow_node(const bipow_node< T, PowOp > &) exprtk_delete
SType2 s2_
Definition: Exprtk.hpp:18026
strvar_node_ptr str1_node_ptr_
Definition: Exprtk.hpp:10142
vector_assignment_node(const vector_assignment_node< T > &) exprtk_delete
ipow_node(const T &v)
Definition: Exprtk.hpp:18043
range_t & range_ref() exprtk_override
Definition: Exprtk.hpp:6747
str_rng_node_ptr str0_rng_node_ptr_
Definition: Exprtk.hpp:10662
T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
Definition: Exprtk.hpp:16911
sf3_var_node< T, SpecialFunction > & operator=(const sf3_var_node< T, SpecialFunction > &) exprtk_delete
stringvar_node< T > * strvar_node_ptr
Definition: Exprtk.hpp:9781
str_sogens_node< T, Operation > & operator=(const str_sogens_node< T, Operation > &) exprtk_delete
vector_elem_rtc_node< T > * vec_node_ptr_
Definition: Exprtk.hpp:11722
void populate_value_list() const
Definition: Exprtk.hpp:14160
assignment_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12153
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
Definition: Exprtk.hpp:17060
cob_node(const T const_var, const expression_ptr branch)
Definition: Exprtk.hpp:17465
ipow_node(const ipow_node< T, PowOp > &) exprtk_delete
const T & v0_
Definition: Exprtk.hpp:11400
T3_ T3
Definition: Exprtk.hpp:16718
swap_node(variable_node_ptr var0, variable_node_ptr var1)
Definition: Exprtk.hpp:9347
const range_t & range_ref() const
Definition: Exprtk.hpp:10930
static T process_1(const Sequence &arg_list)
Definition: Exprtk.hpp:15126
static std::string null_value
Definition: Exprtk.hpp:9531
T0oT1oT2_sf3(const node_type &) exprtk_delete
vector_holder< T > vector_holder_t
Definition: Exprtk.hpp:8362
~str_xrox_node()
Definition: Exprtk.hpp:17666
std::string & ref()
Definition: Exprtk.hpp:9574
T0oT1oT2oT3_sf4ext(const node_type &) exprtk_delete
str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
Definition: Exprtk.hpp:17660
vector_holder_t * vector_holder_
Definition: Exprtk.hpp:8441
bool equality_
Definition: Exprtk.hpp:6623
conditional_vector_node(expression_ptr condition, expression_ptr consequent, expression_ptr alternative)
Definition: Exprtk.hpp:13532
qfunc_t f() const
Definition: Exprtk.hpp:17044
T3 t3_
Definition: Exprtk.hpp:16800
scor_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:13726
T value() const exprtk_override
Definition: Exprtk.hpp:6514
while_loop_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition: Exprtk.hpp:7380
range_interface< T > irange_t
Definition: Exprtk.hpp:9785
const ufunc_t u1_
Definition: Exprtk.hpp:16238
variable_node< T > * var_node_ptr_
Definition: Exprtk.hpp:11642
vds_t & vds() exprtk_override
Definition: Exprtk.hpp:8419
for_loop_bc_node< T > parent_t
Definition: Exprtk.hpp:7859
SType0 s0_
Definition: Exprtk.hpp:17641
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:14556
branch_t consequent_
Definition: Exprtk.hpp:7131
vector_celem_rtc_node< T > * vec_node_ptr_
Definition: Exprtk.hpp:12302
unary_branch_node(const unary_branch_node< T, Operation > &) exprtk_delete
sf3_var_node(const sf3_var_node< T, SpecialFunction > &) exprtk_delete
unary_variable_node(const T &var)
Definition: Exprtk.hpp:16143
vector_elem_node(expression_ptr vec_node, expression_ptr index, vector_holder_ptr vec_holder)
Definition: Exprtk.hpp:8501
vector_node_ptr alternative_node_ptr_
Definition: Exprtk.hpp:13682
branch_t vector_node_
Definition: Exprtk.hpp:8569
const bfunc_t f_
Definition: Exprtk.hpp:16239
vector_size_node(vector_holder_t *vh)
Definition: Exprtk.hpp:8454
binary_ext_node(expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:6903
virtual ~string_range_node()
Definition: Exprtk.hpp:9634
vector_node< T > * vector_node_ptr
Definition: Exprtk.hpp:8363
str_xroxr_node(const node_type &) exprtk_delete
static T process_2(const Sequence &arg_list)
Definition: Exprtk.hpp:15132
const_string_range_node< T > & operator=(const const_string_range_node< T > &) exprtk_delete
~str_xoxr_node()
Definition: Exprtk.hpp:17730
string_literal_node(const std::string &v)
Definition: Exprtk.hpp:6708
bool src_is_ivec_
Definition: Exprtk.hpp:12141
cons_conditional_node(expression_ptr condition, expression_ptr consequent)
Definition: Exprtk.hpp:7144
sos_node(const sos_node< T, SType0, SType1, Operation > &) exprtk_delete
const_string_range_node(const std::string &v, const range_t &rp)
Definition: Exprtk.hpp:9713
vector_access_runtime_check_ptr vec_rt_chk_
Definition: Exprtk.hpp:8755
const std::string value_
Definition: Exprtk.hpp:6762
string_function_node< T, StringFunction > str_function_t
Definition: Exprtk.hpp:14553
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:9028
while_loop_bc_node< T > parent_t
Definition: Exprtk.hpp:7671
uvouv_node< T > & operator=(const uvouv_node< T > &) exprtk_delete
ufunc_t u1()
Definition: Exprtk.hpp:16220
range_interface< T >::range_t range_t
Definition: Exprtk.hpp:9529
bipow_node(expression_ptr branch)
Definition: Exprtk.hpp:18074
assignment_string_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:10422
cob_node< T, Operation > & operator=(const cob_node< T, Operation > &) exprtk_delete
rebasevector_elem_node(expression_ptr vec_node, expression_ptr index, vector_holder_ptr vec_holder)
Definition: Exprtk.hpp:8873
literal_node(const T &v)
Definition: Exprtk.hpp:6632
voc_node(const voc_node< T, Operation > &) exprtk_delete
bov_node(const expression_ptr branch, const T &var)
Definition: Exprtk.hpp:17409
~unary_vector_node()
Definition: Exprtk.hpp:13407
vov_node(const T &var0, const T &var1)
Definition: Exprtk.hpp:17207
const std::string & ref() const
Definition: Exprtk.hpp:9579
~vector_node()
Definition: Exprtk.hpp:8378
assignment_vec_elem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12233
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: Exprtk.hpp:15101
expression_node< T > * move_branch(const std::size_t &) exprtk_override
Definition: Exprtk.hpp:17502
const T & v2_
Definition: Exprtk.hpp:11402
sosos_node(SType0 p0, SType1 p1, SType2 p2)
Definition: Exprtk.hpp:17986
branch_t body_
Definition: Exprtk.hpp:14729
irange_ptr str_range_ptr_
Definition: Exprtk.hpp:9904
vararg_varnode(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:11512
expression_node< T > * branch(const std::size_t &index=0) const exprtk_override
Definition: Exprtk.hpp:6926
vector_node< T > * vec_node_ptr_
Definition: Exprtk.hpp:11970
T * value_
Definition: Exprtk.hpp:8151
bipowinv_node(expression_ptr branch)
Definition: Exprtk.hpp:18152
irange_ptr str1_range_ptr_
Definition: Exprtk.hpp:10050
vov_node< T, Operation > & operator=(const vov_node< T, Operation > &) exprtk_delete
SType1 s1_
Definition: Exprtk.hpp:17642
ipowinv_node(const T &v)
Definition: Exprtk.hpp:18121
std::vector< expression_ptr > arg_list_
Definition: Exprtk.hpp:14169
swap_genstrings_node(const swap_genstrings_node< T > &) exprtk_delete
T & ref() exprtk_override
Definition: Exprtk.hpp:8134
generic_function_node< T, igeneric_function_t > gen_function_t
Definition: Exprtk.hpp:14625
operator_type operation()
Definition: Exprtk.hpp:6921
str_xrox_node(const node_type &) exprtk_delete
unary_variable_node(const unary_variable_node< T, Operation > &) exprtk_delete
conditional_string_node(expression_ptr condition, expression_ptr consequent, expression_ptr alternative)
Definition: Exprtk.hpp:10682
irange_t * irange_ptr
Definition: Exprtk.hpp:9786
T0oT1< T, T0, T1 > & operator=(const T0oT1< T, T0, T1 > &)
Definition: Exprtk.hpp:16610
voc_node< T, Operation > & operator=(const voc_node< T, Operation > &) exprtk_delete
assignment_rebasevec_celem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12353
str_xroxr_node< T, SType0, SType1, RangePack, Operation > node_type
Definition: Exprtk.hpp:17791
std::string type_id() const
Definition: Exprtk.hpp:16859
return_node(const std::vector< typename gen_function_t::expression_ptr > &arg_list, results_context_t &rc)
Definition: Exprtk.hpp:14627
break_node(expression_ptr ret=expression_ptr(0))
Definition: Exprtk.hpp:7213
const T & v0()
Definition: Exprtk.hpp:16205
bipowinv_node(const bipowinv_node< T, PowOp > &) exprtk_delete
const T & ref() const exprtk_override
Definition: Exprtk.hpp:8139
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:7862
~vector_size_node()
Definition: Exprtk.hpp:8458
assignment_vec_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12478
std::vector< expression_ptr > initialiser_list_
Definition: Exprtk.hpp:9331
null_igenfunc< T > igeneric_function_t
Definition: Exprtk.hpp:14623
string_base_node< T > * str_base_ptr
Definition: Exprtk.hpp:9782
T1 t1() const exprtk_override
Definition: Exprtk.hpp:16938
const ufunc_t u0_
Definition: Exprtk.hpp:16237
str_xoxr_node< T, SType0, SType1, RangePack, Operation > node_type
Definition: Exprtk.hpp:17721
std::size_t node_depth() const exprtk_override exprtk_final
Definition: Exprtk.hpp:8085
str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
Definition: Exprtk.hpp:17724
str_function_t::range_t range_t
Definition: Exprtk.hpp:14554
sf4_var_node< T, SpecialFunction > & operator=(const sf4_var_node< T, SpecialFunction > &) exprtk_delete
stringvar_size_node()
Definition: Exprtk.hpp:10312
boc_node(const boc_node< T, Operation > &) exprtk_delete
T1 t1() const
Definition: Exprtk.hpp:16587
bfunc_t f0() const
Definition: Exprtk.hpp:16667
vob_node(const vob_node< T, Operation > &) exprtk_delete
bool side_effect() const exprtk_override
Definition: Exprtk.hpp:12588
branch_t v_
Definition: Exprtk.hpp:11604
const bfunc_t f1_
Definition: Exprtk.hpp:16704
assignment_vec_elem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12193
vector_node< T > * vec0_node_ptr_
Definition: Exprtk.hpp:9514
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:8771
vector_node_ptr temp_vec_node_
Definition: Exprtk.hpp:13683
PowOp operation_t
Definition: Exprtk.hpp:18041
stringvar_node(std::string &v)
Definition: Exprtk.hpp:9537
range_pack< T > range_t
Definition: Exprtk.hpp:6706
unary_branch_node< T, Operation > & operator=(const unary_branch_node< T, Operation > &) exprtk_delete
T0oT1oT2oT3< T, T0, T1, T2, T3, ProcessMode > node_type
Definition: Exprtk.hpp:16719
scand_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:13699
str_sogens_node(const str_sogens_node< T, Operation > &) exprtk_delete
string_literal_node< T > & operator=(const string_literal_node< T > &) exprtk_delete
assignment_vec_elem_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:11693
vector_node(const vds_t &vds, vector_holder_t *vh)
Definition: Exprtk.hpp:8373
std::size_t node_depth() const exprtk_override
Definition: Exprtk.hpp:6616
vector_interface< T > * vec_interface_ptr
Definition: Exprtk.hpp:13524
branch_t alternative_
Definition: Exprtk.hpp:7132
sf3_var_node(const T &v0, const T &v1, const T &v2)
Definition: Exprtk.hpp:11379
cons_conditional_str_node(expression_ptr condition, expression_ptr consequent)
Definition: Exprtk.hpp:10851
functor_t::bfunc_t bfunc_t
Definition: Exprtk.hpp:16182
T0oT1oT2_sf3ext< T, T0, T1, T2, SF3Operation > node_type
Definition: Exprtk.hpp:16909
sosos_node< T, SType0, SType1, SType2, Operation > node_type
Definition: Exprtk.hpp:17983
vector_node_ptr consequent_node_ptr_
Definition: Exprtk.hpp:13681
sf4_var_node(const sf4_var_node< T, SpecialFunction > &) exprtk_delete
rebasevector_celem_node< T > * rbvec_node_ptr_
Definition: Exprtk.hpp:11842
T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
Definition: Exprtk.hpp:17087
variable_node_ptr var1_
Definition: Exprtk.hpp:9366
const std::size_t param_seq_index_
Definition: Exprtk.hpp:14593
assignment_rebasevec_elem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12393
const_string_range_node(const const_string_range_node< T > &) exprtk_delete
range_t rp_
Definition: Exprtk.hpp:6763
vds_t vds_
Definition: Exprtk.hpp:8442
std::size_t parameter_count_
Definition: Exprtk.hpp:14061
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
Definition: Exprtk.hpp:16688
T * access_vector() const
Definition: Exprtk.hpp:8561
string_literal_node(const string_literal_node< T > &) exprtk_delete
str_sogens_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:17876
T0oT1oT2oT3_sf4ext< T, T0, T1, T2, T3, SF4Operation > node_type
Definition: Exprtk.hpp:17085
str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
Definition: Exprtk.hpp:17794
range_t base_range_
Definition: Exprtk.hpp:9905
assignment_vecvec_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12612
T1 t1_
Definition: Exprtk.hpp:16613
tfunc_t f() const
Definition: Exprtk.hpp:16854
const T c_
Definition: Exprtk.hpp:17289
vector_holder_t * vector_holder_ptr
Definition: Exprtk.hpp:8498
assignment_rebasevec_celem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12433
const T & v1_
Definition: Exprtk.hpp:11401
T0oT1oT2_sf3< T, T0, T1, T2 > node_type
Definition: Exprtk.hpp:16814
branch_t condition_
Definition: Exprtk.hpp:7130
T2 t2_
Definition: Exprtk.hpp:16702
vec_binop_vecval_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:13044
T value_type
Definition: Exprtk.hpp:16557
const tfunc_t f_
Definition: Exprtk.hpp:16885
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:9130
boc_node< T, Operation > & operator=(const boc_node< T, Operation > &) exprtk_delete
vob_node(const T &var, const expression_ptr branch)
Definition: Exprtk.hpp:17353
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:6576
std::string type_id() const exprtk_override
Definition: Exprtk.hpp:16677
str_base_ptr str_base_ptr_
Definition: Exprtk.hpp:9903
expression_ptr consequent_
Definition: Exprtk.hpp:10830
variable_node(T &v)
Definition: Exprtk.hpp:8120
while_loop_bc_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition: Exprtk.hpp:7674
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:18071
virtual std::string & ref()
Definition: Exprtk.hpp:9669
functor_t::qfunc_t qfunc_t
Definition: Exprtk.hpp:16996
const T value_
Definition: Exprtk.hpp:6656
null_eq_node(expression_ptr branch, const bool equality=true)
Definition: Exprtk.hpp:6578
const range_t & range_ref() const exprtk_override
Definition: Exprtk.hpp:6752
std::size_t size() const
Definition: Exprtk.hpp:10920
cov_node(const cov_node< T, Operation > &) exprtk_delete
const vds_t & vds() const exprtk_override
Definition: Exprtk.hpp:8424
void release()
Definition: Exprtk.hpp:16281
const T & v1() const exprtk_override
Definition: Exprtk.hpp:17232
void set_c(const T new_c) exprtk_override
Definition: Exprtk.hpp:17487
vector_assignment_node< T > & operator=(const vector_assignment_node< T > &) exprtk_delete
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:16783
vector_node< T > * vec1_node_ptr_
Definition: Exprtk.hpp:9515
vararg_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:11450
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:6611
const bfunc_t f2_
Definition: Exprtk.hpp:16803
vector_elem_node< T > * vec_node_ptr_
Definition: Exprtk.hpp:11682
const T & v3_
Definition: Exprtk.hpp:11437
const std::string * value_
Definition: Exprtk.hpp:10332
const std::size_t size_
Definition: Exprtk.hpp:9332
vector_celem_node(expression_ptr vec_node, const std::size_t index, vector_holder_ptr vec_holder)
Definition: Exprtk.hpp:8585
igeneric_function_t * igeneric_function_ptr
Definition: Exprtk.hpp:14624
repeat_until_loop_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition: Exprtk.hpp:7473
swap_genstrings_node< T > & operator=(const swap_genstrings_node< T > &) exprtk_delete
vector_holder_t * vec_holder()
Definition: Exprtk.hpp:8479
bool zero_value_initialse_
Definition: Exprtk.hpp:9334
const qfunc_t f_
Definition: Exprtk.hpp:17076
vector_interface< T > * ivec_ptr_
Definition: Exprtk.hpp:11603
range_t range() const
Definition: Exprtk.hpp:9664
conditional_node(expression_ptr condition, expression_ptr consequent, expression_ptr alternative)
Definition: Exprtk.hpp:7084
expression_ptr condition_
Definition: Exprtk.hpp:10829
RangePack rp0_
Definition: Exprtk.hpp:17706
assignment_vec_celem_op_rtc_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:12273
switch_n_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:8007
str_base_ptr str1_base_ptr_
Definition: Exprtk.hpp:10048
T1_ T1
Definition: Exprtk.hpp:16716
bfunc_t f1() const
Definition: Exprtk.hpp:16672
string_range_node< T > * str_rng_node_ptr
Definition: Exprtk.hpp:10540
void rebase(std::string &s)
Definition: Exprtk.hpp:9599
string_concat_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: Exprtk.hpp:9927
sosos_node(const node_type &) exprtk_delete
std::string & s2()
Definition: Exprtk.hpp:18017
~vec_binop_valvec_node()
Definition: Exprtk.hpp:13244
const bfunc_t f0_
Definition: Exprtk.hpp:16703
vector_holder_ptr temp_
Definition: Exprtk.hpp:13684
bool const_nonzero_literal_value_initialse_
Definition: Exprtk.hpp:9335
uvouv_node(const uvouv_node< T > &) exprtk_delete
branch_t final_node_
Definition: Exprtk.hpp:11091
repeat_until_loop_bc_rtc_node(expression_ptr condition, expression_ptr loop_body, loop_runtime_check_ptr loop_rt_chk)
Definition: Exprtk.hpp:7755
T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
Definition: Exprtk.hpp:16816
Definition: Exprtk.hpp:7791
T value() const exprtk_override
Definition: Exprtk.hpp:7806
for_loop_node< T > parent_t
Definition: Exprtk.hpp:7794
for_loop_bc_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body)
Definition: Exprtk.hpp:7797
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7795
Definition: Exprtk.hpp:7500
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:7544
branch_t loop_body_
Definition: Exprtk.hpp:7573
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:7504
bool valid() const exprtk_override exprtk_final
Definition: Exprtk.hpp:7549
branch_t condition_
Definition: Exprtk.hpp:7571
for_loop_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body)
Definition: Exprtk.hpp:7506
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7503
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:7554
T value() const exprtk_override
Definition: Exprtk.hpp:7518
std::size_t node_depth() const exprtk_override
Definition: Exprtk.hpp:7562
branch_t initialiser_
Definition: Exprtk.hpp:7570
branch_t incrementor_
Definition: Exprtk.hpp:7572
Definition: Exprtk.hpp:14175
std::vector< expression_ptr > arg_list_
Definition: Exprtk.hpp:14404
std::vector< range_data_type_t > range_list_t
Definition: Exprtk.hpp:14194
variable_node_t * variable_node_ptr_t
Definition: Exprtk.hpp:14182
vector_holder< T > * vh_t
Definition: Exprtk.hpp:14189
range_interface< T > range_interface_t
Definition: Exprtk.hpp:14184
GenericFunction * function_
Definition: Exprtk.hpp:14399
virtual ~generic_function_node()
Definition: Exprtk.hpp:14202
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:14215
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:14188
vector_node< T > vector_node_t
Definition: Exprtk.hpp:14181
std::vector< type_store_t > typestore_list_t
Definition: Exprtk.hpp:14193
std::vector< vecview_t > vv_list_
Definition: Exprtk.hpp:14406
std::vector< T > tmp_vs_t
Definition: Exprtk.hpp:14192
range_data_type< T > range_data_type_t
Definition: Exprtk.hpp:14185
vector_node_t * vector_node_ptr_t
Definition: Exprtk.hpp:14183
typestore_list_t typestore_list_
Definition: Exprtk.hpp:14400
std::vector< branch_t > branch_
Definition: Exprtk.hpp:14405
tmp_vs_t expr_as_vec1_store_
Definition: Exprtk.hpp:14407
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:14340
range_list_t range_list_
Definition: Exprtk.hpp:14408
virtual bool populate_value_list() const
Definition: Exprtk.hpp:14352
T value() const exprtk_override
Definition: Exprtk.hpp:14328
variable_node< T > variable_node_t
Definition: Exprtk.hpp:14180
bool valid() const exprtk_override
Definition: Exprtk.hpp:14345
range_interface< T >::range_t range_t
Definition: Exprtk.hpp:14186
std::vector< std::size_t > range_param_list_
Definition: Exprtk.hpp:14409
std::size_t node_depth() const exprtk_override exprtk_final
Definition: Exprtk.hpp:14220
type_store< T > type_store_t
Definition: Exprtk.hpp:14178
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:14179
virtual bool init_branches()
Definition: Exprtk.hpp:14225
vector_view< T > * vecview_t
Definition: Exprtk.hpp:14190
generic_function_node(const std::vector< expression_ptr > &arg_list, GenericFunction *func=reinterpret_cast< GenericFunction * >(0))
Definition: Exprtk.hpp:14196
Definition: Exprtk.hpp:8097
virtual ~ivariable()
Definition: Exprtk.hpp:8100
virtual const T & ref() const =0
generic_function_node< T, GenericFunction > gen_function_t
Definition: Exprtk.hpp:14508
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:14511
expression_node< T >::node_type type() const exprtk_override exprtk_final
Definition: Exprtk.hpp:14537
std::size_t param_seq_index_
Definition: Exprtk.hpp:14544
gen_function_t::range_t range_t
Definition: Exprtk.hpp:14509
T value() const exprtk_override
Definition: Exprtk.hpp:14518
Definition: Exprtk.hpp:18331
expression_node< typename node_type::value_type > * allocate_cr(const T1 &t1, T2 &t2) const
Definition: Exprtk.hpp:18436
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:18627
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:18679
expression_node< typename node_type::value_type > * allocate_c(const T1 &t1) const
Definition: Exprtk.hpp:18416
expression_node< typename node_type::value_type > * allocate(const Sequence< Type, Allocator > &seq) const
Definition: Exprtk.hpp:18398
expression_node< typename node_type::value_type > * allocate_rc(T1 &t1, const T2 &t2) const
Definition: Exprtk.hpp:18446
expression_node< typename node_type::value_type > * allocate_rr(T1 &t1, T2 &t2) const
Definition: Exprtk.hpp:18456
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[1])
Definition: Exprtk.hpp:18335
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:18593
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) const
Definition: Exprtk.hpp:18665
expression_node< typename node_type::value_type > * allocate(T1 &t1) const
Definition: Exprtk.hpp:18407
expression_node< typename node_type::value_type > * allocate_tt(T1 t1, T2 t2) const
Definition: Exprtk.hpp:18466
expression_node< typename node_type::value_type > * allocate_ttt(T1 t1, T2 t2, T3 t3) const
Definition: Exprtk.hpp:18476
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:18693
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:18550
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:18563
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2) const
Definition: Exprtk.hpp:18426
expression_node< typename node_type::value_type > * allocate_rrrrr(T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5) const
Definition: Exprtk.hpp:18516
expression_node< typename node_type::value_type > * allocate_rrrr(T1 &t1, T2 &t2, T3 &t3, T4 &t4) const
Definition: Exprtk.hpp:18506
expression_node< typename node_type::value_type > * allocate() const
Definition: Exprtk.hpp:18389
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[4])
Definition: Exprtk.hpp:18362
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[5])
Definition: Exprtk.hpp:18371
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) const
Definition: Exprtk.hpp:18538
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:18577
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[6])
Definition: Exprtk.hpp:18380
void free(expression_node< T > *&e) const
Definition: Exprtk.hpp:18705
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3) const
Definition: Exprtk.hpp:18641
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3) const
Definition: Exprtk.hpp:18526
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:18609
expression_node< typename node_type::value_type > * allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
Definition: Exprtk.hpp:18486
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4) const
Definition: Exprtk.hpp:18652
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[3])
Definition: Exprtk.hpp:18353
expression_node< typename node_type::value_type > * allocate_rrr(T1 &t1, T2 &t2, T3 &t3) const
Definition: Exprtk.hpp:18496
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[2])
Definition: Exprtk.hpp:18344
nci_t::node_pp_t node_pp_t
Definition: Exprtk.hpp:5837
nci_t::node_ptr_t node_ptr_t
Definition: Exprtk.hpp:5836
static void collect_nodes(node_ptr_t &root, noderef_list_t &node_delete_list)
Definition: Exprtk.hpp:5858
static void delete_nodes(node_ptr_t &root)
Definition: Exprtk.hpp:5840
node_collector_interface< Node > nci_t
Definition: Exprtk.hpp:5834
nci_t::noderef_list_t noderef_list_t
Definition: Exprtk.hpp:5838
Definition: Exprtk.hpp:14601
virtual ~null_igenfunc()
Definition: Exprtk.hpp:14604
type_store< T > generic_type
Definition: Exprtk.hpp:14607
generic_type::parameter_list parameter_list_t
Definition: Exprtk.hpp:14608
Definition: Exprtk.hpp:7025
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:7051
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7028
bool valid() const exprtk_override
Definition: Exprtk.hpp:7061
std::size_t node_depth() const exprtk_override exprtk_final
Definition: Exprtk.hpp:7056
operator_type operation_
Definition: Exprtk.hpp:7072
quaternary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3)
Definition: Exprtk.hpp:7031
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:7046
T value() const exprtk_override
Definition: Exprtk.hpp:7041
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:7029
Definition: Exprtk.hpp:6667
virtual const range_t & range_ref() const =0
virtual range_t & range_ref()=0
range_pack< T > range_t
Definition: Exprtk.hpp:6670
virtual ~range_interface()
Definition: Exprtk.hpp:6672
T value() const exprtk_override
Definition: Exprtk.hpp:7722
repeat_until_loop_node< T > parent_t
Definition: Exprtk.hpp:7712
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7713
repeat_until_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
Definition: Exprtk.hpp:7715
Definition: Exprtk.hpp:7407
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:7446
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:7434
T value() const exprtk_override
Definition: Exprtk.hpp:7421
std::size_t node_depth() const exprtk_override
Definition: Exprtk.hpp:7452
branch_t loop_body_
Definition: Exprtk.hpp:7460
repeat_until_loop_node(expression_ptr condition, expression_ptr loop_body)
Definition: Exprtk.hpp:7413
bool valid() const exprtk_override exprtk_final
Definition: Exprtk.hpp:7439
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:7411
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7410
branch_t condition_
Definition: Exprtk.hpp:7459
Definition: Exprtk.hpp:4807
Definition: Exprtk.hpp:14597
Definition: Exprtk.hpp:4806
Definition: Exprtk.hpp:16890
virtual ~sf3ext_type_node()
Definition: Exprtk.hpp:16893
Definition: Exprtk.hpp:16087
virtual ~sos_base_node()
Definition: Exprtk.hpp:16090
virtual operator_type operation() const
Definition: Exprtk.hpp:16093
Definition: Exprtk.hpp:16101
virtual operator_type operation() const
Definition: Exprtk.hpp:16107
virtual ~sosos_base_node()
Definition: Exprtk.hpp:16104
Definition: Exprtk.hpp:6683
virtual ~string_base_node()
Definition: Exprtk.hpp:6688
virtual std::string str() const =0
virtual char_cptr base() const =0
range_data_type< T > range_data_type_t
Definition: Exprtk.hpp:6686
virtual std::size_t size() const =0
Definition: Exprtk.hpp:14417
std::string ret_string_
Definition: Exprtk.hpp:14499
string_function_node(StringFunction *func, const std::vector< typename gen_function_t::expression_ptr > &arg_list)
Definition: Exprtk.hpp:14423
const range_t & range_ref() const exprtk_override
Definition: Exprtk.hpp:14491
range_t & range_ref() exprtk_override
Definition: Exprtk.hpp:14486
range_t range_
Definition: Exprtk.hpp:14498
std::size_t size() const exprtk_override
Definition: Exprtk.hpp:14481
T value() const exprtk_override
Definition: Exprtk.hpp:14439
char_cptr base() const exprtk_override
Definition: Exprtk.hpp:14476
range_interface< T >::range_t range_t
Definition: Exprtk.hpp:14421
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:14461
std::string str() const exprtk_override
Definition: Exprtk.hpp:14471
generic_function_node< T, StringFunction > gen_function_t
Definition: Exprtk.hpp:14420
bool valid() const exprtk_override
Definition: Exprtk.hpp:14466
Definition: Exprtk.hpp:7924
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7927
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:7983
switch_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:7932
std::vector< branch_t > arg_list_
Definition: Exprtk.hpp:7995
expression_node< T >::node_type type() const exprtk_override exprtk_final
Definition: Exprtk.hpp:7973
std::size_t node_depth() const exprtk_override exprtk_final
Definition: Exprtk.hpp:7988
bool valid() const exprtk_override
Definition: Exprtk.hpp:7978
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:7928
T value() const exprtk_override
Definition: Exprtk.hpp:7955
Definition: Exprtk.hpp:6956
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:6959
operator_type operation_
Definition: Exprtk.hpp:7019
bool valid() const exprtk_override
Definition: Exprtk.hpp:6999
T value() const exprtk_override
Definition: Exprtk.hpp:6972
trinary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2)
Definition: Exprtk.hpp:6962
std::size_t node_depth() const exprtk_override exprtk_final
Definition: Exprtk.hpp:7012
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:6994
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:7007
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:6960
Definition: Exprtk.hpp:6769
branch_t branch_
Definition: Exprtk.hpp:6826
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:6788
expression_node< T > * branch(const std::size_t &) const exprtk_override
Definition: Exprtk.hpp:6798
unary_node(const operator_type &opr, expression_ptr branch)
Definition: Exprtk.hpp:6775
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:6772
operator_type operation_
Definition: Exprtk.hpp:6825
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:6813
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:6773
operator_type operation()
Definition: Exprtk.hpp:6793
void release()
Definition: Exprtk.hpp:6808
std::size_t node_depth() const exprtk_final
Definition: Exprtk.hpp:6818
T value() const exprtk_override
Definition: Exprtk.hpp:6782
bool valid() const exprtk_override
Definition: Exprtk.hpp:6803
Definition: Exprtk.hpp:16071
virtual operator_type operation() const
Definition: Exprtk.hpp:16077
virtual ~uv_base_node()
Definition: Exprtk.hpp:16074
virtual const T & v() const =0
Definition: Exprtk.hpp:5101
~vec_data_store()
Definition: Exprtk.hpp:5210
data_t & ref()
Definition: Exprtk.hpp:5251
vec_data_store(const std::size_t &size)
Definition: Exprtk.hpp:5196
data_t data()
Definition: Exprtk.hpp:5236
control_block * control_block_
Definition: Exprtk.hpp:5295
void dump() const
Definition: Exprtk.hpp:5256
vec_data_store(const std::size_t &size, data_t data, bool dstrct=false)
Definition: Exprtk.hpp:5200
vec_data_store(const type &vds)
Definition: Exprtk.hpp:5204
T * data_t
Definition: Exprtk.hpp:5105
static std::size_t min_size(const control_block *cb0, const control_block *cb1)
Definition: Exprtk.hpp:5284
type & operator=(const type &vds)
Definition: Exprtk.hpp:5215
vec_data_store()
Definition: Exprtk.hpp:5192
std::size_t size() const
Definition: Exprtk.hpp:5246
static void match_sizes(type &vds0, type &vds1)
Definition: Exprtk.hpp:5275
vec_data_store< T > type
Definition: Exprtk.hpp:5104
data_t data() const
Definition: Exprtk.hpp:5241
vector_view< Type > & vec_view_holder_
Definition: Exprtk.hpp:6426
resizable_vector_impl(vector_holder &vec_view_holder, const Type *vec, const std::size_t &vec_size)
Definition: Exprtk.hpp:6377
void remove_ref(value_ptr *ref) exprtk_override
Definition: Exprtk.hpp:6332
sequence_vector_impl & operator=(const sequence_vector_impl &) exprtk_delete
const Type * vec_
Definition: Exprtk.hpp:6273
sequence_vector_impl(const sequence_vector_impl &) exprtk_delete
virtual ~resizable_vector_impl()
Definition: Exprtk.hpp:6388
void set_ref(value_ptr *ref) exprtk_override
Definition: Exprtk.hpp:6327
resizable_vector_impl & operator=(const resizable_vector_impl &) exprtk_delete
const std::size_t size_
Definition: Exprtk.hpp:6274
value_ptr value_at(const std::size_t &index) const exprtk_override
Definition: Exprtk.hpp:6252
array_vector_impl(const Type *vec, const std::size_t &vec_size)
Definition: Exprtk.hpp:6245
array_vector_impl(const array_vector_impl &) exprtk_delete
vector_view_t & vec_view_
Definition: Exprtk.hpp:6370
exprtk::vector_view< Type > vector_view_t
Definition: Exprtk.hpp:6319
sequence_vector_impl(sequence_t &seq)
Definition: Exprtk.hpp:6285
vector_view_impl(vector_view_t &vec_view)
Definition: Exprtk.hpp:6321
virtual vector_view< Type > * rebaseable_instance() exprtk_override
Definition: Exprtk.hpp:6414
array_vector_impl & operator=(const array_vector_impl &) exprtk_delete
vector_view_impl(const vector_view_impl &) exprtk_delete
vector_view< Type > * rebaseable_instance() exprtk_override
Definition: Exprtk.hpp:6342
std::size_t vector_base_size() const exprtk_override
Definition: Exprtk.hpp:6263
std::size_t vector_size() const exprtk_override
Definition: Exprtk.hpp:6258
sequence_t & sequence_
Definition: Exprtk.hpp:6312
resizable_vector_impl(const resizable_vector_impl &) exprtk_delete
vector_view_impl & operator=(const vector_view_impl &) exprtk_delete
Sequence< Type, Allocator > sequence_t
Definition: Exprtk.hpp:6283
bool rebaseable() const exprtk_override
Definition: Exprtk.hpp:6337
virtual void set_ref(value_ptr *)
Definition: Exprtk.hpp:6223
virtual std::size_t vector_size() const =0
virtual ~vector_holder_base()
Definition: Exprtk.hpp:6195
virtual std::size_t vector_base_size() const =0
std::size_t base_size() const
Definition: Exprtk.hpp:6208
value_ptr data() const
Definition: Exprtk.hpp:6213
value_ptr operator[](const std::size_t &index) const
Definition: Exprtk.hpp:6198
virtual vector_view< Type > * rebaseable_instance()
Definition: Exprtk.hpp:6229
std::size_t size() const
Definition: Exprtk.hpp:6203
virtual bool rebaseable() const
Definition: Exprtk.hpp:6218
virtual void remove_ref(value_ptr *)
Definition: Exprtk.hpp:6226
virtual value_ptr value_at(const std::size_t &) const =0
Definition: Exprtk.hpp:6183
vector_view< Type > * rebaseable_instance()
Definition: Exprtk.hpp:6495
vector_holder_base * vector_holder_base_
Definition: Exprtk.hpp:6505
std::size_t base_size() const
Definition: Exprtk.hpp:6464
value_type * value_ptr
Definition: Exprtk.hpp:6187
vector_holder(Type *vec, const std::size_t &vec_size)
Definition: Exprtk.hpp:6433
void remove_ref(value_ptr *ref)
Definition: Exprtk.hpp:6482
vector_holder(std::vector< Type, Allocator > &vec)
Definition: Exprtk.hpp:6442
const value_ptr const_value_ptr
Definition: Exprtk.hpp:6188
details::vec_data_store< Type > vds_t
Definition: Exprtk.hpp:6431
vector_holder(exprtk::vector_view< Type > &vec)
Definition: Exprtk.hpp:6446
vector_holder(const vector_holder< Type > &) exprtk_delete
std::size_t size() const
Definition: Exprtk.hpp:6459
vector_holder(const vds_t &vds)
Definition: Exprtk.hpp:6437
vector_holder< Type > & operator=(const vector_holder< Type > &) exprtk_delete
vector_holder(vector_holder_t &vec_holder, const vds_t &vds)
Definition: Exprtk.hpp:6450
value_ptr data() const
Definition: Exprtk.hpp:6469
Type value_type
Definition: Exprtk.hpp:6186
vector_holder< Type > vector_holder_t
Definition: Exprtk.hpp:6189
value_ptr operator[](const std::size_t &index) const
Definition: Exprtk.hpp:6454
void set_ref(value_ptr *ref)
Definition: Exprtk.hpp:6474
bool rebaseable() const
Definition: Exprtk.hpp:6490
Definition: Exprtk.hpp:8330
virtual vector_node_ptr vec() const =0
virtual const vds_t & vds() const =0
virtual bool side_effect() const
Definition: Exprtk.hpp:8351
vector_node< T > * vector_node_ptr
Definition: Exprtk.hpp:8333
virtual vector_node_ptr vec()=0
virtual std::size_t size() const =0
virtual ~vector_interface()
Definition: Exprtk.hpp:8336
vec_data_store< T > vds_t
Definition: Exprtk.hpp:8334
virtual std::size_t base_size() const =0
Definition: Exprtk.hpp:8326
Definition: Exprtk.hpp:16009
virtual ~vob_base_node()
Definition: Exprtk.hpp:16012
virtual const T & v() const =0
Definition: Exprtk.hpp:15991
virtual const T & v() const =0
virtual ~voc_base_node()
Definition: Exprtk.hpp:15994
virtual const T c() const =0
virtual operator_type operation() const
Definition: Exprtk.hpp:15997
Definition: Exprtk.hpp:15955
virtual const T & v0() const =0
virtual operator_type operation() const
Definition: Exprtk.hpp:15961
virtual ~vov_base_node()
Definition: Exprtk.hpp:15958
virtual const T & v1() const =0
Definition: Exprtk.hpp:7629
while_loop_node< T > parent_t
Definition: Exprtk.hpp:7632
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7633
while_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
Definition: Exprtk.hpp:7635
T value() const exprtk_override
Definition: Exprtk.hpp:7642
Definition: Exprtk.hpp:7315
void collect_nodes(typename expression_node< T >::noderef_list_t &node_delete_list) exprtk_override
Definition: Exprtk.hpp:7353
std::pair< expression_ptr, bool > branch_t
Definition: Exprtk.hpp:7319
T value() const exprtk_override
Definition: Exprtk.hpp:7329
while_loop_node(expression_ptr condition, expression_ptr loop_body)
Definition: Exprtk.hpp:7321
expression_node< T >::node_type type() const exprtk_override
Definition: Exprtk.hpp:7341
expression_node< T > * expression_ptr
Definition: Exprtk.hpp:7318
branch_t condition_
Definition: Exprtk.hpp:7366
bool valid() const exprtk_override exprtk_final
Definition: Exprtk.hpp:7346
std::size_t node_depth() const exprtk_override
Definition: Exprtk.hpp:7359
branch_t loop_body_
Definition: Exprtk.hpp:7367
Definition: Exprtk.hpp:21155
static bool is_variable(const expression< T > &expr)
Definition: Exprtk.hpp:21163
static bool is_binary(const expression< T > &expr)
Definition: Exprtk.hpp:21173
static bool is_constant(const expression< T > &expr)
Definition: Exprtk.hpp:21158
static bool is_function(const expression< T > &expr)
Definition: Exprtk.hpp:21178
static bool is_unary(const expression< T > &expr)
Definition: Exprtk.hpp:21168
static bool is_null(const expression< T > &expr)
Definition: Exprtk.hpp:21183
Definition: Exprtk.hpp:20773
const control_block::local_data_list_t & local_data_list()
Definition: Exprtk.hpp:21114
expression()
Definition: Exprtk.hpp:20903
details::vector_holder< T > * vector_holder_ptr
Definition: Exprtk.hpp:20777
symbol_table< T > & get_symbol_table(const std::size_t &index=0)
Definition: Exprtk.hpp:21015
expression(const expression< T > &e)
Definition: Exprtk.hpp:20909
void set_expression(const expression_ptr expr)
Definition: Exprtk.hpp:21045
void register_local_var(expression_ptr expr)
Definition: Exprtk.hpp:21061
const symbol_table< T > & get_symbol_table(const std::size_t &index=0) const
Definition: Exprtk.hpp:21010
bool operator!() const
Definition: Exprtk.hpp:20953
void register_symbol_table(symbol_table< T > &st)
Definition: Exprtk.hpp:20997
const results_context_t & results() const
Definition: Exprtk.hpp:21022
bool operator==(const expression< T > &e) const
Definition: Exprtk.hpp:20948
expression(const symbol_table< T > &symbol_table)
Definition: Exprtk.hpp:20916
symtab_list_t get_symbol_table_list() const
Definition: Exprtk.hpp:21040
std::vector< symbol_table< T > > symtab_list_t
Definition: Exprtk.hpp:20778
void register_local_var(vector_holder_ptr vec_holder)
Definition: Exprtk.hpp:21076
bool return_invoked() const
Definition: Exprtk.hpp:21033
friend bool is_valid(const expression< TT > &expr)
results_context< T > results_context_t
Definition: Exprtk.hpp:21020
~expression()
Definition: Exprtk.hpp:20969
void set_retinvk(bool *retinvk_ptr)
Definition: Exprtk.hpp:21135
expression< T > & operator=(const expression< T > &e)
Definition: Exprtk.hpp:20923
void register_local_data(void *data, const std::size_t &size=0, const std::size_t data_mode=0)
Definition: Exprtk.hpp:21091
T value() const
Definition: Exprtk.hpp:20974
expression< T > & release()
Definition: Exprtk.hpp:20961
control_block * control_block_
Definition: Exprtk.hpp:21143
void register_return_results(results_context_t *rc)
Definition: Exprtk.hpp:21127
details::expression_node< T > * expression_ptr
Definition: Exprtk.hpp:20776
Definition: Exprtk.hpp:41013
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:41825
exprtk::symbol_table< T > symbol_table_t
Definition: Exprtk.hpp:41017
std::vector< symbol_table_t * > auxiliary_symtab_list_
Definition: Exprtk.hpp:41880
bool load_vectors_
Definition: Exprtk.hpp:41883
const symbol_table_t & symbol_table() const
Definition: Exprtk.hpp:41607
const T & type
Definition: Exprtk.hpp:41393
std::vector< funcparam_t > fp_map_
Definition: Exprtk.hpp:41879
exprtk::parser< T > parser_t
Definition: Exprtk.hpp:41018
function_compositor()
Definition: Exprtk.hpp:41580
void add_auxiliary_symtab(symbol_table_t &symtab)
Definition: Exprtk.hpp:41612
bool load_variables_
Definition: Exprtk.hpp:41882
std::string error() const
Definition: Exprtk.hpp:41652
bool add(const function &f, const bool override=false)
Definition: Exprtk.hpp:41647
parser_error::type get_error(const std::size_t &index) const
Definition: Exprtk.hpp:41667
~function_compositor()
Definition: Exprtk.hpp:41597
static T return_value(expression_t &e)
Definition: Exprtk.hpp:41501
std::map< std::string, expression_t > expr_map_
Definition: Exprtk.hpp:41878
parser_t parser_
Definition: Exprtk.hpp:41877
std::map< std::string, base_func * > funcparam_t
Definition: Exprtk.hpp:41379
parser_t::settings_store settings_t
Definition: Exprtk.hpp:41019
std::deque< parser_error::type > error_list_
Definition: Exprtk.hpp:41881
void load_vectors(const bool load=true)
Definition: Exprtk.hpp:41622
void clear()
Definition: Exprtk.hpp:41627
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:41679
void remove(const std::string &name, const std::size_t &arg_count)
Definition: Exprtk.hpp:41851
void load_variables(const bool load=true)
Definition: Exprtk.hpp:41617
function_compositor(const symbol_table_t &st)
Definition: Exprtk.hpp:41588
symbol_table_t symbol_table_
Definition: Exprtk.hpp:41876
exprtk::expression< T > expression_t
Definition: Exprtk.hpp:41016
std::size_t error_count() const
Definition: Exprtk.hpp:41662
bool valid(const std::string &name, const std::size_t &arg_count) const
Definition: Exprtk.hpp:41812
bool symbol_used(const std::string &symbol) const
Definition: Exprtk.hpp:41801
symbol_table_t & symbol_table()
Definition: Exprtk.hpp:41602
Definition: Exprtk.hpp:18779
std::size_t & max_num_args()
Definition: Exprtk.hpp:18804
function_traits()
Definition: Exprtk.hpp:18782
std::size_t & min_num_args()
Definition: Exprtk.hpp:18799
bool has_side_effects_
Definition: Exprtk.hpp:18812
std::size_t max_num_args_
Definition: Exprtk.hpp:18814
bool allow_zero_parameters_
Definition: Exprtk.hpp:18811
std::size_t min_num_args_
Definition: Exprtk.hpp:18813
bool & allow_zero_parameters()
Definition: Exprtk.hpp:18789
bool & has_side_effects()
Definition: Exprtk.hpp:18794
Definition: Exprtk.hpp:18863
virtual ~ifunction()
Definition: Exprtk.hpp:18870
ifunction(const std::size_t &pc)
Definition: Exprtk.hpp:18866
Definition: Exprtk.hpp:18974
generic_type::parameter_list parameter_list_t
Definition: Exprtk.hpp:18986
T type
Definition: Exprtk.hpp:18984
igeneric_function(const std::string &param_seq="", const return_type rtr_type=e_rtrn_scalar)
Definition: Exprtk.hpp:18988
type_store< T > generic_type
Definition: Exprtk.hpp:18985
virtual ~igeneric_function()
Definition: Exprtk.hpp:18993
return_type
Definition: Exprtk.hpp:18978
virtual T operator()(parameter_list_t) igeneric_function_empty_body(1) inline virtual T operator()(std return_type rtrn_type
Definition: Exprtk.hpp:19003
Definition: Exprtk.hpp:18959
virtual ~ivararg_function()
Definition: Exprtk.hpp:18962
Definition: Exprtk.hpp:2348
std::string substr(const std::size_t &begin, const std::size_t &end) const
Definition: Exprtk.hpp:2475
token_t operator[](const std::size_t &index) const
Definition: Exprtk.hpp:2448
token_t & next_token()
Definition: Exprtk.hpp:2420
bool finished() const
Definition: Exprtk.hpp:2456
void insert_front(token_t::token_type tk_type)
Definition: Exprtk.hpp:2461
void scan_string()
Definition: Exprtk.hpp:2911
token_t & operator[](const std::size_t &index)
Definition: Exprtk.hpp:2440
bool is_comment_start(details::char_cptr itr) const
Definition: Exprtk.hpp:2501
void scan_symbol()
Definition: Exprtk.hpp:2730
token_t eof_token_
Definition: Exprtk.hpp:3019
void scan_number()
Definition: Exprtk.hpp:2762
token_list_itr_t store_token_itr_
Definition: Exprtk.hpp:3018
void begin()
Definition: Exprtk.hpp:2404
void scan_operator()
Definition: Exprtk.hpp:2665
bool process(const std::string &str)
Definition: Exprtk.hpp:2374
bool empty() const
Definition: Exprtk.hpp:2394
token_list_t::iterator token_list_itr_t
Definition: Exprtk.hpp:2353
void scan_special_function()
Definition: Exprtk.hpp:2869
details::char_t char_t
Definition: Exprtk.hpp:2354
token_list_itr_t token_itr_
Definition: Exprtk.hpp:3017
void store()
Definition: Exprtk.hpp:2410
void restore()
Definition: Exprtk.hpp:2415
token_list_t token_list_
Definition: Exprtk.hpp:3016
details::char_cptr base_itr_
Definition: Exprtk.hpp:3020
generator()
Definition: Exprtk.hpp:2356
void skip_comments()
Definition: Exprtk.hpp:2530
token token_t
Definition: Exprtk.hpp:2351
token_t & peek_next_token()
Definition: Exprtk.hpp:2430
void clear()
Definition: Exprtk.hpp:2364
details::char_cptr s_itr_
Definition: Exprtk.hpp:3021
std::size_t size() const
Definition: Exprtk.hpp:2399
void skip_whitespace()
Definition: Exprtk.hpp:2522
bool is_end(details::char_cptr itr) const
Definition: Exprtk.hpp:2495
std::vector< token_t > token_list_t
Definition: Exprtk.hpp:2352
details::char_cptr s_end_
Definition: Exprtk.hpp:3022
void scan_token()
Definition: Exprtk.hpp:2607
std::string remaining() const
Definition: Exprtk.hpp:2483
void ignore_symbol(const std::string &symbol)
Definition: Exprtk.hpp:3416
std::set< std::string, details::ilesscompare > ignore_set_
Definition: Exprtk.hpp:3465
int insert(const lexer::token &t0, const lexer::token &t1, lexer::token &new_token) exprtk_override
Definition: Exprtk.hpp:3421
commutative_inserter()
Definition: Exprtk.hpp:3412
Definition: Exprtk.hpp:3469
bool state_
Definition: Exprtk.hpp:3724
std::map< std::string, std::pair< std::string, token::token_type >, details::ilesscompare > replace_map_t
Definition: Exprtk.hpp:3797
lexer::token error_token()
Definition: Exprtk.hpp:3671
void clear_errors()
Definition: Exprtk.hpp:3782
bool join(const lexer::token &t0, const lexer::token &t1, const lexer::token &t2, lexer::token &t) exprtk_override
Definition: Exprtk.hpp:3621
std::vector< std::size_t > error_list_
Definition: Exprtk.hpp:3790
bool result() exprtk_override
Definition: Exprtk.hpp:3655
bool modify(lexer::token &t) exprtk_override
Definition: Exprtk.hpp:3836
numeric_checker()
Definition: Exprtk.hpp:3736
void add_invalid(const token_t t0, const token_t t1, const token_t t2)
Definition: Exprtk.hpp:4108
void reset() exprtk_override
Definition: Exprtk.hpp:3676
sequence_validator_3tokens()
Definition: Exprtk.hpp:4044
std::pair< lexer::token::token_type, lexer::token::token_type > token_pair_t
Definition: Exprtk.hpp:3864
std::set< token_pair_t > set_t
Definition: Exprtk.hpp:3865
std::size_t error_count() const
Definition: Exprtk.hpp:3769
std::pair< lexer::token, lexer::token > error(const std::size_t index)
Definition: Exprtk.hpp:3925
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:3813
std::set< token_triplet_t > set_t
Definition: Exprtk.hpp:4038
bracket_checker()
Definition: Exprtk.hpp:3650
sequence_validator()
Definition: Exprtk.hpp:3871
set_t invalid_comb_
Definition: Exprtk.hpp:4028
std::size_t error_index(const std::size_t &i)
Definition: Exprtk.hpp:3774
void add_invalid_set1(const lexer::token::token_type t)
Definition: Exprtk.hpp:3950
lexer::token error_token_
Definition: Exprtk.hpp:3726
bool remove(const std::string &target_symbol)
Definition: Exprtk.hpp:3801
bool invalid_bracket_check(const lexer::token::token_type base, const lexer::token::token_type t)
Definition: Exprtk.hpp:3969
void clear()
Definition: Exprtk.hpp:3829
std::pair< token_t, std::pair< token_t, token_t > > token_triplet_t
Definition: Exprtk.hpp:4037
std::stack< std::pair< char, std::size_t > > stack_
Definition: Exprtk.hpp:3725
std::vector< std::pair< lexer::token, lexer::token > > error_list_
Definition: Exprtk.hpp:4029
bool join(const lexer::token &t0, const lexer::token &t1, lexer::token &t) exprtk_override
Definition: Exprtk.hpp:3476
lexer::token::token_type token_t
Definition: Exprtk.hpp:4036
replace_map_t replace_map_
Definition: Exprtk.hpp:3857
void add_invalid(const lexer::token::token_type base, const lexer::token::token_type t)
Definition: Exprtk.hpp:3945
std::size_t current_index_
Definition: Exprtk.hpp:3789
operator_joiner(const std::size_t &stride)
Definition: Exprtk.hpp:3472
Definition: Exprtk.hpp:3031
virtual bool result()
Definition: Exprtk.hpp:3036
virtual void init()
Definition: Exprtk.hpp:3034
virtual std::size_t process(generator &)
Definition: Exprtk.hpp:3037
virtual ~helper_interface()
Definition: Exprtk.hpp:3038
virtual void reset()
Definition: Exprtk.hpp:3035
Definition: Exprtk.hpp:4276
generator_t lexer_
Definition: Exprtk.hpp:4474
generator_t & lexer()
Definition: Exprtk.hpp:4296
bool token_is_loop(const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4455
void advance_token(const token_advance_mode mode)
Definition: Exprtk.hpp:4339
const generator_t & lexer() const
Definition: Exprtk.hpp:4301
bool token_is_arithmetic_opr(const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4389
bool token_is_left_bracket(const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4425
bool token_is_right_bracket(const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4440
token_advance_mode
Definition: Exprtk.hpp:4334
bool token_is_ineq_opr(const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4407
bool token_is(const std::string &value, const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4376
bool peek_token_is(const token_t::token_type &ttype)
Definition: Exprtk.hpp:4462
void next_token()
Definition: Exprtk.hpp:4318
void restore_token()
Definition: Exprtk.hpp:4312
bool peek_token_is(const std::string &s)
Definition: Exprtk.hpp:4467
token token_t
Definition: Exprtk.hpp:4279
token_t store_current_token_
Definition: Exprtk.hpp:4476
bool init(const std::string &str)
Definition: Exprtk.hpp:4282
generator generator_t
Definition: Exprtk.hpp:4280
token_t current_token_
Definition: Exprtk.hpp:4475
const token_t & peek_next_token()
Definition: Exprtk.hpp:4328
const token_t & current_token() const
Definition: Exprtk.hpp:4323
bool token_is(const token_t::token_type &ttype, const std::string &value, const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4359
void store_token()
Definition: Exprtk.hpp:4306
bool token_is(const token_t::token_type &ttype, const token_advance_mode mode=e_advance)
Definition: Exprtk.hpp:4347
Definition: Exprtk.hpp:3168
std::size_t process(generator &g) exprtk_override
Definition: Exprtk.hpp:3180
virtual int insert(const token &, token &) token_inserter_empty_body inline virtual int insert(const token &
token_inserter(const std::size_t &stride)
Definition: Exprtk.hpp:3171
virtual int const token token &virtual token_inserter_empty_body int insert(const token &, const token &, const token &, token &) token_inserter_empty_body inline virtual int insert(const token &
Definition: Exprtk.hpp:3277
const std::size_t stride_
Definition: Exprtk.hpp:3387
virtual bool join(const token &, const token &, token &)
Definition: Exprtk.hpp:3297
token_joiner(const std::size_t &stride)
Definition: Exprtk.hpp:3280
std::size_t process_stride_3(generator &g)
Definition: Exprtk.hpp:3344
std::size_t process_stride_2(generator &g)
Definition: Exprtk.hpp:3302
std::size_t process(generator &g) exprtk_override
Definition: Exprtk.hpp:3284
virtual bool join(const token &, const token &, const token &, token &)
Definition: Exprtk.hpp:3298
Definition: Exprtk.hpp:3149
virtual bool modify(token &t)=0
std::size_t process(generator &g) exprtk_override
Definition: Exprtk.hpp:3152
Definition: Exprtk.hpp:3042
token_scanner(const std::size_t &stride)
Definition: Exprtk.hpp:3048
const std::size_t stride_
Definition: Exprtk.hpp:3145
std::size_t process(generator &g) exprtk_override
Definition: Exprtk.hpp:3057
virtual ~token_scanner()
Definition: Exprtk.hpp:3045
Definition: Exprtk.hpp:22643
std::pair< std::string, symbol_type > symbol_t
Definition: Exprtk.hpp:22646
bool & collect_variables()
Definition: Exprtk.hpp:22719
bool collect_assignments_
Definition: Exprtk.hpp:22794
void clear()
Definition: Exprtk.hpp:22710
std::vector< std::string > retparam_list_t
Definition: Exprtk.hpp:22744
bool return_present_
Definition: Exprtk.hpp:22795
bool collect_functions_
Definition: Exprtk.hpp:22793
bool final_stmt_return_
Definition: Exprtk.hpp:22796
bool collect_variables_
Definition: Exprtk.hpp:22792
bool final_stmt_return() const
Definition: Exprtk.hpp:22739
symbol_list_t symbol_name_list_
Definition: Exprtk.hpp:22797
symbol_list_t assignment_name_list_
Definition: Exprtk.hpp:22798
bool return_present() const
Definition: Exprtk.hpp:22734
std::vector< symbol_t > symbol_list_t
Definition: Exprtk.hpp:22647
void add_assignment(const std::string &symbol, const symbol_type st)
Definition: Exprtk.hpp:22776
bool & collect_assignments()
Definition: Exprtk.hpp:22729
bool & collect_functions()
Definition: Exprtk.hpp:22724
void add_symbol(const std::string &symbol, const symbol_type st)
Definition: Exprtk.hpp:22753
std::size_t assignment_symbols(Sequence< symbol_t, Allocator > &assignment_list)
Definition: Exprtk.hpp:22686
std::size_t options_
Definition: Exprtk.hpp:22791
retparam_list_t return_param_type_list() const
Definition: Exprtk.hpp:22746
dependent_entity_collector(const std::size_t options=e_ct_none)
Definition: Exprtk.hpp:22649
std::size_t symbols(Sequence< symbol_t, Allocator > &symbols_list)
Definition: Exprtk.hpp:22660
Definition: Exprtk.hpp:29930
expression_node_ptr repeat_until_loop(expression_node_ptr &condition, expression_node_ptr &branch, const bool break_continue_present=false) const
Definition: Exprtk.hpp:31133
void lodge_assignment(symbol_type cst, expression_node_ptr node)
Definition: Exprtk.hpp:32490
bool sf4_optimisable(const std::string &sf4id, quaternary_functor_t &qfunc) const
Definition: Exprtk.hpp:30155
expression_node_ptr conditional(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition: Exprtk.hpp:30848
std::string branch_to_id(expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30350
bool coboc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30416
details::expression_node< Type > * expression_node_ptr
Definition: Exprtk.hpp:29933
bool assign_immutable_symbol(expression_node_ptr node)
Definition: Exprtk.hpp:32590
bool boc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30391
bool special_one_parameter_vararg(const details::operator_type &operation) const
Definition: Exprtk.hpp:31839
expression_node_ptr conditional_vector(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition: Exprtk.hpp:31000
expression_node_ptr const_optimise_varargfunc(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:31808
bool cov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30355
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:32078
expression_node_ptr synthesize_uvec_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition: Exprtk.hpp:31565
bool is_invalid_string_op(const details::operator_type &operation, expression_node_ptr(&branch)[3]) const
Definition: Exprtk.hpp:30541
expression_node_ptr synthesize_sosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39291
expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:32960
expression_node_ptr synthesize_expression(F *f, expression_node_ptr(&branch)[N])
Definition: Exprtk.hpp:39867
expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33355
expression_node_ptr synthesize_uv_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition: Exprtk.hpp:31548
expression_node_ptr vararg_function(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:31900
bool is_invalid_string_op(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30521
expression_node_ptr varnode_optimise_varargfunc(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:31852
expression_node_ptr switch_statement(Sequence< expression_node_ptr, Allocator > &arg_list, const bool default_statement_present)
Definition: Exprtk.hpp:31453
void set_allocator(details::node_allocator &na)
Definition: Exprtk.hpp:30045
bool is_invalid_assignment_op(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30468
expression_node_ptr multi_switch_statement(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:31492
synthesize_map_t synthesize_map_
Definition: Exprtk.hpp:39907
sf4_map_t * sf4_map_
Definition: Exprtk.hpp:39912
expression_node_ptr synthesize_swap_expression(expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33138
bool is_null_present(expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30594
expression_node_ptr synthesize_srosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39317
void set_ibom(inv_binary_op_map_t &inv_binary_op_map)
Definition: Exprtk.hpp:30030
expression_node_ptr const_optimise_switch(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:31278
bool synthesize_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2], expression_node_ptr &result)
Definition: Exprtk.hpp:34321
expression_node_ptr special_function(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition: Exprtk.hpp:31773
bool valid_operator(const details::operator_type &operation, binary_functor_t &bop)
Definition: Exprtk.hpp:30060
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:39238
expression_node_ptr synthesize_csros_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39442
bool is_vector_eqineq_logic_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30602
void set_bom(binary_op_map_t &binary_op_map)
Definition: Exprtk.hpp:30025
bool strength_reduction_enabled_
Definition: Exprtk.hpp:39905
bool is_string_operation(const details::operator_type &operation, expression_node_ptr(&branch)[3]) const
Definition: Exprtk.hpp:30570
const void * base_ptr(expression_node_ptr node)
Definition: Exprtk.hpp:32540
bool binext_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30459
std::string to_str(const details::operator_type &operation) const
Definition: Exprtk.hpp:30261
bool is_constant_foldable(const Sequence< NodePtr, Allocator > &b) const
Definition: Exprtk.hpp:32477
expression_node_ptr synthesize_csosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39353
details::operator_type get_operator(const binary_functor_t &bop) const
Definition: Exprtk.hpp:30084
expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33220
expression_node_ptr varnode_optimise_sf3(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: Exprtk.hpp:31634
expression_node_ptr synthesize_sos_expression_impl(const details::operator_type &opr, T0 s0, T1 s1)
Definition: Exprtk.hpp:39256
expression_node_ptr synthesize_uvouv_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39114
bool is_string_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30562
void set_uom(unary_op_map_t &unary_op_map)
Definition: Exprtk.hpp:30020
void set_parser(parser_t &p)
Definition: Exprtk.hpp:30015
bool is_constpow_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30495
expression_node_ptr synthesize_csocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39397
expression_node_ptr return_envelope(expression_node_ptr body, results_context_t *rc, bool *&return_invoked)
Definition: Exprtk.hpp:32271
bool is_vector_arithmetic_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30624
bool valid_string_operation(const details::operator_type &operation) const
Definition: Exprtk.hpp:30238
bool is_invalid_break_continue_op(expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30511
vector_access_runtime_check_ptr get_vector_access_runtime_check() const
Definition: Exprtk.hpp:31068
expression_node_ptr synthesize_string_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39518
exprtk::parser< Type > parser_t
Definition: Exprtk.hpp:29936
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:31187
bool valid_operator(const details::operator_type &operation, unary_functor_t &uop)
Definition: Exprtk.hpp:30072
expression_node_ptr synthesize_srocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39367
unary_op_map_t * unary_op_map_
Definition: Exprtk.hpp:39908
expression_node_ptr synthesize_assignment_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:32619
expression_node_ptr return_call(std::vector< expression_node_ptr > &arg_list)
Definition: Exprtk.hpp:32228
bool vob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30441
void init_synthesize_map()
Definition: Exprtk.hpp:29940
expression_node_ptr synthesize_csos_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39343
expression_node_ptr synthesize_null_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39721
parser_t * parser_
Definition: Exprtk.hpp:39913
expression_node_ptr while_loop(expression_node_ptr &condition, expression_node_ptr &branch, const bool break_continue_present=false) const
Definition: Exprtk.hpp:31073
expression_node_ptr synthesize_unary_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition: Exprtk.hpp:31581
const Type ctype
Definition: Exprtk.hpp:29938
sf3_map_t * sf3_map_
Definition: Exprtk.hpp:39911
void set_strength_reduction_state(const bool enabled)
Definition: Exprtk.hpp:30050
expression_node_ptr synthesize_srocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39381
bool sf3_optimisable(const std::string &sf3id, trinary_functor_t &tfunc) const
Definition: Exprtk.hpp:30143
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:32298
expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:32688
expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp1)
Definition: Exprtk.hpp:39220
expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33052
expression_node_ptr special_function(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: Exprtk.hpp:31666
bool cardinal_pow_optimisable(const details::operator_type &operation, const T &c) const
Definition: Exprtk.hpp:33350
expression_node_ptr synthesize_string_expression(const details::operator_type &opr, expression_node_ptr(&branch)[3])
Definition: Exprtk.hpp:39605
expression_node_ptr synthesize_sros_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39278
expression_node_ptr synthesize_csocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39428
bool strength_reduction_enabled() const
Definition: Exprtk.hpp:30055
expression_node_ptr varnode_optimise_sf4(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition: Exprtk.hpp:31739
details::node_allocator * node_allocator_
Definition: Exprtk.hpp:39906
bool operation_optimisable(const details::operator_type &operation) const
Definition: Exprtk.hpp:30287
expression_node_ptr synthesize_csrocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39471
expression_node_ptr synthesize_socsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39304
expression_node_ptr synthesize_csrocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39484
expression_node_ptr vectorize_func(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:31875
bool cob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30382
expression_node_ptr synthesize_expression(const details::operator_type &operation, expression_node_ptr(&branch)[N])
Definition: Exprtk.hpp:39818
bool unary_optimisable(const details::operator_type &operation) const
Definition: Exprtk.hpp:30119
expression_node_ptr cardinal_pow_optimisation(const T &v, const T &c)
Definition: Exprtk.hpp:33329
bool is_constant_foldable(NodePtr(&b)[N]) const
Definition: Exprtk.hpp:32461
expression_node_ptr const_optimise_sf3(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: Exprtk.hpp:31596
expression_node_ptr const_optimise_sf4(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition: Exprtk.hpp:31701
expression_node_ptr synthesize_strogen_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39499
std::string branch_to_id(expression_node_ptr branch) const
Definition: Exprtk.hpp:30309
bool bov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30450
expression_node_ptr synthesize_csrosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39455
bool voc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30364
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:32153
inv_binary_op_map_t * inv_binary_op_map_
Definition: Exprtk.hpp:39910
bool sf3_optimisable(const std::string &sf3id, details::operator_type &operation) const
Definition: Exprtk.hpp:30167
loop_runtime_check_ptr get_loop_runtime_check(const loop_runtime_check::loop_types loop_type) const
Definition: Exprtk.hpp:31055
expression_node_ptr vararg_function_call(ivararg_function_t *vaf, std::vector< expression_node_ptr > &arg_list)
Definition: Exprtk.hpp:32036
bool is_shortcircuit_expression(const details::operator_type &operation) const
Definition: Exprtk.hpp:30580
expression_node_ptr cardinal_pow_optimisation_impl(const TType &v, const unsigned int &p)
Definition: Exprtk.hpp:33301
void set_sf3m(sf3_map_t &sf3_map)
Definition: Exprtk.hpp:30035
bool uvouv_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30432
bool is_assignment_operation(const details::operator_type &operation) const
Definition: Exprtk.hpp:30225
bool sf4_optimisable(const std::string &sf4id, details::operator_type &operation) const
Definition: Exprtk.hpp:30179
std::map< std::string, synthesize_functor_t > synthesize_map_t
Definition: Exprtk.hpp:29935
bool cocob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30400
expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp0)
Definition: Exprtk.hpp:39202
binary_op_map_t * binary_op_map_
Definition: Exprtk.hpp:39909
bool vov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: Exprtk.hpp:30373
expression_node_ptr conditional_string(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition: Exprtk.hpp:30924
expression_node_ptr const_optimise_mswitch(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: Exprtk.hpp:31314
expression_node_ptr synthesize_socs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39333
void set_sf4m(sf4_map_t &sf4_map)
Definition: Exprtk.hpp:30040
expression_node_ptr synthesize_sos_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39270
const Type & vtype
Definition: Exprtk.hpp:29937
Definition: Exprtk.hpp:21858
bool add_interval(const interval_point_t begin, const interval_point_t end)
Definition: Exprtk.hpp:21907
bool in_interval(const interval_point_t point, interval_t &interval) const
Definition: Exprtk.hpp:21876
std::map< interval_point_t, interval_t > interval_map_t
Definition: Exprtk.hpp:21863
std::pair< interval_point_t, interval_point_t > interval_t
Definition: Exprtk.hpp:21862
interval_map_t::const_iterator interval_map_citr_t
Definition: Exprtk.hpp:21864
interval_map_t interval_map_
Definition: Exprtk.hpp:21926
IntervalPointType interval_point_t
Definition: Exprtk.hpp:21861
void reset()
Definition: Exprtk.hpp:21871
bool add_interval(const interval_t interval)
Definition: Exprtk.hpp:21919
bool in_interval(const interval_point_t point) const
Definition: Exprtk.hpp:21901
std::size_t size() const
Definition: Exprtk.hpp:21866
Definition: Exprtk.hpp:21551
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:21602
scope_element_manager & operator=(const scope_element_manager &) exprtk_delete
bool empty() const
Definition: Exprtk.hpp:21568
bool add_element(const scope_element &se)
Definition: Exprtk.hpp:21624
scope_element_manager(parser< T > &p)
Definition: Exprtk.hpp:21558
scope_element null_element_
Definition: Exprtk.hpp:21763
expression_node_ptr get_variable(const T &v)
Definition: Exprtk.hpp:21713
scope_element & get_element(const std::string &var_name, const std::size_t index=std::numeric_limits< std::size_t >::max())
Definition: Exprtk.hpp:21581
parser_t & parser_
Definition: Exprtk.hpp:21761
void cleanup()
Definition: Exprtk.hpp:21696
scope_element_manager(const scope_element_manager &) exprtk_delete
std::size_t size() const
Definition: Exprtk.hpp:21563
void free_element(scope_element &se)
Definition: Exprtk.hpp:21667
expression_node_t * expression_node_ptr
Definition: Exprtk.hpp:21554
std::size_t input_param_cnt_
Definition: Exprtk.hpp:21764
scope_element & get_element(const std::size_t &index)
Definition: Exprtk.hpp:21573
std::string get_vector_name(const T *data)
Definition: Exprtk.hpp:21737
variable_node_t * variable_node_ptr
Definition: Exprtk.hpp:21555
std::size_t next_ip_index()
Definition: Exprtk.hpp:21708
std::vector< scope_element > element_
Definition: Exprtk.hpp:21762
parser< T > parser_t
Definition: Exprtk.hpp:21556
void deactivate(const std::size_t &scope_depth)
Definition: Exprtk.hpp:21647
Definition: Exprtk.hpp:21768
scope_handler(const scope_handler &) exprtk_delete
scope_handler(parser< T > &p)
Definition: Exprtk.hpp:21773
~scope_handler()
Definition: Exprtk.hpp:21785
parser_t & parser_
Definition: Exprtk.hpp:21802
scope_handler & operator=(const scope_handler &) exprtk_delete
parser< T > parser_t
Definition: Exprtk.hpp:21771
Definition: Exprtk.hpp:22805
bool enable_collect_assings_
Definition: Exprtk.hpp:23463
settings_store & enable_all_arithmetic_ops()
Definition: Exprtk.hpp:22927
settings_store & enable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
Definition: Exprtk.hpp:23292
bool collect_functions_enabled() const
Definition: Exprtk.hpp:23043
bool control_struct_disabled(const std::string &control_struct) const
Definition: Exprtk.hpp:23108
bool function_disabled(const std::string &function_name) const
Definition: Exprtk.hpp:23100
bool collect_variables_enabled() const
Definition: Exprtk.hpp:23042
bool assignment_enabled(const details::operator_type &assignment) const
Definition: Exprtk.hpp:23082
bool vardef_disabled() const
Definition: Exprtk.hpp:23045
settings_store & disable_all_inequality_ops()
Definition: Exprtk.hpp:23008
std::size_t max_local_vector_size() const
Definition: Exprtk.hpp:23371
bool enable_numeric_check_
Definition: Exprtk.hpp:23456
settings_store & enable_base_function(const settings_base_funcs bf)
Definition: Exprtk.hpp:23238
settings_store & disable_all_control_structures()
Definition: Exprtk.hpp:22972
bool enable_replacer_
Definition: Exprtk.hpp:23454
disabled_entity_set_t::iterator des_itr_t
Definition: Exprtk.hpp:22809
bool enable_joiner_
Definition: Exprtk.hpp:23455
settings_assignment_opr
Definition: Exprtk.hpp:22878
@ e_assign_addass
Definition: Exprtk.hpp:22880
@ e_assign_divass
Definition: Exprtk.hpp:22881
disabled_entity_set_t disabled_arithmetic_set_
Definition: Exprtk.hpp:23471
settings_control_structs
Definition: Exprtk.hpp:22852
@ e_ctrl_repeat_loop
Definition: Exprtk.hpp:22858
@ e_ctrl_switch
Definition: Exprtk.hpp:22855
@ e_ctrl_for_loop
Definition: Exprtk.hpp:22856
@ e_ctrl_while_loop
Definition: Exprtk.hpp:22857
@ e_ctrl_ifelse
Definition: Exprtk.hpp:22854
std::set< std::string, details::ilesscompare > disabled_entity_set_t
Definition: Exprtk.hpp:22808
settings_store & disable_assignment_operation(const settings_assignment_opr assignment)
Definition: Exprtk.hpp:23212
settings_store & enable_commutative_check()
Definition: Exprtk.hpp:22951
std::string inequality_opr_to_string(details::operator_type opr) const
Definition: Exprtk.hpp:23423
settings_compilation_options
Definition: Exprtk.hpp:22814
disabled_entity_set_t disabled_assignment_set_
Definition: Exprtk.hpp:23472
bool assignment_disabled(const details::operator_type assignment_operation) const
Definition: Exprtk.hpp:23124
settings_store & enable_control_structure(const settings_control_structs ctrl_struct)
Definition: Exprtk.hpp:23256
settings_store & enable_all_control_structures()
Definition: Exprtk.hpp:22915
bool disable_rsrvd_sym_usr_
Definition: Exprtk.hpp:23465
bool enable_collect_vars_
Definition: Exprtk.hpp:23461
settings_inequality_opr
Definition: Exprtk.hpp:22885
@ e_ineq_equal
Definition: Exprtk.hpp:22888
@ e_ineq_gte
Definition: Exprtk.hpp:22889
@ e_ineq_eq
Definition: Exprtk.hpp:22887
bool disable_zero_return_
Definition: Exprtk.hpp:23466
bool disable_vardef_
Definition: Exprtk.hpp:23464
bool bracket_check_enabled() const
Definition: Exprtk.hpp:23039
settings_store & disable_logic_operation(const settings_logic_opr logic)
Definition: Exprtk.hpp:23186
settings_store & enable_all_base_functions()
Definition: Exprtk.hpp:22909
settings_store & disable_all_base_functions()
Definition: Exprtk.hpp:22963
settings_store & enable_inequality_operation(const settings_inequality_opr inequality)
Definition: Exprtk.hpp:23328
disabled_entity_set_t disabled_inequality_set_
Definition: Exprtk.hpp:23473
bool logic_enabled(const std::string &logic_operation) const
Definition: Exprtk.hpp:23065
std::string arith_opr_to_string(details::operator_type opr) const
Definition: Exprtk.hpp:23409
bool rsrvd_sym_usr_disabled() const
Definition: Exprtk.hpp:23046
settings_store & enable_all_assignment_ops()
Definition: Exprtk.hpp:22933
std::size_t max_stack_depth() const
Definition: Exprtk.hpp:23361
settings_store & enable_all_logic_ops()
Definition: Exprtk.hpp:22921
settings_store & disable_inequality_operation(const settings_inequality_opr inequality)
Definition: Exprtk.hpp:23225
settings_base_funcs
Definition: Exprtk.hpp:22832
@ e_bf_rad2deg
Definition: Exprtk.hpp:22848
@ e_bf_min
Definition: Exprtk.hpp:22842
@ e_bf_avg
Definition: Exprtk.hpp:22836
@ e_bf_swap
Definition: Exprtk.hpp:22846
@ e_bf_erf
Definition: Exprtk.hpp:22838
@ e_bf_asinh
Definition: Exprtk.hpp:22835
@ e_bf_like
Definition: Exprtk.hpp:22840
@ e_bf_abs
Definition: Exprtk.hpp:22834
@ e_bf_ncdf
Definition: Exprtk.hpp:22843
@ e_bf_roundn
Definition: Exprtk.hpp:22844
@ e_bf_deg2grad
Definition: Exprtk.hpp:22847
@ e_bf_sinc
Definition: Exprtk.hpp:22845
@ e_bf_log2
Definition: Exprtk.hpp:22841
@ e_bf_cosh
Definition: Exprtk.hpp:22837
@ e_bf_floor
Definition: Exprtk.hpp:22839
bool enable_collect_funcs_
Definition: Exprtk.hpp:23462
std::size_t max_stack_depth_
Definition: Exprtk.hpp:23475
bool enable_commutative_check_
Definition: Exprtk.hpp:23459
bool zero_return_disabled() const
Definition: Exprtk.hpp:23047
settings_store & disable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
Definition: Exprtk.hpp:23199
bool control_struct_enabled(const std::string &control_struct) const
Definition: Exprtk.hpp:23057
settings_store & disable_base_function(const settings_base_funcs bf)
Definition: Exprtk.hpp:23160
std::size_t max_local_vector_size_
Definition: Exprtk.hpp:23477
void set_max_node_depth(const std::size_t max_node_depth)
Definition: Exprtk.hpp:23351
settings_store & disable_all_arithmetic_ops()
Definition: Exprtk.hpp:22990
bool commutative_check_enabled() const
Definition: Exprtk.hpp:23036
settings_arithmetic_opr
Definition: Exprtk.hpp:22871
@ e_arith_add
Definition: Exprtk.hpp:22873
@ e_arith_div
Definition: Exprtk.hpp:22874
settings_store & disable_control_structure(const settings_control_structs ctrl_struct)
Definition: Exprtk.hpp:23173
settings_store & disable_commutative_check()
Definition: Exprtk.hpp:23023
void set_max_local_vector_size(const std::size_t max_local_vector_size)
Definition: Exprtk.hpp:23356
disabled_entity_set_t disabled_logic_set_
Definition: Exprtk.hpp:23470
bool enable_sequence_check_
Definition: Exprtk.hpp:23458
std::size_t max_node_depth() const
Definition: Exprtk.hpp:23366
std::size_t max_node_depth_
Definition: Exprtk.hpp:23476
settings_store & enable_logic_operation(const settings_logic_opr logic)
Definition: Exprtk.hpp:23274
bool inequality_enabled(const details::operator_type &inequality) const
Definition: Exprtk.hpp:23091
bool inequality_disabled(const details::operator_type &inequality) const
Definition: Exprtk.hpp:23151
disabled_entity_set_t disabled_ctrl_set_
Definition: Exprtk.hpp:23469
std::string assign_opr_to_string(details::operator_type opr) const
Definition: Exprtk.hpp:23395
settings_store(const std::size_t compile_options=default_compile_all_opts)
Definition: Exprtk.hpp:22901
settings_store & disable_all_logic_ops()
Definition: Exprtk.hpp:22981
settings_store & disable_strength_reduction()
Definition: Exprtk.hpp:23029
disabled_entity_set_t disabled_func_set_
Definition: Exprtk.hpp:23468
settings_store & enable_local_vardef()
Definition: Exprtk.hpp:22945
bool logic_disabled(const std::string &logic_operation) const
Definition: Exprtk.hpp:23116
bool joiner_enabled() const
Definition: Exprtk.hpp:23037
bool enable_strength_reduction_
Definition: Exprtk.hpp:23460
settings_store & enable_strength_reduction()
Definition: Exprtk.hpp:22957
settings_store & disable_local_vardef()
Definition: Exprtk.hpp:23017
bool collect_assignments_enabled() const
Definition: Exprtk.hpp:23044
bool numeric_check_enabled() const
Definition: Exprtk.hpp:23038
bool arithmetic_enabled(const details::operator_type &arithmetic_operation) const
Definition: Exprtk.hpp:23073
void load_compile_options(const std::size_t compile_options)
Definition: Exprtk.hpp:23378
settings_logic_opr
Definition: Exprtk.hpp:22863
@ e_logic_scand
Definition: Exprtk.hpp:22867
@ e_logic_and
Definition: Exprtk.hpp:22865
@ e_logic_not
Definition: Exprtk.hpp:22866
bool replacer_enabled() const
Definition: Exprtk.hpp:23035
bool strength_reduction_enabled() const
Definition: Exprtk.hpp:23041
bool arithmetic_disabled(const details::operator_type arithmetic_operation) const
Definition: Exprtk.hpp:23142
bool function_enabled(const std::string &function_name) const
Definition: Exprtk.hpp:23049
bool logic_disabled(const details::operator_type logic_operation) const
Definition: Exprtk.hpp:23133
bool sequence_check_enabled() const
Definition: Exprtk.hpp:23040
std::string logic_opr_to_string(details::operator_type opr) const
Definition: Exprtk.hpp:23439
settings_store & enable_all_inequality_ops()
Definition: Exprtk.hpp:22939
void set_max_stack_depth(const std::size_t max_stack_depth)
Definition: Exprtk.hpp:23346
settings_store & enable_assignment_operation(const settings_assignment_opr assignment)
Definition: Exprtk.hpp:23310
bool enable_bracket_check_
Definition: Exprtk.hpp:23457
settings_store & disable_all_assignment_ops()
Definition: Exprtk.hpp:22999
Definition: Exprtk.hpp:21930
~stack_limit_handler()
Definition: Exprtk.hpp:21950
stack_limit_handler & operator=(const stack_limit_handler &) exprtk_delete
parser_t & parser_
Definition: Exprtk.hpp:21966
stack_limit_handler(const stack_limit_handler &) exprtk_delete
stack_limit_handler(parser< T > &p)
Definition: Exprtk.hpp:21935
parser< T > parser_t
Definition: Exprtk.hpp:21933
bool operator!()
Definition: Exprtk.hpp:21956
bool limit_exceeded_
Definition: Exprtk.hpp:21967
Definition: Exprtk.hpp:27339
std::size_t paramseq_count() const
Definition: Exprtk.hpp:27430
std::vector< function_prototype_t > function_definition_list_t
Definition: Exprtk.hpp:27356
const return_type_t default_return_type_
Definition: Exprtk.hpp:27595
parser_t & parser_
Definition: Exprtk.hpp:27593
return_type_t return_type(const std::size_t &index) const
Definition: Exprtk.hpp:27440
bool is_valid_token(std::string param_seq, function_prototype_t &funcproto) const
Definition: Exprtk.hpp:27492
parser< T > parser_t
Definition: Exprtk.hpp:27355
bool allow_zero_parameters() const
Definition: Exprtk.hpp:27450
type_checker & operator=(const type_checker &) exprtk_delete
bool verify(const std::string &param_seq, std::size_t &pseq_index)
Definition: Exprtk.hpp:27370
bool invalid_state_
Definition: Exprtk.hpp:27592
bool invalid() const
Definition: Exprtk.hpp:27445
return_type_t
Definition: Exprtk.hpp:27343
type_checker(const type_checker &) exprtk_delete
function_definition_list_t function_definition_list_
Definition: Exprtk.hpp:27596
std::string paramseq(const std::size_t &index) const
Definition: Exprtk.hpp:27435
std::string function_name_
Definition: Exprtk.hpp:27594
std::vector< std::string > split_param_seq(const std::string &param_seq, const details::char_t delimiter='|') const
Definition: Exprtk.hpp:27466
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:27358
void parse_function_prototypes(const std::string &func_prototypes)
Definition: Exprtk.hpp:27541
Definition: Exprtk.hpp:21332
expression_node_ptr parse_string_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition: Exprtk.hpp:27788
std::set< std::string, details::ilesscompare > disabled_func_set_t
Definition: Exprtk.hpp:21433
parser< T > & operator=(const parser< T > &) exprtk_delete
ifunction< T > F
Definition: Exprtk.hpp:21344
sf4_map_t sf4_map_
Definition: Exprtk.hpp:40214
expression_node_ptr parse_swap_statement()
Definition: Exprtk.hpp:28829
lexer::helper::bracket_checker bracket_checker_
Definition: Exprtk.hpp:40228
expression_node_ptr parse_for_loop()
Definition: Exprtk.hpp:25813
details::assignment_node< T > assignment_node_t
Definition: Exprtk.hpp:21397
void enable_unknown_symbol_resolver(unknown_symbol_resolver &usr)
Definition: Exprtk.hpp:23913
expression_node_ptr parse_function_invocation(ifunction< T > *function, const std::string &function_name)
Definition: Exprtk.hpp:24711
interval_container_t< const void * > immutable_memory_map_t
Definition: Exprtk.hpp:29262
settings_store settings_
Definition: Exprtk.hpp:40197
bool is_invalid_inequality_operation(const details::operator_type operation) const
Definition: Exprtk.hpp:24012
details::vector_node< T > vector_node_t
Definition: Exprtk.hpp:21382
expression_node_ptr parse_special_function()
Definition: Exprtk.hpp:27978
expression_node_ptr parse_expression(precedence_level precedence=e_level00)
Definition: Exprtk.hpp:24192
void init_precompilation()
Definition: Exprtk.hpp:23525
void clear_vector_access_runtime_check()
Definition: Exprtk.hpp:23944
std::multimap< std::string, details::base_operation_t, details::ilesscompare > base_ops_map_t
Definition: Exprtk.hpp:21432
details::assignment_vec_elem_node< T > assignment_vec_elem_node_t
Definition: Exprtk.hpp:21398
bool is_invalid_assignment_operation(const details::operator_type operation) const
Definition: Exprtk.hpp:24007
std::map< std::string, std::pair< quaternary_functor_t, operator_t> > sf4_map_t
Definition: Exprtk.hpp:21429
details::trinary_node< T > trinary_node_t
Definition: Exprtk.hpp:21354
details::conditional_string_node< T > conditional_string_node_t
Definition: Exprtk.hpp:21394
bool parse_range(range_t &rp, const bool skip_lsqr=false)
Definition: Exprtk.hpp:26740
binary_op_map_t binary_op_map_
Definition: Exprtk.hpp:40211
details::rebasevector_celem_node< T > rebasevector_celem_node_t
Definition: Exprtk.hpp:21379
details::T0oT1oT2oT3_define< T, cref_t, cref_t, const_t, cref_t > vovocov_t
Definition: Exprtk.hpp:21449
details::vector_size_node< T > vector_size_node_t
Definition: Exprtk.hpp:21383
expression_t compile(const std::string &expression_string, symbol_table_t &symtab)
Definition: Exprtk.hpp:23698
details::unary_node< T > unary_node_t
Definition: Exprtk.hpp:21352
bool compile(const std::string &expression_string, expression< T > &expr)
Definition: Exprtk.hpp:23589
bool valid_vararg_operation(const std::string &symbol) const
Definition: Exprtk.hpp:23970
expression_node_t * expression_node_ptr
Definition: Exprtk.hpp:21409
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:27723
expression_node_ptr parse_vector()
Definition: Exprtk.hpp:27139
details::assignment_vec_elem_rtc_node< T > assignment_vec_elem_rtc_node_t
Definition: Exprtk.hpp:21399
std::map< std::string, std::pair< trinary_functor_t,operator_t> > sf3_map_t
Definition: Exprtk.hpp:21428
parser(const parser< T > &) exprtk_delete
void register_compilation_timeout_check(compilation_check &compchk)
Definition: Exprtk.hpp:23934
details::T0oT1oT2oT3_define< T, cref_t, cref_t, cref_t, cref_t > vovovov_t
Definition: Exprtk.hpp:21447
void load_unary_operations_map(unary_op_map_t &m)
Definition: Exprtk.hpp:40002
void clear_compilation_timeout_check()
Definition: Exprtk.hpp:23949
expression_node_ptr parse_multi_switch_statement()
Definition: Exprtk.hpp:26225
details::switch_node< T > switch_node_t
Definition: Exprtk.hpp:21372
details::T0oT1oT2oT3_define< T, cref_t, const_t, cref_t, cref_t > vocovov_t
Definition: Exprtk.hpp:21450
details::assignment_vecvec_node< T > assignment_vecvec_node_t
Definition: Exprtk.hpp:21404
inv_binary_op_map_t inv_binary_op_map_
Definition: Exprtk.hpp:40212
expression_node_ptr parse_base_operation()
Definition: Exprtk.hpp:24951
std::size_t parse_base_function_call(expression_node_ptr(&param_list)[MaxNumberofParameters], const std::string &function_name="")
Definition: Exprtk.hpp:24879
details::for_loop_rtc_node< T > for_loop_rtc_node_t
Definition: Exprtk.hpp:21363
bool valid_base_operation(const std::string &symbol) const
Definition: Exprtk.hpp:23956
expression_node_ptr parse_continue_statement()
Definition: Exprtk.hpp:28105
details::for_loop_bc_node< T > for_loop_bc_node_t
Definition: Exprtk.hpp:21367
igeneric_function< T > igeneric_function_t
Definition: Exprtk.hpp:21349
vector_holder_t * vector_holder_ptr
Definition: Exprtk.hpp:21414
expression< T >::symtab_list_t symbol_table_list_t
Definition: Exprtk.hpp:21412
unknown_symbol_resolver default_usr_
Definition: Exprtk.hpp:40208
void load_sf3_map(sf3_map_t &sf3_map)
Definition: Exprtk.hpp:40105
std::map< operator_t, unary_functor_t > unary_op_map_t
Definition: Exprtk.hpp:21424
details::while_loop_bc_rtc_node< T > while_loop_bc_rtc_node_t
Definition: Exprtk.hpp:21368
void lodge_symbol(const std::string &symbol, const symbol_type st)
Definition: Exprtk.hpp:26924
parser(const settings_t &settings=settings_t())
Definition: Exprtk.hpp:23484
details::assignment_vec_node< T > assignment_vec_node_t
Definition: Exprtk.hpp:21403
details::range_pack< T > range_t
Definition: Exprtk.hpp:21384
bool is_invalid_logic_operation(const details::operator_type operation) const
Definition: Exprtk.hpp:23997
expression_node_ptr parse_conditional_statement_01(expression_node_ptr condition)
Definition: Exprtk.hpp:25018
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:26578
details::string_concat_node< T > string_concat_node_t
Definition: Exprtk.hpp:21391
expression_node_ptr parse_generic_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition: Exprtk.hpp:27599
details::stringvar_node< T > stringvar_node_t
Definition: Exprtk.hpp:21386
void return_cleanup()
Definition: Exprtk.hpp:40179
functor_t::qfunc_t quaternary_functor_t
Definition: Exprtk.hpp:21417
details::vector_elem_node< T > vector_elem_node_t
Definition: Exprtk.hpp:21374
bool is_invalid_arithmetic_operation(const details::operator_type operation) const
Definition: Exprtk.hpp:24002
interval_t make_memory_range(details::char_cptr begin, const std::size_t size)
Definition: Exprtk.hpp:29277
void pop_current_state()
Definition: Exprtk.hpp:24156
details::T0oT1oT2_define< T, const_t, const_t, cref_t > cocov_t
Definition: Exprtk.hpp:21444
loop_runtime_check_ptr loop_runtime_check_
Definition: Exprtk.hpp:40233
details::while_loop_bc_node< T > while_loop_bc_node_t
Definition: Exprtk.hpp:21365
details::T0oT1_define< T, cref_t, cref_t > vov_t
Definition: Exprtk.hpp:21435
details::expression_node< T > expression_node_t
Definition: Exprtk.hpp:21350
details::vector_celem_rtc_node< T > vector_celem_rtc_node_t
Definition: Exprtk.hpp:21377
dependent_entity_collector dec_
Definition: Exprtk.hpp:40201
std::vector< state_t > current_state_stack_
Definition: Exprtk.hpp:40217
ifunction< T > ifunction_t
Definition: Exprtk.hpp:21347
expression_node_ptr parse_corpus()
Definition: Exprtk.hpp:24035
std::deque< parser_error::type > error_list_
Definition: Exprtk.hpp:40202
lexer::helper::operator_joiner operator_joiner_3_
Definition: Exprtk.hpp:40226
unknown_symbol_resolver * unknown_symbol_resolver_
Definition: Exprtk.hpp:40207
details::while_loop_rtc_node< T > while_loop_rtc_node_t
Definition: Exprtk.hpp:21361
expression_node_ptr parse_vararg_function_call(ivararg_function< T > *vararg_function, const std::string &vararg_function_name)
Definition: Exprtk.hpp:27241
expression_node_ptr parse_switch_statement()
Definition: Exprtk.hpp:26052
details::T0oT1oT2_define< T, const_t, cref_t, cref_t > covov_t
Definition: Exprtk.hpp:21442
details::T0oT1oT2_define< T, cref_t, cref_t, cref_t > vovov_t
Definition: Exprtk.hpp:21439
details::assignment_rebasevec_elem_rtc_node< T > assignment_rebasevec_elem_rtc_node_t
Definition: Exprtk.hpp:21401
details::T0oT1oT2_define< T, cref_t, const_t, cref_t > vocov_t
Definition: Exprtk.hpp:21441
const T const_t
Definition: Exprtk.hpp:21343
parser_helper prsrhlpr_t
Definition: Exprtk.hpp:21460
details::cons_conditional_str_node< T > cons_conditional_str_node_t
Definition: Exprtk.hpp:21395
ivararg_function< T > VAF
Definition: Exprtk.hpp:21345
expression_node_ptr parse_const_string()
Definition: Exprtk.hpp:27037
void register_local_vars(expression< T > &e)
Definition: Exprtk.hpp:39937
vector_access_runtime_check_ptr vector_access_runtime_check_
Definition: Exprtk.hpp:40234
symbol_type
Definition: Exprtk.hpp:22630
void parse_pending_vector_index_operator(expression_node_ptr &expression)
Definition: Exprtk.hpp:26522
settings_store settings_t
Definition: Exprtk.hpp:23482
expression_node_ptr parse_function_call(ifunction< T > *function, const std::string &function_name)
Definition: Exprtk.hpp:24764
void set_synthesis_error(const std::string &synthesis_error_message)
Definition: Exprtk.hpp:39929
details::conditional_node< T > conditional_node_t
Definition: Exprtk.hpp:21356
expression_node_ptr parse_overload_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition: Exprtk.hpp:27839
details::T0oT1oT2oT3_define< T, cref_t, const_t, const_t, cref_t > vococov_t
Definition: Exprtk.hpp:21456
lexer::helper::operator_joiner operator_joiner_2_
Definition: Exprtk.hpp:40225
expression_node_ptr parse_function_call_0(ifunction< T > *function, const std::string &function_name)
Definition: Exprtk.hpp:24851
dependent_entity_collector & dec()
Definition: Exprtk.hpp:23878
functor_t::tfunc_t trinary_functor_t
Definition: Exprtk.hpp:21418
details::T0oT1_define< T, const_t, cref_t > cov_t
Definition: Exprtk.hpp:21436
details::for_loop_node< T > for_loop_node_t
Definition: Exprtk.hpp:21360
functor_t::bfunc_t binary_functor_t
Definition: Exprtk.hpp:21419
void process_lexer_errors()
Definition: Exprtk.hpp:23706
bool post_variable_process(const std::string &symbol)
Definition: Exprtk.hpp:29184
igeneric_function< T > GF
Definition: Exprtk.hpp:21346
details::assignment_string_node< T > assignment_string_node_t
Definition: Exprtk.hpp:21392
lexer::helper::symbol_replacer symbol_replacer_
Definition: Exprtk.hpp:40227
void enable_unknown_symbol_resolver(unknown_symbol_resolver *usr=reinterpret_cast< unknown_symbol_resolver * >(0))
Definition: Exprtk.hpp:23903
ivararg_function< T > ivararg_function_t
Definition: Exprtk.hpp:21348
details::T0oT1oT2oT3_define< T, const_t, cref_t, cref_t, const_t > covovoc_t
Definition: Exprtk.hpp:21455
expression_node_ptr parse_while_loop()
Definition: Exprtk.hpp:25556
settings_store & settings()
Definition: Exprtk.hpp:23850
expression_node_ptr parse_string()
Definition: Exprtk.hpp:26931
details::scand_node< T > scand_node_t
Definition: Exprtk.hpp:21406
std::map< binary_functor_t, operator_t> inv_binary_op_map_t
Definition: Exprtk.hpp:21431
expression_node_ptr parse_define_var_statement()
Definition: Exprtk.hpp:28560
void push_current_state(const state_t current_state)
Definition: Exprtk.hpp:24151
details::binary_node< T > binary_node_t
Definition: Exprtk.hpp:21353
bool remove_replace_symbol(const std::string &symbol)
Definition: Exprtk.hpp:23893
expression_node_ptr parse_conditional_statement()
Definition: Exprtk.hpp:25351
results_context_t * results_context_
Definition: Exprtk.hpp:40206
details::literal_node< T > literal_node_t
Definition: Exprtk.hpp:21351
immutable_symtok_map_t immutable_symtok_map_
Definition: Exprtk.hpp:40220
~parser()
Definition: Exprtk.hpp:23522
symtab_store symtab_store_
Definition: Exprtk.hpp:40200
compilation_check_ptr compilation_check_ptr_
Definition: Exprtk.hpp:40235
sf3_map_t sf3_map_
Definition: Exprtk.hpp:40213
details::repeat_until_loop_node< T > repeat_until_loop_node_t
Definition: Exprtk.hpp:21359
details::repeat_until_loop_bc_node< T > repeat_until_loop_bc_node_t
Definition: Exprtk.hpp:21366
details::assignment_rebasevec_elem_node< T > assignment_rebasevec_elem_node_t
Definition: Exprtk.hpp:21400
std::map< operator_t, trinary_functor_t > trinary_op_map_t
Definition: Exprtk.hpp:21426
expression_node_ptr parse_vararg_function()
Definition: Exprtk.hpp:26341
void lodge_immutable_symbol(const lexer::token &token, const interval_t interval)
Definition: Exprtk.hpp:29282
details::variable_node< T > variable_node_t
Definition: Exprtk.hpp:21373
details::T0oT1oT2oT3_define< T, cref_t, const_t, cref_t, const_t > vocovoc_t
Definition: Exprtk.hpp:21454
details::T0oT1_define< T, cref_t, const_t > voc_t
Definition: Exprtk.hpp:21437
expression_generator< T > expression_generator_
Definition: Exprtk.hpp:40198
expression_node_ptr parse_multi_sequence(const std::string &source="", const bool enforce_crlbrackets=false)
Definition: Exprtk.hpp:26657
expression_node_ptr parse_branch(precedence_level precedence=e_level00)
Definition: Exprtk.hpp:29730
expression_node_ptr parse_break_statement()
Definition: Exprtk.hpp:28030
void load_inv_binary_operations_map(inv_binary_op_map_t &m)
Definition: Exprtk.hpp:40077
details::T0oT1oT2oT3_define< T, const_t, cref_t, cref_t, cref_t > covovov_t
Definition: Exprtk.hpp:21451
lexer::helper::sequence_validator sequence_validator_
Definition: Exprtk.hpp:40230
results_context_t & results_ctx()
Definition: Exprtk.hpp:40169
lexer::helper::commutative_inserter commutative_inserter_
Definition: Exprtk.hpp:40224
interval_t make_memory_range(const T &t)
Definition: Exprtk.hpp:29265
expression< T > expression_t
Definition: Exprtk.hpp:21410
void handle_brkcnt_scope_exit()
Definition: Exprtk.hpp:25550
expression_node_ptr parse_conditional_statement_02(expression_node_ptr condition)
Definition: Exprtk.hpp:25154
details::T0oT1oT2oT3_define< T, cref_t, cref_t, cref_t, const_t > vovovoc_t
Definition: Exprtk.hpp:21448
std::string construct_subexpr(lexer::token &begin_token, lexer::token &end_token)
Definition: Exprtk.hpp:24111
expression_node_ptr parse_not_statement()
Definition: Exprtk.hpp:25534
details::operator_type operator_t
Definition: Exprtk.hpp:21422
bool run_assemblies()
Definition: Exprtk.hpp:23743
details::functor_t< T > functor_t
Definition: Exprtk.hpp:21416
const T & cref_t
Definition: Exprtk.hpp:21342
void register_loop_runtime_check(loop_runtime_check &lrtchk)
Definition: Exprtk.hpp:23924
details::vector_elem_rtc_node< T > vector_elem_rtc_node_t
Definition: Exprtk.hpp:21376
parser_state state_
Definition: Exprtk.hpp:40204
details::for_loop_bc_rtc_node< T > for_loop_bc_rtc_node_t
Definition: Exprtk.hpp:21370
details::conditional_vector_node< T > conditional_vector_node_t
Definition: Exprtk.hpp:21405
details::repeat_until_loop_bc_rtc_node< T > repeat_until_loop_bc_rtc_node_t
Definition: Exprtk.hpp:21369
lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_
Definition: Exprtk.hpp:40231
void set_error(const parser_error::type &error_type)
Definition: Exprtk.hpp:39916
expression_node_ptr parse_null_statement()
Definition: Exprtk.hpp:28023
details::T0oT1oT2_define< T, cref_t, cref_t, const_t > vovoc_t
Definition: Exprtk.hpp:21440
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:27211
lexer::helper::numeric_checker< T > numeric_checker_
Definition: Exprtk.hpp:40229
details::rebasevector_elem_rtc_node< T > rebasevector_elem_rtc_node_t
Definition: Exprtk.hpp:21380
parser_error::type get_error(const std::size_t &index) const
Definition: Exprtk.hpp:23855
void load_binary_operations_map(binary_op_map_t &m)
Definition: Exprtk.hpp:40049
bool post_bracket_process(const typename token_t::token_type &token, expression_node_ptr &branch)
Definition: Exprtk.hpp:29209
bool simplify_unary_negation_branch(expression_node_ptr &node)
Definition: Exprtk.hpp:24476
details::rebasevector_celem_rtc_node< T > rebasevector_celem_rtc_node_t
Definition: Exprtk.hpp:21381
std::string error() const
Definition: Exprtk.hpp:23863
details::node_allocator node_allocator_
Definition: Exprtk.hpp:40199
details::generic_string_range_node< T > generic_string_range_node_t
Definition: Exprtk.hpp:21390
details::T0oT1oT2oT3_define< T, const_t, cref_t, const_t, cref_t > covocov_t
Definition: Exprtk.hpp:21453
details::cons_conditional_node< T > cons_conditional_node_t
Definition: Exprtk.hpp:21357
void register_vector_access_runtime_check(vector_access_runtime_check &vartchk)
Definition: Exprtk.hpp:23929
void remove_last_error()
Definition: Exprtk.hpp:39921
unary_op_map_t unary_op_map_
Definition: Exprtk.hpp:40210
expression_node_ptr parse_define_vector_statement(const std::string &vec_name)
Definition: Exprtk.hpp:28129
expression_node_ptr parse_vector_index(const std::string &vector_name="")
Definition: Exprtk.hpp:27109
scope_element_manager sem_
Definition: Exprtk.hpp:40216
details::assignment_rebasevec_celem_node< T > assignment_rebasevec_celem_node_t
Definition: Exprtk.hpp:21402
expression_node_ptr parse_ternary_conditional_statement(expression_node_ptr condition)
Definition: Exprtk.hpp:25414
functor_t::ufunc_t unary_functor_t
Definition: Exprtk.hpp:21420
expression_node_ptr parse_symbol()
Definition: Exprtk.hpp:29614
bool replace_symbol(const std::string &old_symbol, const std::string &new_symbol)
Definition: Exprtk.hpp:23883
lexer::token token_t
Definition: Exprtk.hpp:21408
details::assignment_string_range_node< T > assignment_string_range_node_t
Definition: Exprtk.hpp:21393
details::scor_node< T > scor_node_t
Definition: Exprtk.hpp:21407
std::map< operator_t, binary_functor_t > binary_op_map_t
Definition: Exprtk.hpp:21425
results_context< T > results_context_t
Definition: Exprtk.hpp:21458
std::string synthesis_error_
Definition: Exprtk.hpp:40215
expression_node_ptr parse_string_range_statement(expression_node_ptr &expression)
Definition: Exprtk.hpp:26434
void register_return_results(expression< T > &e)
Definition: Exprtk.hpp:39996
details::T0oT1oT2_define< T, const_t, cref_t, const_t > covoc_t
Definition: Exprtk.hpp:21443
details::vector_holder< T > vector_holder_t
Definition: Exprtk.hpp:21413
interval_t make_memory_range(const T *begin, const std::size_t size)
Definition: Exprtk.hpp:29272
std::size_t error_count() const
Definition: Exprtk.hpp:23873
expression_node_ptr parse_define_string_statement(const std::string &str_name, expression_node_ptr initialisation_expression)
Definition: Exprtk.hpp:28476
precedence_level
Definition: Exprtk.hpp:21336
@ e_level10
Definition: Exprtk.hpp:21339
@ e_level05
Definition: Exprtk.hpp:21338
@ e_level00
Definition: Exprtk.hpp:21337
details::string_range_node< T > string_range_node_t
Definition: Exprtk.hpp:21388
base_ops_map_t base_ops_map_
Definition: Exprtk.hpp:40209
details::quaternary_node< T > quaternary_node_t
Definition: Exprtk.hpp:21355
std::deque< bool > brkcnt_list_
Definition: Exprtk.hpp:40203
void clear_loop_runtime_check()
Definition: Exprtk.hpp:23939
void disable_unknown_symbol_resolver()
Definition: Exprtk.hpp:23918
immutable_memory_map_t immutable_memory_map_
Definition: Exprtk.hpp:40219
expression_node_ptr parse_return_statement()
Definition: Exprtk.hpp:29063
details::vector_celem_node< T > vector_celem_node_t
Definition: Exprtk.hpp:21375
state_t current_state() const
Definition: Exprtk.hpp:24164
void load_sf4_map(sf4_map_t &sf4_map)
Definition: Exprtk.hpp:40129
details::string_literal_node< T > string_literal_node_t
Definition: Exprtk.hpp:21387
expression_node_ptr parse_symtab_symbol()
Definition: Exprtk.hpp:29288
interval_container_t< const void * >::interval_t interval_t
Definition: Exprtk.hpp:29261
details::T0oT1oT2_define< T, cref_t, const_t, const_t > vococ_t
Definition: Exprtk.hpp:21445
details::while_loop_node< T > while_loop_node_t
Definition: Exprtk.hpp:21358
expression_node_ptr parse_uninitialised_var_statement(const std::string &var_name)
Definition: Exprtk.hpp:28743
std::map< interval_t, token_t > immutable_symtok_map_t
Definition: Exprtk.hpp:29263
bool local_variable_is_shadowed(const std::string &symbol)
Definition: Exprtk.hpp:28554
bool resolve_unknown_symbol_
Definition: Exprtk.hpp:40205
lexer::helper::helper_assembly helper_assembly_
Definition: Exprtk.hpp:40222
symbol_table< T > symbol_table_t
Definition: Exprtk.hpp:21411
details::repeat_until_loop_rtc_node< T > repeat_until_loop_rtc_node_t
Definition: Exprtk.hpp:21362
details::rebasevector_elem_node< T > rebasevector_elem_node_t
Definition: Exprtk.hpp:21378
collect_type
Definition: Exprtk.hpp:22622
static expression_node_ptr error_node()
Definition: Exprtk.hpp:24531
bool parse_pending_string_rangesize(expression_node_ptr &expression)
Definition: Exprtk.hpp:26500
expression_node_ptr parse_repeat_until_loop()
Definition: Exprtk.hpp:25653
bool halt_compilation_check()
Definition: Exprtk.hpp:24171
details::const_string_range_node< T > const_string_range_node_t
Definition: Exprtk.hpp:21389
Definition: Exprtk.hpp:40759
polynomial()
Definition: Exprtk.hpp:40908
virtual ~polynomial()
Definition: Exprtk.hpp:40914
Definition: Exprtk.hpp:4813
type_store_t::parameter_list parameter_list_t
Definition: Exprtk.hpp:4906
type_store_t::scalar_view scalar_t
Definition: Exprtk.hpp:4817
type_store_t::vector_view vector_t
Definition: Exprtk.hpp:4818
bool get_string(const std::size_t &index, std::string &out) const
Definition: Exprtk.hpp:4883
std::size_t count() const
Definition: Exprtk.hpp:4825
void assign(const parameter_list_t &pl)
Definition: Exprtk.hpp:4908
results_context()
Definition: Exprtk.hpp:4821
const type_store_t & operator[](const std::size_t &index) const
Definition: Exprtk.hpp:4838
type_store_t::string_view string_t
Definition: Exprtk.hpp:4819
bool get_vector(const std::size_t &index, std::vector< T > &out) const
Definition: Exprtk.hpp:4878
bool get_scalar(const std::size_t &index, T &out) const
Definition: Exprtk.hpp:4843
bool get_vector(const std::size_t &index, OutputIterator out_itr) const
Definition: Exprtk.hpp:4859
bool results_available_
Definition: Exprtk.hpp:4914
type_store_t & operator[](const std::size_t &index)
Definition: Exprtk.hpp:4833
std::vector< type_store_t > ts_list_t
Definition: Exprtk.hpp:4905
void clear()
Definition: Exprtk.hpp:4900
type_store< T > type_store_t
Definition: Exprtk.hpp:4816
Definition: Exprtk.hpp:42408
generic_type::scalar_view scalar_t
Definition: Exprtk.hpp:42489
close()
Definition: Exprtk.hpp:42463
write()
Definition: Exprtk.hpp:42494
exprtk::igeneric_function< T > igfun_t
Definition: Exprtk.hpp:42411
getline()
Definition: Exprtk.hpp:42607
igfun_t::parameter_list_t parameter_list_t
Definition: Exprtk.hpp:42412
igfun_t::generic_type generic_type
Definition: Exprtk.hpp:42413
open()
Definition: Exprtk.hpp:42418
generic_type::vector_view vector_t
Definition: Exprtk.hpp:42490
generic_type::string_view string_t
Definition: Exprtk.hpp:42414
read()
Definition: Exprtk.hpp:42551
eof()
Definition: Exprtk.hpp:42623
Definition: Exprtk.hpp:42741
sort()
Definition: Exprtk.hpp:43264
generic_type::scalar_view scalar_t
Definition: Exprtk.hpp:42986
all_false()
Definition: Exprtk.hpp:42799
axpbz()
Definition: Exprtk.hpp:43838
assign()
Definition: Exprtk.hpp:43374
shift_left()
Definition: Exprtk.hpp:43146
ror()
Definition: Exprtk.hpp:43095
any_true()
Definition: Exprtk.hpp:42847
generic_type::vector_view vector_t
Definition: Exprtk.hpp:42747
axpy()
Definition: Exprtk.hpp:43539
iota()
Definition: Exprtk.hpp:43426
generic_type::string_view string_t
Definition: Exprtk.hpp:43259
axpby()
Definition: Exprtk.hpp:43586
all_true()
Definition: Exprtk.hpp:42751
sumk()
Definition: Exprtk.hpp:43486
threshold_above()
Definition: Exprtk.hpp:44086
axpbsyz()
Definition: Exprtk.hpp:43785
igfun_t::generic_type generic_type
Definition: Exprtk.hpp:42746
diff()
Definition: Exprtk.hpp:43886
axpbsy()
Definition: Exprtk.hpp:43735
axpbyz()
Definition: Exprtk.hpp:43684
axpyz()
Definition: Exprtk.hpp:43634
any_false()
Definition: Exprtk.hpp:42895
nthelement()
Definition: Exprtk.hpp:43327
shift_right()
Definition: Exprtk.hpp:43204
copy()
Definition: Exprtk.hpp:42991
igfun_t::parameter_list_t parameter_list_t
Definition: Exprtk.hpp:42745
threshold_below()
Definition: Exprtk.hpp:44027
exprtk::igeneric_function< T > igfun_t
Definition: Exprtk.hpp:42744
count()
Definition: Exprtk.hpp:42943
dotk()
Definition: Exprtk.hpp:43980
rol()
Definition: Exprtk.hpp:43044
dot()
Definition: Exprtk.hpp:43934
Definition: Exprtk.hpp:19027
std::string name_
Definition: Exprtk.hpp:19056
details::stringvar_node< T > stringvar_node_t
Definition: Exprtk.hpp:19030
std::string name() const
Definition: Exprtk.hpp:19042
bool valid() const
Definition: Exprtk.hpp:19037
stringvar_base(const std::string &name, stringvar_node_t *svn)
Definition: Exprtk.hpp:19032
void rebase(std::string &s)
Definition: Exprtk.hpp:19048
stringvar_node_t * string_varnode_
Definition: Exprtk.hpp:19057
Definition: Exprtk.hpp:19066
void clear_local_constants()
Definition: Exprtk.hpp:19851
bool add_package(Package &package)
Definition: Exprtk.hpp:20391
symbol_table(const symtab_mutability_type mutability=e_mutable)
Definition: Exprtk.hpp:19787
symtab_mutability_type mutability() const
Definition: Exprtk.hpp:19824
bool remove_vararg_function(const std::string &vararg_function_name)
Definition: Exprtk.hpp:20348
bool add_constant(const std::string &constant_name, const T &value)
Definition: Exprtk.hpp:20103
control_block * control_block_
Definition: Exprtk.hpp:20763
variable_ptr get_variable(const T &var_ref) const
Definition: Exprtk.hpp:19910
std::size_t function_count() const
Definition: Exprtk.hpp:19884
generic_function_ptr get_string_function(const std::string &function_name) const
Definition: Exprtk.hpp:19979
bool add_epsilon()
Definition: Exprtk.hpp:20378
std::size_t get_function_list(Sequence< std::string, Allocator > &function_list) const
Definition: Exprtk.hpp:20450
variable_t * variable_ptr
Definition: Exprtk.hpp:19657
bool is_vararg_function(const std::string &vararg_function_name) const
Definition: Exprtk.hpp:20543
bool remove_variable(const std::string &variable_name, const bool delete_node=true)
Definition: Exprtk.hpp:20322
void clear_variables(const bool delete_node=true)
Definition: Exprtk.hpp:19829
void clear_functions()
Definition: Exprtk.hpp:19834
control_block::st_data local_data_t
Definition: Exprtk.hpp:20751
bool add_vector(const std::string &vector_name, std::vector< T, Allocator > &v)
Definition: Exprtk.hpp:20294
bool is_function(const std::string &function_name) const
Definition: Exprtk.hpp:20535
std::string get_variable_name(const expression_ptr &ptr) const
Definition: Exprtk.hpp:20559
local_data_t & local_data()
Definition: Exprtk.hpp:20753
bool add_function(const std::string &vararg_function_name, vararg_function_t &vararg_function)
Definition: Exprtk.hpp:20144
bool add_function(const std::string &function_name, function_t &function)
Definition: Exprtk.hpp:20132
bool is_stringvar(const std::string &stringvar_name) const
Definition: Exprtk.hpp:20511
stringvar_base< T > get_stringvar_base(const std::string &string_name) const
Definition: Exprtk.hpp:19930
void clear_strings()
Definition: Exprtk.hpp:19839
bool add_infinity()
Definition: Exprtk.hpp:20384
details::vector_holder< T > vector_holder_t
Definition: Exprtk.hpp:19656
bool remove_vector(const std::string &vector_name)
Definition: Exprtk.hpp:20356
bool is_constant_node(const std::string &symbol_name) const
Definition: Exprtk.hpp:20035
stringvar_t * stringvar_ptr
Definition: Exprtk.hpp:19660
symbol_table< T > & operator=(const symbol_table< T > &st)
Definition: Exprtk.hpp:19806
std::size_t get_variable_list(Sequence< std::string, Allocator > &vlist) const
Definition: Exprtk.hpp:20408
bool is_vector(const std::string &vector_name) const
Definition: Exprtk.hpp:20551
std::string get_stringvar_name(const expression_ptr &ptr) const
Definition: Exprtk.hpp:20570
void load_vectors_from(const symbol_table< T > &st)
Definition: Exprtk.hpp:20681
ivararg_function< T > vararg_function_t
Definition: Exprtk.hpp:19663
vararg_function_t * vararg_function_ptr
Definition: Exprtk.hpp:19666
bool valid_symbol(const std::string &symbol, const bool check_reserved_symb=true) const
Definition: Exprtk.hpp:20699
bool add_reserved_function(const std::string &vararg_function_name, vararg_function_t &vararg_function)
Definition: Exprtk.hpp:20225
vector_holder_t * vector_holder_ptr
Definition: Exprtk.hpp:19999
T & variable_ref(const std::string &symbol_name)
Definition: Exprtk.hpp:20011
function_ptr get_function(const std::string &function_name) const
Definition: Exprtk.hpp:19949
void load_from(const symbol_table< T > &st)
Definition: Exprtk.hpp:20587
details::expression_node< T > * expression_ptr
Definition: Exprtk.hpp:19654
igeneric_function< T > generic_function_t
Definition: Exprtk.hpp:19664
std::size_t get_variable_list(Sequence< std::pair< std::string, T >, Allocator > &vlist) const
Definition: Exprtk.hpp:20398
stringvar_ptr get_stringvar(const std::string &string_name) const
Definition: Exprtk.hpp:19920
std::string get_conststr_stringvar_name(const expression_ptr &ptr) const
Definition: Exprtk.hpp:20575
void clear_vectors()
Definition: Exprtk.hpp:19846
const local_data_t & local_data() const
Definition: Exprtk.hpp:20758
bool valid_function(const std::string &symbol) const
Definition: Exprtk.hpp:20725
bool add_vector(const std::string &vector_name, T *v, const std::size_t &v_size)
Definition: Exprtk.hpp:20279
generic_function_t * generic_function_ptr
Definition: Exprtk.hpp:19667
std::size_t variable_count() const
Definition: Exprtk.hpp:19866
bool create_stringvar(const std::string &stringvar_name, const std::string &value=std::string(""))
Definition: Exprtk.hpp:20075
bool remove_stringvar(const std::string &string_name)
Definition: Exprtk.hpp:20331
std::string get_vector_name(const vector_holder_ptr &ptr) const
Definition: Exprtk.hpp:20564
exprtk_define_freefunction(00) exprtk_define_freefunction(01) exprtk_define_freefunction(02) exprtk_define_freefunction(03) exprtk_define_freefunction(04) exprtk_define_freefunction(05) exprtk_define_freefunction(06) exprtk_define_freefunction(07) exprtk_define_freefunction(08) exprtk_define_freefunction(09) exprtk_define_freefunction(10) exprtk_define_freefunction(11) exprtk_define_freefunction(12) exprtk_define_freefunction(13) exprtk_define_freefunction(14) exprtk_define_freefunction(15) inline bool add_reserved_function(const std
Definition: Exprtk.hpp:20202
bool add_constants()
Definition: Exprtk.hpp:20364
variable_ptr get_variable(const std::string &variable_name) const
Definition: Exprtk.hpp:19900
std::string & stringvar_ref(const std::string &symbol_name)
Definition: Exprtk.hpp:20023
symbol_table(const symbol_table< T > &st)
Definition: Exprtk.hpp:19800
bool add_function(const std::string &function_name, generic_function_t &function)
Definition: Exprtk.hpp:20156
generic_function_ptr get_generic_function(const std::string &function_name) const
Definition: Exprtk.hpp:19969
bool create_variable(const std::string &variable_name, const T &value=T(0))
Definition: Exprtk.hpp:20059
void clear()
Definition: Exprtk.hpp:19856
bool add_pi()
Definition: Exprtk.hpp:20371
generic_function_ptr get_overload_function(const std::string &function_name) const
Definition: Exprtk.hpp:19989
std::size_t vector_count() const
Definition: Exprtk.hpp:19892
bool operator==(const symbol_table< T > &st) const
Definition: Exprtk.hpp:19819
bool is_conststr_stringvar(const std::string &symbol_name) const
Definition: Exprtk.hpp:20519
bool add_variable(const std::string &variable_name, T &t, const bool is_constant=false)
Definition: Exprtk.hpp:20091
bool add_vector(const std::string &vector_name, exprtk::vector_view< T > &v)
Definition: Exprtk.hpp:20308
bool is_constant_string(const std::string &symbol_name) const
Definition: Exprtk.hpp:20046
void load_variables_from(const symbol_table< T > &st)
Definition: Exprtk.hpp:20665
bool valid() const
Definition: Exprtk.hpp:20581
symtab_mutability_type
Definition: Exprtk.hpp:19070
bool symbol_exists(const std::string &symbol_name, const bool check_reserved_symb=true) const
Definition: Exprtk.hpp:20477
bool add_reserved_function(const std::string &function_name, generic_function_t &function)
Definition: Exprtk.hpp:20237
details::stringvar_node< T > stringvar_t
Definition: Exprtk.hpp:19659
std::size_t get_stringvar_list(Sequence< std::string, Allocator > &svlist) const
Definition: Exprtk.hpp:20429
bool add_vector(const std::string &vector_name, T(&v)[N])
Definition: Exprtk.hpp:20267
bool add_stringvar(const std::string &stringvar_name, std::string &s, const bool is_constant=false)
Definition: Exprtk.hpp:20119
function_t * function_ptr
Definition: Exprtk.hpp:19665
ifunction< T > function_t
Definition: Exprtk.hpp:19662
std::size_t get_stringvar_list(Sequence< std::pair< std::string, std::string >, Allocator > &svlist) const
Definition: Exprtk.hpp:20419
std::size_t stringvar_count() const
Definition: Exprtk.hpp:19875
details::variable_node< T > variable_t
Definition: Exprtk.hpp:19655
std::size_t get_vector_list(Sequence< std::string, Allocator > &vec_list) const
Definition: Exprtk.hpp:20440
vector_holder_ptr get_vector(const std::string &vector_name) const
Definition: Exprtk.hpp:20001
vararg_function_ptr get_vararg_function(const std::string &vararg_function_name) const
Definition: Exprtk.hpp:19959
bool remove_function(const std::string &function_name)
Definition: Exprtk.hpp:20340
~symbol_table()
Definition: Exprtk.hpp:19794
bool is_variable(const std::string &variable_name) const
Definition: Exprtk.hpp:20502
Definition: Exprtk.hpp:41906
void stop()
Definition: Exprtk.hpp:41953
timer()
Definition: Exprtk.hpp:41937
double time() const
Definition: Exprtk.hpp:41975
bool in_use_
Definition: Exprtk.hpp:41989
struct timeval stop_time_
Definition: Exprtk.hpp:41997
struct timeval start_time_
Definition: Exprtk.hpp:41996
unsigned long long int usec_time() const
Definition: Exprtk.hpp:41959
void start()
Definition: Exprtk.hpp:41947
bool in_use() const
Definition: Exprtk.hpp:41982
Definition: Exprtk.hpp:4631
type_store & operator[](const std::size_t &index)
Definition: Exprtk.hpp:4648
const type_store & operator[](const std::size_t &index) const
Definition: Exprtk.hpp:4653
type_store & front()
Definition: Exprtk.hpp:4658
const type_store & back() const
Definition: Exprtk.hpp:4673
parameter_list(std::vector< type_store > &pl)
Definition: Exprtk.hpp:4634
const type_store & front() const
Definition: Exprtk.hpp:4663
std::size_t size() const
Definition: Exprtk.hpp:4643
bool empty() const
Definition: Exprtk.hpp:4638
type_store & back()
Definition: Exprtk.hpp:4668
std::vector< type_store > & parameter_list_
Definition: Exprtk.hpp:4680
Definition: Exprtk.hpp:4482
const std::size_t base_size_
Definition: Exprtk.hpp:4582
std::size_t size() const
Definition: Exprtk.hpp:4528
std::vector< data_ptr_t * > data_ref_
Definition: Exprtk.hpp:4585
vector_view(data_ptr_t data, const std::size_t &size)
Definition: Exprtk.hpp:4487
T * data_ptr_t
Definition: Exprtk.hpp:4485
T & operator[](const std::size_t index)
Definition: Exprtk.hpp:4539
void rebase(data_ptr_t data)
Definition: Exprtk.hpp:4505
data_ptr_t data_
Definition: Exprtk.hpp:4584
std::size_t base_size() const
Definition: Exprtk.hpp:4523
std::size_t size_
Definition: Exprtk.hpp:4583
void remove_ref(data_ptr_t *data_ref)
Definition: Exprtk.hpp:4553
data_ptr_t data() const
Definition: Exprtk.hpp:4518
void set_ref(data_ptr_t *data_ref)
Definition: Exprtk.hpp:4545
vector_view(const vector_view< T > &vv)
Definition: Exprtk.hpp:4496
bool set_size(const std::size_t new_size)
Definition: Exprtk.hpp:4563
const T & operator[](const std::size_t index) const
Definition: Exprtk.hpp:4533
const
Definition: Sensor.hpp:225
const unsigned int global_loop_batch_size
Definition: Exprtk.hpp:5044
static const double e
Definition: Exprtk.hpp:808
static const double pi
Definition: Exprtk.hpp:809
static const double log2
Definition: Exprtk.hpp:816
static const double _180_pi
Definition: Exprtk.hpp:815
static const double pi_180
Definition: Exprtk.hpp:812
static const double _1_pi
Definition: Exprtk.hpp:813
static const double _2_pi
Definition: Exprtk.hpp:814
static const double pi_2
Definition: Exprtk.hpp:810
static const double sqrt2
Definition: Exprtk.hpp:817
static const double pi_4
Definition: Exprtk.hpp:811
T floor_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1350
bool is_false_impl(const T v)
Definition: Exprtk.hpp:905
T xor_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1210
T ceil_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1346
T shr_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1116
T atan2_impl(const T, const T, int_type_tag)
Definition: Exprtk.hpp:1110
T tanh_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1360
T acosh_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1341
T nor_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1192
bool is_integer_impl(const T &v, real_type_tag)
Definition: Exprtk.hpp:1407
T sinc_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1326
T const_pi_impl(real_type_tag)
Definition: Exprtk.hpp:1372
T asin_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1342
T log10_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1352
T hypot_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1098
T r2d_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1364
T shl_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1128
T logn_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1009
T shl_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1134
T sqrt_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1358
T xnor_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1216
T asinh_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1343
T erf_impl(const T v, int_type_tag)
Definition: Exprtk.hpp:1279
T nand_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1174
T const_e_impl(real_type_tag)
Definition: Exprtk.hpp:1373
T d2r_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1365
T neg_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1354
T pow_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1003
T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag)
Definition: Exprtk.hpp:5394
T process_impl(const operator_type operation, const T arg)
Definition: Exprtk.hpp:5303
T erfc_impl(const T v, int_type_tag)
Definition: Exprtk.hpp:1305
T root_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1048
T and_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1156
T pos_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1355
T log_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1351
_uint64_t to_uint64_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:893
T ncdf_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1311
real_type_tag
Definition: Exprtk.hpp:876
T csc_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1363
_int64_t to_int64_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:887
T log2_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1353
T cot_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1361
exprtk_define_erfc(float,::erfcf) exprtk_define_erfc(double
T or_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1180
T cos_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1347
T sinh_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1357
T nequal_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:979
T roundn_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1074
bool is_integer_impl(const T &, int_type_tag)
Definition: Exprtk.hpp:1413
T modulus_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:991
T sec_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1362
T atan2_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1104
T pow_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:997
T modulus_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:985
T log1p_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1021
T trunc_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1370
exprtk_define_erf(float, ::erff) exprtk_define_erf(double
exprtk_define_epsilon_type(float, 0.00000100000f) exprtk_define_epsilon_type(double
T frac_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1369
T hypot_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1092
T nand_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1168
T min_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:917
T const_qnan_impl(real_type_tag)
Definition: Exprtk.hpp:1374
T equal_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:929
T nequal_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:964
T g2d_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1367
T max_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:923
T exp_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1349
bool is_true_impl(const T v)
Definition: Exprtk.hpp:899
T shr_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1122
T logn_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1015
T sin_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1356
T roundn_impl(const T v0, const T, int_type_tag)
Definition: Exprtk.hpp:1086
T round_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1068
T abs_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:911
T sgn_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1140
T d2g_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1366
T acos_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1340
T tan_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1359
T nor_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1198
T xor_impl(const T v0, const T v1, real_type_tag)
Definition: Exprtk.hpp:1204
T expm1_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:948
int to_int32_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:881
T and_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1162
exprtk_register_real_type_tag(float) exprtk_register_real_type_tag(double) exprtk_register_real_type_tag(long double) exprtk_register_int_type_tag(short) exprtk_register_int_type_tag(int) exprtk_register_int_type_tag(_int64_t) exprtk_register_int_type_tag(unsigned short) exprtk_register_int_type_tag(unsigned int) exprtk_register_int_type_tag(_uint64_t) template< typename T > struct epsilon_type
Definition: Exprtk.hpp:841
T root_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1062
T atanh_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1345
T xnor_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1228
T atan_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1344
T notl_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1368
T or_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:1186
T cosh_impl(const T v, real_type_tag)
Definition: Exprtk.hpp:1348
T equal_impl(const T v0, const T v1, int_type_tag)
Definition: Exprtk.hpp:942
T logn(const T v0, const T v1)
Definition: Exprtk.hpp:1498
T process(const operator_type operation, const T arg0, const T arg1)
Definition: Exprtk.hpp:5439
int to_int32(const T v)
Definition: Exprtk.hpp:1428
T xor_opr(const T v0, const T v1)
Definition: Exprtk.hpp:1575
T hypot(const T v0, const T v1)
Definition: Exprtk.hpp:1519
T pow(const T v0, const T v1)
Definition: Exprtk.hpp:1491
_uint64_t to_uint64(const T v)
Definition: Exprtk.hpp:1442
T nor_opr(const T v0, const T v1)
Definition: Exprtk.hpp:1568
bool is_nan(const T v)
Definition: Exprtk.hpp:1449
T root(const T v0, const T v1)
Definition: Exprtk.hpp:1505
bool is_integer(const T v)
Definition: Exprtk.hpp:1589
T nand_opr(const T v0, const T v1)
Definition: Exprtk.hpp:1554
T min(const T v0, const T v1)
Definition: Exprtk.hpp:1456
T nequal(const T v0, const T v1)
Definition: Exprtk.hpp:1477
T or_opr(const T v0, const T v1)
Definition: Exprtk.hpp:1561
T roundn(const T v0, const T v1)
Definition: Exprtk.hpp:1512
T atan2(const T v0, const T v1)
Definition: Exprtk.hpp:1526
T equal(const T v0, const T v1)
Definition: Exprtk.hpp:1470
T shl(const T v0, const T v1)
Definition: Exprtk.hpp:1540
T and_opr(const T v0, const T v1)
Definition: Exprtk.hpp:1547
T xnor_opr(const T v0, const T v1)
Definition: Exprtk.hpp:1582
_int64_t to_int64(const T v)
Definition: Exprtk.hpp:1435
T modulus(const T v0, const T v1)
Definition: Exprtk.hpp:1484
T max(const T v0, const T v1)
Definition: Exprtk.hpp:1463
T shr(const T v0, const T v1)
Definition: Exprtk.hpp:1533
bool is_string_ccondition_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18288
bool is_left_bracket(const char_t c)
Definition: Exprtk.hpp:138
static bool parse_nan(Iterator &itr, const Iterator end, T &t)
Definition: Exprtk.hpp:1822
bool is_true(const double v)
Definition: Exprtk.hpp:5543
static const double pow10[]
Definition: Exprtk.hpp:793
bool is_voc_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18204
bool is_vector_elem_rtc_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5642
bool string_to_real(Iterator &itr_external, const Iterator end, T &t, numeric::details::real_type_tag)
Definition: Exprtk.hpp:1896
bool all_nodes_variables(expression_node< T > *const (&b)[N])
Definition: Exprtk.hpp:5800
bool is_ivector_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5684
const char_t & back(const std::string &s)
Definition: Exprtk.hpp:268
static const std::string assignment_ops_list[]
Definition: Exprtk.hpp:495
bool all_nodes_valid(expression_node< T > *const (&b)[N])
Definition: Exprtk.hpp:5776
bool is_sign(const char_t c)
Definition: Exprtk.hpp:153
T compute_pow10(T d, const int exponent)
Definition: Exprtk.hpp:1683
const std::size_t size
Definition: Exprtk.hpp:783
bool is_hex_digit(const uchar_t digit)
Definition: Exprtk.hpp:302
bool is_whitespace(const char_t c)
Definition: Exprtk.hpp:99
bool is_ivariable_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5613
bool imatch(const char_t c1, const char_t c2)
Definition: Exprtk.hpp:234
synthesis_node_type_define(const T0 &, const T1 &, e_vov) synthesis_node_type_define(const T0 &
bool is_unary_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5589
bool is_invalid(const char_t c)
Definition: Exprtk.hpp:158
bool is_false(const expression_node< T > *node)
Definition: Exprtk.hpp:5571
bool is_rebasevector_elem_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5654
bool is_base_function(const std::string &function_name)
Definition: Exprtk.hpp:538
bool is_function(const expression_node< T > *node)
Definition: Exprtk.hpp:5743
bool is_t0ot1ot2ot3_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18228
long long int _int64_t
Definition: Exprtk.hpp:97
void construct_branch_pair(std::pair< expression_node< T > *, bool >(&branch)[N], expression_node< T > *b, const std::size_t &index)
Definition: Exprtk.hpp:6526
bool is_reserved_symbol(const std::string &symbol)
Definition: Exprtk.hpp:525
static const std::size_t arithmetic_ops_list_size
Definition: Exprtk.hpp:493
bool is_operator_char(const char_t c)
Definition: Exprtk.hpp:107
bool is_vector_celem_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5636
bool is_control_struct(const std::string &cntrl_strct)
Definition: Exprtk.hpp:551
bool is_bracket(const char_t c)
Definition: Exprtk.hpp:148
static const std::size_t base_function_list_size
Definition: Exprtk.hpp:472
bool is_literal_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5583
bool is_string_assignment_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18264
bool is_sf4ext_node(const expression_node< T > *n)
Definition: Exprtk.hpp:17155
bool is_string_vararg_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18294
bool string_to_type_converter_impl_ref(Iterator &itr, const Iterator end, T &result)
Definition: Exprtk.hpp:1745
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:594
static const std::size_t assignment_ops_list_size
Definition: Exprtk.hpp:501
static const std::string arithmetic_ops_list[]
Definition: Exprtk.hpp:488
bool is_vov_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18192
static const std::string reserved_symbols[]
Definition: Exprtk.hpp:440
bool branch_deletable(const expression_node< T > *node)
Definition: Exprtk.hpp:5768
bool is_uv_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18234
bool is_rebasevector_celem_rtc_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5666
bool is_vector_celem_rtc_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5648
exprtk_define_unary_op(abs) exprtk_define_unary_op(acos) exprtk_define_unary_op(acosh) exprtk_define_unary_op(asin) exprtk_define_unary_op(asinh) exprtk_define_unary_op(atan) exprtk_define_unary_op(atanh) exprtk_define_unary_op(ceil) exprtk_define_unary_op(cos) exprtk_define_unary_op(cosh) exprtk_define_unary_op(cot) exprtk_define_unary_op(csc) exprtk_define_unary_op(d2g) exprtk_define_unary_op(d2r) exprtk_define_unary_op(erf) exprtk_define_unary_op(erfc) exprtk_define_unary_op(exp) exprtk_define_unary_op(expm1) exprtk_define_unary_op(floor) exprtk_define_unary_op(frac) exprtk_define_unary_op(g2d) exprtk_define_unary_op(log) exprtk_define_unary_op(log10) exprtk_define_unary_op(log2) exprtk_define_unary_op(log1p) exprtk_define_unary_op(ncdf) exprtk_define_unary_op(neg) exprtk_define_unary_op(notl) exprtk_define_unary_op(pos) exprtk_define_unary_op(r2d) exprtk_define_unary_op(round) exprtk_define_unary_op(sec) exprtk_define_unary_op(sgn) exprtk_define_unary_op(sin) exprtk_define_unary_op(sinc) exprtk_define_unary_op(sinh) exprtk_define_unary_op(sqrt) exprtk_define_unary_op(tan) exprtk_define_unary_op(tanh) exprtk_define_unary_op(trunc) template< typename T > struct opr_base
Definition: Exprtk.hpp:14756
void case_normalise(std::string &)
Definition: Exprtk.hpp:231
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t t(t/t)") define_sfop3(19
char char_t
Definition: Exprtk.hpp:90
bool is_constant_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5709
const T1 const T2 const T3
Definition: Exprtk.hpp:16533
void dump_vector(const std::string &, const T *, const std::size_t)
Definition: Exprtk.hpp:5096
x y * z
Definition: Exprtk.hpp:11139
static const std::string logic_ops_list[]
Definition: Exprtk.hpp:474
bool is_valid_sf_symbol(const std::string &symbol)
Definition: Exprtk.hpp:253
const T1
Definition: Exprtk.hpp:16489
bool is_binary_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5601
bool is_string_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18240
void dump_ptr(const std::string &, const void *)
Definition: Exprtk.hpp:5093
bool is_valid_string_char(const char_t c)
Definition: Exprtk.hpp:171
T value(details::expression_node< T > *n)
Definition: Exprtk.hpp:15070
bool wc_match(const std::string &wild_card, const std::string &str)
Definition: Exprtk.hpp:656
static bool parse_inf(Iterator &itr, const Iterator end, T &t, const bool negative)
Definition: Exprtk.hpp:1855
bool is_const_string_range_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18258
void load_operations_map(std::multimap< std::string, details::base_operation_t, details::ilesscompare > &m)
Definition: Exprtk.hpp:18716
static const std::string reserved_words[]
Definition: Exprtk.hpp:429
bool is_boc_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18216
bool is_string_condition_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18282
bool valid_exponent(const int exponent, numeric::details::real_type_tag)
Definition: Exprtk.hpp:1889
void disable_type_checking(Parser &p)
Definition: Exprtk.hpp:21324
static const std::string inequality_ops_list[]
Definition: Exprtk.hpp:503
static const std::size_t cntrl_struct_list_size
Definition: Exprtk.hpp:486
bool is_string_function_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18276
bool is_letter_or_digit(const char_t c)
Definition: Exprtk.hpp:133
bool is_cov_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18198
bool is_const_string_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18252
const char_t & front(const std::string &s)
Definition: Exprtk.hpp:263
define_sfop3(00,(x+y)/z,"(t+t)/t") define_sfop3(01
bool is_genricstring_range_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18300
uchar_t const * uchar_cptr
Definition: Exprtk.hpp:95
bool is_null_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5719
T axn(const T a, const T x)
Definition: Exprtk.hpp:11099
T axnb(const T a, const T x, const T b)
Definition: Exprtk.hpp:11106
bool sequence_match(const std::string &pattern, const std::string &str, std::size_t &diff_index, char_t &diff_value)
Definition: Exprtk.hpp:682
T value(const T &t)
Definition: Exprtk.hpp:15088
static const std::size_t inequality_ops_list_size
Definition: Exprtk.hpp:510
std::string to_str(int i)
Definition: Exprtk.hpp:273
operator_type
Definition: Exprtk.hpp:4926
@ e_sf4ext08
Definition: Exprtk.hpp:4981
@ e_sf07
Definition: Exprtk.hpp:4954
@ e_sf4ext14
Definition: Exprtk.hpp:4982
@ e_sf16
Definition: Exprtk.hpp:4957
@ e_tan
Definition: Exprtk.hpp:4942
@ e_sf4ext25
Definition: Exprtk.hpp:4985
@ e_sf71
Definition: Exprtk.hpp:4970
@ e_sf47
Definition: Exprtk.hpp:4964
@ e_root
Definition: Exprtk.hpp:4941
@ e_sf4ext38
Definition: Exprtk.hpp:4988
@ e_sf26
Definition: Exprtk.hpp:4959
@ e_asin
Definition: Exprtk.hpp:4936
@ e_sf4ext57
Definition: Exprtk.hpp:4993
@ e_sf30
Definition: Exprtk.hpp:4960
@ e_sf4ext49
Definition: Exprtk.hpp:4991
@ e_sf94
Definition: Exprtk.hpp:4976
@ e_sf56
Definition: Exprtk.hpp:4967
@ e_sf09
Definition: Exprtk.hpp:4955
@ e_sf62
Definition: Exprtk.hpp:4968
@ e_eq
Definition: Exprtk.hpp:4931
@ e_sffinal
Definition: Exprtk.hpp:4978
@ e_sinc
Definition: Exprtk.hpp:4941
@ e_sf4ext47
Definition: Exprtk.hpp:4990
@ e_sf59
Definition: Exprtk.hpp:4967
@ e_expm1
Definition: Exprtk.hpp:4938
@ e_sf38
Definition: Exprtk.hpp:4962
@ e_like
Definition: Exprtk.hpp:4949
@ e_equal
Definition: Exprtk.hpp:4931
@ e_sf55
Definition: Exprtk.hpp:4966
@ e_sf92
Definition: Exprtk.hpp:4976
@ e_cosh
Definition: Exprtk.hpp:4937
@ e_sf4ext17
Definition: Exprtk.hpp:4983
@ e_sqrt
Definition: Exprtk.hpp:4941
@ e_sec
Definition: Exprtk.hpp:4942
@ e_sf4ext06
Definition: Exprtk.hpp:4980
@ e_sf50
Definition: Exprtk.hpp:4965
@ e_acosh
Definition: Exprtk.hpp:4936
@ e_or
Definition: Exprtk.hpp:4933
@ e_sf49
Definition: Exprtk.hpp:4965
@ e_sf90
Definition: Exprtk.hpp:4975
@ e_sf53
Definition: Exprtk.hpp:4966
@ e_sf63
Definition: Exprtk.hpp:4968
@ e_add
Definition: Exprtk.hpp:4927
@ e_cos
Definition: Exprtk.hpp:4937
@ e_sf37
Definition: Exprtk.hpp:4962
@ e_nand
Definition: Exprtk.hpp:4932
@ e_sf43
Definition: Exprtk.hpp:4963
@ e_sf34
Definition: Exprtk.hpp:4961
@ e_divass
Definition: Exprtk.hpp:4948
@ e_sf91
Definition: Exprtk.hpp:4975
@ e_sf08
Definition: Exprtk.hpp:4955
@ e_sf35
Definition: Exprtk.hpp:4961
@ e_sf72
Definition: Exprtk.hpp:4971
@ e_sf25
Definition: Exprtk.hpp:4959
@ e_sf18
Definition: Exprtk.hpp:4957
@ e_sf27
Definition: Exprtk.hpp:4959
@ e_sf4ext52
Definition: Exprtk.hpp:4992
@ e_smulti
Definition: Exprtk.hpp:4949
@ e_multi
Definition: Exprtk.hpp:4949
@ e_sf01
Definition: Exprtk.hpp:4953
@ e_sf11
Definition: Exprtk.hpp:4955
@ e_sf98
Definition: Exprtk.hpp:4977
@ e_sf44
Definition: Exprtk.hpp:4964
@ e_sf4ext05
Definition: Exprtk.hpp:4980
@ e_sf88
Definition: Exprtk.hpp:4975
@ e_mulass
Definition: Exprtk.hpp:4948
@ e_sf4ext10
Definition: Exprtk.hpp:4981
@ e_sf4ext15
Definition: Exprtk.hpp:4982
@ e_sf4ext36
Definition: Exprtk.hpp:4988
@ e_sf61
Definition: Exprtk.hpp:4968
@ e_addass
Definition: Exprtk.hpp:4947
@ e_sf19
Definition: Exprtk.hpp:4957
@ e_atanh
Definition: Exprtk.hpp:4937
@ e_sf78
Definition: Exprtk.hpp:4972
@ e_sf20
Definition: Exprtk.hpp:4958
@ e_lte
Definition: Exprtk.hpp:4930
@ e_lt
Definition: Exprtk.hpp:4930
@ e_tanh
Definition: Exprtk.hpp:4943
@ e_sf57
Definition: Exprtk.hpp:4967
@ e_sf4ext22
Definition: Exprtk.hpp:4984
@ e_round
Definition: Exprtk.hpp:4940
@ e_clamp
Definition: Exprtk.hpp:4943
@ e_sf04
Definition: Exprtk.hpp:4954
@ e_sf4ext31
Definition: Exprtk.hpp:4986
@ e_logn
Definition: Exprtk.hpp:4939
@ e_prod
Definition: Exprtk.hpp:4930
@ e_sf36
Definition: Exprtk.hpp:4962
@ e_sf4ext16
Definition: Exprtk.hpp:4983
@ e_sf42
Definition: Exprtk.hpp:4963
@ e_sf4ext32
Definition: Exprtk.hpp:4987
@ e_sf73
Definition: Exprtk.hpp:4971
@ e_min
Definition: Exprtk.hpp:4929
@ e_sf4ext03
Definition: Exprtk.hpp:4979
@ e_sf45
Definition: Exprtk.hpp:4964
@ e_sf93
Definition: Exprtk.hpp:4976
@ e_sf54
Definition: Exprtk.hpp:4966
@ e_sf4ext33
Definition: Exprtk.hpp:4987
@ e_sf03
Definition: Exprtk.hpp:4953
@ e_trunc
Definition: Exprtk.hpp:4947
@ e_sf4ext48
Definition: Exprtk.hpp:4991
@ e_ceil
Definition: Exprtk.hpp:4937
@ e_sf4ext01
Definition: Exprtk.hpp:4979
@ e_notl
Definition: Exprtk.hpp:4945
@ e_avg
Definition: Exprtk.hpp:4929
@ e_erfc
Definition: Exprtk.hpp:4946
@ e_sgn
Definition: Exprtk.hpp:4944
@ e_sf4ext04
Definition: Exprtk.hpp:4980
@ e_sf29
Definition: Exprtk.hpp:4960
@ e_sf4ext53
Definition: Exprtk.hpp:4992
@ e_sf66
Definition: Exprtk.hpp:4969
@ e_sf4ext58
Definition: Exprtk.hpp:4993
@ e_sf4ext40
Definition: Exprtk.hpp:4989
@ e_floor
Definition: Exprtk.hpp:4938
@ e_asinh
Definition: Exprtk.hpp:4936
@ e_sf10
Definition: Exprtk.hpp:4955
@ e_mul
Definition: Exprtk.hpp:4928
@ e_acos
Definition: Exprtk.hpp:4935
@ e_sf4ext20
Definition: Exprtk.hpp:4984
@ e_sf79
Definition: Exprtk.hpp:4972
@ e_subass
Definition: Exprtk.hpp:4947
@ e_sf41
Definition: Exprtk.hpp:4963
@ e_mor
Definition: Exprtk.hpp:4934
@ e_sf17
Definition: Exprtk.hpp:4957
@ e_nor
Definition: Exprtk.hpp:4933
@ e_atan
Definition: Exprtk.hpp:4936
@ e_hypot
Definition: Exprtk.hpp:4945
@ e_sf46
Definition: Exprtk.hpp:4964
@ e_gt
Definition: Exprtk.hpp:4932
@ e_sf22
Definition: Exprtk.hpp:4958
@ e_pos
Definition: Exprtk.hpp:4940
@ e_sf4ext27
Definition: Exprtk.hpp:4985
@ e_inrange
Definition: Exprtk.hpp:4944
@ e_sin
Definition: Exprtk.hpp:4941
@ e_sf21
Definition: Exprtk.hpp:4958
@ e_sf06
Definition: Exprtk.hpp:4954
@ e_sf33
Definition: Exprtk.hpp:4961
@ e_xor
Definition: Exprtk.hpp:4933
@ e_sum
Definition: Exprtk.hpp:4930
@ e_sf4ext11
Definition: Exprtk.hpp:4981
@ e_sf4ext28
Definition: Exprtk.hpp:4986
@ e_sf4ext60
Definition: Exprtk.hpp:4994
@ e_exp
Definition: Exprtk.hpp:4938
@ e_log
Definition: Exprtk.hpp:4938
@ e_sf96
Definition: Exprtk.hpp:4977
@ e_sf4ext29
Definition: Exprtk.hpp:4986
@ e_sf51
Definition: Exprtk.hpp:4965
@ e_sf12
Definition: Exprtk.hpp:4956
@ e_xnor
Definition: Exprtk.hpp:4933
@ e_sf4ext37
Definition: Exprtk.hpp:4988
@ e_sf97
Definition: Exprtk.hpp:4977
@ e_sf83
Definition: Exprtk.hpp:4973
@ e_roundn
Definition: Exprtk.hpp:4940
@ e_sf67
Definition: Exprtk.hpp:4969
@ e_sf4ext45
Definition: Exprtk.hpp:4990
@ e_sf39
Definition: Exprtk.hpp:4962
@ e_sf80
Definition: Exprtk.hpp:4973
@ e_sf68
Definition: Exprtk.hpp:4970
@ e_sf87
Definition: Exprtk.hpp:4974
@ e_sf4ext35
Definition: Exprtk.hpp:4987
@ e_sf4ext50
Definition: Exprtk.hpp:4991
@ e_default
Definition: Exprtk.hpp:4927
@ e_ilike
Definition: Exprtk.hpp:4949
@ e_sf40
Definition: Exprtk.hpp:4963
@ e_sf4ext59
Definition: Exprtk.hpp:4993
@ e_sf05
Definition: Exprtk.hpp:4954
@ e_sf4ext00
Definition: Exprtk.hpp:4979
@ e_nequal
Definition: Exprtk.hpp:4931
@ e_sf58
Definition: Exprtk.hpp:4967
@ e_sf77
Definition: Exprtk.hpp:4972
@ e_scor
Definition: Exprtk.hpp:4934
@ e_assign
Definition: Exprtk.hpp:4947
@ e_sf4ext46
Definition: Exprtk.hpp:4990
@ e_sf4ext54
Definition: Exprtk.hpp:4992
@ e_sf48
Definition: Exprtk.hpp:4965
@ e_mand
Definition: Exprtk.hpp:4934
@ e_null
Definition: Exprtk.hpp:4927
@ e_sf13
Definition: Exprtk.hpp:4956
@ e_sf4ext13
Definition: Exprtk.hpp:4982
@ e_abs
Definition: Exprtk.hpp:4935
@ e_sf4ext12
Definition: Exprtk.hpp:4982
@ e_sf85
Definition: Exprtk.hpp:4974
@ e_sf4ext02
Definition: Exprtk.hpp:4979
@ e_shl
Definition: Exprtk.hpp:4935
@ e_sf32
Definition: Exprtk.hpp:4961
@ e_scand
Definition: Exprtk.hpp:4934
@ e_atan2
Definition: Exprtk.hpp:4929
@ e_d2g
Definition: Exprtk.hpp:4945
@ e_sf76
Definition: Exprtk.hpp:4972
@ e_sf02
Definition: Exprtk.hpp:4953
@ e_sf4ext51
Definition: Exprtk.hpp:4991
@ e_sf4ext41
Definition: Exprtk.hpp:4989
@ e_pow
Definition: Exprtk.hpp:4928
@ e_sf4ext61
Definition: Exprtk.hpp:4994
@ e_ne
Definition: Exprtk.hpp:4931
@ e_modass
Definition: Exprtk.hpp:4948
@ e_sf4ext19
Definition: Exprtk.hpp:4983
@ e_sf84
Definition: Exprtk.hpp:4974
@ e_iclamp
Definition: Exprtk.hpp:4943
@ e_sf52
Definition: Exprtk.hpp:4966
@ e_in
Definition: Exprtk.hpp:4948
@ e_sf69
Definition: Exprtk.hpp:4970
@ e_erf
Definition: Exprtk.hpp:4946
@ e_sf75
Definition: Exprtk.hpp:4971
@ e_ncdf
Definition: Exprtk.hpp:4946
@ e_sf65
Definition: Exprtk.hpp:4969
@ e_log1p
Definition: Exprtk.hpp:4939
@ e_sf14
Definition: Exprtk.hpp:4956
@ e_sf4ext43
Definition: Exprtk.hpp:4989
@ e_sf4ext34
Definition: Exprtk.hpp:4987
@ e_and
Definition: Exprtk.hpp:4932
@ e_sf95
Definition: Exprtk.hpp:4976
@ e_sf4ext23
Definition: Exprtk.hpp:4984
@ e_sf4ext44
Definition: Exprtk.hpp:4990
@ e_sf70
Definition: Exprtk.hpp:4970
@ e_gte
Definition: Exprtk.hpp:4932
@ e_cot
Definition: Exprtk.hpp:4943
@ e_log10
Definition: Exprtk.hpp:4939
@ e_div
Definition: Exprtk.hpp:4928
@ e_mod
Definition: Exprtk.hpp:4928
@ e_sf4ext26
Definition: Exprtk.hpp:4985
@ e_sf4ext56
Definition: Exprtk.hpp:4993
@ e_sf28
Definition: Exprtk.hpp:4960
@ e_sf00
Definition: Exprtk.hpp:4953
@ e_r2d
Definition: Exprtk.hpp:4944
@ e_g2d
Definition: Exprtk.hpp:4945
@ e_sf4ext07
Definition: Exprtk.hpp:4980
@ e_sf4ext21
Definition: Exprtk.hpp:4984
@ e_sf74
Definition: Exprtk.hpp:4971
@ e_sf64
Definition: Exprtk.hpp:4969
@ e_sf4ext24
Definition: Exprtk.hpp:4985
@ e_sf4ext42
Definition: Exprtk.hpp:4989
@ e_sf15
Definition: Exprtk.hpp:4956
@ e_sf89
Definition: Exprtk.hpp:4975
@ e_sf99
Definition: Exprtk.hpp:4977
@ e_sf86
Definition: Exprtk.hpp:4974
@ e_d2r
Definition: Exprtk.hpp:4944
@ e_sf4ext39
Definition: Exprtk.hpp:4988
@ e_swap
Definition: Exprtk.hpp:4950
@ e_sf4ext55
Definition: Exprtk.hpp:4992
@ e_sf31
Definition: Exprtk.hpp:4960
@ e_sinh
Definition: Exprtk.hpp:4942
@ e_sf4ext30
Definition: Exprtk.hpp:4986
@ e_neg
Definition: Exprtk.hpp:4940
@ e_shr
Definition: Exprtk.hpp:4935
@ e_sub
Definition: Exprtk.hpp:4927
@ e_sf4ext18
Definition: Exprtk.hpp:4983
@ e_frac
Definition: Exprtk.hpp:4946
@ e_sf60
Definition: Exprtk.hpp:4968
@ e_sf24
Definition: Exprtk.hpp:4959
@ e_log2
Definition: Exprtk.hpp:4939
@ e_sf23
Definition: Exprtk.hpp:4958
@ e_sf82
Definition: Exprtk.hpp:4973
@ e_max
Definition: Exprtk.hpp:4929
@ e_sf4ext09
Definition: Exprtk.hpp:4981
@ e_csc
Definition: Exprtk.hpp:4942
@ e_sf81
Definition: Exprtk.hpp:4973
unsigned long long int _uint64_t
Definition: Exprtk.hpp:96
bool is_variable_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5607
bool is_vector_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5678
bool is_negate_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5757
bool is_swap_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5737
void destroy_node(expression_node< T > *&node)
Definition: Exprtk.hpp:5935
bool is_string_concat_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18270
bool is_reserved_word(const std::string &symbol)
Definition: Exprtk.hpp:512
bool is_letter(const char_t c)
Definition: Exprtk.hpp:122
bool is_vector_elem_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5630
bool wc_imatch(const std::string &wild_card, const std::string &str)
Definition: Exprtk.hpp:669
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t t(t+t)") define_sfop3(16
bool is_return_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5749
const e_voc T1 e_none const e_none T1 e_none T0
Definition: Exprtk.hpp:16499
static const std::size_t reserved_words_size
Definition: Exprtk.hpp:438
static const std::string cntrl_struct_list[]
Definition: Exprtk.hpp:481
bool is_cob_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18210
unsigned char uchar_t
Definition: Exprtk.hpp:93
bool is_generally_string_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18306
memory_context_t< T > make_memory_context(vector_holder< T > &vec_holder, vec_data_store< T > &vds)
Definition: Exprtk.hpp:12790
static const std::string base_function_list[]
Definition: Exprtk.hpp:459
uchar_t hex_to_bin(uchar_t h)
Definition: Exprtk.hpp:309
bool is_digit(const char_t c)
Definition: Exprtk.hpp:128
uchar_t * uchar_ptr
Definition: Exprtk.hpp:94
bool is_rebasevector_celem_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5672
static const std::size_t reserved_symbols_size
Definition: Exprtk.hpp:457
void set_zero_value(std::vector< T > &v)
Definition: Exprtk.hpp:788
bool is_string_range_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18246
void free_node(NodeAllocator &, expression_node< T > *&node)
Definition: Exprtk.hpp:5923
bool is_continue_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5731
bool is_logic_opr(const std::string &lgc_opr)
Definition: Exprtk.hpp:564
const T1 const T2
Definition: Exprtk.hpp:16511
char_t const * char_cptr
Definition: Exprtk.hpp:92
bool parse_hex(Iterator &itr, Iterator end, char_t &result)
Definition: Exprtk.hpp:318
static const std::size_t pow10_size
Definition: Exprtk.hpp:802
pod_set_zero_value(float) pod_set_zero_value(double) pod_set_zero_value(long double) template< typename T > inline void set_zero_value(T *data
char_t * char_ptr
Definition: Exprtk.hpp:91
void free_all_nodes(NodeAllocator &node_allocator, expression_node< T > *(&b)[N])
Definition: Exprtk.hpp:5900
bool is_sf3ext_node(const expression_node< T > *n)
Definition: Exprtk.hpp:16977
bool is_rebasevector_elem_rtc_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5660
bool cleanup_escapes(std::string &s)
Definition: Exprtk.hpp:341
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t x(y+z)
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t x(y/z)
static const std::size_t logic_ops_list_size
Definition: Exprtk.hpp:479
bool is_break_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5725
bool is_right_bracket(const char_t c)
Definition: Exprtk.hpp:143
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:6546
bool is_neg_unary_node(const expression_node< T > *node)
Definition: Exprtk.hpp:5595
bool is_t0ot1ot2_node(const expression_node< T > *node)
Definition: Exprtk.hpp:18222
static char_cptr date
Definition: Exprtk.hpp:44225
static char_cptr min_cpp
Definition: Exprtk.hpp:44226
static std::string data()
Definition: Exprtk.hpp:44228
static char_cptr version
Definition: Exprtk.hpp:44221
static char_cptr library
Definition: Exprtk.hpp:44220
void dump(const lexer::generator &generator)
Definition: Exprtk.hpp:3393
error_mode
Definition: Exprtk.hpp:21198
@ e_helper
Definition: Exprtk.hpp:21206
@ e_lexer
Definition: Exprtk.hpp:21204
@ e_synthesis
Definition: Exprtk.hpp:21205
@ e_parser
Definition: Exprtk.hpp:21207
@ e_symtab
Definition: Exprtk.hpp:21203
@ e_token
Definition: Exprtk.hpp:21201
@ e_numeric
Definition: Exprtk.hpp:21202
@ e_unknown
Definition: Exprtk.hpp:21199
@ e_syntax
Definition: Exprtk.hpp:21200
void dump_error(const type &error)
Definition: Exprtk.hpp:21312
bool update_error(type &error, const std::string &expression)
Definition: Exprtk.hpp:21270
type make_error(const error_mode mode, const std::string &diagnostic="", const std::string &src_location="")
Definition: Exprtk.hpp:21227
type make_error(const error_mode mode, const lexer::token &tk, const std::string &diagnostic="", const std::string &src_location="")
Definition: Exprtk.hpp:21240
std::string to_str(error_mode mode)
Definition: Exprtk.hpp:21254
void print_type(const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
Definition: Exprtk.hpp:42020
file_descriptor * make_handle(T v)
Definition: Exprtk.hpp:42376
file_mode
Definition: Exprtk.hpp:42184
@ e_write
Definition: Exprtk.hpp:42187
@ e_error
Definition: Exprtk.hpp:42185
@ e_rdwrt
Definition: Exprtk.hpp:42188
@ e_read
Definition: Exprtk.hpp:42186
void perform_check()
Definition: Exprtk.hpp:42388
void kahan_sum(T &sum, T &error, const T v)
Definition: Exprtk.hpp:42729
bool invalid_range(const Vector &v, const std::size_t r0, const std::size_t r1)
Definition: Exprtk.hpp:42682
Definition: Exprtk.hpp:60
void enable_zero_parameters(FunctionType &func)
Definition: Exprtk.hpp:18818
bool collect_variables(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
Definition: Exprtk.hpp:40321
vector_access_runtime_check * vector_access_runtime_check_ptr
Definition: Exprtk.hpp:2156
void set_max_num_args(FunctionType &func, const std::size_t &num_args)
Definition: Exprtk.hpp:18856
bool is_valid(const expression< T > &expr)
Definition: Exprtk.hpp:21190
void disable_has_side_effects(FunctionType &func)
Definition: Exprtk.hpp:18841
vector_view< T > make_vector_view(T *data, const std::size_t size, const std::size_t offset=0)
Definition: Exprtk.hpp:4589
compilation_check * compilation_check_ptr
Definition: Exprtk.hpp:2171
void disable_zero_parameters(FunctionType &func)
Definition: Exprtk.hpp:18829
T third_derivative(const expression< T > &e, T &x, const T &h=T(0.0001))
Definition: Exprtk.hpp:40537
bool collect_functions(const std::string &expression, Sequence< std::string, Allocator > &symbol_list)
Definition: Exprtk.hpp:40382
loop_runtime_check * loop_runtime_check_ptr
Definition: Exprtk.hpp:2132
bool compute(const std::string &expression_string, T &result)
Definition: Exprtk.hpp:40649
T derivative(const expression< T > &e, T &x, const T &h=T(0.00000001))
Definition: Exprtk.hpp:40494
T second_derivative(const expression< T > &e, T &x, const T &h=T(0.00001))
Definition: Exprtk.hpp:40515
std::string to_str(const StringView &view)
Definition: Exprtk.hpp:4798
void set_min_num_args(FunctionType &func, const std::size_t &num_args)
Definition: Exprtk.hpp:18847
void enable_has_side_effects(FunctionType &func)
Definition: Exprtk.hpp:18835
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:40442
std::string error_message
Definition: Exprtk.hpp:2162
Definition: Exprtk.hpp:2159
virtual bool continue_compilation(compilation_context &)=0
virtual ~compilation_check()
Definition: Exprtk.hpp:2167
Definition: Exprtk.hpp:17174
details::T0oT1< T, T0, T1 > type0
Definition: Exprtk.hpp:17175
Definition: Exprtk.hpp:16371
static std::string id()
Definition: Exprtk.hpp:16381
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:16372
Definition: Exprtk.hpp:16392
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:16393
static std::string id()
Definition: Exprtk.hpp:16401
Definition: Exprtk.hpp:16412
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:16413
static std::string id()
Definition: Exprtk.hpp:16422
Definition: Exprtk.hpp:16433
static std::string id()
Definition: Exprtk.hpp:16443
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:16434
Definition: Exprtk.hpp:16454
static std::string id()
Definition: Exprtk.hpp:16464
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:16455
Definition: Exprtk.hpp:16366
details::functor_t< T > functor_t
Definition: Exprtk.hpp:16367
functor_t::bfunc_t bfunc_t
Definition: Exprtk.hpp:16368
Definition: Exprtk.hpp:17180
details::T0oT1oT2< T, T0, T1, T2, typename T0oT1oT2process< T >::mode0 > type0
Definition: Exprtk.hpp:17181
details::T0oT1oT2_sf3< T, T0, T1, T2 > sf3_type
Definition: Exprtk.hpp:17183
details::T0oT1oT2< T, T0, T1, T2, typename T0oT1oT2process< T >::mode1 > type1
Definition: Exprtk.hpp:17182
details::sf3ext_type_node< T, T0, T1, T2 > sf3_type_node
Definition: Exprtk.hpp:17184
Definition: Exprtk.hpp:17189
details::T0oT1oT2oT3_sf4< T, T0, T1, T2, T3 > sf4_type
Definition: Exprtk.hpp:17195
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode2 > type2
Definition: Exprtk.hpp:17192
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode0 > type0
Definition: Exprtk.hpp:17190
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode1 > type1
Definition: Exprtk.hpp:17191
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode4 > type4
Definition: Exprtk.hpp:17194
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode3 > type3
Definition: Exprtk.hpp:17193
Definition: Exprtk.hpp:16328
static std::string id()
Definition: Exprtk.hpp:16336
static T process(const T &t0, const T &t1, const T &t2, const bfunc_t bf0, const bfunc_t bf1)
Definition: Exprtk.hpp:16329
Definition: Exprtk.hpp:16346
static std::string id()
Definition: Exprtk.hpp:16354
static T process(const T &t0, const T &t1, const T &t2, const bfunc_t bf0, const bfunc_t bf1)
Definition: Exprtk.hpp:16347
Definition: Exprtk.hpp:16323
details::functor_t< T > functor_t
Definition: Exprtk.hpp:16324
functor_t::bfunc_t bfunc_t
Definition: Exprtk.hpp:16325
Definition: Exprtk.hpp:14812
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14816
static T process(Type t1, Type t2, Type t3)
Definition: Exprtk.hpp:14817
static details::operator_type operation()
Definition: Exprtk.hpp:14820
static void assign(RefType t1, Type t2)
Definition: Exprtk.hpp:14818
opr_base< T >::Type Type
Definition: Exprtk.hpp:14813
opr_base< T >::RefType RefType
Definition: Exprtk.hpp:14814
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14819
Definition: Exprtk.hpp:14964
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14967
static details::operator_type operation()
Definition: Exprtk.hpp:14969
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14968
opr_base< T >::Type Type
Definition: Exprtk.hpp:14965
Definition: Exprtk.hpp:10399
static void execute(std::string &s, char_cptr data, const std::size_t size)
Definition: Exprtk.hpp:10400
Definition: Exprtk.hpp:10393
static void execute(std::string &s, char_cptr data, const std::size_t size)
Definition: Exprtk.hpp:10394
Definition: Exprtk.hpp:5032
base_operation_t(const operator_type t, const unsigned int &np)
Definition: Exprtk.hpp:5033
operator_type type
Definition: Exprtk.hpp:5038
unsigned int num_params
Definition: Exprtk.hpp:5039
Definition: Exprtk.hpp:586
static bool cmp(const char_t c0, const char_t c1)
Definition: Exprtk.hpp:587
virtual bool process(const std::string &unknown_symbol, symbol_table_t &symbol_table, std::string &) exprtk_override
Definition: Exprtk.hpp:40260
exprtk::parser< T > parser_t
Definition: Exprtk.hpp:40254
Definition: Exprtk.hpp:40245
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:40270
parser_t::dependent_entity_collector::symbol_t symbol_t
Definition: Exprtk.hpp:40249
exprtk::symbol_table< T > symbol_table_t
Definition: Exprtk.hpp:40246
parser_t::unknown_symbol_resolver usr_t
Definition: Exprtk.hpp:40250
exprtk::parser< T > parser_t
Definition: Exprtk.hpp:40248
exprtk::expression< T > expression_t
Definition: Exprtk.hpp:40247
Definition: Exprtk.hpp:578
static bool cmp(const char_t c0, const char_t c1)
Definition: Exprtk.hpp:579
Definition: Exprtk.hpp:14851
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14855
static details::operator_type operation()
Definition: Exprtk.hpp:14859
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14858
static void assign(RefType t1, Type t2)
Definition: Exprtk.hpp:14857
opr_base< T >::RefType RefType
Definition: Exprtk.hpp:14853
static T process(Type t1, Type t2, Type t3)
Definition: Exprtk.hpp:14856
opr_base< T >::Type Type
Definition: Exprtk.hpp:14852
Definition: Exprtk.hpp:14932
opr_base< T >::Type Type
Definition: Exprtk.hpp:14933
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14934
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:14935
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14936
static details::operator_type operation()
Definition: Exprtk.hpp:14937
Definition: Exprtk.hpp:14942
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14947
static details::operator_type operation()
Definition: Exprtk.hpp:14948
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14945
opr_base< T >::Type Type
Definition: Exprtk.hpp:14943
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:14946
static void execute(T_(&v)[1], const branch_t(&b)[1])
Definition: Exprtk.hpp:13909
static void execute(T_(&v)[2], const branch_t(&b)[2])
Definition: Exprtk.hpp:13899
static void execute(T_(&v)[3], const branch_t(&b)[3])
Definition: Exprtk.hpp:13888
static void execute(T_(&v)[4], const branch_t(&b)[4])
Definition: Exprtk.hpp:13876
static void execute(T_(&v)[5], const branch_t(&b)[5])
Definition: Exprtk.hpp:13863
static void execute(T_(&v)[6], const branch_t(&b)[6])
Definition: Exprtk.hpp:13849
static void execute(T_(&v)[BranchCount], const branch_t(&b)[BranchCount])
Definition: Exprtk.hpp:13837
static T_ execute(ifunction &f, T_(&v)[10])
Definition: Exprtk.hpp:13991
static T_ execute(ifunction &f, T_(&v)[11])
Definition: Exprtk.hpp:13984
static T_ execute(ifunction &f, T_(&v)[12])
Definition: Exprtk.hpp:13977
static T_ execute(ifunction &f, T_(&v)[13])
Definition: Exprtk.hpp:13970
static T_ execute(ifunction &f, T_(&v)[14])
Definition: Exprtk.hpp:13963
static T_ execute(ifunction &f, T_(&v)[15])
Definition: Exprtk.hpp:13956
static T_ execute(ifunction &f, T_(&v)[16])
Definition: Exprtk.hpp:13949
static T_ execute(ifunction &f, T_(&v)[17])
Definition: Exprtk.hpp:13942
static T_ execute(ifunction &f, T_(&v)[18])
Definition: Exprtk.hpp:13935
static T_ execute(ifunction &f, T_(&v)[19])
Definition: Exprtk.hpp:13928
static T_ execute(ifunction &f, T_(&v)[1])
Definition: Exprtk.hpp:14054
static T_ execute(ifunction &f, T_(&v)[20])
Definition: Exprtk.hpp:13921
static T_ execute(ifunction &f, T_(&v)[2])
Definition: Exprtk.hpp:14047
static T_ execute(ifunction &f, T_(&v)[3])
Definition: Exprtk.hpp:14040
static T_ execute(ifunction &f, T_(&v)[4])
Definition: Exprtk.hpp:14033
static T_ execute(ifunction &f, T_(&v)[5])
Definition: Exprtk.hpp:14026
static T_ execute(ifunction &f, T_(&v)[6])
Definition: Exprtk.hpp:14019
static T_ execute(ifunction &f, T_(&v)[7])
Definition: Exprtk.hpp:14012
static T_ execute(ifunction &f, T_(&v)[8])
Definition: Exprtk.hpp:14005
static T_ execute(ifunction &f, T_(&v)[9])
Definition: Exprtk.hpp:13998
Definition: Exprtk.hpp:13916
static T execute(ifunction &, branch_t(&)[ParamCount])
Definition: Exprtk.hpp:13916
Definition: Exprtk.hpp:2066
const T & Type
Definition: Exprtk.hpp:2074
T(* bfunc_t)(Type t0, Type t1)
Definition: Exprtk.hpp:2078
T & RefType
Definition: Exprtk.hpp:2075
T(* qfunc_t)(Type t0, Type t1, Type t2, Type t3)
Definition: Exprtk.hpp:2076
T(* tfunc_t)(Type t0, Type t1, Type t2)
Definition: Exprtk.hpp:2077
T(* ufunc_t)(Type t0)
Definition: Exprtk.hpp:2079
Definition: Exprtk.hpp:14910
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14915
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14913
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:14914
opr_base< T >::Type Type
Definition: Exprtk.hpp:14911
static details::operator_type operation()
Definition: Exprtk.hpp:14916
Definition: Exprtk.hpp:14921
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14924
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14926
static details::operator_type operation()
Definition: Exprtk.hpp:14927
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:14925
opr_base< T >::Type Type
Definition: Exprtk.hpp:14922
Definition: Exprtk.hpp:245
bool operator()(const std::string &s1, const std::string &s2) const
Definition: Exprtk.hpp:246
Definition: Exprtk.hpp:15046
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:15050
static details::operator_type operation()
Definition: Exprtk.hpp:15052
static T process(const T &, const T &)
Definition: Exprtk.hpp:15049
opr_base< T >::Type Type
Definition: Exprtk.hpp:15047
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:15051
Definition: Exprtk.hpp:15024
opr_base< T >::Type Type
Definition: Exprtk.hpp:15025
static T process(const T &, const T &)
Definition: Exprtk.hpp:15027
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:15029
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:15028
static details::operator_type operation()
Definition: Exprtk.hpp:15030
Definition: Exprtk.hpp:15057
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:15065
opr_base< T >::Type Type
Definition: Exprtk.hpp:15058
static details::operator_type operation()
Definition: Exprtk.hpp:15066
static T process(const T &t0, const T &t1, const T &t2)
Definition: Exprtk.hpp:15060
static T process(const std::string &t0, const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:15061
Definition: Exprtk.hpp:16306
Definition: Exprtk.hpp:16304
Definition: Exprtk.hpp:16308
Definition: Exprtk.hpp:15035
static details::operator_type operation()
Definition: Exprtk.hpp:15041
static T process(const T &, const T &)
Definition: Exprtk.hpp:15038
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:15040
opr_base< T >::Type Type
Definition: Exprtk.hpp:15036
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:15039
Definition: Exprtk.hpp:7272
const details::_uint64_t & max_loop_iterations_
Definition: Exprtk.hpp:7309
_uint64_t iteration_count_
Definition: Exprtk.hpp:7307
bool check() const
Definition: Exprtk.hpp:7288
void reset(const _uint64_t initial_value=0) const
Definition: Exprtk.hpp:7283
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:7273
loop_runtime_check::loop_types loop_type_
Definition: Exprtk.hpp:7310
loop_runtime_check_ptr loop_runtime_check_
Definition: Exprtk.hpp:7308
Definition: Exprtk.hpp:5052
unsigned int batch_size
Definition: Exprtk.hpp:5060
int upper_bound
Definition: Exprtk.hpp:5062
int remainder
Definition: Exprtk.hpp:5061
details(const std::size_t &vsize, const unsigned int loop_batch_size=global_loop_batch_size)
Definition: Exprtk.hpp:5053
Definition: Exprtk.hpp:14888
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14891
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:14892
static details::operator_type operation()
Definition: Exprtk.hpp:14894
opr_base< T >::Type Type
Definition: Exprtk.hpp:14889
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14893
Definition: Exprtk.hpp:14899
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:14903
static details::operator_type operation()
Definition: Exprtk.hpp:14905
opr_base< T >::Type Type
Definition: Exprtk.hpp:14900
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14904
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14902
Definition: Exprtk.hpp:12769
vector_holder_t * vector_holder_ptr
Definition: Exprtk.hpp:12772
vector_node< T > * vector_node_ptr
Definition: Exprtk.hpp:12770
memory_context_t()
Definition: Exprtk.hpp:12774
vector_holder_ptr temp_
Definition: Exprtk.hpp:12785
vector_node_ptr temp_vec_node_
Definition: Exprtk.hpp:12786
vector_holder< T > vector_holder_t
Definition: Exprtk.hpp:12771
void clear()
Definition: Exprtk.hpp:12779
Definition: Exprtk.hpp:14864
opr_base< T >::Type Type
Definition: Exprtk.hpp:14865
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14870
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14868
opr_base< T >::RefType RefType
Definition: Exprtk.hpp:14866
static details::operator_type operation()
Definition: Exprtk.hpp:14871
static void assign(RefType t1, Type t2)
Definition: Exprtk.hpp:14869
Definition: Exprtk.hpp:14825
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14832
opr_base< T >::Type Type
Definition: Exprtk.hpp:14826
opr_base< T >::RefType RefType
Definition: Exprtk.hpp:14827
static details::operator_type operation()
Definition: Exprtk.hpp:14833
static void assign(RefType t1, Type t2)
Definition: Exprtk.hpp:14831
static T process(Type t1, Type t2, Type t3)
Definition: Exprtk.hpp:14830
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14829
Definition: Exprtk.hpp:14974
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14977
static details::operator_type operation()
Definition: Exprtk.hpp:14979
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14978
opr_base< T >::Type Type
Definition: Exprtk.hpp:14975
Definition: Exprtk.hpp:14953
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14958
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14956
opr_base< T >::Type Type
Definition: Exprtk.hpp:14954
static details::operator_type operation()
Definition: Exprtk.hpp:14959
static T process(const std::string &t1, const std::string &t2)
Definition: Exprtk.hpp:14957
virtual void collect_nodes(noderef_list_t &)
Definition: Exprtk.hpp:5455
std::vector< node_pp_t > noderef_list_t
Definition: Exprtk.hpp:5450
Node * node_ptr_t
Definition: Exprtk.hpp:5448
virtual ~node_collector_interface()
Definition: Exprtk.hpp:5452
Node ** node_pp_t
Definition: Exprtk.hpp:5449
Definition: Exprtk.hpp:5946
bool depth_set
Definition: Exprtk.hpp:6103
std::size_t compute_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2) const
Definition: Exprtk.hpp:6039
std::pair< node_ptr_t, bool > nb_pair_t
Definition: Exprtk.hpp:5948
virtual ~node_depth_base()
Definition: Exprtk.hpp:5955
std::size_t max_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2, const BranchType &n3) const
Definition: Exprtk.hpp:6018
virtual std::size_t node_depth() const
Definition: Exprtk.hpp:5958
std::size_t depth
Definition: Exprtk.hpp:6104
std::size_t max_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2) const
Definition: Exprtk.hpp:6011
std::size_t compute_node_depth(const BranchType &n0, const BranchType &n1, const BranchType &n2, const BranchType &n3) const
Definition: Exprtk.hpp:6052
node_depth_base()
Definition: Exprtk.hpp:5950
std::size_t compute_node_depth(const nb_pair_t(&branch)[N]) const
Definition: Exprtk.hpp:5983
void collect(Node *&node, NodeSequence &delete_node_list) const
Definition: Exprtk.hpp:6125
std::size_t compute_node_depth(const Node *const &node) const
Definition: Exprtk.hpp:5960
std::size_t compute_node_depth(const Sequence< nb_pair_t, Allocator > &branch_list) const
Definition: Exprtk.hpp:6085
void collect(const nb_pair_t &branch, NodeSequence &delete_node_list) const
Definition: Exprtk.hpp:6118
std::size_t compute_node_depth(const BranchType &n0, const BranchType &n1) const
Definition: Exprtk.hpp:6027
void collect(const nb_pair_t(&branch)[N], NodeSequence &delete_node_list) const
Definition: Exprtk.hpp:6132
void collect(const Sequence< nb_pair_t, Allocator > &branch, NodeSequence &delete_node_list) const
Definition: Exprtk.hpp:6144
std::size_t compute_node_depth(const Sequence< node_ptr_t, Allocator > &branch_list) const
Definition: Exprtk.hpp:6066
void collect(node_ptr_t const &node, const bool deletable, NodeSequence &delete_node_list) const
Definition: Exprtk.hpp:6107
std::size_t max_node_depth(const BranchType &n0, const BranchType &n1) const
Definition: Exprtk.hpp:6005
Node * node_ptr_t
Definition: Exprtk.hpp:5947
std::size_t compute_node_depth(const nb_pair_t &branch) const
Definition: Exprtk.hpp:5971
void collect(const Sequence< node_ptr_t, Allocator > &branch_list, NodeSequence &delete_node_list) const
Definition: Exprtk.hpp:6156
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:6170
Definition: Exprtk.hpp:16478
static const expression_node< T >::node_type result
Definition: Exprtk.hpp:16478
Definition: Exprtk.hpp:16500
static const expression_node< T >::node_type result
Definition: Exprtk.hpp:16500
Definition: Exprtk.hpp:16522
static const expression_node< T >::node_type result
Definition: Exprtk.hpp:16522
Definition: Exprtk.hpp:14994
opr_base< T >::Type Type
Definition: Exprtk.hpp:14995
static details::operator_type operation()
Definition: Exprtk.hpp:14999
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14998
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14997
unknown_type_tag type
Definition: Exprtk.hpp:829
static T result(const T)
Definition: Exprtk.hpp:1629
static T result(const T v)
Definition: Exprtk.hpp:1619
static T result(const T v)
Definition: Exprtk.hpp:1628
static T result(const T v)
Definition: Exprtk.hpp:1627
static T result(const T v)
Definition: Exprtk.hpp:1626
static T result(const T v)
Definition: Exprtk.hpp:1625
static T result(const T v)
Definition: Exprtk.hpp:1624
static T result(const T v)
Definition: Exprtk.hpp:1623
static T result(const T v)
Definition: Exprtk.hpp:1622
static T result(const T v)
Definition: Exprtk.hpp:1621
static T result(const T v)
Definition: Exprtk.hpp:1620
Definition: Exprtk.hpp:1597
static T result(T v)
Definition: Exprtk.hpp:1598
Definition: Exprtk.hpp:1420
@ bound_length
Definition: Exprtk.hpp:1420
@ max_exp
Definition: Exprtk.hpp:1420
@ min_exp
Definition: Exprtk.hpp:1420
@ length
Definition: Exprtk.hpp:1420
@ size
Definition: Exprtk.hpp:1420
Definition: Exprtk.hpp:14984
static details::operator_type operation()
Definition: Exprtk.hpp:14989
opr_base< T >::Type Type
Definition: Exprtk.hpp:14985
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14988
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14987
static std::string result()
Definition: Exprtk.hpp:16316
Definition: Exprtk.hpp:16313
static std::string result()
Definition: Exprtk.hpp:16313
Definition: Exprtk.hpp:14876
opr_base< T >::RefType RefType
Definition: Exprtk.hpp:14878
opr_base< T >::Type Type
Definition: Exprtk.hpp:14877
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14882
static details::operator_type operation()
Definition: Exprtk.hpp:14883
static void assign(RefType t1, Type t2)
Definition: Exprtk.hpp:14881
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14880
Definition: Exprtk.hpp:8307
strbase_ptr_t str_node
Definition: Exprtk.hpp:8323
range_pack< T > range_t
Definition: Exprtk.hpp:8308
std::size_t type_size
Definition: Exprtk.hpp:8322
string_base_node< T > * strbase_ptr_t
Definition: Exprtk.hpp:8309
std::size_t size
Definition: Exprtk.hpp:8321
range_t * range
Definition: Exprtk.hpp:8319
void * data
Definition: Exprtk.hpp:8320
range_data_type()
Definition: Exprtk.hpp:8311
Definition: Exprtk.hpp:8159
std::size_t const_size() const
Definition: Exprtk.hpp:8260
cached_range_t cache
Definition: Exprtk.hpp:8274
std::size_t cache_size() const
Definition: Exprtk.hpp:8265
range_pack()
Definition: Exprtk.hpp:8163
std::pair< bool, expression_node_ptr > n1_e
Definition: Exprtk.hpp:8271
expression_node< T > * expression_node_ptr
Definition: Exprtk.hpp:8160
std::pair< std::size_t, std::size_t > cached_range_t
Definition: Exprtk.hpp:8161
std::pair< bool, std::size_t > n0_c
Definition: Exprtk.hpp:8272
std::pair< bool, std::size_t > n1_c
Definition: Exprtk.hpp:8273
void free()
Definition: Exprtk.hpp:8180
bool var_range() const
Definition: Exprtk.hpp:8215
std::pair< bool, expression_node_ptr > n0_e
Definition: Exprtk.hpp:8270
bool const_range() const
Definition: Exprtk.hpp:8209
void clear()
Definition: Exprtk.hpp:8171
Definition: Exprtk.hpp:754
static void process(T *base_ptr, const std::size_t size)
Definition: Exprtk.hpp:755
Definition: Exprtk.hpp:11114
details::functor_t< T >::Type Type
Definition: Exprtk.hpp:11115
functor_t::tfunc_t trinary_functor_t
Definition: Exprtk.hpp:11118
functor_t::ufunc_t unary_functor_t
Definition: Exprtk.hpp:11120
details::functor_t< T > functor_t
Definition: Exprtk.hpp:11116
functor_t::bfunc_t binary_functor_t
Definition: Exprtk.hpp:11119
functor_t::qfunc_t quaternary_functor_t
Definition: Exprtk.hpp:11117
Definition: Exprtk.hpp:14838
static void assign(RefType t1, Type t2)
Definition: Exprtk.hpp:14844
static T process(Type t1, Type t2, Type t3)
Definition: Exprtk.hpp:14843
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:14842
opr_base< T >::RefType RefType
Definition: Exprtk.hpp:14840
static details::operator_type operation()
Definition: Exprtk.hpp:14846
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:14845
opr_base< T >::Type Type
Definition: Exprtk.hpp:14839
Definition: Exprtk.hpp:15696
vector_interface< T > * ivector_ptr
Definition: Exprtk.hpp:15697
static T process(const ivector_ptr v)
Definition: Exprtk.hpp:15699
Definition: Exprtk.hpp:15895
static T process(const ivector_ptr v)
Definition: Exprtk.hpp:15898
vector_interface< T > * ivector_ptr
Definition: Exprtk.hpp:15896
data_t data
Definition: Exprtk.hpp:5173
bool destruct
Definition: Exprtk.hpp:5174
std::size_t size
Definition: Exprtk.hpp:5172
void create_data()
Definition: Exprtk.hpp:5181
static void destroy(control_block *&cntrl_blck)
Definition: Exprtk.hpp:5155
static control_block * create(const std::size_t &dsize, data_t data_ptr=data_t(0), bool dstrct=false)
Definition: Exprtk.hpp:5142
control_block & operator=(const control_block &) exprtk_delete
std::size_t ref_count
Definition: Exprtk.hpp:5171
control_block()
Definition: Exprtk.hpp:5111
control_block(const control_block &) exprtk_delete
control_block(const std::size_t &dsize)
Definition: Exprtk.hpp:5118
~control_block()
Definition: Exprtk.hpp:5132
control_block(const std::size_t &dsize, data_t dptr, bool dstrct=false)
Definition: Exprtk.hpp:5125
Definition: Exprtk.hpp:15931
vector_interface< T > * ivector_ptr
Definition: Exprtk.hpp:15932
static T process(const ivector_ptr v)
Definition: Exprtk.hpp:15934
Definition: Exprtk.hpp:15907
vector_interface< T > * ivector_ptr
Definition: Exprtk.hpp:15908
static T process(const ivector_ptr v)
Definition: Exprtk.hpp:15910
Definition: Exprtk.hpp:15796
vector_interface< T > * ivector_ptr
Definition: Exprtk.hpp:15797
static T process(const ivector_ptr v)
Definition: Exprtk.hpp:15799
Definition: Exprtk.hpp:15014
static details::operator_type operation()
Definition: Exprtk.hpp:15019
opr_base< T >::Type Type
Definition: Exprtk.hpp:15015
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:15018
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:15017
Definition: Exprtk.hpp:15004
static expression_node< T >::node_type type()
Definition: Exprtk.hpp:15008
static details::operator_type operation()
Definition: Exprtk.hpp:15009
opr_base< T >::Type Type
Definition: Exprtk.hpp:15005
static T process(Type t1, Type t2)
Definition: Exprtk.hpp:15007
void * pointer
Definition: Exprtk.hpp:20806
std::size_t size
Definition: Exprtk.hpp:20808
data_pack(void *ptr, const data_type dt, const std::size_t sz=0)
Definition: Exprtk.hpp:20800
data_type type
Definition: Exprtk.hpp:20807
data_pack()
Definition: Exprtk.hpp:20794
Definition: Exprtk.hpp:20781
std::vector< data_pack > local_data_list_t
Definition: Exprtk.hpp:20811
std::size_t ref_count
Definition: Exprtk.hpp:20891
static cntrl_blck_ptr_t create(expression_ptr e)
Definition: Exprtk.hpp:20870
expression_ptr expr
Definition: Exprtk.hpp:20892
control_block(expression_ptr e)
Definition: Exprtk.hpp:20823
~control_block()
Definition: Exprtk.hpp:20831
control_block()
Definition: Exprtk.hpp:20815
results_context_t * results
Definition: Exprtk.hpp:20894
static void destroy(cntrl_blck_ptr_t &cntrl_blck)
Definition: Exprtk.hpp:20875
data_type
Definition: Exprtk.hpp:20783
@ e_expr
Definition: Exprtk.hpp:20785
@ e_data
Definition: Exprtk.hpp:20787
@ e_unknown
Definition: Exprtk.hpp:20784
@ e_vecdata
Definition: Exprtk.hpp:20788
@ e_vecholder
Definition: Exprtk.hpp:20786
results_context< T > results_context_t
Definition: Exprtk.hpp:20812
bool retinv_null
Definition: Exprtk.hpp:20895
local_data_list_t local_data_list
Definition: Exprtk.hpp:20893
control_block * cntrl_blck_ptr_t
Definition: Exprtk.hpp:20813
Definition: Exprtk.hpp:41159
virtual ~base_func()
Definition: Exprtk.hpp:41177
void copy(const varref_t &src_v, var_t &dest_v)
Definition: Exprtk.hpp:41303
virtual T value(expression_t &e)
Definition: Exprtk.hpp:41365
std::deque< var_t > param_stack
Definition: Exprtk.hpp:41375
std::size_t stack_depth
Definition: Exprtk.hpp:41374
base_func(const std::size_t &pc=0)
Definition: Exprtk.hpp:41169
void pre()
Definition: Exprtk.hpp:41265
exprtk::ifunction< T > function_t
Definition: Exprtk.hpp:41161
void copy(const var_t &src_v, lvr_vec_t &dest_v)
Definition: Exprtk.hpp:41338
void copy(const lvr_vec_t &src_v, var_t &dest_v)
Definition: Exprtk.hpp:41319
void post()
Definition: Exprtk.hpp:41285
const T & type
Definition: Exprtk.hpp:41160
void update(const T &v0, const T &v1, const T &v2, const T &v3)
Definition: Exprtk.hpp:41199
std::vector< T * > varref_t
Definition: Exprtk.hpp:41162
void update(const T &v0, const T &v1, const T &v2)
Definition: Exprtk.hpp:41193
varref_t v
Definition: Exprtk.hpp:41371
std::size_t local_var_stack_size
Definition: Exprtk.hpp:41373
void update(const T &v0, const T &v1)
Definition: Exprtk.hpp:41188
std::vector< lvarref_t > lvr_vec_t
Definition: Exprtk.hpp:41165
void update(const T &v0, const T &v1, const T &v2, const T &v3, const T &v4, const T &v5)
Definition: Exprtk.hpp:41212
void copy(const var_t &src_v, varref_t &dest_v)
Definition: Exprtk.hpp:41311
lvr_vec_t lv
Definition: Exprtk.hpp:41372
std::vector< T > var_t
Definition: Exprtk.hpp:41163
std::deque< var_t > local_stack
Definition: Exprtk.hpp:41376
expression_t expression
Definition: Exprtk.hpp:41370
function_t & setup(expression_t &expr)
Definition: Exprtk.hpp:41223
void update(const T &v0, const T &v1, const T &v2, const T &v3, const T &v4)
Definition: Exprtk.hpp:41205
void update(const T &v0)
Definition: Exprtk.hpp:41183
std::pair< T *, std::size_t > lvarref_t
Definition: Exprtk.hpp:41164
void clear_stack()
Definition: Exprtk.hpp:41357
Definition: Exprtk.hpp:41382
func_0param()
Definition: Exprtk.hpp:41385
Definition: Exprtk.hpp:41418
func_1param()
Definition: Exprtk.hpp:41421
Definition: Exprtk.hpp:41432
func_2param()
Definition: Exprtk.hpp:41435
Definition: Exprtk.hpp:41446
func_3param()
Definition: Exprtk.hpp:41449
Definition: Exprtk.hpp:41460
func_4param()
Definition: Exprtk.hpp:41463
Definition: Exprtk.hpp:41474
func_5param()
Definition: Exprtk.hpp:41477
Definition: Exprtk.hpp:41488
func_6param()
Definition: Exprtk.hpp:41491
Definition: Exprtk.hpp:41022
function & name(const std::string &n)
Definition: Exprtk.hpp:41089
function & vars(const std::string &v0, const std::string &v1, const std::string &v2)
Definition: Exprtk.hpp:41115
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:41137
std::deque< std::string > v_
Definition: Exprtk.hpp:41153
std::string name_
Definition: Exprtk.hpp:41151
function & vars(const std::string &v0, const std::string &v1, const std::string &v2, const std::string &v3)
Definition: Exprtk.hpp:41125
function & vars(const std::string &v0, const std::string &v1)
Definition: Exprtk.hpp:41107
function & var(const std::string &v)
Definition: Exprtk.hpp:41101
function & expression(const std::string &e)
Definition: Exprtk.hpp:41095
std::string expression_
Definition: Exprtk.hpp:41152
Definition: Exprtk.hpp:41397
scoped_bft & operator=(const scoped_bft &) exprtk_delete
scoped_bft(BaseFuncType &bft)
Definition: Exprtk.hpp:41398
BaseFuncType & bft_
Definition: Exprtk.hpp:41409
scoped_bft(const scoped_bft &) exprtk_delete
~scoped_bft()
Definition: Exprtk.hpp:41404
Definition: Exprtk.hpp:4118
std::vector< lexer::token_inserter * > token_inserter_list
Definition: Exprtk.hpp:4266
bool register_inserter(lexer::token_inserter *inserter)
Definition: Exprtk.hpp:4161
lexer::token_joiner * error_token_joiner
Definition: Exprtk.hpp:4270
std::vector< lexer::token_joiner * > token_joiner_list
Definition: Exprtk.hpp:4265
bool run_inserters(lexer::generator &g)
Definition: Exprtk.hpp:4219
bool register_scanner(lexer::token_scanner *scanner)
Definition: Exprtk.hpp:4119
bool run_joiners(lexer::generator &g)
Definition: Exprtk.hpp:4197
std::vector< lexer::token_modifier * > token_modifier_list
Definition: Exprtk.hpp:4264
bool register_joiner(lexer::token_joiner *joiner)
Definition: Exprtk.hpp:4147
bool register_modifier(lexer::token_modifier *modifier)
Definition: Exprtk.hpp:4133
lexer::token_modifier * error_token_modifier
Definition: Exprtk.hpp:4269
std::vector< lexer::token_scanner * > token_scanner_list
Definition: Exprtk.hpp:4263
bool run_scanners(lexer::generator &g)
Definition: Exprtk.hpp:4241
lexer::token_scanner * error_token_scanner
Definition: Exprtk.hpp:4268
bool run_modifiers(lexer::generator &g)
Definition: Exprtk.hpp:4175
lexer::token_inserter * error_token_inserter
Definition: Exprtk.hpp:4271
Definition: Exprtk.hpp:2176
token & set_string(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: Exprtk.hpp:2241
std::size_t position
Definition: Exprtk.hpp:2344
bool is_error() const
Definition: Exprtk.hpp:2331
token & set_string(const std::string &s, const std::size_t p)
Definition: Exprtk.hpp:2250
token & set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: Exprtk.hpp:2221
token & set_operator(const token_type tt, const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: Exprtk.hpp:2209
token & set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: Exprtk.hpp:2231
std::string value
Definition: Exprtk.hpp:2343
token & set_error(const token_type et, const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: Exprtk.hpp:2259
void clear()
Definition: Exprtk.hpp:2201
token()
Definition: Exprtk.hpp:2195
static std::string to_str(token_type t)
Definition: Exprtk.hpp:2284
token_type type
Definition: Exprtk.hpp:2342
token_type
Definition: Exprtk.hpp:2178
@ e_divass
Definition: Exprtk.hpp:2183
@ e_rbracket
Definition: Exprtk.hpp:2187
@ e_addass
Definition: Exprtk.hpp:2182
@ e_lte
Definition: Exprtk.hpp:2185
@ e_err_number
Definition: Exprtk.hpp:2180
@ e_error
Definition: Exprtk.hpp:2179
@ e_rsqrbracket
Definition: Exprtk.hpp:2188
@ e_assign
Definition: Exprtk.hpp:2182
@ e_swap
Definition: Exprtk.hpp:2186
@ e_lsqrbracket
Definition: Exprtk.hpp:2188
@ e_pow
Definition: Exprtk.hpp:2191
@ e_mulass
Definition: Exprtk.hpp:2183
@ e_div
Definition: Exprtk.hpp:2190
@ e_shr
Definition: Exprtk.hpp:2184
@ e_comma
Definition: Exprtk.hpp:2189
@ e_lt
Definition: Exprtk.hpp:2186
@ e_symbol
Definition: Exprtk.hpp:2181
@ e_string
Definition: Exprtk.hpp:2182
@ e_err_sfunc
Definition: Exprtk.hpp:2180
@ e_sub
Definition: Exprtk.hpp:2190
@ e_lbracket
Definition: Exprtk.hpp:2187
@ e_rcrlbracket
Definition: Exprtk.hpp:2188
@ e_eof
Definition: Exprtk.hpp:2181
@ e_lcrlbracket
Definition: Exprtk.hpp:2189
@ e_err_symbol
Definition: Exprtk.hpp:2179
@ e_gte
Definition: Exprtk.hpp:2185
@ e_eq
Definition: Exprtk.hpp:2187
@ e_shl
Definition: Exprtk.hpp:2184
@ e_number
Definition: Exprtk.hpp:2181
@ e_modass
Definition: Exprtk.hpp:2184
@ e_subass
Definition: Exprtk.hpp:2183
@ e_mod
Definition: Exprtk.hpp:2191
@ e_ternary
Definition: Exprtk.hpp:2192
@ e_err_string
Definition: Exprtk.hpp:2180
@ e_gt
Definition: Exprtk.hpp:2186
@ e_add
Definition: Exprtk.hpp:2189
@ e_mul
Definition: Exprtk.hpp:2190
@ e_ne
Definition: Exprtk.hpp:2185
@ e_colon
Definition: Exprtk.hpp:2191
violation_type violation
Definition: Exprtk.hpp:2114
loop_types loop
Definition: Exprtk.hpp:2113
details::_uint64_t iteration_count
Definition: Exprtk.hpp:2115
Definition: Exprtk.hpp:2085
virtual void handle_runtime_violation(const violation_context &)
Definition: Exprtk.hpp:2123
loop_types loop_set
Definition: Exprtk.hpp:2102
virtual bool check()
Definition: Exprtk.hpp:2118
loop_types
Definition: Exprtk.hpp:2087
@ e_while_loop
Definition: Exprtk.hpp:2090
@ e_repeat_until_loop
Definition: Exprtk.hpp:2091
@ e_for_loop
Definition: Exprtk.hpp:2089
@ e_invalid
Definition: Exprtk.hpp:2088
details::_uint64_t max_loop_iterations
Definition: Exprtk.hpp:2109
violation_type
Definition: Exprtk.hpp:2096
@ e_iteration_count
Definition: Exprtk.hpp:2098
virtual ~loop_runtime_check()
Definition: Exprtk.hpp:2128
loop_runtime_check()
Definition: Exprtk.hpp:2104
Definition: Exprtk.hpp:21832
static bool is_greater(const T_ &v, const T_ &end)
Definition: Exprtk.hpp:21844
static bool end_inclusive()
Definition: Exprtk.hpp:21849
static bool is_less(const T_ &v, const T_ &begin)
Definition: Exprtk.hpp:21839
static bool is_within(const T_ &v, const T_ &begin, const T_ &end)
Definition: Exprtk.hpp:21833
static T process(const arg_list_t &arg)
Definition: Exprtk.hpp:31357
static T process(const arg_list_t &arg)
Definition: Exprtk.hpp:31369
static T process(const arg_list_t &arg)
Definition: Exprtk.hpp:31381
static T process(const arg_list_t &arg)
Definition: Exprtk.hpp:31394
static T process(const arg_list_t &arg)
Definition: Exprtk.hpp:31407
static T process(const arg_list_t &arg)
Definition: Exprtk.hpp:31421
static T process(const arg_list_t &arg)
Definition: Exprtk.hpp:31435
std::vector< std::pair< expression_node_ptr, bool > > arg_list_t
Definition: Exprtk.hpp:31350
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33393
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33842
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33618
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33704
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34166
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33961
cocov_t::type0 node_type
Definition: Exprtk.hpp:35448
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: Exprtk.hpp:35449
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35463
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35566
cocov_t::sf3_type sf3_type
Definition: Exprtk.hpp:35461
cocov_t::type1 node_type
Definition: Exprtk.hpp:35460
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34370
covoc_t::sf3_type sf3_type
Definition: Exprtk.hpp:35211
covoc_t::type0 node_type
Definition: Exprtk.hpp:35210
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35213
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35316
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35332
covoc_t::sf3_type sf3_type
Definition: Exprtk.hpp:35330
covoc_t::type1 node_type
Definition: Exprtk.hpp:35329
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35435
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:36377
covocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:36199
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:36205
covocov_t::type0 node_type
Definition: Exprtk.hpp:36198
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:37370
covocov_t::type1 node_type
Definition: Exprtk.hpp:37324
covocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37325
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37331
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37873
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:37912
covocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37867
covocov_t::type2 node_type
Definition: Exprtk.hpp:37866
covocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38371
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38377
covocov_t::type3 node_type
Definition: Exprtk.hpp:38370
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:38415
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38919
covocov_t::type4 node_type
Definition: Exprtk.hpp:38912
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:38957
covocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38913
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35131
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35082
covov_t::sf3_type sf3_type
Definition: Exprtk.hpp:35080
covov_t::type0 node_type
Definition: Exprtk.hpp:35079
covov_t::sf3_type sf3_type
Definition: Exprtk.hpp:35145
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35147
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35197
covov_t::type1 node_type
Definition: Exprtk.hpp:35144
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:36643
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:36815
covovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:36637
covovoc_t::type0 node_type
Definition: Exprtk.hpp:36636
covovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:37446
covovoc_t::type1 node_type
Definition: Exprtk.hpp:37445
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:37490
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37451
covovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:37988
covovoc_t::type2 node_type
Definition: Exprtk.hpp:37987
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:38033
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37994
covovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:38492
covovoc_t::type3 node_type
Definition: Exprtk.hpp:38491
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38498
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:38537
covovoc_t::type4 node_type
Definition: Exprtk.hpp:39033
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:39040
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:39079
covovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:39034
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:36183
covovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:36110
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:36116
covovov_t::type0 node_type
Definition: Exprtk.hpp:36109
covovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37264
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:37309
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37270
covovov_t::type1 node_type
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:37851
covovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37806
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37812
covovov_t::type2 node_type
Definition: Exprtk.hpp:37805
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:38355
covovov_t::type3 node_type
Definition: Exprtk.hpp:38310
covovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38311
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38317
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:38897
covovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38853
covovov_t::type4 node_type
Definition: Exprtk.hpp:38852
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38859
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:34474
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &sf3opr, T0 t0, T1 t1, T2 t2)
Definition: Exprtk.hpp:34450
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:34600
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:34493
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:34664
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:34558
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:34642
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:34541
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:33543
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34405
vococ_t::sf3_type sf3_type
Definition: Exprtk.hpp:35580
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35693
vococ_t::type0 node_type
Definition: Exprtk.hpp:35579
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35582
vococ_t::type0 node_type
Definition: Exprtk.hpp:35706
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: Exprtk.hpp:35708
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:36837
vococov_t::type0 node_type
Definition: Exprtk.hpp:36830
vococov_t::sf4_type sf4_type
Definition: Exprtk.hpp:36831
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:37008
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:37550
vococov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37506
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37512
vococov_t::type1 node_type
Definition: Exprtk.hpp:37505
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: Exprtk.hpp:38049
vococov_t::type2 node_type
Definition: Exprtk.hpp:38048
static std::string id(expression_generator< Type > &, const details::operator_type, const details::operator_type, const details::operator_type)
Definition: Exprtk.hpp:38058
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:38597
vococov_t::type3 node_type
Definition: Exprtk.hpp:38552
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38559
vococov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38553
vococov_t::type4 node_type
Definition: Exprtk.hpp:39094
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: Exprtk.hpp:39095
static std::string id(expression_generator< Type > &, const details::operator_type, const details::operator_type, const details::operator_type)
Definition: Exprtk.hpp:39104
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35001
vocov_t::type0 node_type
Definition: Exprtk.hpp:34949
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34952
vocov_t::sf3_type sf3_type
Definition: Exprtk.hpp:34950
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:35066
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35017
vocov_t::type1 node_type
Definition: Exprtk.hpp:35014
vocov_t::sf3_type sf3_type
Definition: Exprtk.hpp:35015
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:36399
vocovoc_t::type0 node_type
Definition: Exprtk.hpp:36392
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:36621
vocovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:36393
vocovoc_t::type1 node_type
Definition: Exprtk.hpp:37385
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37392
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:37430
vocovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:37386
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37934
vocovoc_t::type2 node_type
Definition: Exprtk.hpp:37927
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:37972
vocovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:37928
vocovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:38431
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38437
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:38476
vocovoc_t::type3 node_type
Definition: Exprtk.hpp:38430
vocovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:38973
vocovoc_t::type4 node_type
Definition: Exprtk.hpp:38972
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:39018
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38979
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:36027
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:36094
vocovov_t::type0 node_type
Definition: Exprtk.hpp:36020
vocovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:36021
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37210
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:37248
vocovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37204
vocovov_t::type1 node_type
Definition: Exprtk.hpp:37203
vocovov_t::type2 node_type
Definition: Exprtk.hpp:37745
vocovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37746
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37752
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:37790
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:38295
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38257
vocovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38251
vocovov_t::type3 node_type
Definition: Exprtk.hpp:38250
vocovov_t::type4 node_type
Definition: Exprtk.hpp:38793
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38800
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:38837
vocovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38794
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34346
vovoc_t::type0 node_type
Definition: Exprtk.hpp:34818
vovoc_t::sf3_type sf3_type
Definition: Exprtk.hpp:34819
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:34871
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34821
vovoc_t::type1 node_type
Definition: Exprtk.hpp:34884
vovoc_t::sf3_type sf3_type
Definition: Exprtk.hpp:34885
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:34936
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34887
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35938
vovocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:35932
vovocov_t::type0 node_type
Definition: Exprtk.hpp:35931
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:36005
vovocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37144
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37150
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:37188
vovocov_t::type1 node_type
Definition: Exprtk.hpp:37143
vovocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37686
vovocov_t::type2 node_type
Definition: Exprtk.hpp:37685
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37692
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:37730
vovocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38191
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38197
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:38235
vovocov_t::type3 node_type
Definition: Exprtk.hpp:38190
vovocov_t::type4 node_type
Definition: Exprtk.hpp:38733
vovocov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38734
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:38778
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38740
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:34740
vovov_t::sf3_type sf3_type
Definition: Exprtk.hpp:34689
vovov_t::type0 node_type
Definition: Exprtk.hpp:34688
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34691
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: Exprtk.hpp:34805
vovov_t::type1 node_type
Definition: Exprtk.hpp:34753
vovov_t::sf3_type sf3_type
Definition: Exprtk.hpp:34754
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:34756
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35849
vovovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:35843
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:35916
vovovoc_t::type0 node_type
Definition: Exprtk.hpp:35842
vovovoc_t::type1 node_type
Definition: Exprtk.hpp:37083
vovovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:37084
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37090
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:37128
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37632
vovovoc_t::type2 node_type
Definition: Exprtk.hpp:37625
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:37670
vovovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:37626
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:38175
vovovoc_t::type3 node_type
Definition: Exprtk.hpp:38129
vovovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:38130
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38136
vovovoc_t::type4 node_type
Definition: Exprtk.hpp:38672
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38679
vovovoc_t::sf4_type sf4_type
Definition: Exprtk.hpp:38673
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:38718
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:35827
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:35727
vovovov_t::type0 node_type
Definition: Exprtk.hpp:35720
vovovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:35721
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:37068
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37030
vovovov_t::type1 node_type
Definition: Exprtk.hpp:37023
vovovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37024
vovovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:37566
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:37610
vovovov_t::type2 node_type
Definition: Exprtk.hpp:37565
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:37572
vovovov_t::type3 node_type
Definition: Exprtk.hpp:38069
vovovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38070
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38076
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:38114
vovovov_t::sf4_type sf4_type
Definition: Exprtk.hpp:38613
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:38657
vovovov_t::type4 node_type
Definition: Exprtk.hpp:38612
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: Exprtk.hpp:38619
Definition: Exprtk.hpp:21807
static bool is_less(const T_ &v, const T_ &begin)
Definition: Exprtk.hpp:21814
static bool is_within(const T_ &v, const T_ &begin, const T_ &end)
Definition: Exprtk.hpp:21808
static bool end_inclusive()
Definition: Exprtk.hpp:21824
static bool is_greater(const T_ &v, const T_ &end)
Definition: Exprtk.hpp:21819
static expression_node_ptr process(parser< Type > &p, const details::operator_type opt_type, const std::string &sf_name)
Definition: Exprtk.hpp:27914
Definition: Exprtk.hpp:22529
bool parsing_break_stmt
Definition: Exprtk.hpp:22562
void activate_side_effect(const std::string &)
Definition: Exprtk.hpp:22548
void reset()
Definition: Exprtk.hpp:22536
parser_state()
Definition: Exprtk.hpp:22530
bool return_stmt_present
Definition: Exprtk.hpp:22563
std::size_t parsing_loop_stmt_count
Definition: Exprtk.hpp:22568
std::size_t stack_depth
Definition: Exprtk.hpp:22567
bool type_check_enabled
Definition: Exprtk.hpp:22565
bool parsing_return_stmt
Definition: Exprtk.hpp:22561
bool side_effect_present
Definition: Exprtk.hpp:22564
std::size_t scope_depth
Definition: Exprtk.hpp:22566
Definition: Exprtk.hpp:21463
void clear()
Definition: Exprtk.hpp:21516
stringvar_node_ptr str_node
Definition: Exprtk.hpp:21546
variable_node_t * variable_node_ptr
Definition: Exprtk.hpp:21474
details::vector_holder< T > vector_holder_t
Definition: Exprtk.hpp:21473
stringvar_node_t * stringvar_node_ptr
Definition: Exprtk.hpp:21478
std::size_t size
Definition: Exprtk.hpp:21535
vector_holder_ptr vec_node
Definition: Exprtk.hpp:21544
std::size_t depth
Definition: Exprtk.hpp:21537
expression_node_ptr var_node
Definition: Exprtk.hpp:21543
bool active
Definition: Exprtk.hpp:21541
element_type
Definition: Exprtk.hpp:21465
@ e_none
Definition: Exprtk.hpp:21466
@ e_vecelem
Definition: Exprtk.hpp:21469
@ e_variable
Definition: Exprtk.hpp:21467
@ e_vector
Definition: Exprtk.hpp:21468
std::size_t ip_index
Definition: Exprtk.hpp:21539
scope_element()
Definition: Exprtk.hpp:21481
expression_node_t * expression_node_ptr
Definition: Exprtk.hpp:21476
std::string name
Definition: Exprtk.hpp:21534
element_type type
Definition: Exprtk.hpp:21540
vector_holder_t * vector_holder_ptr
Definition: Exprtk.hpp:21475
std::size_t ref_count
Definition: Exprtk.hpp:21538
std::size_t index
Definition: Exprtk.hpp:21536
void * data
Definition: Exprtk.hpp:21542
Definition: Exprtk.hpp:24669
~scoped_bool_negator()
Definition: Exprtk.hpp:24674
scoped_bool_negator(bool &bb)
Definition: Exprtk.hpp:24670
bool & b
Definition: Exprtk.hpp:24677
Definition: Exprtk.hpp:24681
bool & b
Definition: Exprtk.hpp:24692
scoped_bool_or_restorer(bool &bb)
Definition: Exprtk.hpp:24682
bool original_value_
Definition: Exprtk.hpp:24693
~scoped_bool_or_restorer()
Definition: Exprtk.hpp:24687
Definition: Exprtk.hpp:24564
scoped_delete< Type, N > & operator=(const scoped_delete< Type, N > &) exprtk_delete
Type * ptr_t
Definition: Exprtk.hpp:24565
scoped_delete(parser< T > &pr, ptr_t(&p)[N])
Definition: Exprtk.hpp:24573
ptr_t * p_
Definition: Exprtk.hpp:24592
parser< T > & parser_
Definition: Exprtk.hpp:24591
bool delete_ptr
Definition: Exprtk.hpp:24590
~scoped_delete()
Definition: Exprtk.hpp:24579
scoped_delete(parser< T > &pr, ptr_t &p)
Definition: Exprtk.hpp:24567
scoped_delete(const scoped_delete< Type, N > &) exprtk_delete
Definition: Exprtk.hpp:24602
parser< T > & parser_
Definition: Exprtk.hpp:24625
std::deque< ptr_t > & deq_
Definition: Exprtk.hpp:24626
scoped_deq_delete(parser< T > &pr, std::deque< ptr_t > &deq)
Definition: Exprtk.hpp:24605
bool delete_ptr
Definition: Exprtk.hpp:24624
Type * ptr_t
Definition: Exprtk.hpp:24603
~scoped_deq_delete()
Definition: Exprtk.hpp:24611
scoped_deq_delete< Type > & operator=(const scoped_deq_delete< Type > &) exprtk_delete
scoped_deq_delete(const scoped_deq_delete< Type > &) exprtk_delete
Definition: Exprtk.hpp:24537
scoped_expression_delete(parser< T > &pr, expression_node_ptr &expression)
Definition: Exprtk.hpp:24538
scoped_expression_delete(const scoped_expression_delete &) exprtk_delete
scoped_expression_delete & operator=(const scoped_expression_delete &) exprtk_delete
bool delete_ptr
Definition: Exprtk.hpp:24552
~scoped_expression_delete()
Definition: Exprtk.hpp:24544
parser< T > & parser_
Definition: Exprtk.hpp:24553
expression_node_ptr & expression_
Definition: Exprtk.hpp:24554
Definition: Exprtk.hpp:24697
~scoped_inc_dec()
Definition: Exprtk.hpp:24702
scoped_inc_dec(std::size_t &v)
Definition: Exprtk.hpp:24698
std::size_t & v_
Definition: Exprtk.hpp:24708
Definition: Exprtk.hpp:24636
scoped_vec_delete(parser< T > &pr, std::vector< ptr_t > &vec)
Definition: Exprtk.hpp:24639
parser< T > & parser_
Definition: Exprtk.hpp:24659
std::vector< ptr_t > & vec_
Definition: Exprtk.hpp:24660
bool delete_ptr
Definition: Exprtk.hpp:24658
scoped_vec_delete< Type > & operator=(const scoped_vec_delete< Type > &) exprtk_delete
Type * ptr_t
Definition: Exprtk.hpp:24637
~scoped_vec_delete()
Definition: Exprtk.hpp:24645
scoped_vec_delete(const scoped_vec_delete< Type > &) exprtk_delete
Definition: Exprtk.hpp:24126
precedence_level right
Definition: Exprtk.hpp:24146
void reset()
Definition: Exprtk.hpp:24138
token_t token
Definition: Exprtk.hpp:24148
void set(const precedence_level &l, const precedence_level &r, const details::operator_type &o, const token_t tkn=token_t())
Definition: Exprtk.hpp:24127
precedence_level left
Definition: Exprtk.hpp:24145
details::operator_type operation
Definition: Exprtk.hpp:24147
const symbol_table_t * symbol_table
Definition: Exprtk.hpp:22014
stringvar_ptr str_var
Definition: Exprtk.hpp:22015
string_context()
Definition: Exprtk.hpp:22009
const symbol_table_t * symbol_table
Definition: Exprtk.hpp:21991
variable_context()
Definition: Exprtk.hpp:21986
variable_ptr variable
Definition: Exprtk.hpp:21992
vector_holder_ptr vector_holder
Definition: Exprtk.hpp:22003
vector_context()
Definition: Exprtk.hpp:21997
const symbol_table_t * symbol_table
Definition: Exprtk.hpp:22002
Definition: Exprtk.hpp:21971
stringvar_ptr get_stringvar(const std::string &string_name) const
Definition: Exprtk.hpp:22150
std::string get_vector_name(const vector_holder_ptr &ptr) const
Definition: Exprtk.hpp:22495
symbol_table_t::function_ptr function_ptr
Definition: Exprtk.hpp:21976
symbol_table_t::variable_ptr variable_ptr
Definition: Exprtk.hpp:21975
function_ptr get_function(const std::string &function_name) const
Definition: Exprtk.hpp:22172
bool is_stringvar(const std::string &stringvar_name) const
Definition: Exprtk.hpp:22403
symbol_table_list_t symtab_list_
Definition: Exprtk.hpp:21972
std::string get_stringvar_name(const expression_node_ptr &ptr) const
Definition: Exprtk.hpp:22501
bool valid() const
Definition: Exprtk.hpp:22029
generic_function_ptr get_generic_function(const std::string &function_name) const
Definition: Exprtk.hpp:22214
vector_holder_ptr get_vector(const std::string &vector_name) const
Definition: Exprtk.hpp:22302
symbol_table_t::vararg_function_ptr vararg_function_ptr
Definition: Exprtk.hpp:21981
symbol_table_t::vector_holder_ptr vector_holder_ptr
Definition: Exprtk.hpp:21980
bool is_conststr_stringvar(const std::string &symbol_name) const
Definition: Exprtk.hpp:22419
symbol_table_t::local_data_t local_data_t
Definition: Exprtk.hpp:21974
bool is_constant_node(const std::string &symbol_name) const
Definition: Exprtk.hpp:22327
variable_context get_variable_context(const std::string &variable_name) const
Definition: Exprtk.hpp:22059
variable_ptr get_variable(const T &var_ref) const
Definition: Exprtk.hpp:22105
string_context get_string_context(const std::string &string_name) const
Definition: Exprtk.hpp:22124
bool symbol_exists(const std::string &symbol) const
Definition: Exprtk.hpp:22368
bool is_constant_string(const std::string &symbol_name) const
Definition: Exprtk.hpp:22349
bool is_variable(const std::string &variable_name) const
Definition: Exprtk.hpp:22386
symbol_table_t::stringvar_ptr stringvar_ptr
Definition: Exprtk.hpp:21978
vector_context get_vector_context(const std::string &vector_name) const
Definition: Exprtk.hpp:22277
vararg_function_ptr get_vararg_function(const std::string &vararg_function_name) const
Definition: Exprtk.hpp:22193
symbol_table_t & get_symbol_table(const std::size_t &index=0)
Definition: Exprtk.hpp:22522
bool is_vararg_function(const std::string &vararg_function_name) const
Definition: Exprtk.hpp:22458
bool valid_function_name(const std::string &symbol) const
Definition: Exprtk.hpp:22051
generic_function_ptr get_overload_function(const std::string &function_name) const
Definition: Exprtk.hpp:22256
bool is_vector(const std::string &vector_name) const
Definition: Exprtk.hpp:22474
bool empty() const
Definition: Exprtk.hpp:22019
const local_data_t & local_data(const std::size_t &index=0) const
Definition: Exprtk.hpp:22517
std::string get_variable_name(const expression_node_ptr &ptr) const
Definition: Exprtk.hpp:22490
void clear()
Definition: Exprtk.hpp:22024
generic_function_ptr get_string_function(const std::string &function_name) const
Definition: Exprtk.hpp:22235
bool valid_symbol(const std::string &symbol) const
Definition: Exprtk.hpp:22043
symbol_table_t::generic_function_ptr generic_function_ptr
Definition: Exprtk.hpp:21982
variable_ptr get_variable(const std::string &variable_name) const
Definition: Exprtk.hpp:22084
bool is_function(const std::string &function_name) const
Definition: Exprtk.hpp:22442
std::string get_conststr_stringvar_name(const expression_node_ptr &ptr) const
Definition: Exprtk.hpp:22506
local_data_t & local_data(const std::size_t &index=0)
Definition: Exprtk.hpp:22512
std::string param_seq
Definition: Exprtk.hpp:27352
return_type_t return_type
Definition: Exprtk.hpp:27351
Definition: Exprtk.hpp:22574
usr_mode
Definition: Exprtk.hpp:22584
virtual ~unknown_symbol_resolver()
Definition: Exprtk.hpp:22595
unknown_symbol_resolver(const usr_mode m=e_usrmode_default)
Definition: Exprtk.hpp:22591
virtual bool process(const std::string &, symbol_table_t &, std::string &)
Definition: Exprtk.hpp:22613
virtual bool process(const std::string &, usr_symbol_type &st, T &default_value, std::string &error_message)
Definition: Exprtk.hpp:22598
usr_symbol_type
Definition: Exprtk.hpp:22577
usr_mode mode
Definition: Exprtk.hpp:22589
Definition: Exprtk.hpp:21211
std::string error_line
Definition: Exprtk.hpp:21222
std::size_t line_no
Definition: Exprtk.hpp:21223
std::size_t column_no
Definition: Exprtk.hpp:21224
std::string diagnostic
Definition: Exprtk.hpp:21220
error_mode mode
Definition: Exprtk.hpp:21219
std::string src_location
Definition: Exprtk.hpp:21221
type()
Definition: Exprtk.hpp:21212
lexer::token token
Definition: Exprtk.hpp:21218
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:40794
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:40781
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:40768
static T evaluate(const Type x, const Type c1, const Type c0)
Definition: Exprtk.hpp:40897
static T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
Definition: Exprtk.hpp:40887
static T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: Exprtk.hpp:40877
static T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: Exprtk.hpp:40867
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:40855
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:40843
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:40831
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:40819
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:40807
Definition: Exprtk.hpp:40763
Definition: Exprtk.hpp:42045
generic_type::string_view string_t
Definition: Exprtk.hpp:42050
igeneric_function< T >::generic_type generic_type
Definition: Exprtk.hpp:42046
static void print(const string_t &s)
Definition: Exprtk.hpp:42091
igeneric_function< T >::parameter_list_t parameter_list_t
Definition: Exprtk.hpp:42047
static void print(const std::string &scalar_format, const scalar_t &s)
Definition: Exprtk.hpp:42075
generic_type::scalar_view scalar_t
Definition: Exprtk.hpp:42048
exprtk::details::numeric::details::number_type< T >::type num_type
Definition: Exprtk.hpp:42051
static void print(const std::string &scalar_format, const vector_t &v)
Definition: Exprtk.hpp:42080
static void process(const std::string &scalar_format, parameter_list_t parameters)
Definition: Exprtk.hpp:42053
generic_type::vector_view vector_t
Definition: Exprtk.hpp:42049
Definition: Exprtk.hpp:42101
igeneric_function< T >::parameter_list_t parameter_list_t
Definition: Exprtk.hpp:42102
std::string scalar_format_
Definition: Exprtk.hpp:42118
println(const std::string &scalar_format="%10.5f")
Definition: Exprtk.hpp:42128
print(const std::string &scalar_format="%10.5f")
Definition: Exprtk.hpp:42106
void close(Ptr &p)
Definition: Exprtk.hpp:42258
bool getline(std::string &s)
Definition: Exprtk.hpp:42323
file_mode mode
Definition: Exprtk.hpp:42200
file_descriptor(const std::string &fname, const std::string &access)
Definition: Exprtk.hpp:42193
std::string file_name
Definition: Exprtk.hpp:42201
bool write(const View &view, const std::size_t amount, const std::size_t offset=0)
Definition: Exprtk.hpp:42286
bool close()
Definition: Exprtk.hpp:42266
void * stream_ptr
Definition: Exprtk.hpp:42199
bool eof() const
Definition: Exprtk.hpp:42333
bool open()
Definition: Exprtk.hpp:42203
bool read(View &view, const std::size_t amount, const std::size_t offset=0)
Definition: Exprtk.hpp:42305
file_mode get_file_mode(const std::string &access) const
Definition: Exprtk.hpp:42344
Definition: Exprtk.hpp:42637
read< T > r
Definition: Exprtk.hpp:42641
bool register_package(exprtk::symbol_table< T > &symtab)
Definition: Exprtk.hpp:42645
close< T > c
Definition: Exprtk.hpp:42639
eof< T > e
Definition: Exprtk.hpp:42643
write< T > w
Definition: Exprtk.hpp:42640
getline< T > g
Definition: Exprtk.hpp:42642
open< T > o
Definition: Exprtk.hpp:42638
Definition: Exprtk.hpp:42146
bool register_package(exprtk::symbol_table< T > &symtab)
Definition: Exprtk.hpp:42150
println< T > pl
Definition: Exprtk.hpp:42148
print< T > p
Definition: Exprtk.hpp:42147
igfun_t::generic_type generic_type
Definition: Exprtk.hpp:42699
exprtk::igeneric_function< T > igfun_t
Definition: Exprtk.hpp:42697
generic_type::vector_view vector_t
Definition: Exprtk.hpp:42701
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:42703
generic_type::scalar_view scalar_t
Definition: Exprtk.hpp:42700
igfun_t::parameter_list_t parameter_list_t
Definition: Exprtk.hpp:42698
Definition: Exprtk.hpp:44134
axpby< T > b1_axpby
Definition: Exprtk.hpp:44151
dotk< T > dtk
Definition: Exprtk.hpp:44159
threshold_below< T > tb
Definition: Exprtk.hpp:44161
nthelement< T > ne
Definition: Exprtk.hpp:44146
bool register_package(exprtk::symbol_table< T > &symtab)
Definition: Exprtk.hpp:44163
iota< T > ia
Definition: Exprtk.hpp:44148
dot< T > dt
Definition: Exprtk.hpp:44158
sort< T > st
Definition: Exprtk.hpp:44145
any_true< T > nt
Definition: Exprtk.hpp:44137
axpy< T > b1_axpy
Definition: Exprtk.hpp:44150
copy< T > cp
Definition: Exprtk.hpp:44140
count< T > c
Definition: Exprtk.hpp:44139
axpbyz< T > b1_axpbyz
Definition: Exprtk.hpp:44153
any_false< T > nf
Definition: Exprtk.hpp:44138
all_false< T > af
Definition: Exprtk.hpp:44136
sumk< T > sk
Definition: Exprtk.hpp:44149
all_true< T > at
Definition: Exprtk.hpp:44135
axpbsy< T > b1_axpbsy
Definition: Exprtk.hpp:44154
rol< T > rl
Definition: Exprtk.hpp:44141
ror< T > rr
Definition: Exprtk.hpp:44142
assign< T > an
Definition: Exprtk.hpp:44147
axpbz< T > b1_axpbz
Definition: Exprtk.hpp:44156
threshold_above< T > ta
Definition: Exprtk.hpp:44160
diff< T > df
Definition: Exprtk.hpp:44157
axpyz< T > b1_axpyz
Definition: Exprtk.hpp:44152
shift_right< T > sr
Definition: Exprtk.hpp:44144
shift_left< T > sl
Definition: Exprtk.hpp:44143
axpbsyz< T > b1_axpbsyz
Definition: Exprtk.hpp:44155
type_store< vector_holder_t, vector_holder_t > vector_store
Definition: Exprtk.hpp:19682
static st_data * create()
Definition: Exprtk.hpp:19713
type_store< function_t, function_t > function_store
Definition: Exprtk.hpp:19677
std::list< std::string > local_stringvar_list_
Definition: Exprtk.hpp:19725
std::set< std::string > reserved_symbol_table_
Definition: Exprtk.hpp:19726
bool is_reserved_symbol(const std::string &symbol) const
Definition: Exprtk.hpp:19708
std::list< T > local_symbol_list_
Definition: Exprtk.hpp:19724
static void destroy(st_data *&sd)
Definition: Exprtk.hpp:19718
type_store< vararg_function_t, vararg_function_t > vararg_function_store
Definition: Exprtk.hpp:19678
type_store< generic_function_t, generic_function_t > string_function_store
Definition: Exprtk.hpp:19680
std::vector< ifunction< T > * > free_function_list_
Definition: Exprtk.hpp:19727
~st_data()
Definition: Exprtk.hpp:19700
type_store< generic_function_t, generic_function_t > overload_function_store
Definition: Exprtk.hpp:19681
type_store< generic_function_t, generic_function_t > generic_function_store
Definition: Exprtk.hpp:19679
type_store< stringvar_t, std::string > stringvar_store
Definition: Exprtk.hpp:19684
type_store< variable_t, T > variable_store
Definition: Exprtk.hpp:19676
st_data()
Definition: Exprtk.hpp:19687
Definition: Exprtk.hpp:19673
~control_block()
Definition: Exprtk.hpp:19742
control_block()
Definition: Exprtk.hpp:19730
std::size_t ref_count
Definition: Exprtk.hpp:19780
symtab_mutability_type mutability_
Definition: Exprtk.hpp:19782
control_block(st_data *data)
Definition: Exprtk.hpp:19736
static void destroy(control_block *&cntrl_blck, SymTab *sym_tab)
Definition: Exprtk.hpp:19756
st_data * data_
Definition: Exprtk.hpp:19781
void set_mutability(const symtab_mutability_type mutability)
Definition: Exprtk.hpp:19775
static control_block * create()
Definition: Exprtk.hpp:19750
Definition: Exprtk.hpp:19096
freefunc10(ff10_functor ff)
Definition: Exprtk.hpp:19202
ff02_functor f
Definition: Exprtk.hpp:19122
freefunc04(ff04_functor ff)
Definition: Exprtk.hpp:19139
ff12_functor f
Definition: Exprtk.hpp:19229
freefunc02(ff02_functor ff)
Definition: Exprtk.hpp:19119
freefunc11(ff11_functor ff)
Definition: Exprtk.hpp:19213
ff13_functor f
Definition: Exprtk.hpp:19241
freefunc12(ff12_functor ff)
Definition: Exprtk.hpp:19224
freefunc13(ff13_functor ff)
Definition: Exprtk.hpp:19236
freefunc15(ff15_functor ff)
Definition: Exprtk.hpp:19260
ff15_functor f
Definition: Exprtk.hpp:19265
ff01_functor f
Definition: Exprtk.hpp:19112
ff04_functor f
Definition: Exprtk.hpp:19142
freefunc08(ff08_functor ff)
Definition: Exprtk.hpp:19180
freefunc07(ff07_functor ff)
Definition: Exprtk.hpp:19169
freefunc14(ff14_functor ff)
Definition: Exprtk.hpp:19248
ff03_functor f
Definition: Exprtk.hpp:19132
freefunc09(ff09_functor ff)
Definition: Exprtk.hpp:19191
freefunc03(ff03_functor ff)
Definition: Exprtk.hpp:19129
ff09_functor f
Definition: Exprtk.hpp:19195
ff11_functor f
Definition: Exprtk.hpp:19217
ff07_functor f
Definition: Exprtk.hpp:19173
ff14_functor f
Definition: Exprtk.hpp:19253
freefunc06(ff06_functor ff)
Definition: Exprtk.hpp:19159
freefunc00(ff00_functor ff)
Definition: Exprtk.hpp:19099
ff10_functor f
Definition: Exprtk.hpp:19206
ff08_functor f
Definition: Exprtk.hpp:19184
freefunc01(ff01_functor ff)
Definition: Exprtk.hpp:19109
ff06_functor f
Definition: Exprtk.hpp:19162
ff00_functor f
Definition: Exprtk.hpp:19102
Definition: Exprtk.hpp:19146
ff05_functor f
Definition: Exprtk.hpp:19152
freefunc05(ff05_functor ff)
Definition: Exprtk.hpp:19149
Definition: Exprtk.hpp:19298
exprtk_define_process(variable_node_t) exprtk_define_process(vector_t) exprtk_define_process(stringvar_node_t) template< typename DeleteType > static inline void process(std
Definition: Exprtk.hpp:19305
static bool test(const variable_node_t *p, const void *ptr)
Definition: Exprtk.hpp:19521
static bool test(const PtrType, const void *)
Definition: Exprtk.hpp:19512
static std::pair< bool, vector_t * > make(std::pair< T *, std::size_t > v, const bool is_const=false)
Definition: Exprtk.hpp:19391
static std::pair< bool, vector_t * > make(std::deque< T, Allocator > &v, const bool is_const=false)
Definition: Exprtk.hpp:19417
static std::pair< bool, vector_t * > make(std::vector< T, Allocator > &v, const bool is_const=false)
Definition: Exprtk.hpp:19400
static std::pair< bool, vector_t * > make(exprtk::vector_view< T > &v, const bool is_const=false)
Definition: Exprtk.hpp:19408
Definition: Exprtk.hpp:19270
details::stringvar_node< T > stringvar_node_t
Definition: Exprtk.hpp:19278
std::size_t size
Definition: Exprtk.hpp:19291
bool remove(const std::string &symbol_name, const bool delete_node=true)
Definition: Exprtk.hpp:19547
type_map_t::iterator tm_itr_t
Definition: Exprtk.hpp:19285
igeneric_function< T > igeneric_function_t
Definition: Exprtk.hpp:19275
std::map< std::string, type_pair_t, details::ilesscompare > type_map_t
Definition: Exprtk.hpp:19284
type_t * type_ptr
Definition: Exprtk.hpp:19282
details::variable_node< T > variable_node_t
Definition: Exprtk.hpp:19272
std::size_t get_list(Sequence< std::string, Allocator > &vlist) const
Definition: Exprtk.hpp:19633
bool add_impl(const std::string &symbol_name, RType t, const bool is_const)
Definition: Exprtk.hpp:19365
type_map_t::const_iterator tm_const_itr_t
Definition: Exprtk.hpp:19286
type_store()
Definition: Exprtk.hpp:19293
type_map_t map
Definition: Exprtk.hpp:19290
type_ptr get(const std::string &symbol_name) const
Definition: Exprtk.hpp:19499
std::string entity_name(const PtrType &ptr) const
Definition: Exprtk.hpp:19329
RawType & type_ref(const std::string &symbol_name)
Definition: Exprtk.hpp:19567
std::pair< bool, type_ptr > type_pair_t
Definition: Exprtk.hpp:19283
bool add(const std::string &symbol_name, std::vector< T, Allocator > &v, const bool is_const=false)
Definition: Exprtk.hpp:19437
bool is_constant(const std::string &symbol_name) const
Definition: Exprtk.hpp:19349
bool add(const std::string &symbol_name, RawType &t_, const bool is_const=false)
Definition: Exprtk.hpp:19456
bool symbol_exists(const std::string &symbol_name) const
Definition: Exprtk.hpp:19318
bool add(const std::string &symbol_name, T(&v)[v_size], const bool is_const=false)
Definition: Exprtk.hpp:19424
ivararg_function< T > ivararg_function_t
Definition: Exprtk.hpp:19274
type_ptr get_from_varptr(const void *ptr) const
Definition: Exprtk.hpp:19528
bool add(const std::string &symbol_name, std::deque< T, Allocator > &v, const bool is_const=false)
Definition: Exprtk.hpp:19450
bool add(const std::string &symbol_name, exprtk::vector_view< T > &v, const bool is_const=false)
Definition: Exprtk.hpp:19443
ifunction< T > ifunction_t
Definition: Exprtk.hpp:19273
void clear(const bool delete_node=true)
Definition: Exprtk.hpp:19587
details::expression_node< T > * expression_ptr
Definition: Exprtk.hpp:19271
details::vector_holder< T > vector_t
Definition: Exprtk.hpp:19276
std::size_t get_list(Sequence< std::pair< std::string, RawType >, Allocator > &list) const
Definition: Exprtk.hpp:19611
bool add(const std::string &symbol_name, T *v, const std::size_t v_size, const bool is_const=false)
Definition: Exprtk.hpp:19430
Type type_t
Definition: Exprtk.hpp:19281
Definition: Exprtk.hpp:42003
symbol_table< T > symbol_table_t
Definition: Exprtk.hpp:42004
expression< T > expression_t
Definition: Exprtk.hpp:42005
function_compositor< T > compositor_t
Definition: Exprtk.hpp:42008
compositor_t::function function_t
Definition: Exprtk.hpp:42009
parser_error::type error_t
Definition: Exprtk.hpp:42007
parser< T > parser_t
Definition: Exprtk.hpp:42006
Definition: Exprtk.hpp:4737
bool to_uint(UIntType &u) const
Definition: Exprtk.hpp:4781
scalar_view(type_store_t &ts)
Definition: Exprtk.hpp:4741
type_store< T > type_store_t
Definition: Exprtk.hpp:4738
scalar_view(const type_store_t &ts)
Definition: Exprtk.hpp:4745
T & v_
Definition: Exprtk.hpp:4793
bool to_int(IntType &i) const
Definition: Exprtk.hpp:4770
T value_t
Definition: Exprtk.hpp:4739
Definition: Exprtk.hpp:4687
value_t & operator[](const std::size_t &i)
Definition: Exprtk.hpp:4706
type_view(type_store_t &ts)
Definition: Exprtk.hpp:4691
ViewType value_t
Definition: Exprtk.hpp:4689
value_t * begin()
Definition: Exprtk.hpp:4717
const value_t * begin() const
Definition: Exprtk.hpp:4716
value_t * end()
Definition: Exprtk.hpp:4724
type_view(const type_store_t &ts)
Definition: Exprtk.hpp:4696
std::size_t size() const
Definition: Exprtk.hpp:4701
value_t * data_
Definition: Exprtk.hpp:4730
const value_t & operator[](const std::size_t &i) const
Definition: Exprtk.hpp:4711
type_store_t & ts_
Definition: Exprtk.hpp:4729
const value_t * end() const
Definition: Exprtk.hpp:4719
type_store< T > type_store_t
Definition: Exprtk.hpp:4688
Definition: Exprtk.hpp:4606
type_view< T > vector_view
Definition: Exprtk.hpp:4733
store_type
Definition: Exprtk.hpp:4608
@ e_vector
Definition: Exprtk.hpp:4611
@ e_string
Definition: Exprtk.hpp:4612
@ e_scalar
Definition: Exprtk.hpp:4610
@ e_unknown
Definition: Exprtk.hpp:4609
type_store()
Definition: Exprtk.hpp:4615
std::size_t size
Definition: Exprtk.hpp:4627
void * data
Definition: Exprtk.hpp:4623
T * vec_data
Definition: Exprtk.hpp:4624
type_view< char > string_view
Definition: Exprtk.hpp:4734
store_type type
Definition: Exprtk.hpp:4628
std::size_t type_size
Definition: Exprtk.hpp:2141
void * access_ptr
Definition: Exprtk.hpp:2140
Definition: Exprtk.hpp:2135
virtual bool handle_runtime_violation(violation_context &)
Definition: Exprtk.hpp:2147
virtual ~vector_access_runtime_check()
Definition: Exprtk.hpp:2144