00000 | /* 
 00001 |  ****************************************************************** 
 00002 |  *           C++ Mathematical Expression Toolkit Library          * 
 00003 |  *                                                                * 
 00004 |  * Author: Arash Partow (1999-2024)                               * 
 00005 |  * URL: https://www.partow.net/programming/exprtk/index.html      * 
 00006 |  *                                                                * 
 00007 |  * Copyright notice:                                              * 
 00008 |  * Free use of the C++ Mathematical Expression Toolkit Library is * 
 00009 |  * permitted under the guidelines and in accordance with the most * 
 00010 |  * current version of the MIT License.                            * 
 00011 |  * https://www.opensource.org/licenses/MIT                        * 
 00012 |  * SPDX-License-Identifier: MIT                                   * 
 00013 |  *                                                                * 
 00014 |  * Example expressions:                                           * 
 00015 |  * (00) (y + x / y) * (x - y / x)                                 * 
 00016 |  * (01) (x^2 / sin(2 * pi / y)) - x / 2                           * 
 00017 |  * (02) sqrt(1 - (x^2))                                           * 
 00018 |  * (03) 1 - sin(2 * x) + cos(pi / y)                              * 
 00019 |  * (04) a * exp(2 * t) + c                                        * 
 00020 |  * (05) if(((x + 2) == 3) and ((y + 5) <= 9), 1 + w, 2 / z)       * 
 00021 |  * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x          * 
 00022 |  * (07) z := x + sin(2 * pi / y)                                  * 
 00023 |  * (08) u := 2 * (pi * z) / (w := x + cos(y / pi))                * 
 00024 |  * (09) clamp(-1, sin(2 * pi * x) + cos(y / 2 * pi), +1)          * 
 00025 |  * (10) inrange(-2, m, +2) == if(({-2 <= m} and [m <= +2]), 1, 0) * 
 00026 |  * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1)  * 
 00027 |  * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)]                  * 
 00028 |  *                                                                * 
 00029 |  ****************************************************************** 
 00030 | */ 
 00031 |  
 00032 |  
 00033 | #ifndef INCLUDE_EXPRTK_HPP 
 00034 | #define INCLUDE_EXPRTK_HPP 
 00035 |  
 00036 |  
 00037 | #include <algorithm> 
 00038 | #include <cassert> 
 00039 | #include <cctype> 
 00040 | #include <cmath> 
 00041 | #include <cstdio> 
 00042 | #include <cstdlib> 
 00043 | #include <cstring> 
 00044 | #include <deque> 
 00045 | #include <functional> 
 00046 | #include <iterator> 
 00047 | #include <limits> 
 00048 | #include <list> 
 00049 | #include <map> 
 00050 | #include <set> 
 00051 | #include <stack> 
 00052 | #include <stdexcept> 
 00053 | #include <string> 
 00054 | #include <utility> 
 00055 | #include <vector> 
 00056 |  
 00057 |  
 00058 | namespace exprtk 
 00059 | { 
 00060 |    #ifdef exprtk_enable_debugging 
 00061 |      #define exprtk_debug(params) printf params 
 00062 |    #else 
 00063 |      #define exprtk_debug(params) (void)0 
 00064 |    #endif 
 00065 |  
 00066 |    #define exprtk_error_location             \ 
 00067 |    "exprtk.hpp:" + details::to_str(__LINE__) \ 
 00068 |  
 00069 |    #if __cplusplus >= 201103L 
 00070 |       #define exprtk_override override 
 00071 |       #define exprtk_final    final 
 00072 |       #define exprtk_delete   = delete 
 00073 |    #else 
 00074 |       #define exprtk_override 
 00075 |       #define exprtk_final 
 00076 |       #define exprtk_delete 
 00077 |    #endif 
 00078 |  
 00079 |    #if __cplusplus >= 201603L 
 00080 |       #define exprtk_fallthrough [[fallthrough]]; 
 00081 |    #elif __cplusplus >= 201103L 
 00082 |       #define exprtk_fallthrough [[gnu::fallthrough]]; 
 00083 |    #else 
 00084 |       #ifndef _MSC_VER 
 00085 |       #define exprtk_fallthrough __attribute__ ((fallthrough)); 
 00086 |       #else 
 00087 |       #define exprtk_fallthrough 
 00088 |       #endif 
 00089 |    #endif 
 00090 |  
 00091 |    namespace details 
 00092 |    { 
 00093 |       typedef char                   char_t; 
 00094 |       typedef char_t*                char_ptr; 
 00095 |       typedef char_t const*          char_cptr; 
 00096 |       typedef unsigned char          uchar_t; 
 00097 |       typedef uchar_t*               uchar_ptr; 
 00098 |       typedef uchar_t const*         uchar_cptr; 
 00099 |       typedef unsigned long long int _uint64_t; 
 00100 |       typedef long long int          _int64_t; 
 00101 |  
 00102 |       inline bool is_whitespace(const char_t c) 
 00103 |       { 
 00104 |          return (' '  == c) || ('\n' == c) || 
 00105 |                 ('\r' == c) || ('\t' == c) || 
 00106 |                 ('\b' == c) || ('\v' == c) || 
 00107 |                 ('\f' == c) ; 
 00108 |       } 
 00109 |  
 00110 |       inline bool is_operator_char(const char_t c) 
 00111 |       { 
 00112 |          return ('+' == c) || ('-' == c) || 
 00113 |                 ('*' == c) || ('/' == c) || 
 00114 |                 ('^' == c) || ('<' == c) || 
 00115 |                 ('>' == c) || ('=' == c) || 
 00116 |                 (',' == c) || ('!' == c) || 
 00117 |                 ('(' == c) || (')' == c) || 
 00118 |                 ('[' == c) || (']' == c) || 
 00119 |                 ('{' == c) || ('}' == c) || 
 00120 |                 ('%' == c) || (':' == c) || 
 00121 |                 ('?' == c) || ('&' == c) || 
 00122 |                 ('|' == c) || (';' == c) ; 
 00123 |       } 
 00124 |  
 00125 |       inline bool is_letter(const char_t c) 
 00126 |       { 
 00127 |          return (('a' <= c) && (c <= 'z')) || 
 00128 |                 (('A' <= c) && (c <= 'Z')) ; 
 00129 |       } 
 00130 |  
 00131 |       inline bool is_digit(const char_t c) 
 00132 |       { 
 00133 |          return ('0' <= c) && (c <= '9'); 
 00134 |       } 
 00135 |  
 00136 |       inline bool is_letter_or_digit(const char_t c) 
 00137 |       { 
 00138 |          return is_letter(c) || is_digit(c); 
 00139 |       } 
 00140 |  
 00141 |       inline bool is_left_bracket(const char_t c) 
 00142 |       { 
 00143 |          return ('(' == c) || ('[' == c) || ('{' == c); 
 00144 |       } 
 00145 |  
 00146 |       inline bool is_right_bracket(const char_t c) 
 00147 |       { 
 00148 |          return (')' == c) || (']' == c) || ('}' == c); 
 00149 |       } 
 00150 |  
 00151 |       inline bool is_bracket(const char_t c) 
 00152 |       { 
 00153 |          return is_left_bracket(c) || is_right_bracket(c); 
 00154 |       } 
 00155 |  
 00156 |       inline bool is_sign(const char_t c) 
 00157 |       { 
 00158 |          return ('+' == c) || ('-' == c); 
 00159 |       } 
 00160 |  
 00161 |       inline bool is_invalid(const char_t c) 
 00162 |       { 
 00163 |          return !is_whitespace   (c) && 
 00164 |                 !is_operator_char(c) && 
 00165 |                 !is_letter       (c) && 
 00166 |                 !is_digit        (c) && 
 00167 |                 ('.'  != c)          && 
 00168 |                 ('_'  != c)          && 
 00169 |                 ('$'  != c)          && 
 00170 |                 ('~'  != c)          && 
 00171 |                 ('\'' != c); 
 00172 |       } 
 00173 |  
 00174 |       inline bool is_valid_string_char(const char_t c) 
 00175 |       { 
 00176 |          return std::isprint(static_cast<uchar_t>(c)) || 
 00177 |                 is_whitespace(c); 
 00178 |       } 
 00179 |  
 00180 |       #ifndef exprtk_disable_caseinsensitivity 
 00181 |       inline void case_normalise(std::string& s) 
 00182 |       { 
 00183 |          for (std::size_t i = 0; i < s.size(); ++i) 
 00184 |          { 
 00185 |             s[i] = static_cast<std::string::value_type>(std::tolower(s[i])); 
 00186 |          } 
 00187 |       } 
 00188 |  
 00189 |       inline bool imatch(const char_t c1, const char_t c2) 
 00190 |       { 
 00191 |          return std::tolower(c1) == std::tolower(c2); 
 00192 |       } 
 00193 |  
 00194 |       inline bool imatch(const std::string& s1, const std::string& s2) 
 00195 |       { 
 00196 |          if (s1.size() == s2.size()) 
 00197 |          { 
 00198 |             for (std::size_t i = 0; i < s1.size(); ++i) 
 00199 |             { 
 00200 |                if (std::tolower(s1[i]) != std::tolower(s2[i])) 
 00201 |                { 
 00202 |                   return false; 
 00203 |                } 
 00204 |             } 
 00205 |  
 00206 |             return true; 
 00207 |          } 
 00208 |  
 00209 |          return false; 
 00210 |       } 
 00211 |  
 00212 |       struct ilesscompare 
 00213 |       { 
 00214 |          inline bool operator() (const std::string& s1, const std::string& s2) const 
 00215 |          { 
 00216 |             const std::size_t length = std::min(s1.size(),s2.size()); 
 00217 |  
 00218 |             for (std::size_t i = 0; i < length; ++i) 
 00219 |             { 
 00220 |                const char_t c1 = static_cast<char_t>(std::tolower(s1[i])); 
 00221 |                const char_t c2 = static_cast<char_t>(std::tolower(s2[i])); 
 00222 |  
 00223 |                if (c1 < c2) 
 00224 |                   return true; 
 00225 |                else if (c2 < c1) 
 00226 |                   return false; 
 00227 |             } 
 00228 |  
 00229 |             return s1.size() < s2.size(); 
 00230 |          } 
 00231 |       }; 
 00232 |  
 00233 |       #else 
 00234 |       inline void case_normalise(std::string&) 
 00235 |       {} 
 00236 |  
 00237 |       inline bool imatch(const char_t c1, const char_t c2) 
 00238 |       { 
 00239 |          return c1 == c2; 
 00240 |       } 
 00241 |  
 00242 |       inline bool imatch(const std::string& s1, const std::string& s2) 
 00243 |       { 
 00244 |          return s1 == s2; 
 00245 |       } 
 00246 |  
 00247 |       struct ilesscompare 
 00248 |       { 
 00249 |          inline bool operator() (const std::string& s1, const std::string& s2) const 
 00250 |          { 
 00251 |             return s1 < s2; 
 00252 |          } 
 00253 |       }; 
 00254 |       #endif 
 00255 |  
 00256 |       inline bool is_valid_sf_symbol(const std::string& symbol) 
 00257 |       { 
 00258 |          // Special function: $f12 or $F34 
 00259 |          return (4 == symbol.size())  && 
 00260 |                 ('$' == symbol[0])    && 
 00261 |                 imatch('f',symbol[1]) && 
 00262 |                 is_digit(symbol[2])   && 
 00263 |                 is_digit(symbol[3]); 
 00264 |       } 
 00265 |  
 00266 |       inline const char_t& front(const std::string& s) 
 00267 |       { 
 00268 |          return s[0]; 
 00269 |       } 
 00270 |  
 00271 |       inline const char_t& back(const std::string& s) 
 00272 |       { 
 00273 |          return s[s.size() - 1]; 
 00274 |       } 
 00275 |  
 00276 |       inline std::string to_str(int i) 
 00277 |       { 
 00278 |          if (0 == i) 
 00279 |             return std::string("0"); 
 00280 |  
 00281 |          std::string result; 
 00282 |  
 00283 |          const int sign = (i < 0) ? -1 : 1; 
 00284 |  
 00285 |          for ( ; i; i /= 10) 
 00286 |          { 
 00287 |             result += '0' + static_cast<char_t>(sign * (i % 10)); 
 00288 |          } 
 00289 |  
 00290 |          if (sign < 0) 
 00291 |          { 
 00292 |             result += '-'; 
 00293 |          } 
 00294 |  
 00295 |          std::reverse(result.begin(), result.end()); 
 00296 |  
 00297 |          return result; 
 00298 |       } 
 00299 |  
 00300 |       inline std::string to_str(std::size_t i) 
 00301 |       { 
 00302 |          return to_str(static_cast<int>(i)); 
 00303 |       } 
 00304 |  
 00305 |       inline bool is_hex_digit(const uchar_t digit) 
 00306 |       { 
 00307 |          return (('0' <= digit) && (digit <= '9')) || 
 00308 |                 (('A' <= digit) && (digit <= 'F')) || 
 00309 |                 (('a' <= digit) && (digit <= 'f')) ; 
 00310 |       } 
 00311 |  
 00312 |       inline uchar_t hex_to_bin(uchar_t h) 
 00313 |       { 
 00314 |          if (('0' <= h) && (h <= '9')) 
 00315 |             return (h - '0'); 
 00316 |          else 
 00317 |             return static_cast<uchar_t>(std::toupper(h) - 'A' + 10); 
 00318 |       } 
 00319 |  
 00320 |       template <typename Iterator> 
 00321 |       inline bool parse_hex(Iterator& itr, Iterator end, 
 00322 |                             char_t& result) 
 00323 |       { 
 00324 |          if ( 
 00325 |               (end ==  (itr    ))               || 
 00326 |               (end ==  (itr + 1))               || 
 00327 |               (end ==  (itr + 2))               || 
 00328 |               (end ==  (itr + 3))               || 
 00329 |               ('0' != *(itr    ))               || 
 00330 |               ('X' != std::toupper(*(itr + 1))) || 
 00331 |               (!is_hex_digit(*(itr + 2)))       || 
 00332 |               (!is_hex_digit(*(itr + 3))) 
 00333 |             ) 
 00334 |          { 
 00335 |             return false; 
 00336 |          } 
 00337 |  
 00338 |          result = hex_to_bin(static_cast<uchar_t>(*(itr + 2))) << 4 | 
 00339 |                   hex_to_bin(static_cast<uchar_t>(*(itr + 3))) ; 
 00340 |  
 00341 |          return true; 
 00342 |       } 
 00343 |  
 00344 |       inline bool cleanup_escapes(std::string& s) 
 00345 |       { 
 00346 |          typedef std::string::iterator str_itr_t; 
 00347 |  
 00348 |          str_itr_t itr1 = s.begin(); 
 00349 |          str_itr_t itr2 = s.begin(); 
 00350 |          str_itr_t end  = s.end  (); 
 00351 |  
 00352 |          std::size_t removal_count  = 0; 
 00353 |  
 00354 |          while (end != itr1) 
 00355 |          { 
 00356 |             if ('\\' == (*itr1)) 
 00357 |             { 
 00358 |                if (end == ++itr1) 
 00359 |                { 
 00360 |                   return false; 
 00361 |                } 
 00362 |                else if (parse_hex(itr1, end, *itr2)) 
 00363 |                { 
 00364 |                   itr1 += 4; 
 00365 |                   itr2 += 1; 
 00366 |                   removal_count += 4; 
 00367 |                } 
 00368 |                else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; } 
 00369 |                else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; } 
 00370 |                else if ('f' == (*itr1)) { (*itr2++) = '\f'; ++itr1; ++removal_count; } 
 00371 |                else if ('n' == (*itr1)) { (*itr2++) = '\n'; ++itr1; ++removal_count; } 
 00372 |                else if ('r' == (*itr1)) { (*itr2++) = '\r'; ++itr1; ++removal_count; } 
 00373 |                else if ('t' == (*itr1)) { (*itr2++) = '\t'; ++itr1; ++removal_count; } 
 00374 |                else if ('v' == (*itr1)) { (*itr2++) = '\v'; ++itr1; ++removal_count; } 
 00375 |                else if ('0' == (*itr1)) { (*itr2++) = '\0'; ++itr1; ++removal_count; } 
 00376 |                else 
 00377 |                { 
 00378 |                   (*itr2++) = (*itr1++); 
 00379 |                   ++removal_count; 
 00380 |                } 
 00381 |  
 00382 |                continue; 
 00383 |             } 
 00384 |             else 
 00385 |                (*itr2++) = (*itr1++); 
 00386 |          } 
 00387 |  
 00388 |          if ((removal_count > s.size()) || (0 == removal_count)) 
 00389 |             return false; 
 00390 |  
 00391 |          s.resize(s.size() - removal_count); 
 00392 |  
 00393 |          return true; 
 00394 |       } 
 00395 |  
 00396 |       class build_string 
 00397 |       { 
 00398 |       public: 
 00399 |  
 00400 |          explicit build_string(const std::size_t& initial_size = 64) 
 00401 |          { 
 00402 |             data_.reserve(initial_size); 
 00403 |          } 
 00404 |  
 00405 |          inline build_string& operator << (const std::string& s) 
 00406 |          { 
 00407 |             data_ += s; 
 00408 |             return (*this); 
 00409 |          } 
 00410 |  
 00411 |          inline build_string& operator << (char_cptr s) 
 00412 |          { 
 00413 |             data_ += std::string(s); 
 00414 |             return (*this); 
 00415 |          } 
 00416 |  
 00417 |          inline operator std::string () const 
 00418 |          { 
 00419 |             return data_; 
 00420 |          } 
 00421 |  
 00422 |          inline std::string as_string() const 
 00423 |          { 
 00424 |             return data_; 
 00425 |          } 
 00426 |  
 00427 |       private: 
 00428 |  
 00429 |          std::string data_; 
 00430 |       }; 
 00431 |  
 00432 |       static const std::string reserved_words[] = 
 00433 |       { 
 00434 |          "assert",  "break", "case", "continue", "const",  "default", 
 00435 |          "false", "for", "if", "else", "ilike", "in", "like",  "and", 
 00436 |          "nand",  "nor",  "not",  "null",  "or",  "repeat", "return", 
 00437 |          "shl",  "shr",  "swap",  "switch",  "true",  "until", "var", 
 00438 |          "while", "xnor", "xor", "&", "|" 
 00439 |       }; 
 00440 |  
 00441 |       static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string); 
 00442 |  
 00443 |       static const std::string reserved_symbols[] = 
 00444 |       { 
 00445 |          "abs", "acos",  "acosh", "and",  "asin", "asinh",  "assert", 
 00446 |          "atan", "atanh",  "atan2", "avg",  "break", "case",  "ceil", 
 00447 |          "clamp", "continue", "const",  "cos", "cosh", "cot",  "csc", 
 00448 |          "default",  "deg2grad", "deg2rad",  "equal", "erf",  "erfc", 
 00449 |          "exp", "expm1", "false", "floor", "for", "frac", "grad2deg", 
 00450 |          "hypot", "iclamp", "if",  "else", "ilike", "in",  "inrange", 
 00451 |          "like",  "log",  "log10", "log2",  "logn",  "log1p", "mand", 
 00452 |          "max", "min",  "mod", "mor",  "mul", "ncdf",  "nand", "nor", 
 00453 |          "not",   "not_equal",   "null",   "or",   "pow",  "rad2deg", 
 00454 |          "repeat", "return", "root", "round", "roundn", "sec", "sgn", 
 00455 |          "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum",  "swap", 
 00456 |          "switch", "tan",  "tanh", "true",  "trunc", "until",  "var", 
 00457 |          "while", "xnor", "xor", "&", "|" 
 00458 |       }; 
 00459 |  
 00460 |       static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string); 
 00461 |  
 00462 |       static const std::string base_function_list[] = 
 00463 |       { 
 00464 |          "abs", "acos",  "acosh", "asin",  "asinh", "atan",  "atanh", 
 00465 |          "atan2",  "avg",  "ceil",  "clamp",  "cos",  "cosh",  "cot", 
 00466 |          "csc",  "equal",  "erf",  "erfc",  "exp",  "expm1", "floor", 
 00467 |          "frac", "hypot", "iclamp",  "like", "log", "log10",  "log2", 
 00468 |          "logn", "log1p", "mand", "max", "min", "mod", "mor",  "mul", 
 00469 |          "ncdf",  "pow",  "root",  "round",  "roundn",  "sec", "sgn", 
 00470 |          "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh", 
 00471 |          "trunc",  "not_equal",  "inrange",  "deg2grad",   "deg2rad", 
 00472 |          "rad2deg", "grad2deg" 
 00473 |       }; 
 00474 |  
 00475 |       static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string); 
 00476 |  
 00477 |       static const std::string logic_ops_list[] = 
 00478 |       { 
 00479 |          "and", "nand", "nor", "not", "or",  "xnor", "xor", "&", "|" 
 00480 |       }; 
 00481 |  
 00482 |       static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string); 
 00483 |  
 00484 |       static const std::string cntrl_struct_list[] = 
 00485 |       { 
 00486 |          "if", "switch", "for", "while", "repeat", "return" 
 00487 |       }; 
 00488 |  
 00489 |       static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string); 
 00490 |  
 00491 |       static const std::string arithmetic_ops_list[] = 
 00492 |       { 
 00493 |          "+", "-", "*", "/", "%", "^" 
 00494 |       }; 
 00495 |  
 00496 |       static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string); 
 00497 |  
 00498 |       static const std::string assignment_ops_list[] = 
 00499 |       { 
 00500 |          ":=", "+=", "-=", 
 00501 |          "*=", "/=", "%=" 
 00502 |       }; 
 00503 |  
 00504 |       static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string); 
 00505 |  
 00506 |       static const std::string inequality_ops_list[] = 
 00507 |       { 
 00508 |          "<",  "<=", "==", 
 00509 |          "=",  "!=", "<>", 
 00510 |          ">=",  ">" 
 00511 |       }; 
 00512 |  
 00513 |       static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string); 
 00514 |  
 00515 |       inline bool is_reserved_word(const std::string& symbol) 
 00516 |       { 
 00517 |          for (std::size_t i = 0; i < reserved_words_size; ++i) 
 00518 |          { 
 00519 |             if (imatch(symbol, reserved_words[i])) 
 00520 |             { 
 00521 |                return true; 
 00522 |             } 
 00523 |          } 
 00524 |  
 00525 |          return false; 
 00526 |       } 
 00527 |  
 00528 |       inline bool is_reserved_symbol(const std::string& symbol) 
 00529 |       { 
 00530 |          for (std::size_t i = 0; i < reserved_symbols_size; ++i) 
 00531 |          { 
 00532 |             if (imatch(symbol, reserved_symbols[i])) 
 00533 |             { 
 00534 |                return true; 
 00535 |             } 
 00536 |          } 
 00537 |  
 00538 |          return false; 
 00539 |       } 
 00540 |  
 00541 |       inline bool is_base_function(const std::string& function_name) 
 00542 |       { 
 00543 |          for (std::size_t i = 0; i < base_function_list_size; ++i) 
 00544 |          { 
 00545 |             if (imatch(function_name, base_function_list[i])) 
 00546 |             { 
 00547 |                return true; 
 00548 |             } 
 00549 |          } 
 00550 |  
 00551 |          return false; 
 00552 |       } 
 00553 |  
 00554 |       inline bool is_control_struct(const std::string& cntrl_strct) 
 00555 |       { 
 00556 |          for (std::size_t i = 0; i < cntrl_struct_list_size; ++i) 
 00557 |          { 
 00558 |             if (imatch(cntrl_strct, cntrl_struct_list[i])) 
 00559 |             { 
 00560 |                return true; 
 00561 |             } 
 00562 |          } 
 00563 |  
 00564 |          return false; 
 00565 |       } 
 00566 |  
 00567 |       inline bool is_logic_opr(const std::string& lgc_opr) 
 00568 |       { 
 00569 |          for (std::size_t i = 0; i < logic_ops_list_size; ++i) 
 00570 |          { 
 00571 |             if (imatch(lgc_opr, logic_ops_list[i])) 
 00572 |             { 
 00573 |                return true; 
 00574 |             } 
 00575 |          } 
 00576 |  
 00577 |          return false; 
 00578 |       } 
 00579 |  
 00580 |       struct cs_match 
 00581 |       { 
 00582 |          static inline bool cmp(const char_t c0, const char_t c1) 
 00583 |          { 
 00584 |             return (c0 == c1); 
 00585 |          } 
 00586 |       }; 
 00587 |  
 00588 |       struct cis_match 
 00589 |       { 
 00590 |          static inline bool cmp(const char_t c0, const char_t c1) 
 00591 |          { 
 00592 |             return (std::tolower(c0) == std::tolower(c1)); 
 00593 |          } 
 00594 |       }; 
 00595 |  
 00596 |       template <typename Iterator, typename Compare> 
 00597 |       inline bool match_impl(const Iterator pattern_begin, 
 00598 |                              const Iterator pattern_end  , 
 00599 |                              const Iterator data_begin   , 
 00600 |                              const Iterator data_end     , 
 00601 |                              const typename std::iterator_traits<Iterator>::value_type& zero_or_more, 
 00602 |                              const typename std::iterator_traits<Iterator>::value_type& exactly_one ) 
 00603 |       { 
 00604 |          typedef typename std::iterator_traits<Iterator>::value_type type; 
 00605 |  
 00606 |          const Iterator null_itr(0); 
 00607 |  
 00608 |          Iterator p_itr  = pattern_begin; 
 00609 |          Iterator d_itr  = data_begin; 
 00610 |          Iterator np_itr = null_itr; 
 00611 |          Iterator nd_itr = null_itr; 
 00612 |  
 00613 |          for ( ; ; ) 
 00614 |          { 
 00615 |             if (p_itr != pattern_end) 
 00616 |             { 
 00617 |                const type c = *(p_itr); 
 00618 |  
 00619 |                if ((data_end != d_itr) && (Compare::cmp(c,*(d_itr)) || (exactly_one == c))) 
 00620 |                { 
 00621 |                   ++d_itr; 
 00622 |                   ++p_itr; 
 00623 |                   continue; 
 00624 |                } 
 00625 |                else if (zero_or_more == c) 
 00626 |                { 
 00627 |                   while ((pattern_end != p_itr) && (zero_or_more == *(p_itr))) 
 00628 |                   { 
 00629 |                      ++p_itr; 
 00630 |                   } 
 00631 |  
 00632 |                   const type d = *(p_itr); 
 00633 |  
 00634 |                   while ((data_end != d_itr) && !(Compare::cmp(d,*(d_itr)) || (exactly_one == d))) 
 00635 |                   { 
 00636 |                      ++d_itr; 
 00637 |                   } 
 00638 |  
 00639 |                   // set backtrack iterators 
 00640 |                   np_itr = p_itr - 1; 
 00641 |                   nd_itr = d_itr + 1; 
 00642 |  
 00643 |                   continue; 
 00644 |                } 
 00645 |             } 
 00646 |             else if (data_end == d_itr) 
 00647 |                break; 
 00648 |  
 00649 |             if ((data_end == d_itr) || (null_itr == nd_itr)) 
 00650 |                 return false; 
 00651 |  
 00652 |             p_itr = np_itr; 
 00653 |             d_itr = nd_itr; 
 00654 |          } 
 00655 |  
 00656 |          return true; 
 00657 |       } 
 00658 |  
 00659 |       inline bool wc_match(const std::string& wild_card, 
 00660 |                            const std::string& str) 
 00661 |       { 
 00662 |          return match_impl<char_cptr,cs_match> 
 00663 |                 ( 
 00664 |                    wild_card.data(), 
 00665 |                    wild_card.data() + wild_card.size(), 
 00666 |                    str.data(), 
 00667 |                    str.data() + str.size(), 
 00668 |                    '*', '?' 
 00669 |                 ); 
 00670 |       } 
 00671 |  
 00672 |       inline bool wc_imatch(const std::string& wild_card, 
 00673 |                             const std::string& str) 
 00674 |       { 
 00675 |          return match_impl<char_cptr,cis_match> 
 00676 |                 ( 
 00677 |                    wild_card.data(), 
 00678 |                    wild_card.data() + wild_card.size(), 
 00679 |                    str.data(), 
 00680 |                    str.data() + str.size(), 
 00681 |                    '*', '?' 
 00682 |                 ); 
 00683 |       } 
 00684 |  
 00685 |       inline bool sequence_match(const std::string& pattern, 
 00686 |                                  const std::string& str, 
 00687 |                                  std::size_t&       diff_index, 
 00688 |                                  char_t&            diff_value) 
 00689 |       { 
 00690 |          if (str.empty()) 
 00691 |          { 
 00692 |             return ("Z" == pattern); 
 00693 |          } 
 00694 |          else if ('*' == pattern[0]) 
 00695 |             return false; 
 00696 |  
 00697 |          typedef std::string::const_iterator itr_t; 
 00698 |  
 00699 |          itr_t p_itr = pattern.begin(); 
 00700 |          itr_t s_itr = str    .begin(); 
 00701 |  
 00702 |          const itr_t p_end = pattern.end(); 
 00703 |          const itr_t s_end = str    .end(); 
 00704 |  
 00705 |          while ((s_end != s_itr) && (p_end != p_itr)) 
 00706 |          { 
 00707 |             if ('*' == (*p_itr)) 
 00708 |             { 
 00709 |                const char_t target = static_cast<char_t>(std::toupper(*(p_itr - 1))); 
 00710 |  
 00711 |                if ('*' == target) 
 00712 |                { 
 00713 |                   diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr)); 
 00714 |                   diff_value = static_cast<char_t>(std::toupper(*p_itr)); 
 00715 |  
 00716 |                   return false; 
 00717 |                } 
 00718 |                else 
 00719 |                   ++p_itr; 
 00720 |  
 00721 |                while (s_itr != s_end) 
 00722 |                { 
 00723 |                   if (target != std::toupper(*s_itr)) 
 00724 |                      break; 
 00725 |                   else 
 00726 |                      ++s_itr; 
 00727 |                } 
 00728 |  
 00729 |                continue; 
 00730 |             } 
 00731 |             else if ( 
 00732 |                       ('?' != *p_itr) && 
 00733 |                       std::toupper(*p_itr) != std::toupper(*s_itr) 
 00734 |                     ) 
 00735 |             { 
 00736 |                diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr)); 
 00737 |                diff_value = static_cast<char_t>(std::toupper(*p_itr)); 
 00738 |  
 00739 |                return false; 
 00740 |             } 
 00741 |  
 00742 |             ++p_itr; 
 00743 |             ++s_itr; 
 00744 |          } 
 00745 |  
 00746 |          return ( 
 00747 |                   (s_end == s_itr) && 
 00748 |                   ( 
 00749 |                     (p_end ==  p_itr) || 
 00750 |                     ('*'   == *p_itr) 
 00751 |                   ) 
 00752 |                 ); 
 00753 |       } 
 00754 |  
 00755 |       template<typename T> 
 00756 |       struct set_zero_value_impl 
 00757 |       { 
 00758 |          static inline void process(T* base_ptr, const std::size_t size) 
 00759 |          { 
 00760 |             const T zero = T(0); 
 00761 |             for (std::size_t i = 0; i < size; ++i) 
 00762 |             { 
 00763 |                base_ptr[i] = zero; 
 00764 |             } 
 00765 |          } 
 00766 |       }; 
 00767 |  
 00768 |       #define pod_set_zero_value(T)                                      \ 
 00769 |       template <>                                                        \ 
 00770 |       struct set_zero_value_impl<T>                                      \ 
 00771 |       {                                                                  \ 
 00772 |          static inline void process(T* base_ptr, const std::size_t size) \ 
 00773 |          { std::memset(base_ptr, 0x00, size * sizeof(T)); }              \ 
 00774 |       };                                                                 \ 
 00775 |  
 00776 |       pod_set_zero_value(float      ) 
 00777 |       pod_set_zero_value(double     ) 
 00778 |       pod_set_zero_value(long double) 
 00779 |  
 00780 |       #ifdef pod_set_zero_value 
 00781 |       #undef pod_set_zero_value 
 00782 |       #endif 
 00783 |  
 00784 |       template<typename T> 
 00785 |       inline void set_zero_value(T* data, const std::size_t size) 
 00786 |       { 
 00787 |          set_zero_value_impl<T>::process(data,size); 
 00788 |       } 
 00789 |  
 00790 |       template<typename T> 
 00791 |       inline void set_zero_value(std::vector<T>& v) 
 00792 |       { 
 00793 |          set_zero_value(v.data(),v.size()); 
 00794 |       } 
 00795 |  
 00796 |       static const double pow10[] = 
 00797 |       { 
 00798 |          1.0, 
 00799 |          1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 
 00800 |          1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 
 00801 |          1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012, 
 00802 |          1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016 
 00803 |       }; 
 00804 |  
 00805 |       static const std::size_t pow10_size = sizeof(pow10) / sizeof(double); 
 00806 |  
 00807 |       namespace numeric 
 00808 |       { 
 00809 |          namespace constant 
 00810 |          { 
 00811 |             static const double e       =  2.71828182845904523536028747135266249775724709369996; 
 00812 |             static const double pi      =  3.14159265358979323846264338327950288419716939937510; 
 00813 |             static const double pi_2    =  1.57079632679489661923132169163975144209858469968755; 
 00814 |             static const double pi_4    =  0.78539816339744830961566084581987572104929234984378; 
 00815 |             static const double pi_180  =  0.01745329251994329576923690768488612713442871888542; 
 00816 |             static const double _1_pi   =  0.31830988618379067153776752674502872406891929148091; 
 00817 |             static const double _2_pi   =  0.63661977236758134307553505349005744813783858296183; 
 00818 |             static const double _180_pi = 57.29577951308232087679815481410517033240547246656443; 
 00819 |             static const double log2    =  0.69314718055994530941723212145817656807550013436026; 
 00820 |             static const double sqrt2   =  1.41421356237309504880168872420969807856967187537695; 
 00821 |          } 
 00822 |  
 00823 |          namespace details 
 00824 |          { 
 00825 |             struct unknown_type_tag { unknown_type_tag() {} }; 
 00826 |             struct real_type_tag    { real_type_tag   () {} }; 
 00827 |             struct int_type_tag     { int_type_tag    () {} }; 
 00828 |  
 00829 |             template <typename T> 
 00830 |             struct number_type 
 00831 |             { 
 00832 |                typedef unknown_type_tag type; 
 00833 |                number_type() {} 
 00834 |             }; 
 00835 |  
 00836 |             #define exprtk_register_real_type_tag(T)          \ 
 00837 |             template <> struct number_type<T>                 \ 
 00838 |             { typedef real_type_tag type; number_type() {} }; \ 
 00839 |  
 00840 |             #define exprtk_register_int_type_tag(T)           \ 
 00841 |             template <> struct number_type<T>                 \ 
 00842 |             { typedef int_type_tag type; number_type() {} };  \ 
 00843 |  
 00844 |             exprtk_register_real_type_tag(float      ) 
 00845 |             exprtk_register_real_type_tag(double     ) 
 00846 |             exprtk_register_real_type_tag(long double) 
 00847 |  
 00848 |             exprtk_register_int_type_tag(short         ) 
 00849 |             exprtk_register_int_type_tag(int           ) 
 00850 |             exprtk_register_int_type_tag(_int64_t      ) 
 00851 |             exprtk_register_int_type_tag(unsigned short) 
 00852 |             exprtk_register_int_type_tag(unsigned int  ) 
 00853 |             exprtk_register_int_type_tag(_uint64_t     ) 
 00854 |  
 00855 |             #undef exprtk_register_real_type_tag 
 00856 |             #undef exprtk_register_int_type_tag 
 00857 |  
 00858 |             template <typename T> 
 00859 |             struct epsilon_type {}; 
 00860 |  
 00861 |             #define exprtk_define_epsilon_type(Type, Epsilon)      \ 
 00862 |             template <> struct epsilon_type<Type>                  \ 
 00863 |             {                                                      \ 
 00864 |                static inline Type value()                          \ 
 00865 |                {                                                   \ 
 00866 |                   const Type epsilon = static_cast<Type>(Epsilon); \ 
 00867 |                   return epsilon;                                  \ 
 00868 |                }                                                   \ 
 00869 |             };                                                     \ 
 00870 |  
 00871 |             exprtk_define_epsilon_type(float      , 0.00000100000f) 
 00872 |             exprtk_define_epsilon_type(double     , 0.000000000100) 
 00873 |             exprtk_define_epsilon_type(long double, 0.000000000001) 
 00874 |  
 00875 |             #undef exprtk_define_epsilon_type 
 00876 |  
 00877 |             template <typename T> 
 00878 |             inline bool is_nan_impl(const T v, real_type_tag) 
 00879 |             { 
 00880 |                return std::not_equal_to<T>()(v,v); 
 00881 |             } 
 00882 |  
 00883 |             template <typename T> 
 00884 |             inline int to_int32_impl(const T v, real_type_tag) 
 00885 |             { 
 00886 |                return static_cast<int>(v); 
 00887 |             } 
 00888 |  
 00889 |             template <typename T> 
 00890 |             inline _int64_t to_int64_impl(const T v, real_type_tag) 
 00891 |             { 
 00892 |                return static_cast<_int64_t>(v); 
 00893 |             } 
 00894 |  
 00895 |             template <typename T> 
 00896 |             inline _uint64_t to_uint64_impl(const T v, real_type_tag) 
 00897 |             { 
 00898 |                return static_cast<_uint64_t>(v); 
 00899 |             } 
 00900 |  
 00901 |             template <typename T> 
 00902 |             inline bool is_true_impl(const T v) 
 00903 |             { 
 00904 |                return std::not_equal_to<T>()(T(0),v); 
 00905 |             } 
 00906 |  
 00907 |             template <typename T> 
 00908 |             inline bool is_false_impl(const T v) 
 00909 |             { 
 00910 |                return std::equal_to<T>()(T(0),v); 
 00911 |             } 
 00912 |  
 00913 |             template <typename T> 
 00914 |             inline T abs_impl(const T v, real_type_tag) 
 00915 |             { 
 00916 |                return ((v < T(0)) ? -v : v); 
 00917 |             } 
 00918 |  
 00919 |             template <typename T> 
 00920 |             inline T min_impl(const T v0, const T v1, real_type_tag) 
 00921 |             { 
 00922 |                return std::min<T>(v0,v1); 
 00923 |             } 
 00924 |  
 00925 |             template <typename T> 
 00926 |             inline T max_impl(const T v0, const T v1, real_type_tag) 
 00927 |             { 
 00928 |                return std::max<T>(v0,v1); 
 00929 |             } 
 00930 |  
 00931 |             template <typename T> 
 00932 |             inline T equal_impl(const T v0, const T v1, real_type_tag) 
 00933 |             { 
 00934 |                const T epsilon = epsilon_type<T>::value(); 
 00935 |                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); 
 00936 |             } 
 00937 |  
 00938 |             inline float equal_impl(const float v0, const float v1, real_type_tag) 
 00939 |             { 
 00940 |                const float epsilon = epsilon_type<float>::value(); 
 00941 |                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; 
 00942 |             } 
 00943 |  
 00944 |             template <typename T> 
 00945 |             inline T equal_impl(const T v0, const T v1, int_type_tag) 
 00946 |             { 
 00947 |                return (v0 == v1) ? 1 : 0; 
 00948 |             } 
 00949 |  
 00950 |             template <typename T> 
 00951 |             inline T expm1_impl(const T v, real_type_tag) 
 00952 |             { 
 00953 |                // return std::expm1<T>(v); 
 00954 |                if (abs_impl(v,real_type_tag()) < T(0.00001)) 
 00955 |                   return v + (T(0.5) * v * v); 
 00956 |                else 
 00957 |                   return std::exp(v) - T(1); 
 00958 |             } 
 00959 |  
 00960 |             template <typename T> 
 00961 |             inline T expm1_impl(const T v, int_type_tag) 
 00962 |             { 
 00963 |                return T(std::exp<double>(v)) - T(1); 
 00964 |             } 
 00965 |  
 00966 |             template <typename T> 
 00967 |             inline T nequal_impl(const T v0, const T v1, real_type_tag) 
 00968 |             { 
 00969 |                typedef real_type_tag rtg; 
 00970 |                const T epsilon = epsilon_type<T>::value(); 
 00971 |                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); 
 00972 |             } 
 00973 |  
 00974 |             inline float nequal_impl(const float v0, const float v1, real_type_tag) 
 00975 |             { 
 00976 |                typedef real_type_tag rtg; 
 00977 |                const float epsilon = epsilon_type<float>::value(); 
 00978 |                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; 
 00979 |             } 
 00980 |  
 00981 |             template <typename T> 
 00982 |             inline T nequal_impl(const T v0, const T v1, int_type_tag) 
 00983 |             { 
 00984 |                return (v0 != v1) ? 1 : 0; 
 00985 |             } 
 00986 |  
 00987 |             template <typename T> 
 00988 |             inline T modulus_impl(const T v0, const T v1, real_type_tag) 
 00989 |             { 
 00990 |                return std::fmod(v0,v1); 
 00991 |             } 
 00992 |  
 00993 |             template <typename T> 
 00994 |             inline T modulus_impl(const T v0, const T v1, int_type_tag) 
 00995 |             { 
 00996 |                return v0 % v1; 
 00997 |             } 
 00998 |  
 00999 |             template <typename T> 
 01000 |             inline T pow_impl(const T v0, const T v1, real_type_tag) 
 01001 |             { 
 01002 |                return std::pow(v0,v1); 
 01003 |             } 
 01004 |  
 01005 |             template <typename T> 
 01006 |             inline T pow_impl(const T v0, const T v1, int_type_tag) 
 01007 |             { 
 01008 |                return std::pow(static_cast<double>(v0),static_cast<double>(v1)); 
 01009 |             } 
 01010 |  
 01011 |             template <typename T> 
 01012 |             inline T logn_impl(const T v0, const T v1, real_type_tag) 
 01013 |             { 
 01014 |                return std::log(v0) / std::log(v1); 
 01015 |             } 
 01016 |  
 01017 |             template <typename T> 
 01018 |             inline T logn_impl(const T v0, const T v1, int_type_tag) 
 01019 |             { 
 01020 |                return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag())); 
 01021 |             } 
 01022 |  
 01023 |             template <typename T> 
 01024 |             inline T log1p_impl(const T v, real_type_tag) 
 01025 |             { 
 01026 |                if (v > T(-1)) 
 01027 |                { 
 01028 |                   if (abs_impl(v,real_type_tag()) > T(0.0001)) 
 01029 |                   { 
 01030 |                      return std::log(T(1) + v); 
 01031 |                   } 
 01032 |                   else 
 01033 |                      return (T(-0.5) * v + T(1)) * v; 
 01034 |                } 
 01035 |  
 01036 |                return std::numeric_limits<T>::quiet_NaN(); 
 01037 |             } 
 01038 |  
 01039 |             template <typename T> 
 01040 |             inline T log1p_impl(const T v, int_type_tag) 
 01041 |             { 
 01042 |                if (v > T(-1)) 
 01043 |                { 
 01044 |                   return std::log(T(1) + v); 
 01045 |                } 
 01046 |  
 01047 |                return std::numeric_limits<T>::quiet_NaN(); 
 01048 |             } 
 01049 |  
 01050 |             template <typename T> 
 01051 |             inline T root_impl(const T v0, const T v1, real_type_tag) 
 01052 |             { 
 01053 |                if (v0 < T(0)) 
 01054 |                { 
 01055 |                   return (v1 == std::trunc(v1)) && (modulus_impl(v1, T(2), real_type_tag()) != T(0)) ? 
 01056 |                          -std::pow(abs_impl(v0, real_type_tag()), T(1) / v1) : 
 01057 |                           std::numeric_limits<double>::quiet_NaN(); 
 01058 |                } 
 01059 |  
 01060 |                return std::pow(v0, T(1) / v1); 
 01061 |             } 
 01062 |  
 01063 |             template <typename T> 
 01064 |             inline T root_impl(const T v0, const T v1, int_type_tag) 
 01065 |             { 
 01066 |                return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()); 
 01067 |             } 
 01068 |  
 01069 |             template <typename T> 
 01070 |             inline T round_impl(const T v, real_type_tag) 
 01071 |             { 
 01072 |                return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5))); 
 01073 |             } 
 01074 |  
 01075 |             template <typename T> 
 01076 |             inline T roundn_impl(const T v0, const T v1, real_type_tag) 
 01077 |             { 
 01078 |                const int index = std::max<int>(0, std::min<int>(pow10_size - 1, static_cast<int>(std::floor(v1)))); 
 01079 |                const T p10 = T(pow10[index]); 
 01080 |  
 01081 |                if (v0 < T(0)) 
 01082 |                   return T(std::ceil ((v0 * p10) - T(0.5)) / p10); 
 01083 |                else 
 01084 |                   return T(std::floor((v0 * p10) + T(0.5)) / p10); 
 01085 |             } 
 01086 |  
 01087 |             template <typename T> 
 01088 |             inline T roundn_impl(const T v0, const T, int_type_tag) 
 01089 |             { 
 01090 |                return v0; 
 01091 |             } 
 01092 |  
 01093 |             template <typename T> 
 01094 |             inline T hypot_impl(const T v0, const T v1, real_type_tag) 
 01095 |             { 
 01096 |                return std::sqrt((v0 * v0) + (v1 * v1)); 
 01097 |             } 
 01098 |  
 01099 |             template <typename T> 
 01100 |             inline T hypot_impl(const T v0, const T v1, int_type_tag) 
 01101 |             { 
 01102 |                return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1)))); 
 01103 |             } 
 01104 |  
 01105 |             template <typename T> 
 01106 |             inline T atan2_impl(const T v0, const T v1, real_type_tag) 
 01107 |             { 
 01108 |                return std::atan2(v0,v1); 
 01109 |             } 
 01110 |  
 01111 |             template <typename T> 
 01112 |             inline T atan2_impl(const T, const T, int_type_tag) 
 01113 |             { 
 01114 |                return 0; 
 01115 |             } 
 01116 |  
 01117 |             template <typename T> 
 01118 |             inline T shr_impl(const T v0, const T v1, real_type_tag) 
 01119 |             { 
 01120 |                return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1)))); 
 01121 |             } 
 01122 |  
 01123 |             template <typename T> 
 01124 |             inline T shr_impl(const T v0, const T v1, int_type_tag) 
 01125 |             { 
 01126 |                return v0 >> v1; 
 01127 |             } 
 01128 |  
 01129 |             template <typename T> 
 01130 |             inline T shl_impl(const T v0, const T v1, real_type_tag) 
 01131 |             { 
 01132 |                return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1))); 
 01133 |             } 
 01134 |  
 01135 |             template <typename T> 
 01136 |             inline T shl_impl(const T v0, const T v1, int_type_tag) 
 01137 |             { 
 01138 |                return v0 << v1; 
 01139 |             } 
 01140 |  
 01141 |             template <typename T> 
 01142 |             inline T sgn_impl(const T v, real_type_tag) 
 01143 |             { 
 01144 |                if      (v > T(0)) return T(+1); 
 01145 |                else if (v < T(0)) return T(-1); 
 01146 |                else               return T( 0); 
 01147 |             } 
 01148 |  
 01149 |             template <typename T> 
 01150 |             inline T sgn_impl(const T v, int_type_tag) 
 01151 |             { 
 01152 |                if      (v > T(0)) return T(+1); 
 01153 |                else if (v < T(0)) return T(-1); 
 01154 |                else               return T( 0); 
 01155 |             } 
 01156 |  
 01157 |             template <typename T> 
 01158 |             inline T and_impl(const T v0, const T v1, real_type_tag) 
 01159 |             { 
 01160 |                return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0); 
 01161 |             } 
 01162 |  
 01163 |             template <typename T> 
 01164 |             inline T and_impl(const T v0, const T v1, int_type_tag) 
 01165 |             { 
 01166 |                return v0 && v1; 
 01167 |             } 
 01168 |  
 01169 |             template <typename T> 
 01170 |             inline T nand_impl(const T v0, const T v1, real_type_tag) 
 01171 |             { 
 01172 |                return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0); 
 01173 |             } 
 01174 |  
 01175 |             template <typename T> 
 01176 |             inline T nand_impl(const T v0, const T v1, int_type_tag) 
 01177 |             { 
 01178 |                return !(v0 && v1); 
 01179 |             } 
 01180 |  
 01181 |             template <typename T> 
 01182 |             inline T or_impl(const T v0, const T v1, real_type_tag) 
 01183 |             { 
 01184 |                return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0); 
 01185 |             } 
 01186 |  
 01187 |             template <typename T> 
 01188 |             inline T or_impl(const T v0, const T v1, int_type_tag) 
 01189 |             { 
 01190 |                return (v0 || v1); 
 01191 |             } 
 01192 |  
 01193 |             template <typename T> 
 01194 |             inline T nor_impl(const T v0, const T v1, real_type_tag) 
 01195 |             { 
 01196 |                return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0); 
 01197 |             } 
 01198 |  
 01199 |             template <typename T> 
 01200 |             inline T nor_impl(const T v0, const T v1, int_type_tag) 
 01201 |             { 
 01202 |                return !(v0 || v1); 
 01203 |             } 
 01204 |  
 01205 |             template <typename T> 
 01206 |             inline T xor_impl(const T v0, const T v1, real_type_tag) 
 01207 |             { 
 01208 |                return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0); 
 01209 |             } 
 01210 |  
 01211 |             template <typename T> 
 01212 |             inline T xor_impl(const T v0, const T v1, int_type_tag) 
 01213 |             { 
 01214 |                return v0 ^ v1; 
 01215 |             } 
 01216 |  
 01217 |             template <typename T> 
 01218 |             inline T xnor_impl(const T v0, const T v1, real_type_tag) 
 01219 |             { 
 01220 |                const bool v0_true = is_true_impl(v0); 
 01221 |                const bool v1_true = is_true_impl(v1); 
 01222 |  
 01223 |                if ((v0_true &&  v1_true) || (!v0_true && !v1_true)) 
 01224 |                   return T(1); 
 01225 |                else 
 01226 |                   return T(0); 
 01227 |             } 
 01228 |  
 01229 |             template <typename T> 
 01230 |             inline T xnor_impl(const T v0, const T v1, int_type_tag) 
 01231 |             { 
 01232 |                const bool v0_true = is_true_impl(v0); 
 01233 |                const bool v1_true = is_true_impl(v1); 
 01234 |  
 01235 |                if ((v0_true &&  v1_true) || (!v0_true && !v1_true)) 
 01236 |                   return T(1); 
 01237 |                else 
 01238 |                   return T(0); 
 01239 |             } 
 01240 |  
 01241 |             #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER) 
 01242 |             #define exprtk_define_erf(TT, impl)                \ 
 01243 |             inline TT erf_impl(const TT v) { return impl(v); } \ 
 01244 |  
 01245 |             exprtk_define_erf(float      , ::erff) 
 01246 |             exprtk_define_erf(double     , ::erf ) 
 01247 |             exprtk_define_erf(long double, ::erfl) 
 01248 |             #undef exprtk_define_erf 
 01249 |             #endif 
 01250 |  
 01251 |             template <typename T> 
 01252 |             inline T erf_impl(const T v, real_type_tag) 
 01253 |             { 
 01254 |                #if defined(_MSC_VER) && (_MSC_VER < 1900) 
 01255 |                // Credits: Abramowitz & Stegun Equations 7.1.25-28 
 01256 |                static const T c[] = 
 01257 |                { 
 01258 |                   T( 1.26551223), T(1.00002368), 
 01259 |                   T( 0.37409196), T(0.09678418), 
 01260 |                   T(-0.18628806), T(0.27886807), 
 01261 |                   T(-1.13520398), T(1.48851587), 
 01262 |                   T(-0.82215223), T(0.17087277) 
 01263 |                }; 
 01264 |  
 01265 |                const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag())); 
 01266 |  
 01267 |                const T result = T(1) - t * std::exp((-v * v) - 
 01268 |                                             c[0] + t * (c[1] + t * 
 01269 |                                            (c[2] + t * (c[3] + t * 
 01270 |                                            (c[4] + t * (c[5] + t * 
 01271 |                                            (c[6] + t * (c[7] + t * 
 01272 |                                            (c[8] + t * (c[9])))))))))); 
 01273 |  
 01274 |                return (v >= T(0)) ? result : -result; 
 01275 |                #else 
 01276 |                return erf_impl(v); 
 01277 |                #endif 
 01278 |             } 
 01279 |  
 01280 |             template <typename T> 
 01281 |             inline T erf_impl(const T v, int_type_tag) 
 01282 |             { 
 01283 |                return erf_impl(static_cast<double>(v),real_type_tag()); 
 01284 |             } 
 01285 |  
 01286 |             #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER) 
 01287 |             #define exprtk_define_erfc(TT, impl)                \ 
 01288 |             inline TT erfc_impl(const TT v) { return impl(v); } \ 
 01289 |  
 01290 |             exprtk_define_erfc(float      ,::erfcf) 
 01291 |             exprtk_define_erfc(double     ,::erfc ) 
 01292 |             exprtk_define_erfc(long double,::erfcl) 
 01293 |             #undef exprtk_define_erfc 
 01294 |             #endif 
 01295 |  
 01296 |             template <typename T> 
 01297 |             inline T erfc_impl(const T v, real_type_tag) 
 01298 |             { 
 01299 |                #if defined(_MSC_VER) && (_MSC_VER < 1900) 
 01300 |                return T(1) - erf_impl(v,real_type_tag()); 
 01301 |                #else 
 01302 |                return erfc_impl(v); 
 01303 |                #endif 
 01304 |             } 
 01305 |  
 01306 |             template <typename T> 
 01307 |             inline T erfc_impl(const T v, int_type_tag) 
 01308 |             { 
 01309 |                return erfc_impl(static_cast<double>(v),real_type_tag()); 
 01310 |             } 
 01311 |  
 01312 |             template <typename T> 
 01313 |             inline T ncdf_impl(const T v, real_type_tag) 
 01314 |             { 
 01315 |                return T(0.5) * erfc_impl(-(v / T(numeric::constant::sqrt2)),real_type_tag()); 
 01316 |             } 
 01317 |  
 01318 |             template <typename T> 
 01319 |             inline T ncdf_impl(const T v, int_type_tag) 
 01320 |             { 
 01321 |                return ncdf_impl(static_cast<double>(v),real_type_tag()); 
 01322 |             } 
 01323 |  
 01324 |             template <typename T> 
 01325 |             inline T sinc_impl(const T v, real_type_tag) 
 01326 |             { 
 01327 |                if (std::abs(v) >= std::numeric_limits<T>::epsilon()) 
 01328 |                    return(std::sin(v) / v); 
 01329 |                else 
 01330 |                   return T(1); 
 01331 |             } 
 01332 |  
 01333 |             template <typename T> 
 01334 |             inline T sinc_impl(const T v, int_type_tag) 
 01335 |             { 
 01336 |                return sinc_impl(static_cast<double>(v),real_type_tag()); 
 01337 |             } 
 01338 |  
 01339 |             #if __cplusplus >= 201103L 
 01340 |             template <typename T> 
 01341 |             inline T acosh_impl(const T v, real_type_tag) 
 01342 |             { 
 01343 |                return std::acosh(v); 
 01344 |             } 
 01345 |  
 01346 |             template <typename T> 
 01347 |             inline T asinh_impl(const T v, real_type_tag) 
 01348 |             { 
 01349 |                return std::asinh(v); 
 01350 |             } 
 01351 |  
 01352 |             template <typename T> 
 01353 |             inline T atanh_impl(const T v, real_type_tag) 
 01354 |             { 
 01355 |                return std::atanh(v); 
 01356 |             } 
 01357 |             #else 
 01358 |             template <typename T> 
 01359 |             inline T acosh_impl(const T v, real_type_tag) 
 01360 |             { 
 01361 |                return std::log(v + std::sqrt((v * v) - T(1))); 
 01362 |             } 
 01363 |  
 01364 |             template <typename T> 
 01365 |             inline T asinh_impl(const T v, real_type_tag) 
 01366 |             { 
 01367 |                return std::log(v + std::sqrt((v * v) + T(1))); 
 01368 |             } 
 01369 |  
 01370 |             template <typename T> 
 01371 |             inline T atanh_impl(const T v, real_type_tag) 
 01372 |             { 
 01373 |                return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); 
 01374 |             } 
 01375 |             #endif 
 01376 |  
 01377 |             template <typename T> inline T  acos_impl(const T v, real_type_tag) { return std::acos (v); } 
 01378 |             template <typename T> inline T  asin_impl(const T v, real_type_tag) { return std::asin (v); } 
 01379 |             template <typename T> inline T  atan_impl(const T v, real_type_tag) { return std::atan (v); } 
 01380 |             template <typename T> inline T  ceil_impl(const T v, real_type_tag) { return std::ceil (v); } 
 01381 |             template <typename T> inline T   cos_impl(const T v, real_type_tag) { return std::cos  (v); } 
 01382 |             template <typename T> inline T  cosh_impl(const T v, real_type_tag) { return std::cosh (v); } 
 01383 |             template <typename T> inline T   exp_impl(const T v, real_type_tag) { return std::exp  (v); } 
 01384 |             template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); } 
 01385 |             template <typename T> inline T   log_impl(const T v, real_type_tag) { return std::log  (v); } 
 01386 |             template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); } 
 01387 |             template <typename T> inline T  log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); } 
 01388 |             template <typename T> inline T   neg_impl(const T v, real_type_tag) { return -v;            } 
 01389 |             template <typename T> inline T   pos_impl(const T v, real_type_tag) { return +v;            } 
 01390 |             template <typename T> inline T   sin_impl(const T v, real_type_tag) { return std::sin  (v); } 
 01391 |             template <typename T> inline T  sinh_impl(const T v, real_type_tag) { return std::sinh (v); } 
 01392 |             template <typename T> inline T  sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); } 
 01393 |             template <typename T> inline T   tan_impl(const T v, real_type_tag) { return std::tan  (v); } 
 01394 |             template <typename T> inline T  tanh_impl(const T v, real_type_tag) { return std::tanh (v); } 
 01395 |             template <typename T> inline T   cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); } 
 01396 |             template <typename T> inline T   sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); } 
 01397 |             template <typename T> inline T   csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); } 
 01398 |             template <typename T> inline T   r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); } 
 01399 |             template <typename T> inline T   d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180));  } 
 01400 |             template <typename T> inline T   d2g_impl(const T v, real_type_tag) { return (v * T(10.0/9.0)); } 
 01401 |             template <typename T> inline T   g2d_impl(const T v, real_type_tag) { return (v * T(9.0/10.0)); } 
 01402 |             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)); } 
 01403 |             template <typename T> inline T  frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); } 
 01404 |             template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v));    } 
 01405 |  
 01406 |             template <typename T> inline T   const_pi_impl(real_type_tag) { return T(numeric::constant::pi);            } 
 01407 |             template <typename T> inline T    const_e_impl(real_type_tag) { return T(numeric::constant::e);             } 
 01408 |             template <typename T> inline T const_qnan_impl(real_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01409 |  
 01410 |             template <typename T> inline T   abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); } 
 01411 |             template <typename T> inline T   exp_impl(const T v, int_type_tag) { return std::exp  (v); } 
 01412 |             template <typename T> inline T   log_impl(const T v, int_type_tag) { return std::log  (v); } 
 01413 |             template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); } 
 01414 |             template <typename T> inline T  log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); } 
 01415 |             template <typename T> inline T   neg_impl(const T v, int_type_tag) { return -v;            } 
 01416 |             template <typename T> inline T   pos_impl(const T v, int_type_tag) { return +v;            } 
 01417 |             template <typename T> inline T  ceil_impl(const T v, int_type_tag) { return v;             } 
 01418 |             template <typename T> inline T floor_impl(const T v, int_type_tag) { return v;             } 
 01419 |             template <typename T> inline T round_impl(const T v, int_type_tag) { return v;             } 
 01420 |             template <typename T> inline T  notl_impl(const T v, int_type_tag) { return !v;            } 
 01421 |             template <typename T> inline T  sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); } 
 01422 |             template <typename T> inline T  frac_impl(const T  , int_type_tag) { return T(0);          } 
 01423 |             template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v;             } 
 01424 |             template <typename T> inline T  acos_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01425 |             template <typename T> inline T acosh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01426 |             template <typename T> inline T  asin_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01427 |             template <typename T> inline T asinh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01428 |             template <typename T> inline T  atan_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01429 |             template <typename T> inline T atanh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01430 |             template <typename T> inline T   cos_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01431 |             template <typename T> inline T  cosh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01432 |             template <typename T> inline T   sin_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01433 |             template <typename T> inline T  sinh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01434 |             template <typename T> inline T   tan_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01435 |             template <typename T> inline T  tanh_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01436 |             template <typename T> inline T   cot_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01437 |             template <typename T> inline T   sec_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01438 |             template <typename T> inline T   csc_impl(const T  , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); } 
 01439 |  
 01440 |             template <typename T> 
 01441 |             inline bool is_integer_impl(const T& v, real_type_tag) 
 01442 |             { 
 01443 |                return std::equal_to<T>()(T(0),std::fmod(v,T(1))); 
 01444 |             } 
 01445 |  
 01446 |             template <typename T> 
 01447 |             inline bool is_integer_impl(const T&, int_type_tag) 
 01448 |             { 
 01449 |                return true; 
 01450 |             } 
 01451 |          } 
 01452 |  
 01453 |          template <typename Type> 
 01454 |          struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; }; 
 01455 |  
 01456 |          template <> struct numeric_info<int        > { enum { length = 10, size = 16, bound_length = 9 }; }; 
 01457 |          template <> struct numeric_info<float      > { enum { min_exp =  -38, max_exp =  +38 }; }; 
 01458 |          template <> struct numeric_info<double     > { enum { min_exp = -308, max_exp = +308 }; }; 
 01459 |          template <> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308 }; }; 
 01460 |  
 01461 |          template <typename T> 
 01462 |          inline int to_int32(const T v) 
 01463 |          { 
 01464 |             const typename details::number_type<T>::type num_type; 
 01465 |             return to_int32_impl(v, num_type); 
 01466 |          } 
 01467 |  
 01468 |          template <typename T> 
 01469 |          inline _int64_t to_int64(const T v) 
 01470 |          { 
 01471 |             const typename details::number_type<T>::type num_type; 
 01472 |             return to_int64_impl(v, num_type); 
 01473 |          } 
 01474 |  
 01475 |          template <typename T> 
 01476 |          inline _uint64_t to_uint64(const T v) 
 01477 |          { 
 01478 |             const typename details::number_type<T>::type num_type; 
 01479 |             return to_uint64_impl(v, num_type); 
 01480 |          } 
 01481 |  
 01482 |          template <typename T> 
 01483 |          inline bool is_nan(const T v) 
 01484 |          { 
 01485 |             const typename details::number_type<T>::type num_type; 
 01486 |             return is_nan_impl(v, num_type); 
 01487 |          } 
 01488 |  
 01489 |          template <typename T> 
 01490 |          inline T min(const T v0, const T v1) 
 01491 |          { 
 01492 |             const typename details::number_type<T>::type num_type; 
 01493 |             return min_impl(v0, v1, num_type); 
 01494 |          } 
 01495 |  
 01496 |          template <typename T> 
 01497 |          inline T max(const T v0, const T v1) 
 01498 |          { 
 01499 |             const typename details::number_type<T>::type num_type; 
 01500 |             return max_impl(v0, v1, num_type); 
 01501 |          } 
 01502 |  
 01503 |          template <typename T> 
 01504 |          inline T equal(const T v0, const T v1) 
 01505 |          { 
 01506 |             const typename details::number_type<T>::type num_type; 
 01507 |             return equal_impl(v0, v1, num_type); 
 01508 |          } 
 01509 |  
 01510 |          template <typename T> 
 01511 |          inline T nequal(const T v0, const T v1) 
 01512 |          { 
 01513 |             const typename details::number_type<T>::type num_type; 
 01514 |             return nequal_impl(v0, v1, num_type); 
 01515 |          } 
 01516 |  
 01517 |          template <typename T> 
 01518 |          inline T modulus(const T v0, const T v1) 
 01519 |          { 
 01520 |             const typename details::number_type<T>::type num_type; 
 01521 |             return modulus_impl(v0, v1, num_type); 
 01522 |          } 
 01523 |  
 01524 |          template <typename T> 
 01525 |          inline T pow(const T v0, const T v1) 
 01526 |          { 
 01527 |             const typename details::number_type<T>::type num_type; 
 01528 |             return pow_impl(v0, v1, num_type); 
 01529 |          } 
 01530 |  
 01531 |          template <typename T> 
 01532 |          inline T logn(const T v0, const T v1) 
 01533 |          { 
 01534 |             const typename details::number_type<T>::type num_type; 
 01535 |             return logn_impl(v0, v1, num_type); 
 01536 |          } 
 01537 |  
 01538 |          template <typename T> 
 01539 |          inline T root(const T v0, const T v1) 
 01540 |          { 
 01541 |             const typename details::number_type<T>::type num_type; 
 01542 |             return root_impl(v0, v1, num_type); 
 01543 |          } 
 01544 |  
 01545 |          template <typename T> 
 01546 |          inline T roundn(const T v0, const T v1) 
 01547 |          { 
 01548 |             const typename details::number_type<T>::type num_type; 
 01549 |             return roundn_impl(v0, v1, num_type); 
 01550 |          } 
 01551 |  
 01552 |          template <typename T> 
 01553 |          inline T hypot(const T v0, const T v1) 
 01554 |          { 
 01555 |             const typename details::number_type<T>::type num_type; 
 01556 |             return hypot_impl(v0, v1, num_type); 
 01557 |          } 
 01558 |  
 01559 |          template <typename T> 
 01560 |          inline T atan2(const T v0, const T v1) 
 01561 |          { 
 01562 |             const typename details::number_type<T>::type num_type; 
 01563 |             return atan2_impl(v0, v1, num_type); 
 01564 |          } 
 01565 |  
 01566 |          template <typename T> 
 01567 |          inline T shr(const T v0, const T v1) 
 01568 |          { 
 01569 |             const typename details::number_type<T>::type num_type; 
 01570 |             return shr_impl(v0, v1, num_type); 
 01571 |          } 
 01572 |  
 01573 |          template <typename T> 
 01574 |          inline T shl(const T v0, const T v1) 
 01575 |          { 
 01576 |             const typename details::number_type<T>::type num_type; 
 01577 |             return shl_impl(v0, v1, num_type); 
 01578 |          } 
 01579 |  
 01580 |          template <typename T> 
 01581 |          inline T and_opr(const T v0, const T v1) 
 01582 |          { 
 01583 |             const typename details::number_type<T>::type num_type; 
 01584 |             return and_impl(v0, v1, num_type); 
 01585 |          } 
 01586 |  
 01587 |          template <typename T> 
 01588 |          inline T nand_opr(const T v0, const T v1) 
 01589 |          { 
 01590 |             const typename details::number_type<T>::type num_type; 
 01591 |             return nand_impl(v0, v1, num_type); 
 01592 |          } 
 01593 |  
 01594 |          template <typename T> 
 01595 |          inline T or_opr(const T v0, const T v1) 
 01596 |          { 
 01597 |             const typename details::number_type<T>::type num_type; 
 01598 |             return or_impl(v0, v1, num_type); 
 01599 |          } 
 01600 |  
 01601 |          template <typename T> 
 01602 |          inline T nor_opr(const T v0, const T v1) 
 01603 |          { 
 01604 |             const typename details::number_type<T>::type num_type; 
 01605 |             return nor_impl(v0, v1, num_type); 
 01606 |          } 
 01607 |  
 01608 |          template <typename T> 
 01609 |          inline T xor_opr(const T v0, const T v1) 
 01610 |          { 
 01611 |             const typename details::number_type<T>::type num_type; 
 01612 |             return xor_impl(v0, v1, num_type); 
 01613 |          } 
 01614 |  
 01615 |          template <typename T> 
 01616 |          inline T xnor_opr(const T v0, const T v1) 
 01617 |          { 
 01618 |             const typename details::number_type<T>::type num_type; 
 01619 |             return xnor_impl(v0, v1, num_type); 
 01620 |          } 
 01621 |  
 01622 |          template <typename T> 
 01623 |          inline bool is_integer(const T v) 
 01624 |          { 
 01625 |             const typename details::number_type<T>::type num_type; 
 01626 |             return is_integer_impl(v, num_type); 
 01627 |          } 
 01628 |  
 01629 |          template <typename T, unsigned int N> 
 01630 |          struct fast_exp 
 01631 |          { 
 01632 |             static inline T result(T v) 
 01633 |             { 
 01634 |                unsigned int k = N; 
 01635 |                T l = T(1); 
 01636 |  
 01637 |                while (k) 
 01638 |                { 
 01639 |                   if (1 == (k % 2)) 
 01640 |                   { 
 01641 |                      l *= v; 
 01642 |                      --k; 
 01643 |                   } 
 01644 |  
 01645 |                   v *= v; 
 01646 |                   k /= 2; 
 01647 |                } 
 01648 |  
 01649 |                return l; 
 01650 |             } 
 01651 |          }; 
 01652 |  
 01653 |          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; } }; 
 01654 |          template <typename T> struct fast_exp<T, 9> { static inline T result(const T v) { return fast_exp<T,8>::result(v) * v; } }; 
 01655 |          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; } }; 
 01656 |          template <typename T> struct fast_exp<T, 7> { static inline T result(const T v) { return fast_exp<T,6>::result(v) * v; } }; 
 01657 |          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; } }; 
 01658 |          template <typename T> struct fast_exp<T, 5> { static inline T result(const T v) { return fast_exp<T,4>::result(v) * v; } }; 
 01659 |          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; } }; 
 01660 |          template <typename T> struct fast_exp<T, 3> { static inline T result(const T v) { return v * v * v; } }; 
 01661 |          template <typename T> struct fast_exp<T, 2> { static inline T result(const T v) { return v * v;     } }; 
 01662 |          template <typename T> struct fast_exp<T, 1> { static inline T result(const T v) { return v;         } }; 
 01663 |          template <typename T> struct fast_exp<T, 0> { static inline T result(const T  ) { return T(1);      } }; 
 01664 |  
 01665 |          #define exprtk_define_unary_function(FunctionName)        \ 
 01666 |          template <typename T>                                     \ 
 01667 |          inline T FunctionName (const T v)                         \ 
 01668 |          {                                                         \ 
 01669 |             const typename details::number_type<T>::type num_type; \ 
 01670 |             return  FunctionName##_impl(v,num_type);               \ 
 01671 |          }                                                         \ 
 01672 |  
 01673 |          exprtk_define_unary_function(abs  ) 
 01674 |          exprtk_define_unary_function(acos ) 
 01675 |          exprtk_define_unary_function(acosh) 
 01676 |          exprtk_define_unary_function(asin ) 
 01677 |          exprtk_define_unary_function(asinh) 
 01678 |          exprtk_define_unary_function(atan ) 
 01679 |          exprtk_define_unary_function(atanh) 
 01680 |          exprtk_define_unary_function(ceil ) 
 01681 |          exprtk_define_unary_function(cos  ) 
 01682 |          exprtk_define_unary_function(cosh ) 
 01683 |          exprtk_define_unary_function(exp  ) 
 01684 |          exprtk_define_unary_function(expm1) 
 01685 |          exprtk_define_unary_function(floor) 
 01686 |          exprtk_define_unary_function(log  ) 
 01687 |          exprtk_define_unary_function(log10) 
 01688 |          exprtk_define_unary_function(log2 ) 
 01689 |          exprtk_define_unary_function(log1p) 
 01690 |          exprtk_define_unary_function(neg  ) 
 01691 |          exprtk_define_unary_function(pos  ) 
 01692 |          exprtk_define_unary_function(round) 
 01693 |          exprtk_define_unary_function(sin  ) 
 01694 |          exprtk_define_unary_function(sinc ) 
 01695 |          exprtk_define_unary_function(sinh ) 
 01696 |          exprtk_define_unary_function(sqrt ) 
 01697 |          exprtk_define_unary_function(tan  ) 
 01698 |          exprtk_define_unary_function(tanh ) 
 01699 |          exprtk_define_unary_function(cot  ) 
 01700 |          exprtk_define_unary_function(sec  ) 
 01701 |          exprtk_define_unary_function(csc  ) 
 01702 |          exprtk_define_unary_function(r2d  ) 
 01703 |          exprtk_define_unary_function(d2r  ) 
 01704 |          exprtk_define_unary_function(d2g  ) 
 01705 |          exprtk_define_unary_function(g2d  ) 
 01706 |          exprtk_define_unary_function(notl ) 
 01707 |          exprtk_define_unary_function(sgn  ) 
 01708 |          exprtk_define_unary_function(erf  ) 
 01709 |          exprtk_define_unary_function(erfc ) 
 01710 |          exprtk_define_unary_function(ncdf ) 
 01711 |          exprtk_define_unary_function(frac ) 
 01712 |          exprtk_define_unary_function(trunc) 
 01713 |          #undef exprtk_define_unary_function 
 01714 |       } 
 01715 |  
 01716 |       template <typename T> 
 01717 |       inline T compute_pow10(T d, const int exponent) 
 01718 |       { 
 01719 |          static const double fract10[] = 
 01720 |          { 
 01721 |             0.0, 
 01722 |             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, 
 01723 |             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, 
 01724 |             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, 
 01725 |             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, 
 01726 |             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, 
 01727 |             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, 
 01728 |             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, 
 01729 |             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, 
 01730 |             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, 
 01731 |             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, 
 01732 |             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, 
 01733 |             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, 
 01734 |             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, 
 01735 |             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, 
 01736 |             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, 
 01737 |             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, 
 01738 |             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, 
 01739 |             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, 
 01740 |             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, 
 01741 |             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, 
 01742 |             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, 
 01743 |             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, 
 01744 |             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, 
 01745 |             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, 
 01746 |             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, 
 01747 |             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, 
 01748 |             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, 
 01749 |             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, 
 01750 |             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, 
 01751 |             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, 
 01752 |             1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308 
 01753 |          }; 
 01754 |  
 01755 |          static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double)); 
 01756 |  
 01757 |          const int e = std::abs(exponent); 
 01758 |  
 01759 |          if (exponent >= std::numeric_limits<T>::min_exponent10) 
 01760 |          { 
 01761 |             if (e < fract10_size) 
 01762 |             { 
 01763 |                if (exponent > 0) 
 01764 |                   return T(d * fract10[e]); 
 01765 |                else 
 01766 |                   return T(d / fract10[e]); 
 01767 |             } 
 01768 |             else 
 01769 |                return T(d * std::pow(10.0, 10.0 * exponent)); 
 01770 |          } 
 01771 |          else 
 01772 |          { 
 01773 |                      d /= T(fract10[           -std::numeric_limits<T>::min_exponent10]); 
 01774 |             return T(d /    fract10[-exponent + std::numeric_limits<T>::min_exponent10]); 
 01775 |          } 
 01776 |       } 
 01777 |  
 01778 |       template <typename Iterator, typename T> 
 01779 |       inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result) 
 01780 |       { 
 01781 |          if (itr == end) 
 01782 |             return false; 
 01783 |  
 01784 |          const bool negative = ('-' == (*itr)); 
 01785 |  
 01786 |          if (negative || ('+' == (*itr))) 
 01787 |          { 
 01788 |             if (end == ++itr) 
 01789 |                return false; 
 01790 |          } 
 01791 |  
 01792 |          static const uchar_t zero = static_cast<uchar_t>('0'); 
 01793 |  
 01794 |          while ((end != itr) && (zero == (*itr))) ++itr; 
 01795 |  
 01796 |          bool return_result = true; 
 01797 |          unsigned int digit = 0; 
 01798 |          const std::size_t length = static_cast<std::size_t>(std::distance(itr,end)); 
 01799 |  
 01800 |          if (length <= 4) 
 01801 |          { 
 01802 |             switch (length) 
 01803 |             { 
 01804 |                #ifdef exprtk_use_lut 
 01805 |  
 01806 |                #define exprtk_process_digit                          \ 
 01807 |                if ((digit = details::digit_table[(int)*itr++]) < 10) \ 
 01808 |                   result = result * 10 + (digit);                    \ 
 01809 |                else                                                  \ 
 01810 |                {                                                     \ 
 01811 |                   return_result = false;                             \ 
 01812 |                   break;                                             \ 
 01813 |                }                                                     \ 
 01814 |                exprtk_fallthrough                                    \ 
 01815 |  
 01816 |                #else 
 01817 |  
 01818 |                #define exprtk_process_digit        \ 
 01819 |                if ((digit = (*itr++ - zero)) < 10) \ 
 01820 |                   result = result * T(10) + digit; \ 
 01821 |                else                                \ 
 01822 |                {                                   \ 
 01823 |                   return_result = false;           \ 
 01824 |                   break;                           \ 
 01825 |                }                                   \ 
 01826 |                exprtk_fallthrough                  \ 
 01827 |  
 01828 |                #endif 
 01829 |  
 01830 |                case 4 : exprtk_process_digit 
 01831 |                case 3 : exprtk_process_digit 
 01832 |                case 2 : exprtk_process_digit 
 01833 |                case 1 : if ((digit = (*itr - zero))>= 10) 
 01834 |                         { 
 01835 |                            digit = 0; 
 01836 |                            return_result = false; 
 01837 |                         } 
 01838 |  
 01839 |                #undef exprtk_process_digit 
 01840 |             } 
 01841 |          } 
 01842 |          else 
 01843 |             return_result = false; 
 01844 |  
 01845 |          if (length && return_result) 
 01846 |          { 
 01847 |             result = result * 10 + static_cast<T>(digit); 
 01848 |             ++itr; 
 01849 |          } 
 01850 |  
 01851 |          result = negative ? -result : result; 
 01852 |          return return_result; 
 01853 |       } 
 01854 |  
 01855 |       template <typename Iterator, typename T> 
 01856 |       static inline bool parse_nan(Iterator& itr, const Iterator end, T& t) 
 01857 |       { 
 01858 |          typedef typename std::iterator_traits<Iterator>::value_type type; 
 01859 |  
 01860 |          static const std::size_t nan_length = 3; 
 01861 |  
 01862 |          if (std::distance(itr,end) != static_cast<int>(nan_length)) 
 01863 |             return false; 
 01864 |  
 01865 |          if (static_cast<type>('n') == (*itr)) 
 01866 |          { 
 01867 |             if ( 
 01868 |                  (static_cast<type>('a') != *(itr + 1)) || 
 01869 |                  (static_cast<type>('n') != *(itr + 2)) 
 01870 |                ) 
 01871 |             { 
 01872 |                return false; 
 01873 |             } 
 01874 |          } 
 01875 |          else if ( 
 01876 |                    (static_cast<type>('A') != *(itr + 1)) || 
 01877 |                    (static_cast<type>('N') != *(itr + 2)) 
 01878 |                  ) 
 01879 |          { 
 01880 |             return false; 
 01881 |          } 
 01882 |  
 01883 |          t = std::numeric_limits<T>::quiet_NaN(); 
 01884 |  
 01885 |          return true; 
 01886 |       } 
 01887 |  
 01888 |       template <typename Iterator, typename T> 
 01889 |       static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, const bool negative) 
 01890 |       { 
 01891 |          static const char_t inf_uc[] = "INFINITY" 
 01892 |          static const char_t inf_lc[] = "infinity" 
 01893 |          static const std::size_t inf_length = 8; 
 01894 |  
 01895 |          const std::size_t length = static_cast<std::size_t>(std::distance(itr,end)); 
 01896 |  
 01897 |          if ((3 != length) && (inf_length != length)) 
 01898 |             return false; 
 01899 |  
 01900 |          char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc; 
 01901 |  
 01902 |          while (end != itr) 
 01903 |          { 
 01904 |             if (*inf_itr == static_cast<char_t>(*itr)) 
 01905 |             { 
 01906 |                ++itr; 
 01907 |                ++inf_itr; 
 01908 |                continue; 
 01909 |             } 
 01910 |             else 
 01911 |                return false; 
 01912 |          } 
 01913 |  
 01914 |          if (negative) 
 01915 |             t = -std::numeric_limits<T>::infinity(); 
 01916 |          else 
 01917 |             t =  std::numeric_limits<T>::infinity(); 
 01918 |  
 01919 |          return true; 
 01920 |       } 
 01921 |  
 01922 |       template <typename T> 
 01923 |       inline bool valid_exponent(const int exponent, numeric::details::real_type_tag) 
 01924 |       { 
 01925 |          using namespace details::numeric; 
 01926 |          return (numeric_info<T>::min_exp <= exponent) && (exponent <= numeric_info<T>::max_exp); 
 01927 |       } 
 01928 |  
 01929 |       template <typename Iterator, typename T> 
 01930 |       inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t, numeric::details::real_type_tag) 
 01931 |       { 
 01932 |          if (end == itr_external) return false; 
 01933 |  
 01934 |          Iterator itr = itr_external; 
 01935 |  
 01936 |          T d = T(0); 
 01937 |  
 01938 |          const bool negative = ('-' == (*itr)); 
 01939 |  
 01940 |          if (negative || '+' == (*itr)) 
 01941 |          { 
 01942 |             if (end == ++itr) 
 01943 |                return false; 
 01944 |          } 
 01945 |  
 01946 |          bool instate = false; 
 01947 |  
 01948 |          static const char_t zero = static_cast<uchar_t>('0'); 
 01949 |  
 01950 |          #define parse_digit_1(d)          \ 
 01951 |          if ((digit = (*itr - zero)) < 10) \ 
 01952 |             { d = d * T(10) + digit; }     \ 
 01953 |          else                              \ 
 01954 |             { break; }                     \ 
 01955 |          if (end == ++itr) break;          \ 
 01956 |  
 01957 |          #define parse_digit_2(d)          \ 
 01958 |          if ((digit = (*itr - zero)) < 10) \ 
 01959 |             { d = d * T(10) + digit; }     \ 
 01960 |          else                              \ 
 01961 |             { break; }                     \ 
 01962 |             ++itr;                         \ 
 01963 |  
 01964 |          if ('.' != (*itr)) 
 01965 |          { 
 01966 |             const Iterator curr = itr; 
 01967 |  
 01968 |             while ((end != itr) && (zero == (*itr))) ++itr; 
 01969 |  
 01970 |             while (end != itr) 
 01971 |             { 
 01972 |                unsigned int digit; 
 01973 |                parse_digit_1(d) 
 01974 |                parse_digit_1(d) 
 01975 |                parse_digit_2(d) 
 01976 |             } 
 01977 |  
 01978 |             if (curr != itr) instate = true; 
 01979 |          } 
 01980 |  
 01981 |          int exponent = 0; 
 01982 |  
 01983 |          if (end != itr) 
 01984 |          { 
 01985 |             if ('.' == (*itr)) 
 01986 |             { 
 01987 |                const Iterator curr = ++itr; 
 01988 |                T tmp_d = T(0); 
 01989 |  
 01990 |                while (end != itr) 
 01991 |                { 
 01992 |                   unsigned int digit; 
 01993 |                   parse_digit_1(tmp_d) 
 01994 |                   parse_digit_1(tmp_d) 
 01995 |                   parse_digit_2(tmp_d) 
 01996 |                } 
 01997 |  
 01998 |                if (curr != itr) 
 01999 |                { 
 02000 |                   instate = true; 
 02001 |  
 02002 |                   const int frac_exponent = static_cast<int>(-std::distance(curr, itr)); 
 02003 |  
 02004 |                   if (!valid_exponent<T>(frac_exponent, numeric::details::real_type_tag())) 
 02005 |                      return false; 
 02006 |  
 02007 |                   d += compute_pow10(tmp_d, frac_exponent); 
 02008 |                } 
 02009 |  
 02010 |                #undef parse_digit_1 
 02011 |                #undef parse_digit_2 
 02012 |             } 
 02013 |  
 02014 |             if (end != itr) 
 02015 |             { 
 02016 |                typename std::iterator_traits<Iterator>::value_type c = (*itr); 
 02017 |  
 02018 |                if (('e' == c) || ('E' == c)) 
 02019 |                { 
 02020 |                   int exp = 0; 
 02021 |  
 02022 |                   if (!details::string_to_type_converter_impl_ref(++itr, end, exp)) 
 02023 |                   { 
 02024 |                      if (end == itr) 
 02025 |                         return false; 
 02026 |                      else 
 02027 |                         c = (*itr); 
 02028 |                   } 
 02029 |  
 02030 |                   exponent += exp; 
 02031 |                } 
 02032 |  
 02033 |                if (end != itr) 
 02034 |                { 
 02035 |                   if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c)) 
 02036 |                      ++itr; 
 02037 |                   else if ('#' == c) 
 02038 |                   { 
 02039 |                      if (end == ++itr) 
 02040 |                         return false; 
 02041 |                      else if (('I' <= (*itr)) && ((*itr) <= 'n')) 
 02042 |                      { 
 02043 |                         if (('i' == (*itr)) || ('I' == (*itr))) 
 02044 |                         { 
 02045 |                            return parse_inf(itr, end, t, negative); 
 02046 |                         } 
 02047 |                         else if (('n' == (*itr)) || ('N' == (*itr))) 
 02048 |                         { 
 02049 |                            return parse_nan(itr, end, t); 
 02050 |                         } 
 02051 |                         else 
 02052 |                            return false; 
 02053 |                      } 
 02054 |                      else 
 02055 |                         return false; 
 02056 |                   } 
 02057 |                   else if (('I' <= (*itr)) && ((*itr) <= 'n')) 
 02058 |                   { 
 02059 |                      if (('i' == (*itr)) || ('I' == (*itr))) 
 02060 |                      { 
 02061 |                         return parse_inf(itr, end, t, negative); 
 02062 |                      } 
 02063 |                      else if (('n' == (*itr)) || ('N' == (*itr))) 
 02064 |                      { 
 02065 |                         return parse_nan(itr, end, t); 
 02066 |                      } 
 02067 |                      else 
 02068 |                         return false; 
 02069 |                   } 
 02070 |                   else 
 02071 |                      return false; 
 02072 |                } 
 02073 |             } 
 02074 |          } 
 02075 |  
 02076 |          if ((end != itr) || (!instate)) 
 02077 |             return false; 
 02078 |          else if (!valid_exponent<T>(exponent, numeric::details::real_type_tag())) 
 02079 |             return false; 
 02080 |          else if (exponent) 
 02081 |             d = compute_pow10(d,exponent); 
 02082 |  
 02083 |          t = static_cast<T>((negative) ? -d : d); 
 02084 |          return true; 
 02085 |       } 
 02086 |  
 02087 |       template <typename T> 
 02088 |       inline bool string_to_real(const std::string& s, T& t) 
 02089 |       { 
 02090 |          const typename numeric::details::number_type<T>::type num_type; 
 02091 |  
 02092 |          char_cptr begin = s.data(); 
 02093 |          char_cptr end   = s.data() + s.size(); 
 02094 |  
 02095 |          return string_to_real(begin, end, t, num_type); 
 02096 |       } 
 02097 |  
 02098 |       template <typename T> 
 02099 |       struct functor_t 
 02100 |       { 
 02101 |          /* 
 02102 |             Note: The following definitions for Type, may require tweaking 
 02103 |                   based on the compiler and target architecture. The benchmark 
 02104 |                   should provide enough information to make the right choice. 
 02105 |          */ 
 02106 |          //typedef T Type; 
 02107 |          //typedef const T Type; 
 02108 |          typedef const T& Type; 
 02109 |          typedef       T& RefType; 
 02110 |          typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3); 
 02111 |          typedef T (*tfunc_t)(Type t0, Type t1, Type t2); 
 02112 |          typedef T (*bfunc_t)(Type t0, Type t1); 
 02113 |          typedef T (*ufunc_t)(Type t0); 
 02114 |       }; 
 02115 |  
 02116 |    } // namespace details 
 02117 |  
 02118 |    struct loop_runtime_check 
 02119 |    { 
 02120 |       enum loop_types 
 02121 |       { 
 02122 |          e_invalid           = 0, 
 02123 |          e_for_loop          = 1, 
 02124 |          e_while_loop        = 2, 
 02125 |          e_repeat_until_loop = 4, 
 02126 |          e_all_loops         = 7 
 02127 |       }; 
 02128 |  
 02129 |       enum violation_type 
 02130 |       { 
 02131 |           e_unknown         = 0, 
 02132 |           e_iteration_count = 1, 
 02133 |           e_timeout         = 2 
 02134 |       }; 
 02135 |  
 02136 |       loop_types loop_set; 
 02137 |  
 02138 |       loop_runtime_check() 
 02139 |       : loop_set(e_invalid) 
 02140 |       , max_loop_iterations(0) 
 02141 |       {} 
 02142 |  
 02143 |       details::_uint64_t max_loop_iterations; 
 02144 |  
 02145 |       struct violation_context 
 02146 |       { 
 02147 |          loop_types loop; 
 02148 |          violation_type violation; 
 02149 |          details::_uint64_t iteration_count; 
 02150 |       }; 
 02151 |  
 02152 |       virtual bool check() 
 02153 |       { 
 02154 |          return true; 
 02155 |       } 
 02156 |  
 02157 |       virtual void handle_runtime_violation(const violation_context&) 
 02158 |       { 
 02159 |          throw std::runtime_error("ExprTk Loop runtime violation."); 
 02160 |       } 
 02161 |  
 02162 |       virtual ~loop_runtime_check() 
 02163 |       {} 
 02164 |    }; 
 02165 |  
 02166 |    typedef loop_runtime_check* loop_runtime_check_ptr; 
 02167 |  
 02168 |    struct vector_access_runtime_check 
 02169 |    { 
 02170 |       struct violation_context 
 02171 |       { 
 02172 |          void* base_ptr; 
 02173 |          void* end_ptr; 
 02174 |          void* access_ptr; 
 02175 |          std::size_t type_size; 
 02176 |       }; 
 02177 |  
 02178 |       virtual ~vector_access_runtime_check() 
 02179 |       {} 
 02180 |  
 02181 |       virtual bool handle_runtime_violation(violation_context& /*context*/) 
 02182 |       { 
 02183 |          throw std::runtime_error("ExprTk runtime vector access violation."); 
 02184 |          #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 02185 |          return false; 
 02186 |          #endif 
 02187 |       } 
 02188 |    }; 
 02189 |  
 02190 |    typedef vector_access_runtime_check* vector_access_runtime_check_ptr; 
 02191 |  
 02192 |    struct assert_check 
 02193 |    { 
 02194 |       struct assert_context 
 02195 |       { 
 02196 |          std::string condition; 
 02197 |          std::string message; 
 02198 |          std::string id; 
 02199 |          std::size_t offet; 
 02200 |       }; 
 02201 |  
 02202 |       virtual ~assert_check() 
 02203 |       {} 
 02204 |  
 02205 |       virtual void handle_assert(const assert_context& /*context*/) 
 02206 |       { 
 02207 |       } 
 02208 |    }; 
 02209 |  
 02210 |    typedef assert_check* assert_check_ptr; 
 02211 |  
 02212 |    struct compilation_check 
 02213 |    { 
 02214 |       struct compilation_context 
 02215 |       { 
 02216 |          std::string error_message; 
 02217 |       }; 
 02218 |  
 02219 |       virtual bool continue_compilation(compilation_context& /*context*/) = 0; 
 02220 |  
 02221 |       virtual ~compilation_check() 
 02222 |       {} 
 02223 |    }; 
 02224 |  
 02225 |    typedef compilation_check* compilation_check_ptr; 
 02226 |  
 02227 |    namespace lexer 
 02228 |    { 
 02229 |       struct token 
 02230 |       { 
 02231 |          enum token_type 
 02232 |          { 
 02233 |             e_none        =   0, e_error       =   1, e_err_symbol  =   2, 
 02234 |             e_err_number  =   3, e_err_string  =   4, e_err_sfunc   =   5, 
 02235 |             e_eof         =   6, e_number      =   7, e_symbol      =   8, 
 02236 |             e_string      =   9, e_assign      =  10, e_addass      =  11, 
 02237 |             e_subass      =  12, e_mulass      =  13, e_divass      =  14, 
 02238 |             e_modass      =  15, e_shr         =  16, e_shl         =  17, 
 02239 |             e_lte         =  18, e_ne          =  19, e_gte         =  20, 
 02240 |             e_swap        =  21, e_lt          = '<', e_gt          = '>', 
 02241 |             e_eq          = '=', e_rbracket    = ')', e_lbracket    = '(', 
 02242 |             e_rsqrbracket = ']', e_lsqrbracket = '[', e_rcrlbracket = '}', 
 02243 |             e_lcrlbracket = '{', e_comma       = ',', e_add         = '+', 
 02244 |             e_sub         = '-', e_div         = '/', e_mul         = '*', 
 02245 |             e_mod         = '%', e_pow         = '^', e_colon       = ':', 
 02246 |             e_ternary     = '?' 
 02247 |          }; 
 02248 |  
 02249 |          token() 
 02250 |          : type(e_none) 
 02251 |          , value("") 
 02252 |          , position(std::numeric_limits<std::size_t>::max()) 
 02253 |          {} 
 02254 |  
 02255 |          void clear() 
 02256 |          { 
 02257 |             type     = e_none; 
 02258 |             value    = "" 
 02259 |             position = std::numeric_limits<std::size_t>::max(); 
 02260 |          } 
 02261 |  
 02262 |          template <typename Iterator> 
 02263 |          inline token& set_operator(const token_type tt, 
 02264 |                                     const Iterator begin, const Iterator end, 
 02265 |                                     const Iterator base_begin = Iterator(0)) 
 02266 |          { 
 02267 |             type = tt; 
 02268 |             value.assign(begin,end); 
 02269 |             if (base_begin) 
 02270 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02271 |             return (*this); 
 02272 |          } 
 02273 |  
 02274 |          template <typename Iterator> 
 02275 |          inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0)) 
 02276 |          { 
 02277 |             type = e_symbol; 
 02278 |             value.assign(begin,end); 
 02279 |             if (base_begin) 
 02280 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02281 |             return (*this); 
 02282 |          } 
 02283 |  
 02284 |          template <typename Iterator> 
 02285 |          inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0)) 
 02286 |          { 
 02287 |             type = e_number; 
 02288 |             value.assign(begin,end); 
 02289 |             if (base_begin) 
 02290 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02291 |             return (*this); 
 02292 |          } 
 02293 |  
 02294 |          template <typename Iterator> 
 02295 |          inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0)) 
 02296 |          { 
 02297 |             type = e_string; 
 02298 |             value.assign(begin,end); 
 02299 |             if (base_begin) 
 02300 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02301 |             return (*this); 
 02302 |          } 
 02303 |  
 02304 |          inline token& set_string(const std::string& s, const std::size_t p) 
 02305 |          { 
 02306 |             type     = e_string; 
 02307 |             value    = s; 
 02308 |             position = p; 
 02309 |             return (*this); 
 02310 |          } 
 02311 |  
 02312 |          template <typename Iterator> 
 02313 |          inline token& set_error(const token_type et, 
 02314 |                                  const Iterator begin, const Iterator end, 
 02315 |                                  const Iterator base_begin = Iterator(0)) 
 02316 |          { 
 02317 |             if ( 
 02318 |                  (e_error      == et) || 
 02319 |                  (e_err_symbol == et) || 
 02320 |                  (e_err_number == et) || 
 02321 |                  (e_err_string == et) || 
 02322 |                  (e_err_sfunc  == et) 
 02323 |                ) 
 02324 |             { 
 02325 |                type = et; 
 02326 |             } 
 02327 |             else 
 02328 |                type = e_error; 
 02329 |  
 02330 |             value.assign(begin,end); 
 02331 |  
 02332 |             if (base_begin) 
 02333 |                position = static_cast<std::size_t>(std::distance(base_begin,begin)); 
 02334 |  
 02335 |             return (*this); 
 02336 |          } 
 02337 |  
 02338 |          static inline std::string to_str(token_type t) 
 02339 |          { 
 02340 |             switch (t) 
 02341 |             { 
 02342 |                case e_none        : return "NONE" 
 02343 |                case e_error       : return "ERROR" 
 02344 |                case e_err_symbol  : return "ERROR_SYMBOL" 
 02345 |                case e_err_number  : return "ERROR_NUMBER" 
 02346 |                case e_err_string  : return "ERROR_STRING" 
 02347 |                case e_eof         : return "EOF" 
 02348 |                case e_number      : return "NUMBER" 
 02349 |                case e_symbol      : return "SYMBOL" 
 02350 |                case e_string      : return "STRING" 
 02351 |                case e_assign      : return ":=" 
 02352 |                case e_addass      : return "+=" 
 02353 |                case e_subass      : return "-=" 
 02354 |                case e_mulass      : return "*=" 
 02355 |                case e_divass      : return "/=" 
 02356 |                case e_modass      : return "%=" 
 02357 |                case e_shr         : return ">>" 
 02358 |                case e_shl         : return "<<" 
 02359 |                case e_lte         : return "<=" 
 02360 |                case e_ne          : return "!=" 
 02361 |                case e_gte         : return ">=" 
 02362 |                case e_lt          : return "<" 
 02363 |                case e_gt          : return ">" 
 02364 |                case e_eq          : return "=" 
 02365 |                case e_rbracket    : return ")" 
 02366 |                case e_lbracket    : return "(" 
 02367 |                case e_rsqrbracket : return "]" 
 02368 |                case e_lsqrbracket : return "[" 
 02369 |                case e_rcrlbracket : return "}" 
 02370 |                case e_lcrlbracket : return "{" 
 02371 |                case e_comma       : return "," 
 02372 |                case e_add         : return "+" 
 02373 |                case e_sub         : return "-" 
 02374 |                case e_div         : return "/" 
 02375 |                case e_mul         : return "*" 
 02376 |                case e_mod         : return "%" 
 02377 |                case e_pow         : return "^" 
 02378 |                case e_colon       : return ":" 
 02379 |                case e_ternary     : return "?" 
 02380 |                case e_swap        : return "<=>" 
 02381 |                default            : return "UNKNOWN" 
 02382 |             } 
 02383 |          } 
 02384 |  
 02385 |          static inline std::string seperator_to_str(const token_type t) 
 02386 |          { 
 02387 |             switch (t) 
 02388 |             { 
 02389 |                case e_comma : return "," 
 02390 |                case e_colon : return ":" 
 02391 |                case e_eof   : return "" 
 02392 |                default      : return "UNKNOWN" 
 02393 |             } 
 02394 |  
 02395 |             #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 02396 |             return "UNKNOWN" 
 02397 |             #endif 
 02398 |          } 
 02399 |  
 02400 |          inline bool is_error() const 
 02401 |          { 
 02402 |             return ( 
 02403 |                      (e_error      == type) || 
 02404 |                      (e_err_symbol == type) || 
 02405 |                      (e_err_number == type) || 
 02406 |                      (e_err_string == type) || 
 02407 |                      (e_err_sfunc  == type) 
 02408 |                    ); 
 02409 |          } 
 02410 |  
 02411 |          token_type type; 
 02412 |          std::string value; 
 02413 |          std::size_t position; 
 02414 |       }; 
 02415 |  
 02416 |       class generator 
 02417 |       { 
 02418 |       public: 
 02419 |  
 02420 |          typedef token token_t; 
 02421 |          typedef std::vector<token_t> token_list_t; 
 02422 |          typedef token_list_t::iterator token_list_itr_t; 
 02423 |          typedef details::char_t char_t; 
 02424 |  
 02425 |          generator() 
 02426 |          : base_itr_(0) 
 02427 |          , s_itr_   (0) 
 02428 |          , s_end_   (0) 
 02429 |          { 
 02430 |             clear(); 
 02431 |          } 
 02432 |  
 02433 |          inline void clear() 
 02434 |          { 
 02435 |             base_itr_ = 0; 
 02436 |             s_itr_    = 0; 
 02437 |             s_end_    = 0; 
 02438 |             token_list_.clear(); 
 02439 |             token_itr_ = token_list_.end(); 
 02440 |             store_token_itr_ = token_list_.end(); 
 02441 |          } 
 02442 |  
 02443 |          inline bool process(const std::string& str) 
 02444 |          { 
 02445 |             base_itr_ = str.data(); 
 02446 |             s_itr_    = str.data(); 
 02447 |             s_end_    = str.data() + str.size(); 
 02448 |  
 02449 |             eof_token_.set_operator(token_t::e_eof, s_end_, s_end_, base_itr_); 
 02450 |             token_list_.clear(); 
 02451 |  
 02452 |             while (!is_end(s_itr_)) 
 02453 |             { 
 02454 |                scan_token(); 
 02455 |  
 02456 |                if (!token_list_.empty() && token_list_.back().is_error()) 
 02457 |                   return false; 
 02458 |             } 
 02459 |  
 02460 |             return true; 
 02461 |          } 
 02462 |  
 02463 |          inline bool empty() const 
 02464 |          { 
 02465 |             return token_list_.empty(); 
 02466 |          } 
 02467 |  
 02468 |          inline std::size_t size() const 
 02469 |          { 
 02470 |             return token_list_.size(); 
 02471 |          } 
 02472 |  
 02473 |          inline void begin() 
 02474 |          { 
 02475 |             token_itr_ = token_list_.begin(); 
 02476 |             store_token_itr_ = token_list_.begin(); 
 02477 |          } 
 02478 |  
 02479 |          inline void store() 
 02480 |          { 
 02481 |             store_token_itr_ = token_itr_; 
 02482 |          } 
 02483 |  
 02484 |          inline void restore() 
 02485 |          { 
 02486 |             token_itr_ = store_token_itr_; 
 02487 |          } 
 02488 |  
 02489 |          inline token_t& next_token() 
 02490 |          { 
 02491 |             if (token_list_.end() != token_itr_) 
 02492 |             { 
 02493 |                return *token_itr_++; 
 02494 |             } 
 02495 |             else 
 02496 |                return eof_token_; 
 02497 |          } 
 02498 |  
 02499 |          inline token_t& peek_next_token() 
 02500 |          { 
 02501 |             if (token_list_.end() != token_itr_) 
 02502 |             { 
 02503 |                return *token_itr_; 
 02504 |             } 
 02505 |             else 
 02506 |                return eof_token_; 
 02507 |          } 
 02508 |  
 02509 |          inline token_t& operator[](const std::size_t& index) 
 02510 |          { 
 02511 |             if (index < token_list_.size()) 
 02512 |             { 
 02513 |                return token_list_[index]; 
 02514 |             } 
 02515 |             else 
 02516 |                return eof_token_; 
 02517 |          } 
 02518 |  
 02519 |          inline token_t operator[](const std::size_t& index) const 
 02520 |          { 
 02521 |             if (index < token_list_.size()) 
 02522 |             { 
 02523 |                return token_list_[index]; 
 02524 |             } 
 02525 |             else 
 02526 |                return eof_token_; 
 02527 |          } 
 02528 |  
 02529 |          inline bool finished() const 
 02530 |          { 
 02531 |             return (token_list_.end() == token_itr_); 
 02532 |          } 
 02533 |  
 02534 |          inline void insert_front(token_t::token_type tk_type) 
 02535 |          { 
 02536 |             if ( 
 02537 |                  !token_list_.empty() && 
 02538 |                  (token_list_.end() != token_itr_) 
 02539 |                ) 
 02540 |             { 
 02541 |                token_t t = *token_itr_; 
 02542 |  
 02543 |                t.type     = tk_type; 
 02544 |                token_itr_ = token_list_.insert(token_itr_,t); 
 02545 |             } 
 02546 |          } 
 02547 |  
 02548 |          inline std::string substr(const std::size_t& begin, const std::size_t& end) const 
 02549 |          { 
 02550 |             const details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_; 
 02551 |             const details::char_cptr end_itr   = ((base_itr_ + end  ) < s_end_) ? (base_itr_ + end  ) : s_end_; 
 02552 |  
 02553 |             return std::string(begin_itr,end_itr); 
 02554 |          } 
 02555 |  
 02556 |          inline std::string remaining() const 
 02557 |          { 
 02558 |             if (finished()) 
 02559 |                return "" 
 02560 |             else if (token_list_.begin() != token_itr_) 
 02561 |                return std::string(base_itr_ + (token_itr_ - 1)->position, s_end_); 
 02562 |             else 
 02563 |                return std::string(base_itr_ + token_itr_->position, s_end_); 
 02564 |          } 
 02565 |  
 02566 |       private: 
 02567 |  
 02568 |          inline bool is_end(details::char_cptr itr) const 
 02569 |          { 
 02570 |             return (s_end_ == itr); 
 02571 |          } 
 02572 |  
 02573 |          #ifndef exprtk_disable_comments 
 02574 |          inline bool is_comment_start(details::char_cptr itr) const 
 02575 |          { 
 02576 |             const char_t c0 = *(itr + 0); 
 02577 |             const char_t c1 = *(itr + 1); 
 02578 |  
 02579 |             if ('#' == c0) 
 02580 |                return true; 
 02581 |             else if (!is_end(itr + 1)) 
 02582 |             { 
 02583 |                if (('/' == c0) && ('/' == c1)) return true; 
 02584 |                if (('/' == c0) && ('*' == c1)) return true; 
 02585 |             } 
 02586 |             return false; 
 02587 |          } 
 02588 |          #else 
 02589 |          inline bool is_comment_start(details::char_cptr) const 
 02590 |          { 
 02591 |             return false; 
 02592 |          } 
 02593 |          #endif 
 02594 |  
 02595 |          inline void skip_whitespace() 
 02596 |          { 
 02597 |             while (!is_end(s_itr_) && details::is_whitespace(*s_itr_)) 
 02598 |             { 
 02599 |                ++s_itr_; 
 02600 |             } 
 02601 |          } 
 02602 |  
 02603 |          inline void skip_comments() 
 02604 |          { 
 02605 |             #ifndef exprtk_disable_comments 
 02606 |             // The following comment styles are supported: 
 02607 |             // 1. // .... \n 
 02608 |             // 2. #  .... \n 
 02609 |             // 3. /* .... */ 
 02610 |             struct test 
 02611 |             { 
 02612 |                static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr) 
 02613 |                { 
 02614 |                   mode = 0; 
 02615 |                   if      ('#' == c0)    { mode = 1; incr = 1; } 
 02616 |                   else if ('/' == c0) 
 02617 |                   { 
 02618 |                      if      ('/' == c1) { mode = 1; incr = 2; } 
 02619 |                      else if ('*' == c1) { mode = 2; incr = 2; } 
 02620 |                   } 
 02621 |                   return (0 != mode); 
 02622 |                } 
 02623 |  
 02624 |                static inline bool comment_end(const char_t c0, const char_t c1, int& mode) 
 02625 |                { 
 02626 |                   if ( 
 02627 |                        ((1 == mode) && ('\n' == c0)) || 
 02628 |                        ((2 == mode) && ( '*' == c0) && ('/' == c1)) 
 02629 |                      ) 
 02630 |                   { 
 02631 |                      mode = 0; 
 02632 |                      return true; 
 02633 |                   } 
 02634 |                   else 
 02635 |                      return false; 
 02636 |                } 
 02637 |             }; 
 02638 |  
 02639 |             int mode      = 0; 
 02640 |             int increment = 0; 
 02641 |  
 02642 |             if (is_end(s_itr_)) 
 02643 |                return; 
 02644 |             else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment)) 
 02645 |                return; 
 02646 |  
 02647 |             details::char_cptr cmt_start = s_itr_; 
 02648 |  
 02649 |             s_itr_ += increment; 
 02650 |  
 02651 |             while (!is_end(s_itr_)) 
 02652 |             { 
 02653 |                if ((1 == mode) && test::comment_end(*s_itr_, 0, mode)) 
 02654 |                { 
 02655 |                   ++s_itr_; 
 02656 |                   return; 
 02657 |                } 
 02658 |  
 02659 |                if ((2 == mode)) 
 02660 |                { 
 02661 |                   if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode)) 
 02662 |                   { 
 02663 |                      s_itr_ += 2; 
 02664 |                      return; 
 02665 |                   } 
 02666 |                } 
 02667 |  
 02668 |                ++s_itr_; 
 02669 |             } 
 02670 |  
 02671 |             if (2 == mode) 
 02672 |             { 
 02673 |                token_t t; 
 02674 |                t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_); 
 02675 |                token_list_.push_back(t); 
 02676 |             } 
 02677 |             #endif 
 02678 |          } 
 02679 |  
 02680 |          inline bool next_is_digit(const details::char_cptr itr) const 
 02681 |          { 
 02682 |             return ((itr + 1) != s_end_) && 
 02683 |                    details::is_digit(*(itr + 1)); 
 02684 |          } 
 02685 |  
 02686 |          inline void scan_token() 
 02687 |          { 
 02688 |             const char_t c = *s_itr_; 
 02689 |  
 02690 |             if (details::is_whitespace(c)) 
 02691 |             { 
 02692 |                skip_whitespace(); 
 02693 |                return; 
 02694 |             } 
 02695 |             else if (is_comment_start(s_itr_)) 
 02696 |             { 
 02697 |                skip_comments(); 
 02698 |                return; 
 02699 |             } 
 02700 |             else if (details::is_operator_char(c)) 
 02701 |             { 
 02702 |                scan_operator(); 
 02703 |                return; 
 02704 |             } 
 02705 |             else if (details::is_letter(c)) 
 02706 |             { 
 02707 |                scan_symbol(); 
 02708 |                return; 
 02709 |             } 
 02710 |             else if (('.' == c) && !next_is_digit(s_itr_)) 
 02711 |             { 
 02712 |                scan_operator(); 
 02713 |                return; 
 02714 |             } 
 02715 |             else if (details::is_digit(c) || ('.' == c)) 
 02716 |             { 
 02717 |                scan_number(); 
 02718 |                return; 
 02719 |             } 
 02720 |             else if ('$' == c) 
 02721 |             { 
 02722 |                scan_special_function(); 
 02723 |                return; 
 02724 |             } 
 02725 |             #ifndef exprtk_disable_string_capabilities 
 02726 |             else if ('\'' == c) 
 02727 |             { 
 02728 |                scan_string(); 
 02729 |                return; 
 02730 |             } 
 02731 |             #endif 
 02732 |             else if ('~' == c) 
 02733 |             { 
 02734 |                token_t t; 
 02735 |                t.set_symbol(s_itr_, s_itr_ + 1, base_itr_); 
 02736 |                token_list_.push_back(t); 
 02737 |                ++s_itr_; 
 02738 |                return; 
 02739 |             } 
 02740 |             else 
 02741 |             { 
 02742 |                token_t t; 
 02743 |                t.set_error(token::e_error, s_itr_, s_itr_ + 2, base_itr_); 
 02744 |                token_list_.push_back(t); 
 02745 |                ++s_itr_; 
 02746 |             } 
 02747 |          } 
 02748 |  
 02749 |          inline void scan_operator() 
 02750 |          { 
 02751 |             token_t t; 
 02752 |  
 02753 |             const char_t c0 = s_itr_[0]; 
 02754 |  
 02755 |             if (!is_end(s_itr_ + 1)) 
 02756 |             { 
 02757 |                const char_t c1 = s_itr_[1]; 
 02758 |  
 02759 |                if (!is_end(s_itr_ + 2)) 
 02760 |                { 
 02761 |                   const char_t c2 = s_itr_[2]; 
 02762 |  
 02763 |                   if ((c0 == '<') && (c1 == '=') && (c2 == '>')) 
 02764 |                   { 
 02765 |                      t.set_operator(token_t::e_swap, s_itr_, s_itr_ + 3, base_itr_); 
 02766 |                      token_list_.push_back(t); 
 02767 |                      s_itr_ += 3; 
 02768 |                      return; 
 02769 |                   } 
 02770 |                } 
 02771 |  
 02772 |                token_t::token_type ttype = token_t::e_none; 
 02773 |  
 02774 |                if      ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte; 
 02775 |                else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte; 
 02776 |                else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne; 
 02777 |                else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne; 
 02778 |                else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq; 
 02779 |                else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign; 
 02780 |                else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl; 
 02781 |                else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr; 
 02782 |                else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass; 
 02783 |                else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass; 
 02784 |                else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass; 
 02785 |                else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass; 
 02786 |                else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass; 
 02787 |  
 02788 |                if (token_t::e_none != ttype) 
 02789 |                { 
 02790 |                   t.set_operator(ttype, s_itr_, s_itr_ + 2, base_itr_); 
 02791 |                   token_list_.push_back(t); 
 02792 |                   s_itr_ += 2; 
 02793 |                   return; 
 02794 |                } 
 02795 |             } 
 02796 |  
 02797 |             if ('<' == c0) 
 02798 |                t.set_operator(token_t::e_lt , s_itr_, s_itr_ + 1, base_itr_); 
 02799 |             else if ('>' == c0) 
 02800 |                t.set_operator(token_t::e_gt , s_itr_, s_itr_ + 1, base_itr_); 
 02801 |             else if (';' == c0) 
 02802 |                t.set_operator(token_t::e_eof, s_itr_, s_itr_ + 1, base_itr_); 
 02803 |             else if ('&' == c0) 
 02804 |                t.set_symbol(s_itr_, s_itr_ + 1, base_itr_); 
 02805 |             else if ('|' == c0) 
 02806 |                t.set_symbol(s_itr_, s_itr_ + 1, base_itr_); 
 02807 |             else 
 02808 |                t.set_operator(token_t::token_type(c0), s_itr_, s_itr_ + 1, base_itr_); 
 02809 |  
 02810 |             token_list_.push_back(t); 
 02811 |             ++s_itr_; 
 02812 |          } 
 02813 |  
 02814 |          inline void scan_symbol() 
 02815 |          { 
 02816 |             details::char_cptr initial_itr = s_itr_; 
 02817 |  
 02818 |             while (!is_end(s_itr_)) 
 02819 |             { 
 02820 |                if (!details::is_letter_or_digit(*s_itr_) && ('_' != (*s_itr_))) 
 02821 |                { 
 02822 |                   if ('.' != (*s_itr_)) 
 02823 |                      break; 
 02824 |                   /* 
 02825 |                      Permit symbols that contain a 'dot' 
 02826 |                      Allowed   : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123 
 02827 |                      Disallowed: .abc, abc.<white-space>, abc.<eof>, abc.<operator +,-,*,/...> 
 02828 |                   */ 
 02829 |                   if ( 
 02830 |                        (s_itr_ != initial_itr)                     && 
 02831 |                        !is_end(s_itr_ + 1)                         && 
 02832 |                        !details::is_letter_or_digit(*(s_itr_ + 1)) && 
 02833 |                        ('_' != (*(s_itr_ + 1))) 
 02834 |                      ) 
 02835 |                      break; 
 02836 |                } 
 02837 |  
 02838 |                ++s_itr_; 
 02839 |             } 
 02840 |  
 02841 |             token_t t; 
 02842 |             t.set_symbol(initial_itr, s_itr_, base_itr_); 
 02843 |             token_list_.push_back(t); 
 02844 |          } 
 02845 |  
 02846 |          inline void scan_number() 
 02847 |          { 
 02848 |             /* 
 02849 |                Attempt to match a valid numeric value in one of the following formats: 
 02850 |                (01) 123456 
 02851 |                (02) 123456. 
 02852 |                (03) 123.456 
 02853 |                (04) 123.456e3 
 02854 |                (05) 123.456E3 
 02855 |                (06) 123.456e+3 
 02856 |                (07) 123.456E+3 
 02857 |                (08) 123.456e-3 
 02858 |                (09) 123.456E-3 
 02859 |                (00) .1234 
 02860 |                (11) .1234e3 
 02861 |                (12) .1234E+3 
 02862 |                (13) .1234e+3 
 02863 |                (14) .1234E-3 
 02864 |                (15) .1234e-3 
 02865 |             */ 
 02866 |  
 02867 |             details::char_cptr initial_itr = s_itr_; 
 02868 |             bool dot_found                 = false; 
 02869 |             bool e_found                   = false; 
 02870 |             bool post_e_sign_found         = false; 
 02871 |             bool post_e_digit_found        = false; 
 02872 |             token_t t; 
 02873 |  
 02874 |             while (!is_end(s_itr_)) 
 02875 |             { 
 02876 |                if ('.' == (*s_itr_)) 
 02877 |                { 
 02878 |                   if (dot_found) 
 02879 |                   { 
 02880 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02881 |                      token_list_.push_back(t); 
 02882 |  
 02883 |                      return; 
 02884 |                   } 
 02885 |  
 02886 |                   dot_found = true; 
 02887 |                   ++s_itr_; 
 02888 |  
 02889 |                   continue; 
 02890 |                } 
 02891 |                else if ('e' == std::tolower(*s_itr_)) 
 02892 |                { 
 02893 |                   const char_t& c = *(s_itr_ + 1); 
 02894 |  
 02895 |                   if (is_end(s_itr_ + 1)) 
 02896 |                   { 
 02897 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02898 |                      token_list_.push_back(t); 
 02899 |  
 02900 |                      return; 
 02901 |                   } 
 02902 |                   else if ( 
 02903 |                             ('+' != c) && 
 02904 |                             ('-' != c) && 
 02905 |                             !details::is_digit(c) 
 02906 |                           ) 
 02907 |                   { 
 02908 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02909 |                      token_list_.push_back(t); 
 02910 |  
 02911 |                      return; 
 02912 |                   } 
 02913 |  
 02914 |                   e_found = true; 
 02915 |                   ++s_itr_; 
 02916 |  
 02917 |                   continue; 
 02918 |                } 
 02919 |                else if (e_found && details::is_sign(*s_itr_) && !post_e_digit_found) 
 02920 |                { 
 02921 |                   if (post_e_sign_found) 
 02922 |                   { 
 02923 |                      t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_); 
 02924 |                      token_list_.push_back(t); 
 02925 |  
 02926 |                      return; 
 02927 |                   } 
 02928 |  
 02929 |                   post_e_sign_found = true; 
 02930 |                   ++s_itr_; 
 02931 |  
 02932 |                   continue; 
 02933 |                } 
 02934 |                else if (e_found && details::is_digit(*s_itr_)) 
 02935 |                { 
 02936 |                   post_e_digit_found = true; 
 02937 |                   ++s_itr_; 
 02938 |  
 02939 |                   continue; 
 02940 |                } 
 02941 |                else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_)) 
 02942 |                   break; 
 02943 |                else 
 02944 |                   ++s_itr_; 
 02945 |             } 
 02946 |  
 02947 |             t.set_numeric(initial_itr, s_itr_, base_itr_); 
 02948 |             token_list_.push_back(t); 
 02949 |  
 02950 |             return; 
 02951 |          } 
 02952 |  
 02953 |          inline void scan_special_function() 
 02954 |          { 
 02955 |             details::char_cptr initial_itr = s_itr_; 
 02956 |             token_t t; 
 02957 |  
 02958 |             // $fdd(x,x,x) = at least 11 chars 
 02959 |             if (std::distance(s_itr_,s_end_) < 11) 
 02960 |             { 
 02961 |                t.set_error( 
 02962 |                   token::e_err_sfunc, 
 02963 |                   initial_itr, std::min(initial_itr + 11, s_end_), 
 02964 |                   base_itr_); 
 02965 |                token_list_.push_back(t); 
 02966 |  
 02967 |                return; 
 02968 |             } 
 02969 |  
 02970 |             if ( 
 02971 |                  !(('$' == *s_itr_)                       && 
 02972 |                    (details::imatch  ('f',*(s_itr_ + 1))) && 
 02973 |                    (details::is_digit(*(s_itr_ + 2)))     && 
 02974 |                    (details::is_digit(*(s_itr_ + 3)))) 
 02975 |                ) 
 02976 |             { 
 02977 |                t.set_error( 
 02978 |                   token::e_err_sfunc, 
 02979 |                   initial_itr, std::min(initial_itr + 4, s_end_), 
 02980 |                   base_itr_); 
 02981 |                token_list_.push_back(t); 
 02982 |  
 02983 |                return; 
 02984 |             } 
 02985 |  
 02986 |             s_itr_ += 4; // $fdd = 4chars 
 02987 |  
 02988 |             t.set_symbol(initial_itr, s_itr_, base_itr_); 
 02989 |             token_list_.push_back(t); 
 02990 |  
 02991 |             return; 
 02992 |          } 
 02993 |  
 02994 |          #ifndef exprtk_disable_string_capabilities 
 02995 |          inline void scan_string() 
 02996 |          { 
 02997 |             details::char_cptr initial_itr = s_itr_ + 1; 
 02998 |             token_t t; 
 02999 |  
 03000 |             if (std::distance(s_itr_,s_end_) < 2) 
 03001 |             { 
 03002 |                t.set_error(token::e_err_string, s_itr_, s_end_, base_itr_); 
 03003 |                token_list_.push_back(t); 
 03004 |  
 03005 |                return; 
 03006 |             } 
 03007 |  
 03008 |             ++s_itr_; 
 03009 |  
 03010 |             bool escaped_found = false; 
 03011 |             bool escaped = false; 
 03012 |  
 03013 |             while (!is_end(s_itr_)) 
 03014 |             { 
 03015 |                if (!details::is_valid_string_char(*s_itr_)) 
 03016 |                { 
 03017 |                   t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03018 |                   token_list_.push_back(t); 
 03019 |  
 03020 |                   return; 
 03021 |                } 
 03022 |                else if (!escaped && ('\\' == *s_itr_)) 
 03023 |                { 
 03024 |                   escaped_found = true; 
 03025 |                   escaped = true; 
 03026 |                   ++s_itr_; 
 03027 |  
 03028 |                   continue; 
 03029 |                } 
 03030 |                else if (!escaped) 
 03031 |                { 
 03032 |                   if ('\'' == *s_itr_) 
 03033 |                      break; 
 03034 |                } 
 03035 |                else if (escaped) 
 03036 |                { 
 03037 |                   if ( 
 03038 |                        !is_end(s_itr_) && ('0' == *(s_itr_)) && 
 03039 |                        ((s_itr_ + 4) <= s_end_) 
 03040 |                      ) 
 03041 |                   { 
 03042 |                      const bool x_separator = ('X' == std::toupper(*(s_itr_ + 1))); 
 03043 |  
 03044 |                      const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) && 
 03045 |                                               details::is_hex_digit(*(s_itr_ + 3)) ; 
 03046 |  
 03047 |                      if (!(x_separator && both_digits)) 
 03048 |                      { 
 03049 |                         t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03050 |                         token_list_.push_back(t); 
 03051 |  
 03052 |                         return; 
 03053 |                      } 
 03054 |                      else 
 03055 |                         s_itr_ += 3; 
 03056 |                   } 
 03057 |  
 03058 |                   escaped = false; 
 03059 |                } 
 03060 |  
 03061 |                ++s_itr_; 
 03062 |             } 
 03063 |  
 03064 |             if (is_end(s_itr_)) 
 03065 |             { 
 03066 |                t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03067 |                token_list_.push_back(t); 
 03068 |  
 03069 |                return; 
 03070 |             } 
 03071 |  
 03072 |             if (!escaped_found) 
 03073 |                t.set_string(initial_itr, s_itr_, base_itr_); 
 03074 |             else 
 03075 |             { 
 03076 |                std::string parsed_string(initial_itr,s_itr_); 
 03077 |  
 03078 |                if (!details::cleanup_escapes(parsed_string)) 
 03079 |                { 
 03080 |                   t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); 
 03081 |                   token_list_.push_back(t); 
 03082 |  
 03083 |                   return; 
 03084 |                } 
 03085 |  
 03086 |                t.set_string( 
 03087 |                   parsed_string, 
 03088 |                   static_cast<std::size_t>(std::distance(base_itr_,initial_itr))); 
 03089 |             } 
 03090 |  
 03091 |             token_list_.push_back(t); 
 03092 |             ++s_itr_; 
 03093 |  
 03094 |             return; 
 03095 |          } 
 03096 |          #endif 
 03097 |  
 03098 |       private: 
 03099 |  
 03100 |          token_list_t       token_list_; 
 03101 |          token_list_itr_t   token_itr_; 
 03102 |          token_list_itr_t   store_token_itr_; 
 03103 |          token_t            eof_token_; 
 03104 |          details::char_cptr base_itr_; 
 03105 |          details::char_cptr s_itr_; 
 03106 |          details::char_cptr s_end_; 
 03107 |  
 03108 |          friend class token_scanner; 
 03109 |          friend class token_modifier; 
 03110 |          friend class token_inserter; 
 03111 |          friend class token_joiner; 
 03112 |       }; // class generator 
 03113 |  
 03114 |       class helper_interface 
 03115 |       { 
 03116 |       public: 
 03117 |  
 03118 |          virtual void init()                     {              } 
 03119 |          virtual void reset()                    {              } 
 03120 |          virtual bool result()                   { return true; } 
 03121 |          virtual std::size_t process(generator&) { return 0;    } 
 03122 |          virtual ~helper_interface()             {              } 
 03123 |       }; 
 03124 |  
 03125 |       class token_scanner : public helper_interface 
 03126 |       { 
 03127 |       public: 
 03128 |  
 03129 |          virtual ~token_scanner() 
 03130 |          {} 
 03131 |  
 03132 |          explicit token_scanner(const std::size_t& stride) 
 03133 |          : stride_(stride) 
 03134 |          { 
 03135 |             if (stride > 4) 
 03136 |             { 
 03137 |                throw std::invalid_argument("token_scanner() - Invalid stride value"); 
 03138 |             } 
 03139 |          } 
 03140 |  
 03141 |          inline std::size_t process(generator& g) exprtk_override 
 03142 |          { 
 03143 |             if (g.token_list_.size() >= stride_) 
 03144 |             { 
 03145 |                for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i) 
 03146 |                { 
 03147 |                   token t; 
 03148 |  
 03149 |                   switch (stride_) 
 03150 |                   { 
 03151 |                      case 1 : 
 03152 |                               { 
 03153 |                                  const token& t0 = g.token_list_[i]; 
 03154 |  
 03155 |                                  if (!operator()(t0)) 
 03156 |                                  { 
 03157 |                                     return 0; 
 03158 |                                  } 
 03159 |                               } 
 03160 |                               break; 
 03161 |  
 03162 |                      case 2 : 
 03163 |                               { 
 03164 |                                  const token& t0 = g.token_list_[i    ]; 
 03165 |                                  const token& t1 = g.token_list_[i + 1]; 
 03166 |  
 03167 |                                  if (!operator()(t0, t1)) 
 03168 |                                  { 
 03169 |                                     return 0; 
 03170 |                                  } 
 03171 |                               } 
 03172 |                               break; 
 03173 |  
 03174 |                      case 3 : 
 03175 |                               { 
 03176 |                                  const token& t0 = g.token_list_[i    ]; 
 03177 |                                  const token& t1 = g.token_list_[i + 1]; 
 03178 |                                  const token& t2 = g.token_list_[i + 2]; 
 03179 |  
 03180 |                                  if (!operator()(t0, t1, t2)) 
 03181 |                                  { 
 03182 |                                     return 0; 
 03183 |                                  } 
 03184 |                               } 
 03185 |                               break; 
 03186 |  
 03187 |                      case 4 : 
 03188 |                               { 
 03189 |                                  const token& t0 = g.token_list_[i    ]; 
 03190 |                                  const token& t1 = g.token_list_[i + 1]; 
 03191 |                                  const token& t2 = g.token_list_[i + 2]; 
 03192 |                                  const token& t3 = g.token_list_[i + 3]; 
 03193 |  
 03194 |                                  if (!operator()(t0, t1, t2, t3)) 
 03195 |                                  { 
 03196 |                                     return 0; 
 03197 |                                  } 
 03198 |                               } 
 03199 |                               break; 
 03200 |                   } 
 03201 |                } 
 03202 |             } 
 03203 |  
 03204 |             return 0; 
 03205 |          } 
 03206 |  
 03207 |          virtual bool operator() (const token&) 
 03208 |          { 
 03209 |             return false; 
 03210 |          } 
 03211 |  
 03212 |          virtual bool operator() (const token&, const token&) 
 03213 |          { 
 03214 |             return false; 
 03215 |          } 
 03216 |  
 03217 |          virtual bool operator() (const token&, const token&, const token&) 
 03218 |          { 
 03219 |             return false; 
 03220 |          } 
 03221 |  
 03222 |          virtual bool operator() (const token&, const token&, const token&, const token&) 
 03223 |          { 
 03224 |             return false; 
 03225 |          } 
 03226 |  
 03227 |       private: 
 03228 |  
 03229 |          const std::size_t stride_; 
 03230 |       }; // class token_scanner 
 03231 |  
 03232 |       class token_modifier : public helper_interface 
 03233 |       { 
 03234 |       public: 
 03235 |  
 03236 |          inline std::size_t process(generator& g) exprtk_override 
 03237 |          { 
 03238 |             std::size_t changes = 0; 
 03239 |  
 03240 |             for (std::size_t i = 0; i < g.token_list_.size(); ++i) 
 03241 |             { 
 03242 |                if (modify(g.token_list_[i])) changes++; 
 03243 |             } 
 03244 |  
 03245 |             return changes; 
 03246 |          } 
 03247 |  
 03248 |          virtual bool modify(token& t) = 0; 
 03249 |       }; 
 03250 |  
 03251 |       class token_inserter : public helper_interface 
 03252 |       { 
 03253 |       public: 
 03254 |  
 03255 |          explicit token_inserter(const std::size_t& stride) 
 03256 |          : stride_(stride) 
 03257 |          { 
 03258 |             if (stride > 5) 
 03259 |             { 
 03260 |                throw std::invalid_argument("token_inserter() - Invalid stride value"); 
 03261 |             } 
 03262 |          } 
 03263 |  
 03264 |          inline std::size_t process(generator& g) exprtk_override 
 03265 |          { 
 03266 |             if (g.token_list_.empty()) 
 03267 |                return 0; 
 03268 |             else if (g.token_list_.size() < stride_) 
 03269 |                return 0; 
 03270 |  
 03271 |             std::size_t changes = 0; 
 03272 |  
 03273 |             typedef std::pair<std::size_t, token> insert_t; 
 03274 |             std::vector<insert_t> insert_list; 
 03275 |             insert_list.reserve(10000); 
 03276 |  
 03277 |             for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i) 
 03278 |             { 
 03279 |                int insert_index = -1; 
 03280 |                token t; 
 03281 |  
 03282 |                switch (stride_) 
 03283 |                { 
 03284 |                   case 1 : insert_index = insert(g.token_list_[i],t); 
 03285 |                            break; 
 03286 |  
 03287 |                   case 2 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], t); 
 03288 |                            break; 
 03289 |  
 03290 |                   case 3 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], g.token_list_[i + 2], t); 
 03291 |                            break; 
 03292 |  
 03293 |                   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); 
 03294 |                            break; 
 03295 |  
 03296 |                   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); 
 03297 |                            break; 
 03298 |                } 
 03299 |  
 03300 |                if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1))) 
 03301 |                { 
 03302 |                   insert_list.push_back(insert_t(i, t)); 
 03303 |                   changes++; 
 03304 |                } 
 03305 |             } 
 03306 |  
 03307 |             if (!insert_list.empty()) 
 03308 |             { 
 03309 |                generator::token_list_t token_list; 
 03310 |  
 03311 |                std::size_t insert_index = 0; 
 03312 |  
 03313 |                for (std::size_t i = 0; i < g.token_list_.size(); ++i) 
 03314 |                { 
 03315 |                   token_list.push_back(g.token_list_[i]); 
 03316 |  
 03317 |                   if ( 
 03318 |                        (insert_index < insert_list.size()) && 
 03319 |                        (insert_list[insert_index].first == i) 
 03320 |                      ) 
 03321 |                   { 
 03322 |                      token_list.push_back(insert_list[insert_index].second); 
 03323 |                      insert_index++; 
 03324 |                   } 
 03325 |                } 
 03326 |  
 03327 |                std::swap(g.token_list_,token_list); 
 03328 |             } 
 03329 |  
 03330 |             return changes; 
 03331 |          } 
 03332 |  
 03333 |          #define token_inserter_empty_body \ 
 03334 |          {                                 \ 
 03335 |             return -1;                     \ 
 03336 |          }                                 \ 
 03337 |  
 03338 |          inline virtual int insert(const token&, token&) 
 03339 |          token_inserter_empty_body 
 03340 |  
 03341 |          inline virtual int insert(const token&, const token&, token&) 
 03342 |          token_inserter_empty_body 
 03343 |  
 03344 |          inline virtual int insert(const token&, const token&, const token&, token&) 
 03345 |          token_inserter_empty_body 
 03346 |  
 03347 |          inline virtual int insert(const token&, const token&, const token&, const token&, token&) 
 03348 |          token_inserter_empty_body 
 03349 |  
 03350 |          inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&) 
 03351 |          token_inserter_empty_body 
 03352 |  
 03353 |          #undef token_inserter_empty_body 
 03354 |  
 03355 |       private: 
 03356 |  
 03357 |          const std::size_t stride_; 
 03358 |       }; 
 03359 |  
 03360 |       class token_joiner : public helper_interface 
 03361 |       { 
 03362 |       public: 
 03363 |  
 03364 |          explicit token_joiner(const std::size_t& stride) 
 03365 |          : stride_(stride) 
 03366 |          {} 
 03367 |  
 03368 |          inline std::size_t process(generator& g) exprtk_override 
 03369 |          { 
 03370 |             if (g.token_list_.empty()) 
 03371 |                return 0; 
 03372 |  
 03373 |             switch (stride_) 
 03374 |             { 
 03375 |                case 2  : return process_stride_2(g); 
 03376 |                case 3  : return process_stride_3(g); 
 03377 |                default : return 0; 
 03378 |             } 
 03379 |          } 
 03380 |  
 03381 |          virtual bool join(const token&, const token&, token&)               { return false; } 
 03382 |          virtual bool join(const token&, const token&, const token&, token&) { return false; } 
 03383 |  
 03384 |       private: 
 03385 |  
 03386 |          inline std::size_t process_stride_2(generator& g) 
 03387 |          { 
 03388 |             if (g.token_list_.size() < 2) 
 03389 |                return 0; 
 03390 |  
 03391 |             std::size_t changes = 0; 
 03392 |  
 03393 |             generator::token_list_t token_list; 
 03394 |             token_list.reserve(10000); 
 03395 |  
 03396 |             for (int i = 0; i < static_cast<int>(g.token_list_.size() - 1); ++i) 
 03397 |             { 
 03398 |                token t; 
 03399 |  
 03400 |                for ( ; ; ) 
 03401 |                { 
 03402 |                   if (!join(g[i], g[i + 1], t)) 
 03403 |                   { 
 03404 |                      token_list.push_back(g[i]); 
 03405 |                      break; 
 03406 |                   } 
 03407 |  
 03408 |                   token_list.push_back(t); 
 03409 |  
 03410 |                   ++changes; 
 03411 |  
 03412 |                   i += 2; 
 03413 |  
 03414 |                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 1)) 
 03415 |                      break; 
 03416 |                } 
 03417 |             } 
 03418 |  
 03419 |             token_list.push_back(g.token_list_.back()); 
 03420 |  
 03421 |             assert(token_list.size() <= g.token_list_.size()); 
 03422 |  
 03423 |             std::swap(token_list, g.token_list_); 
 03424 |  
 03425 |             return changes; 
 03426 |          } 
 03427 |  
 03428 |          inline std::size_t process_stride_3(generator& g) 
 03429 |          { 
 03430 |             if (g.token_list_.size() < 3) 
 03431 |                return 0; 
 03432 |  
 03433 |             std::size_t changes = 0; 
 03434 |  
 03435 |             generator::token_list_t token_list; 
 03436 |             token_list.reserve(10000); 
 03437 |  
 03438 |             for (int i = 0; i < static_cast<int>(g.token_list_.size() - 2); ++i) 
 03439 |             { 
 03440 |                token t; 
 03441 |  
 03442 |                for ( ; ; ) 
 03443 |                { 
 03444 |                   if (!join(g[i], g[i + 1], g[i + 2], t)) 
 03445 |                   { 
 03446 |                      token_list.push_back(g[i]); 
 03447 |                      break; 
 03448 |                   } 
 03449 |  
 03450 |                   token_list.push_back(t); 
 03451 |  
 03452 |                   ++changes; 
 03453 |  
 03454 |                   i += 3; 
 03455 |  
 03456 |                   if (static_cast<std::size_t>(i) >= (g.token_list_.size() - 2)) 
 03457 |                      break; 
 03458 |                } 
 03459 |             } 
 03460 |  
 03461 |             token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 2)); 
 03462 |             token_list.push_back(*(g.token_list_.begin() + g.token_list_.size() - 1)); 
 03463 |  
 03464 |             assert(token_list.size() <= g.token_list_.size()); 
 03465 |  
 03466 |             std::swap(token_list, g.token_list_); 
 03467 |  
 03468 |             return changes; 
 03469 |          } 
 03470 |  
 03471 |          const std::size_t stride_; 
 03472 |       }; 
 03473 |  
 03474 |       namespace helper 
 03475 |       { 
 03476 |  
 03477 |          inline void dump(const lexer::generator& generator) 
 03478 |          { 
 03479 |             for (std::size_t i = 0; i < generator.size(); ++i) 
 03480 |             { 
 03481 |                const lexer::token& t = generator[i]; 
 03482 |                printf("Token[%02d] @ %03d  %6s  -->  '%s'\n", 
 03483 |                       static_cast<int>(i), 
 03484 |                       static_cast<int>(t.position), 
 03485 |                       t.to_str(t.type).c_str(), 
 03486 |                       t.value.c_str()); 
 03487 |             } 
 03488 |          } 
 03489 |  
 03490 |          class commutative_inserter : public lexer::token_inserter 
 03491 |          { 
 03492 |          public: 
 03493 |  
 03494 |             using lexer::token_inserter::insert; 
 03495 |  
 03496 |             commutative_inserter() 
 03497 |             : lexer::token_inserter(2) 
 03498 |             {} 
 03499 |  
 03500 |             inline void ignore_symbol(const std::string& symbol) 
 03501 |             { 
 03502 |                ignore_set_.insert(symbol); 
 03503 |             } 
 03504 |  
 03505 |             inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) exprtk_override 
 03506 |             { 
 03507 |                bool match         = false; 
 03508 |                new_token.type     = lexer::token::e_mul; 
 03509 |                new_token.value    = "*" 
 03510 |                new_token.position = t1.position; 
 03511 |  
 03512 |                if (t0.type == lexer::token::e_symbol) 
 03513 |                { 
 03514 |                   if (ignore_set_.end() != ignore_set_.find(t0.value)) 
 03515 |                   { 
 03516 |                      return -1; 
 03517 |                   } 
 03518 |                   else if (!t0.value.empty() && ('$' == t0.value[0])) 
 03519 |                   { 
 03520 |                      return -1; 
 03521 |                   } 
 03522 |                } 
 03523 |  
 03524 |                if (t1.type == lexer::token::e_symbol) 
 03525 |                { 
 03526 |                   if (ignore_set_.end() != ignore_set_.find(t1.value)) 
 03527 |                   { 
 03528 |                      return -1; 
 03529 |                   } 
 03530 |                } 
 03531 |                if      ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03532 |                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lbracket   )) match = true; 
 03533 |                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lcrlbracket)) match = true; 
 03534 |                else if ((t0.type == lexer::token::e_number     ) && (t1.type == lexer::token::e_lsqrbracket)) match = true; 
 03535 |                else if ((t0.type == lexer::token::e_symbol     ) && (t1.type == lexer::token::e_number     )) match = true; 
 03536 |                else if ((t0.type == lexer::token::e_rbracket   ) && (t1.type == lexer::token::e_number     )) match = true; 
 03537 |                else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number     )) match = true; 
 03538 |                else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number     )) match = true; 
 03539 |                else if ((t0.type == lexer::token::e_rbracket   ) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03540 |                else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03541 |                else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03542 |                else if ((t0.type == lexer::token::e_symbol     ) && (t1.type == lexer::token::e_symbol     )) match = true; 
 03543 |  
 03544 |                return (match) ? 1 : -1; 
 03545 |             } 
 03546 |  
 03547 |          private: 
 03548 |  
 03549 |             std::set<std::string,details::ilesscompare> ignore_set_; 
 03550 |          }; 
 03551 |  
 03552 |          class operator_joiner exprtk_final : public token_joiner 
 03553 |          { 
 03554 |          public: 
 03555 |  
 03556 |             explicit operator_joiner(const std::size_t& stride) 
 03557 |             : token_joiner(stride) 
 03558 |             {} 
 03559 |  
 03560 |             inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) exprtk_override 
 03561 |             { 
 03562 |                // ': =' --> ':=' 
 03563 |                if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq)) 
 03564 |                { 
 03565 |                   t.type     = lexer::token::e_assign; 
 03566 |                   t.value    = ":=" 
 03567 |                   t.position = t0.position; 
 03568 |  
 03569 |                   return true; 
 03570 |                } 
 03571 |                // '+ =' --> '+=' 
 03572 |                else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq)) 
 03573 |                { 
 03574 |                   t.type     = lexer::token::e_addass; 
 03575 |                   t.value    = "+=" 
 03576 |                   t.position = t0.position; 
 03577 |  
 03578 |                   return true; 
 03579 |                } 
 03580 |                // '- =' --> '-=' 
 03581 |                else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq)) 
 03582 |                { 
 03583 |                   t.type     = lexer::token::e_subass; 
 03584 |                   t.value    = "-=" 
 03585 |                   t.position = t0.position; 
 03586 |  
 03587 |                   return true; 
 03588 |                } 
 03589 |                // '* =' --> '*=' 
 03590 |                else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq)) 
 03591 |                { 
 03592 |                   t.type     = lexer::token::e_mulass; 
 03593 |                   t.value    = "*=" 
 03594 |                   t.position = t0.position; 
 03595 |  
 03596 |                   return true; 
 03597 |                } 
 03598 |                // '/ =' --> '/=' 
 03599 |                else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq)) 
 03600 |                { 
 03601 |                   t.type     = lexer::token::e_divass; 
 03602 |                   t.value    = "/=" 
 03603 |                   t.position = t0.position; 
 03604 |  
 03605 |                   return true; 
 03606 |                } 
 03607 |                // '% =' --> '%=' 
 03608 |                else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq)) 
 03609 |                { 
 03610 |                   t.type     = lexer::token::e_modass; 
 03611 |                   t.value    = "%=" 
 03612 |                   t.position = t0.position; 
 03613 |  
 03614 |                   return true; 
 03615 |                } 
 03616 |                // '> =' --> '>=' 
 03617 |                else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq)) 
 03618 |                { 
 03619 |                   t.type     = lexer::token::e_gte; 
 03620 |                   t.value    = ">=" 
 03621 |                   t.position = t0.position; 
 03622 |  
 03623 |                   return true; 
 03624 |                } 
 03625 |                // '< =' --> '<=' 
 03626 |                else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq)) 
 03627 |                { 
 03628 |                   t.type     = lexer::token::e_lte; 
 03629 |                   t.value    = "<=" 
 03630 |                   t.position = t0.position; 
 03631 |  
 03632 |                   return true; 
 03633 |                } 
 03634 |                // '= =' --> '==' 
 03635 |                else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq)) 
 03636 |                { 
 03637 |                   t.type     = lexer::token::e_eq; 
 03638 |                   t.value    = "==" 
 03639 |                   t.position = t0.position; 
 03640 |  
 03641 |                   return true; 
 03642 |                } 
 03643 |                // '! =' --> '!=' 
 03644 |                else if ((static_cast<details::char_t>(t0.type) == '!') && (t1.type == lexer::token::e_eq)) 
 03645 |                { 
 03646 |                   t.type     = lexer::token::e_ne; 
 03647 |                   t.value    = "!=" 
 03648 |                   t.position = t0.position; 
 03649 |  
 03650 |                   return true; 
 03651 |                } 
 03652 |                // '< >' --> '<>' 
 03653 |                else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt)) 
 03654 |                { 
 03655 |                   t.type     = lexer::token::e_ne; 
 03656 |                   t.value    = "<>" 
 03657 |                   t.position = t0.position; 
 03658 |  
 03659 |                   return true; 
 03660 |                } 
 03661 |                // '<= >' --> '<=>' 
 03662 |                else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt)) 
 03663 |                { 
 03664 |                   t.type     = lexer::token::e_swap; 
 03665 |                   t.value    = "<=>" 
 03666 |                   t.position = t0.position; 
 03667 |  
 03668 |                   return true; 
 03669 |                } 
 03670 |                // '+ -' --> '-' 
 03671 |                else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_sub)) 
 03672 |                { 
 03673 |                   t.type     = lexer::token::e_sub; 
 03674 |                   t.value    = "-" 
 03675 |                   t.position = t0.position; 
 03676 |  
 03677 |                   return true; 
 03678 |                } 
 03679 |                // '- +' --> '-' 
 03680 |                else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_add)) 
 03681 |                { 
 03682 |                   t.type     = lexer::token::e_sub; 
 03683 |                   t.value    = "-" 
 03684 |                   t.position = t0.position; 
 03685 |  
 03686 |                   return true; 
 03687 |                } 
 03688 |                // '- -' --> '+' 
 03689 |                else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub)) 
 03690 |                { 
 03691 |                   /* 
 03692 |                      Note: May need to reconsider this when wanting to implement 
 03693 |                      pre/postfix decrement operator 
 03694 |                   */ 
 03695 |                   t.type     = lexer::token::e_add; 
 03696 |                   t.value    = "+" 
 03697 |                   t.position = t0.position; 
 03698 |  
 03699 |                   return true; 
 03700 |                } 
 03701 |                else 
 03702 |                   return false; 
 03703 |             } 
 03704 |  
 03705 |             inline bool join(const lexer::token& t0, 
 03706 |                              const lexer::token& t1, 
 03707 |                              const lexer::token& t2, 
 03708 |                              lexer::token& t) exprtk_override 
 03709 |             { 
 03710 |                // '[ * ]' --> '[*]' 
 03711 |                if ( 
 03712 |                     (t0.type == lexer::token::e_lsqrbracket) && 
 03713 |                     (t1.type == lexer::token::e_mul        ) && 
 03714 |                     (t2.type == lexer::token::e_rsqrbracket) 
 03715 |                   ) 
 03716 |                { 
 03717 |                   t.type     = lexer::token::e_symbol; 
 03718 |                   t.value    = "[*]" 
 03719 |                   t.position = t0.position; 
 03720 |  
 03721 |                   return true; 
 03722 |                } 
 03723 |                else 
 03724 |                   return false; 
 03725 |             } 
 03726 |          }; 
 03727 |  
 03728 |          class bracket_checker exprtk_final : public lexer::token_scanner 
 03729 |          { 
 03730 |          public: 
 03731 |  
 03732 |             using lexer::token_scanner::operator(); 
 03733 |  
 03734 |             bracket_checker() 
 03735 |             : token_scanner(1) 
 03736 |             , state_(true) 
 03737 |             {} 
 03738 |  
 03739 |             bool result() exprtk_override 
 03740 |             { 
 03741 |                if (!stack_.empty()) 
 03742 |                { 
 03743 |                   lexer::token t; 
 03744 |                   t.value      = stack_.top().first; 
 03745 |                   t.position   = stack_.top().second; 
 03746 |                   error_token_ = t; 
 03747 |                   state_       = false; 
 03748 |  
 03749 |                   return false; 
 03750 |                } 
 03751 |                else 
 03752 |                   return state_; 
 03753 |             } 
 03754 |  
 03755 |             lexer::token error_token() 
 03756 |             { 
 03757 |                return error_token_; 
 03758 |             } 
 03759 |  
 03760 |             void reset() exprtk_override 
 03761 |             { 
 03762 |                // Why? because msvc doesn't support swap properly. 
 03763 |                stack_ = std::stack<std::pair<char,std::size_t> >(); 
 03764 |                state_ = true; 
 03765 |                error_token_.clear(); 
 03766 |             } 
 03767 |  
 03768 |             bool operator() (const lexer::token& t) exprtk_override 
 03769 |             { 
 03770 |                if ( 
 03771 |                     !t.value.empty()                       && 
 03772 |                     (lexer::token::e_string != t.type)     && 
 03773 |                     (lexer::token::e_symbol != t.type)     && 
 03774 |                     exprtk::details::is_bracket(t.value[0]) 
 03775 |                   ) 
 03776 |                { 
 03777 |                   details::char_t c = t.value[0]; 
 03778 |  
 03779 |                   if      (t.type == lexer::token::e_lbracket   ) stack_.push(std::make_pair(')',t.position)); 
 03780 |                   else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position)); 
 03781 |                   else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position)); 
 03782 |                   else if (exprtk::details::is_right_bracket(c)) 
 03783 |                   { 
 03784 |                      if (stack_.empty()) 
 03785 |                      { 
 03786 |                         state_       = false; 
 03787 |                         error_token_ = t; 
 03788 |  
 03789 |                         return false; 
 03790 |                      } 
 03791 |                      else if (c != stack_.top().first) 
 03792 |                      { 
 03793 |                         state_       = false; 
 03794 |                         error_token_ = t; 
 03795 |  
 03796 |                         return false; 
 03797 |                      } 
 03798 |                      else 
 03799 |                         stack_.pop(); 
 03800 |                   } 
 03801 |                } 
 03802 |  
 03803 |                return true; 
 03804 |             } 
 03805 |  
 03806 |          private: 
 03807 |  
 03808 |             bool state_; 
 03809 |             std::stack<std::pair<char,std::size_t> > stack_; 
 03810 |             lexer::token error_token_; 
 03811 |          }; 
 03812 |  
 03813 |          template <typename T> 
 03814 |          class numeric_checker exprtk_final : public lexer::token_scanner 
 03815 |          { 
 03816 |          public: 
 03817 |  
 03818 |             using lexer::token_scanner::operator(); 
 03819 |  
 03820 |             numeric_checker() 
 03821 |             : token_scanner (1) 
 03822 |             , current_index_(0) 
 03823 |             {} 
 03824 |  
 03825 |             bool result() exprtk_override 
 03826 |             { 
 03827 |                return error_list_.empty(); 
 03828 |             } 
 03829 |  
 03830 |             void reset() exprtk_override 
 03831 |             { 
 03832 |                error_list_.clear(); 
 03833 |                current_index_ = 0; 
 03834 |             } 
 03835 |  
 03836 |             bool operator() (const lexer::token& t) exprtk_override 
 03837 |             { 
 03838 |                if (token::e_number == t.type) 
 03839 |                { 
 03840 |                   T v; 
 03841 |  
 03842 |                   if (!exprtk::details::string_to_real(t.value,v)) 
 03843 |                   { 
 03844 |                      error_list_.push_back(current_index_); 
 03845 |                   } 
 03846 |                } 
 03847 |  
 03848 |                ++current_index_; 
 03849 |  
 03850 |                return true; 
 03851 |             } 
 03852 |  
 03853 |             std::size_t error_count() const 
 03854 |             { 
 03855 |                return error_list_.size(); 
 03856 |             } 
 03857 |  
 03858 |             std::size_t error_index(const std::size_t& i) 
 03859 |             { 
 03860 |                if (i < error_list_.size()) 
 03861 |                   return error_list_[i]; 
 03862 |                else 
 03863 |                   return std::numeric_limits<std::size_t>::max(); 
 03864 |             } 
 03865 |  
 03866 |             void clear_errors() 
 03867 |             { 
 03868 |                error_list_.clear(); 
 03869 |             } 
 03870 |  
 03871 |          private: 
 03872 |  
 03873 |             std::size_t current_index_; 
 03874 |             std::vector<std::size_t> error_list_; 
 03875 |          }; 
 03876 |  
 03877 |          class symbol_replacer exprtk_final : public lexer::token_modifier 
 03878 |          { 
 03879 |          private: 
 03880 |  
 03881 |             typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t; 
 03882 |  
 03883 |          public: 
 03884 |  
 03885 |             bool remove(const std::string& target_symbol) 
 03886 |             { 
 03887 |                const replace_map_t::iterator itr = replace_map_.find(target_symbol); 
 03888 |  
 03889 |                if (replace_map_.end() == itr) 
 03890 |                   return false; 
 03891 |  
 03892 |                replace_map_.erase(itr); 
 03893 |  
 03894 |                return true; 
 03895 |             } 
 03896 |  
 03897 |             bool add_replace(const std::string& target_symbol, 
 03898 |                              const std::string& replace_symbol, 
 03899 |                              const lexer::token::token_type token_type = lexer::token::e_symbol) 
 03900 |             { 
 03901 |                const replace_map_t::iterator itr = replace_map_.find(target_symbol); 
 03902 |  
 03903 |                if (replace_map_.end() != itr) 
 03904 |                { 
 03905 |                   return false; 
 03906 |                } 
 03907 |  
 03908 |                replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type); 
 03909 |  
 03910 |                return true; 
 03911 |             } 
 03912 |  
 03913 |             void clear() 
 03914 |             { 
 03915 |                replace_map_.clear(); 
 03916 |             } 
 03917 |  
 03918 |          private: 
 03919 |  
 03920 |             bool modify(lexer::token& t) exprtk_override 
 03921 |             { 
 03922 |                if (lexer::token::e_symbol == t.type) 
 03923 |                { 
 03924 |                   if (replace_map_.empty()) 
 03925 |                      return false; 
 03926 |  
 03927 |                   const replace_map_t::iterator itr = replace_map_.find(t.value); 
 03928 |  
 03929 |                   if (replace_map_.end() != itr) 
 03930 |                   { 
 03931 |                      t.value = itr->second.first; 
 03932 |                      t.type  = itr->second.second; 
 03933 |  
 03934 |                      return true; 
 03935 |                   } 
 03936 |                } 
 03937 |  
 03938 |                return false; 
 03939 |             } 
 03940 |  
 03941 |             replace_map_t replace_map_; 
 03942 |          }; 
 03943 |  
 03944 |          class sequence_validator exprtk_final : public lexer::token_scanner 
 03945 |          { 
 03946 |          private: 
 03947 |  
 03948 |             typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t; 
 03949 |             typedef std::set<token_pair_t> set_t; 
 03950 |  
 03951 |          public: 
 03952 |  
 03953 |             using lexer::token_scanner::operator(); 
 03954 |  
 03955 |             sequence_validator() 
 03956 |             : lexer::token_scanner(2) 
 03957 |             { 
 03958 |                add_invalid(lexer::token::e_number, lexer::token::e_number); 
 03959 |                add_invalid(lexer::token::e_string, lexer::token::e_string); 
 03960 |                add_invalid(lexer::token::e_number, lexer::token::e_string); 
 03961 |                add_invalid(lexer::token::e_string, lexer::token::e_number); 
 03962 |  
 03963 |                add_invalid_set1(lexer::token::e_assign ); 
 03964 |                add_invalid_set1(lexer::token::e_shr    ); 
 03965 |                add_invalid_set1(lexer::token::e_shl    ); 
 03966 |                add_invalid_set1(lexer::token::e_lte    ); 
 03967 |                add_invalid_set1(lexer::token::e_ne     ); 
 03968 |                add_invalid_set1(lexer::token::e_gte    ); 
 03969 |                add_invalid_set1(lexer::token::e_lt     ); 
 03970 |                add_invalid_set1(lexer::token::e_gt     ); 
 03971 |                add_invalid_set1(lexer::token::e_eq     ); 
 03972 |                add_invalid_set1(lexer::token::e_comma  ); 
 03973 |                add_invalid_set1(lexer::token::e_add    ); 
 03974 |                add_invalid_set1(lexer::token::e_sub    ); 
 03975 |                add_invalid_set1(lexer::token::e_div    ); 
 03976 |                add_invalid_set1(lexer::token::e_mul    ); 
 03977 |                add_invalid_set1(lexer::token::e_mod    ); 
 03978 |                add_invalid_set1(lexer::token::e_pow    ); 
 03979 |                add_invalid_set1(lexer::token::e_colon  ); 
 03980 |                add_invalid_set1(lexer::token::e_ternary); 
 03981 |             } 
 03982 |  
 03983 |             bool result() exprtk_override 
 03984 |             { 
 03985 |                return error_list_.empty(); 
 03986 |             } 
 03987 |  
 03988 |             bool operator() (const lexer::token& t0, const lexer::token& t1) exprtk_override 
 03989 |             { 
 03990 |                const set_t::value_type p = std::make_pair(t0.type,t1.type); 
 03991 |  
 03992 |                if (invalid_bracket_check(t0.type,t1.type)) 
 03993 |                { 
 03994 |                   error_list_.push_back(std::make_pair(t0,t1)); 
 03995 |                } 
 03996 |                else if (invalid_comb_.find(p) != invalid_comb_.end()) 
 03997 |                { 
 03998 |                   error_list_.push_back(std::make_pair(t0,t1)); 
 03999 |                } 
 04000 |  
 04001 |                return true; 
 04002 |             } 
 04003 |  
 04004 |             std::size_t error_count() const 
 04005 |             { 
 04006 |                return error_list_.size(); 
 04007 |             } 
 04008 |  
 04009 |             std::pair<lexer::token,lexer::token> error(const std::size_t index) 
 04010 |             { 
 04011 |                if (index < error_list_.size()) 
 04012 |                { 
 04013 |                   return error_list_[index]; 
 04014 |                } 
 04015 |                else 
 04016 |                { 
 04017 |                   static const lexer::token error_token; 
 04018 |                   return std::make_pair(error_token,error_token); 
 04019 |                } 
 04020 |             } 
 04021 |  
 04022 |             void clear_errors() 
 04023 |             { 
 04024 |                error_list_.clear(); 
 04025 |             } 
 04026 |  
 04027 |          private: 
 04028 |  
 04029 |             void add_invalid(const lexer::token::token_type base, const lexer::token::token_type t) 
 04030 |             { 
 04031 |                invalid_comb_.insert(std::make_pair(base,t)); 
 04032 |             } 
 04033 |  
 04034 |             void add_invalid_set1(const lexer::token::token_type t) 
 04035 |             { 
 04036 |                add_invalid(t, lexer::token::e_assign); 
 04037 |                add_invalid(t, lexer::token::e_shr   ); 
 04038 |                add_invalid(t, lexer::token::e_shl   ); 
 04039 |                add_invalid(t, lexer::token::e_lte   ); 
 04040 |                add_invalid(t, lexer::token::e_ne    ); 
 04041 |                add_invalid(t, lexer::token::e_gte   ); 
 04042 |                add_invalid(t, lexer::token::e_lt    ); 
 04043 |                add_invalid(t, lexer::token::e_gt    ); 
 04044 |                add_invalid(t, lexer::token::e_eq    ); 
 04045 |                add_invalid(t, lexer::token::e_comma ); 
 04046 |                add_invalid(t, lexer::token::e_div   ); 
 04047 |                add_invalid(t, lexer::token::e_mul   ); 
 04048 |                add_invalid(t, lexer::token::e_mod   ); 
 04049 |                add_invalid(t, lexer::token::e_pow   ); 
 04050 |                add_invalid(t, lexer::token::e_colon ); 
 04051 |             } 
 04052 |  
 04053 |             bool invalid_bracket_check(const lexer::token::token_type base, const lexer::token::token_type t) 
 04054 |             { 
 04055 |                if (details::is_right_bracket(static_cast<details::char_t>(base))) 
 04056 |                { 
 04057 |                   switch (t) 
 04058 |                   { 
 04059 |                      case lexer::token::e_assign : return (']' != base); 
 04060 |                      case lexer::token::e_string : return (')' != base); 
 04061 |                      default                     : return false; 
 04062 |                   } 
 04063 |                } 
 04064 |                else if (details::is_left_bracket(static_cast<details::char_t>(base))) 
 04065 |                { 
 04066 |                   if (details::is_right_bracket(static_cast<details::char_t>(t))) 
 04067 |                      return false; 
 04068 |                   else if (details::is_left_bracket(static_cast<details::char_t>(t))) 
 04069 |                      return false; 
 04070 |                   else 
 04071 |                   { 
 04072 |                      switch (t) 
 04073 |                      { 
 04074 |                         case lexer::token::e_number  : return false; 
 04075 |                         case lexer::token::e_symbol  : return false; 
 04076 |                         case lexer::token::e_string  : return false; 
 04077 |                         case lexer::token::e_add     : return false; 
 04078 |                         case lexer::token::e_sub     : return false; 
 04079 |                         case lexer::token::e_colon   : return false; 
 04080 |                         case lexer::token::e_ternary : return false; 
 04081 |                         default                      : return true ; 
 04082 |                      } 
 04083 |                   } 
 04084 |                } 
 04085 |                else if (details::is_right_bracket(static_cast<details::char_t>(t))) 
 04086 |                { 
 04087 |                   switch (base) 
 04088 |                   { 
 04089 |                      case lexer::token::e_number  : return false; 
 04090 |                      case lexer::token::e_symbol  : return false; 
 04091 |                      case lexer::token::e_string  : return false; 
 04092 |                      case lexer::token::e_eof     : return false; 
 04093 |                      case lexer::token::e_colon   : return false; 
 04094 |                      case lexer::token::e_ternary : return false; 
 04095 |                      default                      : return true ; 
 04096 |                   } 
 04097 |                } 
 04098 |                else if (details::is_left_bracket(static_cast<details::char_t>(t))) 
 04099 |                { 
 04100 |                   switch (base) 
 04101 |                   { 
 04102 |                      case lexer::token::e_rbracket    : return true; 
 04103 |                      case lexer::token::e_rsqrbracket : return true; 
 04104 |                      case lexer::token::e_rcrlbracket : return true; 
 04105 |                      default                          : return false; 
 04106 |                   } 
 04107 |                } 
 04108 |  
 04109 |                return false; 
 04110 |             } 
 04111 |  
 04112 |             set_t invalid_comb_; 
 04113 |             std::vector<std::pair<lexer::token,lexer::token> > error_list_; 
 04114 |          }; 
 04115 |  
 04116 |          class sequence_validator_3tokens exprtk_final : public lexer::token_scanner 
 04117 |          { 
 04118 |          private: 
 04119 |  
 04120 |             typedef lexer::token::token_type token_t; 
 04121 |             typedef std::pair<token_t,std::pair<token_t,token_t> > token_triplet_t; 
 04122 |             typedef std::set<token_triplet_t> set_t; 
 04123 |  
 04124 |          public: 
 04125 |  
 04126 |             using lexer::token_scanner::operator(); 
 04127 |  
 04128 |             sequence_validator_3tokens() 
 04129 |             : lexer::token_scanner(3) 
 04130 |             { 
 04131 |                add_invalid(lexer::token::e_number , lexer::token::e_number , lexer::token::e_number); 
 04132 |                add_invalid(lexer::token::e_string , lexer::token::e_string , lexer::token::e_string); 
 04133 |                add_invalid(lexer::token::e_comma  , lexer::token::e_comma  , lexer::token::e_comma ); 
 04134 |  
 04135 |                add_invalid(lexer::token::e_add    , lexer::token::e_add    , lexer::token::e_add   ); 
 04136 |                add_invalid(lexer::token::e_sub    , lexer::token::e_sub    , lexer::token::e_sub   ); 
 04137 |                add_invalid(lexer::token::e_div    , lexer::token::e_div    , lexer::token::e_div   ); 
 04138 |                add_invalid(lexer::token::e_mul    , lexer::token::e_mul    , lexer::token::e_mul   ); 
 04139 |                add_invalid(lexer::token::e_mod    , lexer::token::e_mod    , lexer::token::e_mod   ); 
 04140 |                add_invalid(lexer::token::e_pow    , lexer::token::e_pow    , lexer::token::e_pow   ); 
 04141 |  
 04142 |                add_invalid(lexer::token::e_add    , lexer::token::e_sub    , lexer::token::e_add   ); 
 04143 |                add_invalid(lexer::token::e_sub    , lexer::token::e_add    , lexer::token::e_sub   ); 
 04144 |                add_invalid(lexer::token::e_div    , lexer::token::e_mul    , lexer::token::e_div   ); 
 04145 |                add_invalid(lexer::token::e_mul    , lexer::token::e_div    , lexer::token::e_mul   ); 
 04146 |                add_invalid(lexer::token::e_mod    , lexer::token::e_pow    , lexer::token::e_mod   ); 
 04147 |                add_invalid(lexer::token::e_pow    , lexer::token::e_mod    , lexer::token::e_pow   ); 
 04148 |             } 
 04149 |  
 04150 |             bool result() exprtk_override 
 04151 |             { 
 04152 |                return error_list_.empty(); 
 04153 |             } 
 04154 |  
 04155 |             bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2) exprtk_override 
 04156 |             { 
 04157 |                const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type)); 
 04158 |  
 04159 |                if (invalid_comb_.find(p) != invalid_comb_.end()) 
 04160 |                { 
 04161 |                   error_list_.push_back(std::make_pair(t0,t1)); 
 04162 |                } 
 04163 |  
 04164 |                return true; 
 04165 |             } 
 04166 |  
 04167 |             std::size_t error_count() const 
 04168 |             { 
 04169 |                return error_list_.size(); 
 04170 |             } 
 04171 |  
 04172 |             std::pair<lexer::token,lexer::token> error(const std::size_t index) 
 04173 |             { 
 04174 |                if (index < error_list_.size()) 
 04175 |                { 
 04176 |                   return error_list_[index]; 
 04177 |                } 
 04178 |                else 
 04179 |                { 
 04180 |                   static const lexer::token error_token; 
 04181 |                   return std::make_pair(error_token,error_token); 
 04182 |                } 
 04183 |             } 
 04184 |  
 04185 |             void clear_errors() 
 04186 |             { 
 04187 |                error_list_.clear(); 
 04188 |             } 
 04189 |  
 04190 |          private: 
 04191 |  
 04192 |             void add_invalid(const token_t t0, const token_t t1, const token_t t2) 
 04193 |             { 
 04194 |                invalid_comb_.insert(std::make_pair(t0,std::make_pair(t1,t2))); 
 04195 |             } 
 04196 |  
 04197 |             set_t invalid_comb_; 
 04198 |             std::vector<std::pair<lexer::token,lexer::token> > error_list_; 
 04199 |          }; 
 04200 |  
 04201 |          struct helper_assembly 
 04202 |          { 
 04203 |             inline bool register_scanner(lexer::token_scanner* scanner) 
 04204 |             { 
 04205 |                if (token_scanner_list.end() != std::find(token_scanner_list.begin(), 
 04206 |                                                          token_scanner_list.end  (), 
 04207 |                                                          scanner)) 
 04208 |                { 
 04209 |                   return false; 
 04210 |                } 
 04211 |  
 04212 |                token_scanner_list.push_back(scanner); 
 04213 |  
 04214 |                return true; 
 04215 |             } 
 04216 |  
 04217 |             inline bool register_modifier(lexer::token_modifier* modifier) 
 04218 |             { 
 04219 |                if (token_modifier_list.end() != std::find(token_modifier_list.begin(), 
 04220 |                                                           token_modifier_list.end  (), 
 04221 |                                                           modifier)) 
 04222 |                { 
 04223 |                   return false; 
 04224 |                } 
 04225 |  
 04226 |                token_modifier_list.push_back(modifier); 
 04227 |  
 04228 |                return true; 
 04229 |             } 
 04230 |  
 04231 |             inline bool register_joiner(lexer::token_joiner* joiner) 
 04232 |             { 
 04233 |                if (token_joiner_list.end() != std::find(token_joiner_list.begin(), 
 04234 |                                                         token_joiner_list.end  (), 
 04235 |                                                         joiner)) 
 04236 |                { 
 04237 |                   return false; 
 04238 |                } 
 04239 |  
 04240 |                token_joiner_list.push_back(joiner); 
 04241 |  
 04242 |                return true; 
 04243 |             } 
 04244 |  
 04245 |             inline bool register_inserter(lexer::token_inserter* inserter) 
 04246 |             { 
 04247 |                if (token_inserter_list.end() != std::find(token_inserter_list.begin(), 
 04248 |                                                           token_inserter_list.end  (), 
 04249 |                                                           inserter)) 
 04250 |                { 
 04251 |                   return false; 
 04252 |                } 
 04253 |  
 04254 |                token_inserter_list.push_back(inserter); 
 04255 |  
 04256 |                return true; 
 04257 |             } 
 04258 |  
 04259 |             inline bool run_modifiers(lexer::generator& g) 
 04260 |             { 
 04261 |                error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0); 
 04262 |  
 04263 |                for (std::size_t i = 0; i < token_modifier_list.size(); ++i) 
 04264 |                { 
 04265 |                   lexer::token_modifier& modifier = (*token_modifier_list[i]); 
 04266 |  
 04267 |                   modifier.reset(); 
 04268 |                   modifier.process(g); 
 04269 |  
 04270 |                   if (!modifier.result()) 
 04271 |                   { 
 04272 |                      error_token_modifier = token_modifier_list[i]; 
 04273 |  
 04274 |                      return false; 
 04275 |                   } 
 04276 |                } 
 04277 |  
 04278 |                return true; 
 04279 |             } 
 04280 |  
 04281 |             inline bool run_joiners(lexer::generator& g) 
 04282 |             { 
 04283 |                error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0); 
 04284 |  
 04285 |                for (std::size_t i = 0; i < token_joiner_list.size(); ++i) 
 04286 |                { 
 04287 |                   lexer::token_joiner& joiner = (*token_joiner_list[i]); 
 04288 |  
 04289 |                   joiner.reset(); 
 04290 |                   joiner.process(g); 
 04291 |  
 04292 |                   if (!joiner.result()) 
 04293 |                   { 
 04294 |                      error_token_joiner = token_joiner_list[i]; 
 04295 |  
 04296 |                      return false; 
 04297 |                   } 
 04298 |                } 
 04299 |  
 04300 |                return true; 
 04301 |             } 
 04302 |  
 04303 |             inline bool run_inserters(lexer::generator& g) 
 04304 |             { 
 04305 |                error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0); 
 04306 |  
 04307 |                for (std::size_t i = 0; i < token_inserter_list.size(); ++i) 
 04308 |                { 
 04309 |                   lexer::token_inserter& inserter = (*token_inserter_list[i]); 
 04310 |  
 04311 |                   inserter.reset(); 
 04312 |                   inserter.process(g); 
 04313 |  
 04314 |                   if (!inserter.result()) 
 04315 |                   { 
 04316 |                      error_token_inserter = token_inserter_list[i]; 
 04317 |  
 04318 |                      return false; 
 04319 |                   } 
 04320 |                } 
 04321 |  
 04322 |                return true; 
 04323 |             } 
 04324 |  
 04325 |             inline bool run_scanners(lexer::generator& g) 
 04326 |             { 
 04327 |                error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0); 
 04328 |  
 04329 |                for (std::size_t i = 0; i < token_scanner_list.size(); ++i) 
 04330 |                { 
 04331 |                   lexer::token_scanner& scanner = (*token_scanner_list[i]); 
 04332 |  
 04333 |                   scanner.reset(); 
 04334 |                   scanner.process(g); 
 04335 |  
 04336 |                   if (!scanner.result()) 
 04337 |                   { 
 04338 |                      error_token_scanner = token_scanner_list[i]; 
 04339 |  
 04340 |                      return false; 
 04341 |                   } 
 04342 |                } 
 04343 |  
 04344 |                return true; 
 04345 |             } 
 04346 |  
 04347 |             std::vector<lexer::token_scanner*>  token_scanner_list; 
 04348 |             std::vector<lexer::token_modifier*> token_modifier_list; 
 04349 |             std::vector<lexer::token_joiner*>   token_joiner_list; 
 04350 |             std::vector<lexer::token_inserter*> token_inserter_list; 
 04351 |  
 04352 |             lexer::token_scanner*  error_token_scanner; 
 04353 |             lexer::token_modifier* error_token_modifier; 
 04354 |             lexer::token_joiner*   error_token_joiner; 
 04355 |             lexer::token_inserter* error_token_inserter; 
 04356 |          }; 
 04357 |       } 
 04358 |  
 04359 |       class parser_helper 
 04360 |       { 
 04361 |       public: 
 04362 |  
 04363 |          typedef token     token_t; 
 04364 |          typedef generator generator_t; 
 04365 |  
 04366 |          inline bool init(const std::string& str) 
 04367 |          { 
 04368 |             if (!lexer_.process(str)) 
 04369 |             { 
 04370 |                return false; 
 04371 |             } 
 04372 |  
 04373 |             lexer_.begin(); 
 04374 |  
 04375 |             next_token(); 
 04376 |  
 04377 |             return true; 
 04378 |          } 
 04379 |  
 04380 |          inline generator_t& lexer() 
 04381 |          { 
 04382 |             return lexer_; 
 04383 |          } 
 04384 |  
 04385 |          inline const generator_t& lexer() const 
 04386 |          { 
 04387 |             return lexer_; 
 04388 |          } 
 04389 |  
 04390 |          inline void store_token() 
 04391 |          { 
 04392 |             lexer_.store(); 
 04393 |             store_current_token_ = current_token_; 
 04394 |          } 
 04395 |  
 04396 |          inline void restore_token() 
 04397 |          { 
 04398 |             lexer_.restore(); 
 04399 |             current_token_ = store_current_token_; 
 04400 |          } 
 04401 |  
 04402 |          inline void next_token() 
 04403 |          { 
 04404 |             current_token_ = lexer_.next_token(); 
 04405 |          } 
 04406 |  
 04407 |          inline const token_t& current_token() const 
 04408 |          { 
 04409 |             return current_token_; 
 04410 |          } 
 04411 |  
 04412 |          inline const token_t& peek_next_token() 
 04413 |          { 
 04414 |             return lexer_.peek_next_token(); 
 04415 |          } 
 04416 |  
 04417 |          enum token_advance_mode 
 04418 |          { 
 04419 |             e_hold    = 0, 
 04420 |             e_advance = 1 
 04421 |          }; 
 04422 |  
 04423 |          inline void advance_token(const token_advance_mode mode) 
 04424 |          { 
 04425 |             if (e_advance == mode) 
 04426 |             { 
 04427 |                next_token(); 
 04428 |             } 
 04429 |          } 
 04430 |  
 04431 |          inline bool token_is(const token_t::token_type& ttype, const token_advance_mode mode = e_advance) 
 04432 |          { 
 04433 |             if (current_token().type != ttype) 
 04434 |             { 
 04435 |                return false; 
 04436 |             } 
 04437 |  
 04438 |             advance_token(mode); 
 04439 |  
 04440 |             return true; 
 04441 |          } 
 04442 |  
 04443 |          inline bool token_is(const token_t::token_type& ttype, 
 04444 |                               const std::string& value, 
 04445 |                               const token_advance_mode mode = e_advance) 
 04446 |          { 
 04447 |             if ( 
 04448 |                  (current_token().type != ttype) || 
 04449 |                  !exprtk::details::imatch(value,current_token().value) 
 04450 |                ) 
 04451 |             { 
 04452 |                return false; 
 04453 |             } 
 04454 |  
 04455 |             advance_token(mode); 
 04456 |  
 04457 |             return true; 
 04458 |          } 
 04459 |  
 04460 |          inline bool token_is(const std::string& value, 
 04461 |                               const token_advance_mode mode = e_advance) 
 04462 |          { 
 04463 |             if (!exprtk::details::imatch(value,current_token().value)) 
 04464 |             { 
 04465 |                return false; 
 04466 |             } 
 04467 |  
 04468 |             advance_token(mode); 
 04469 |  
 04470 |             return true; 
 04471 |          } 
 04472 |  
 04473 |          inline bool token_is_arithmetic_opr(const token_advance_mode mode = e_advance) 
 04474 |          { 
 04475 |             switch (current_token().type) 
 04476 |             { 
 04477 |                case token_t::e_add : 
 04478 |                case token_t::e_sub : 
 04479 |                case token_t::e_div : 
 04480 |                case token_t::e_mul : 
 04481 |                case token_t::e_mod : 
 04482 |                case token_t::e_pow : break; 
 04483 |                default             : return false; 
 04484 |             } 
 04485 |  
 04486 |             advance_token(mode); 
 04487 |  
 04488 |             return true; 
 04489 |          } 
 04490 |  
 04491 |          inline bool token_is_ineq_opr(const token_advance_mode mode = e_advance) 
 04492 |          { 
 04493 |             switch (current_token().type) 
 04494 |             { 
 04495 |                case token_t::e_eq  : 
 04496 |                case token_t::e_lte : 
 04497 |                case token_t::e_ne  : 
 04498 |                case token_t::e_gte : 
 04499 |                case token_t::e_lt  : 
 04500 |                case token_t::e_gt  : break; 
 04501 |                default             : return false; 
 04502 |             } 
 04503 |  
 04504 |             advance_token(mode); 
 04505 |  
 04506 |             return true; 
 04507 |          } 
 04508 |  
 04509 |          inline bool token_is_left_bracket(const token_advance_mode mode = e_advance) 
 04510 |          { 
 04511 |             switch (current_token().type) 
 04512 |             { 
 04513 |                case token_t::e_lbracket    : 
 04514 |                case token_t::e_lcrlbracket : 
 04515 |                case token_t::e_lsqrbracket : break; 
 04516 |                default                     : return false; 
 04517 |             } 
 04518 |  
 04519 |             advance_token(mode); 
 04520 |  
 04521 |             return true; 
 04522 |          } 
 04523 |  
 04524 |          inline bool token_is_right_bracket(const token_advance_mode mode = e_advance) 
 04525 |          { 
 04526 |             switch (current_token().type) 
 04527 |             { 
 04528 |                case token_t::e_rbracket    : 
 04529 |                case token_t::e_rcrlbracket : 
 04530 |                case token_t::e_rsqrbracket : break; 
 04531 |                default                     : return false; 
 04532 |             } 
 04533 |  
 04534 |             advance_token(mode); 
 04535 |  
 04536 |             return true; 
 04537 |          } 
 04538 |  
 04539 |          inline bool token_is_bracket(const token_advance_mode mode = e_advance) 
 04540 |          { 
 04541 |             switch (current_token().type) 
 04542 |             { 
 04543 |                case token_t::e_rbracket    : 
 04544 |                case token_t::e_rcrlbracket : 
 04545 |                case token_t::e_rsqrbracket : 
 04546 |                case token_t::e_lbracket    : 
 04547 |                case token_t::e_lcrlbracket : 
 04548 |                case token_t::e_lsqrbracket : break; 
 04549 |                default                     : return false; 
 04550 |             } 
 04551 |  
 04552 |             advance_token(mode); 
 04553 |  
 04554 |             return true; 
 04555 |          } 
 04556 |  
 04557 |          inline bool token_is_loop(const token_advance_mode mode = e_advance) 
 04558 |          { 
 04559 |             return token_is("for"   , mode) || 
 04560 |                    token_is("while" , mode) || 
 04561 |                    token_is("repeat", mode) ; 
 04562 |          } 
 04563 |  
 04564 |          inline bool peek_token_is(const token_t::token_type& ttype) 
 04565 |          { 
 04566 |             return (lexer_.peek_next_token().type == ttype); 
 04567 |          } 
 04568 |  
 04569 |          inline bool peek_token_is(const std::string& s) 
 04570 |          { 
 04571 |             return (exprtk::details::imatch(lexer_.peek_next_token().value,s)); 
 04572 |          } 
 04573 |  
 04574 |       private: 
 04575 |  
 04576 |          generator_t lexer_; 
 04577 |          token_t     current_token_; 
 04578 |          token_t     store_current_token_; 
 04579 |       }; 
 04580 |    } 
 04581 |  
 04582 |    template <typename T> 
 04583 |    class vector_view 
 04584 |    { 
 04585 |    public: 
 04586 |  
 04587 |       typedef T* data_ptr_t; 
 04588 |  
 04589 |       vector_view(data_ptr_t data, const std::size_t& size) 
 04590 |       : base_size_(size) 
 04591 |       , size_(size) 
 04592 |       , data_(data) 
 04593 |       , data_ref_(0) 
 04594 |       { 
 04595 |          assert(size_ > 0); 
 04596 |       } 
 04597 |  
 04598 |       vector_view(const vector_view<T>& vv) 
 04599 |       : base_size_(vv.base_size_) 
 04600 |       , size_(vv.size_) 
 04601 |       , data_(vv.data_) 
 04602 |       , data_ref_(0) 
 04603 |       { 
 04604 |          assert(size_ > 0); 
 04605 |       } 
 04606 |  
 04607 |       inline void rebase(data_ptr_t data) 
 04608 |       { 
 04609 |          data_ = data; 
 04610 |  
 04611 |          if (!data_ref_.empty()) 
 04612 |          { 
 04613 |             for (std::size_t i = 0; i < data_ref_.size(); ++i) 
 04614 |             { 
 04615 |                (*data_ref_[i]) = data; 
 04616 |             } 
 04617 |          } 
 04618 |       } 
 04619 |  
 04620 |       inline data_ptr_t data() const 
 04621 |       { 
 04622 |          return data_; 
 04623 |       } 
 04624 |  
 04625 |       inline std::size_t base_size() const 
 04626 |       { 
 04627 |          return base_size_; 
 04628 |       } 
 04629 |  
 04630 |       inline std::size_t size() const 
 04631 |       { 
 04632 |          return size_; 
 04633 |       } 
 04634 |  
 04635 |       inline const T& operator[](const std::size_t index) const 
 04636 |       { 
 04637 |          assert(index < size_); 
 04638 |          return data_[index]; 
 04639 |       } 
 04640 |  
 04641 |       inline T& operator[](const std::size_t index) 
 04642 |       { 
 04643 |          assert(index < size_); 
 04644 |          return data_[index]; 
 04645 |       } 
 04646 |  
 04647 |       void set_ref(data_ptr_t* data_ref) 
 04648 |       { 
 04649 |          data_ref_.push_back(data_ref); 
 04650 |          exprtk_debug(("vector_view::set_ref() - data_ref: %p data_ref_.size(): %d\n", 
 04651 |                        reinterpret_cast<void*>(data_ref), 
 04652 |                        static_cast<int>(data_ref_.size()))); 
 04653 |       } 
 04654 |  
 04655 |       void remove_ref(data_ptr_t* data_ref) 
 04656 |       { 
 04657 |          data_ref_.erase( 
 04658 |             std::remove(data_ref_.begin(), data_ref_.end(), data_ref), 
 04659 |             data_ref_.end()); 
 04660 |          exprtk_debug(("vector_view::remove_ref() - data_ref: %p data_ref_.size(): %d\n", 
 04661 |                        reinterpret_cast<void*>(data_ref), 
 04662 |                        static_cast<int>(data_ref_.size()))); 
 04663 |       } 
 04664 |  
 04665 |       bool set_size(const std::size_t new_size) 
 04666 |       { 
 04667 |          if ((new_size > 0) && (new_size <= base_size_)) 
 04668 |          { 
 04669 |             size_ = new_size; 
 04670 |             exprtk_debug(("vector_view::set_size() - data_: %p size: %lu\n", 
 04671 |                           reinterpret_cast<void*>(data_), 
 04672 |                           size_)); 
 04673 |             return true; 
 04674 |          } 
 04675 |  
 04676 |          exprtk_debug(("vector_view::set_size() - error invalid new_size: %lu  base_size: %lu\n", 
 04677 |                        new_size, 
 04678 |                        base_size_)); 
 04679 |          return false; 
 04680 |       } 
 04681 |  
 04682 |    private: 
 04683 |  
 04684 |       const std::size_t base_size_; 
 04685 |       std::size_t size_; 
 04686 |       data_ptr_t  data_; 
 04687 |       std::vector<data_ptr_t*> data_ref_; 
 04688 |    }; 
 04689 |  
 04690 |    template <typename T> 
 04691 |    inline vector_view<T> make_vector_view(T* data, 
 04692 |                                           const std::size_t size, const std::size_t offset = 0) 
 04693 |    { 
 04694 |       return vector_view<T>(data + offset, size); 
 04695 |    } 
 04696 |  
 04697 |    template <typename T> 
 04698 |    inline vector_view<T> make_vector_view(std::vector<T>& v, 
 04699 |                                           const std::size_t size, const std::size_t offset = 0) 
 04700 |    { 
 04701 |       return vector_view<T>(v.data() + offset, size); 
 04702 |    } 
 04703 |  
 04704 |    template <typename T> class results_context; 
 04705 |  
 04706 |    template <typename T> 
 04707 |    struct type_store 
 04708 |    { 
 04709 |       enum store_type 
 04710 |       { 
 04711 |          e_unknown, 
 04712 |          e_scalar , 
 04713 |          e_vector , 
 04714 |          e_string 
 04715 |       }; 
 04716 |  
 04717 |       type_store() 
 04718 |       : data(0) 
 04719 |       , size(0) 
 04720 |       , type(e_unknown) 
 04721 |       {} 
 04722 |  
 04723 |       union 
 04724 |       { 
 04725 |          void* data; 
 04726 |          T*    vec_data; 
 04727 |       }; 
 04728 |  
 04729 |       std::size_t size; 
 04730 |       store_type  type; 
 04731 |  
 04732 |       class parameter_list 
 04733 |       { 
 04734 |       public: 
 04735 |  
 04736 |          explicit parameter_list(std::vector<type_store>& pl) 
 04737 |          : parameter_list_(pl) 
 04738 |          {} 
 04739 |  
 04740 |          inline bool empty() const 
 04741 |          { 
 04742 |             return parameter_list_.empty(); 
 04743 |          } 
 04744 |  
 04745 |          inline std::size_t size() const 
 04746 |          { 
 04747 |             return parameter_list_.size(); 
 04748 |          } 
 04749 |  
 04750 |          inline type_store& operator[](const std::size_t& index) 
 04751 |          { 
 04752 |             return parameter_list_[index]; 
 04753 |          } 
 04754 |  
 04755 |          inline const type_store& operator[](const std::size_t& index) const 
 04756 |          { 
 04757 |             return parameter_list_[index]; 
 04758 |          } 
 04759 |  
 04760 |          inline type_store& front() 
 04761 |          { 
 04762 |             return parameter_list_[0]; 
 04763 |          } 
 04764 |  
 04765 |          inline const type_store& front() const 
 04766 |          { 
 04767 |             return parameter_list_[0]; 
 04768 |          } 
 04769 |  
 04770 |          inline type_store& back() 
 04771 |          { 
 04772 |             return parameter_list_.back(); 
 04773 |          } 
 04774 |  
 04775 |          inline const type_store& back() const 
 04776 |          { 
 04777 |             return parameter_list_.back(); 
 04778 |          } 
 04779 |  
 04780 |       private: 
 04781 |  
 04782 |          std::vector<type_store>& parameter_list_; 
 04783 |  
 04784 |          friend class results_context<T>; 
 04785 |       }; 
 04786 |  
 04787 |       template <typename ViewType> 
 04788 |       struct type_view 
 04789 |       { 
 04790 |          typedef type_store<T> type_store_t; 
 04791 |          typedef ViewType      value_t; 
 04792 |  
 04793 |          explicit type_view(type_store_t& ts) 
 04794 |          : ts_(ts) 
 04795 |          , data_(reinterpret_cast<value_t*>(ts_.data)) 
 04796 |          {} 
 04797 |  
 04798 |          explicit type_view(const type_store_t& ts) 
 04799 |          : ts_(const_cast<type_store_t&>(ts)) 
 04800 |          , data_(reinterpret_cast<value_t*>(ts_.data)) 
 04801 |          {} 
 04802 |  
 04803 |          inline std::size_t size() const 
 04804 |          { 
 04805 |             return ts_.size; 
 04806 |          } 
 04807 |  
 04808 |          inline value_t& operator[](const std::size_t& i) 
 04809 |          { 
 04810 |             return data_[i]; 
 04811 |          } 
 04812 |  
 04813 |          inline const value_t& operator[](const std::size_t& i) const 
 04814 |          { 
 04815 |             return data_[i]; 
 04816 |          } 
 04817 |  
 04818 |          inline const value_t* begin() const { return data_; } 
 04819 |          inline       value_t* begin()       { return data_; } 
 04820 |  
 04821 |          inline const value_t* end() const 
 04822 |          { 
 04823 |             return static_cast<value_t*>(data_ + ts_.size); 
 04824 |          } 
 04825 |  
 04826 |          inline value_t* end() 
 04827 |          { 
 04828 |             return static_cast<value_t*>(data_ + ts_.size); 
 04829 |          } 
 04830 |  
 04831 |          type_store_t& ts_; 
 04832 |          value_t* data_; 
 04833 |       }; 
 04834 |  
 04835 |       typedef type_view<T>    vector_view; 
 04836 |       typedef type_view<char> string_view; 
 04837 |  
 04838 |       struct scalar_view 
 04839 |       { 
 04840 |          typedef type_store<T> type_store_t; 
 04841 |          typedef T value_t; 
 04842 |  
 04843 |          explicit scalar_view(type_store_t& ts) 
 04844 |          : v_(*reinterpret_cast<value_t*>(ts.data)) 
 04845 |          {} 
 04846 |  
 04847 |          explicit scalar_view(const type_store_t& ts) 
 04848 |          : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data)) 
 04849 |          {} 
 04850 |  
 04851 |          inline value_t& operator() () 
 04852 |          { 
 04853 |             return v_; 
 04854 |          } 
 04855 |  
 04856 |          inline const value_t& operator() () const 
 04857 |          { 
 04858 |             return v_; 
 04859 |          } 
 04860 |  
 04861 |          inline operator value_t() const 
 04862 |          { 
 04863 |             return v_; 
 04864 |          } 
 04865 |  
 04866 |          inline operator value_t() 
 04867 |          { 
 04868 |             return v_; 
 04869 |          } 
 04870 |  
 04871 |          template <typename IntType> 
 04872 |          inline bool to_int(IntType& i) const 
 04873 |          { 
 04874 |             if (!exprtk::details::numeric::is_integer(v_)) 
 04875 |                return false; 
 04876 |  
 04877 |             i = static_cast<IntType>(v_); 
 04878 |  
 04879 |             return true; 
 04880 |          } 
 04881 |  
 04882 |          template <typename UIntType> 
 04883 |          inline bool to_uint(UIntType& u) const 
 04884 |          { 
 04885 |             if (v_ < T(0)) 
 04886 |                return false; 
 04887 |             else if (!exprtk::details::numeric::is_integer(v_)) 
 04888 |                return false; 
 04889 |  
 04890 |             u = static_cast<UIntType>(v_); 
 04891 |  
 04892 |             return true; 
 04893 |          } 
 04894 |  
 04895 |          T& v_; 
 04896 |       }; 
 04897 |    }; 
 04898 |  
 04899 |    template <typename StringView> 
 04900 |    inline std::string to_str(const StringView& view) 
 04901 |    { 
 04902 |       return std::string(view.begin(),view.size()); 
 04903 |    } 
 04904 |  
 04905 |    #ifndef exprtk_disable_return_statement 
 04906 |    namespace details 
 04907 |    { 
 04908 |       template <typename T> class return_node; 
 04909 |       template <typename T> class return_envelope_node; 
 04910 |    } 
 04911 |    #endif 
 04912 |  
 04913 |    template <typename T> 
 04914 |    class results_context 
 04915 |    { 
 04916 |    public: 
 04917 |  
 04918 |       typedef type_store<T> type_store_t; 
 04919 |       typedef typename type_store_t::scalar_view scalar_t; 
 04920 |       typedef typename type_store_t::vector_view vector_t; 
 04921 |       typedef typename type_store_t::string_view string_t; 
 04922 |  
 04923 |       results_context() 
 04924 |       : results_available_(false) 
 04925 |       {} 
 04926 |  
 04927 |       inline std::size_t count() const 
 04928 |       { 
 04929 |          if (results_available_) 
 04930 |             return parameter_list_.size(); 
 04931 |          else 
 04932 |             return 0; 
 04933 |       } 
 04934 |  
 04935 |       inline type_store_t& operator[](const std::size_t& index) 
 04936 |       { 
 04937 |          return parameter_list_[index]; 
 04938 |       } 
 04939 |  
 04940 |       inline const type_store_t& operator[](const std::size_t& index) const 
 04941 |       { 
 04942 |          return parameter_list_[index]; 
 04943 |       } 
 04944 |  
 04945 |       inline bool get_scalar(const std::size_t& index, T& out) const 
 04946 |       { 
 04947 |          if ( 
 04948 |               (index < parameter_list_.size()) && 
 04949 |               (parameter_list_[index].type == type_store_t::e_scalar) 
 04950 |             ) 
 04951 |          { 
 04952 |             const scalar_t scalar(parameter_list_[index]); 
 04953 |             out = scalar(); 
 04954 |             return true; 
 04955 |          } 
 04956 |  
 04957 |          return false; 
 04958 |       } 
 04959 |  
 04960 |       template <typename OutputIterator> 
 04961 |       inline bool get_vector(const std::size_t& index, OutputIterator out_itr) const 
 04962 |       { 
 04963 |          if ( 
 04964 |               (index < parameter_list_.size()) && 
 04965 |               (parameter_list_[index].type == type_store_t::e_vector) 
 04966 |             ) 
 04967 |          { 
 04968 |             const vector_t vector(parameter_list_[index]); 
 04969 |             for (std::size_t i = 0; i < vector.size(); ++i) 
 04970 |             { 
 04971 |                *(out_itr++) = vector[i]; 
 04972 |             } 
 04973 |  
 04974 |             return true; 
 04975 |          } 
 04976 |  
 04977 |          return false; 
 04978 |       } 
 04979 |  
 04980 |       inline bool get_vector(const std::size_t& index, std::vector<T>& out) const 
 04981 |       { 
 04982 |          return get_vector(index,std::back_inserter(out)); 
 04983 |       } 
 04984 |  
 04985 |       inline bool get_string(const std::size_t& index, std::string& out) const 
 04986 |       { 
 04987 |          if ( 
 04988 |               (index < parameter_list_.size()) && 
 04989 |               (parameter_list_[index].type == type_store_t::e_string) 
 04990 |             ) 
 04991 |          { 
 04992 |             const string_t str(parameter_list_[index]); 
 04993 |             out.assign(str.begin(),str.size()); 
 04994 |             return true; 
 04995 |          } 
 04996 |  
 04997 |          return false; 
 04998 |       } 
 04999 |  
 05000 |    private: 
 05001 |  
 05002 |       inline void clear() 
 05003 |       { 
 05004 |          results_available_ = false; 
 05005 |       } 
 05006 |  
 05007 |       typedef std::vector<type_store_t> ts_list_t; 
 05008 |       typedef typename type_store_t::parameter_list parameter_list_t; 
 05009 |  
 05010 |       inline void assign(const parameter_list_t& pl) 
 05011 |       { 
 05012 |          parameter_list_    = pl.parameter_list_; 
 05013 |          results_available_ = true; 
 05014 |       } 
 05015 |  
 05016 |       bool results_available_; 
 05017 |       ts_list_t parameter_list_; 
 05018 |  
 05019 |       #ifndef exprtk_disable_return_statement 
 05020 |       friend class details::return_node<T>; 
 05021 |       friend class details::return_envelope_node<T>; 
 05022 |       #endif 
 05023 |    }; 
 05024 |  
 05025 |    namespace details 
 05026 |    { 
 05027 |       enum operator_type 
 05028 |       { 
 05029 |          e_default , e_null    , e_add     , e_sub     , 
 05030 |          e_mul     , e_div     , e_mod     , e_pow     , 
 05031 |          e_atan2   , e_min     , e_max     , e_avg     , 
 05032 |          e_sum     , e_prod    , e_lt      , e_lte     , 
 05033 |          e_eq      , e_equal   , e_ne      , e_nequal  , 
 05034 |          e_gte     , e_gt      , e_and     , e_nand    , 
 05035 |          e_or      , e_nor     , e_xor     , e_xnor    , 
 05036 |          e_mand    , e_mor     , e_scand   , e_scor    , 
 05037 |          e_shr     , e_shl     , e_abs     , e_acos    , 
 05038 |          e_acosh   , e_asin    , e_asinh   , e_atan    , 
 05039 |          e_atanh   , e_ceil    , e_cos     , e_cosh    , 
 05040 |          e_exp     , e_expm1   , e_floor   , e_log     , 
 05041 |          e_log10   , e_log2    , e_log1p   , e_logn    , 
 05042 |          e_neg     , e_pos     , e_round   , e_roundn  , 
 05043 |          e_root    , e_sqrt    , e_sin     , e_sinc    , 
 05044 |          e_sinh    , e_sec     , e_csc     , e_tan     , 
 05045 |          e_tanh    , e_cot     , e_clamp   , e_iclamp  , 
 05046 |          e_inrange , e_sgn     , e_r2d     , e_d2r     , 
 05047 |          e_d2g     , e_g2d     , e_hypot   , e_notl    , 
 05048 |          e_erf     , e_erfc    , e_ncdf    , e_frac    , 
 05049 |          e_trunc   , e_assign  , e_addass  , e_subass  , 
 05050 |          e_mulass  , e_divass  , e_modass  , e_in      , 
 05051 |          e_like    , e_ilike   , e_multi   , e_smulti  , 
 05052 |          e_swap    , 
 05053 |  
 05054 |          // Do not add new functions/operators after this point. 
 05055 |          e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003, 
 05056 |          e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007, 
 05057 |          e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011, 
 05058 |          e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015, 
 05059 |          e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019, 
 05060 |          e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023, 
 05061 |          e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027, 
 05062 |          e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031, 
 05063 |          e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035, 
 05064 |          e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039, 
 05065 |          e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043, 
 05066 |          e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047, 
 05067 |          e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051, 
 05068 |          e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055, 
 05069 |          e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059, 
 05070 |          e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063, 
 05071 |          e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067, 
 05072 |          e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071, 
 05073 |          e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075, 
 05074 |          e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079, 
 05075 |          e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083, 
 05076 |          e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087, 
 05077 |          e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091, 
 05078 |          e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095, 
 05079 |          e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099, 
 05080 |          e_sffinal  = 1100, 
 05081 |          e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003, 
 05082 |          e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007, 
 05083 |          e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011, 
 05084 |          e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015, 
 05085 |          e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019, 
 05086 |          e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023, 
 05087 |          e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027, 
 05088 |          e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031, 
 05089 |          e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035, 
 05090 |          e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039, 
 05091 |          e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043, 
 05092 |          e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047, 
 05093 |          e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051, 
 05094 |          e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055, 
 05095 |          e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059, 
 05096 |          e_sf4ext60 = 2060, e_sf4ext61 = 2061 
 05097 |       }; 
 05098 |  
 05099 |       inline std::string to_str(const operator_type opr) 
 05100 |       { 
 05101 |          switch (opr) 
 05102 |          { 
 05103 |             case e_add    : return  "+"  ; 
 05104 |             case e_sub    : return  "-"  ; 
 05105 |             case e_mul    : return  "*"  ; 
 05106 |             case e_div    : return  "/"  ; 
 05107 |             case e_mod    : return  "%"  ; 
 05108 |             case e_pow    : return  "^"  ; 
 05109 |             case e_assign : return ":="  ; 
 05110 |             case e_addass : return "+="  ; 
 05111 |             case e_subass : return "-="  ; 
 05112 |             case e_mulass : return "*="  ; 
 05113 |             case e_divass : return "/="  ; 
 05114 |             case e_modass : return "%="  ; 
 05115 |             case e_lt     : return  "<"  ; 
 05116 |             case e_lte    : return "<="  ; 
 05117 |             case e_eq     : return "=="  ; 
 05118 |             case e_equal  : return  "="  ; 
 05119 |             case e_ne     : return "!="  ; 
 05120 |             case e_nequal : return "<>"  ; 
 05121 |             case e_gte    : return ">="  ; 
 05122 |             case e_gt     : return  ">"  ; 
 05123 |             case e_and    : return "and" ; 
 05124 |             case e_or     : return "or"  ; 
 05125 |             case e_xor    : return "xor" ; 
 05126 |             case e_nand   : return "nand" 
 05127 |             case e_nor    : return "nor" ; 
 05128 |             case e_xnor   : return "xnor" 
 05129 |             default       : return "N/A" ; 
 05130 |          } 
 05131 |       } 
 05132 |  
 05133 |       struct base_operation_t 
 05134 |       { 
 05135 |          base_operation_t(const operator_type t, const unsigned int& np) 
 05136 |          : type(t) 
 05137 |          , num_params(np) 
 05138 |          {} 
 05139 |  
 05140 |          operator_type type; 
 05141 |          unsigned int num_params; 
 05142 |       }; 
 05143 |  
 05144 |       namespace loop_unroll 
 05145 |       { 
 05146 |          const unsigned int global_loop_batch_size = 
 05147 |          #ifndef exprtk_disable_superscalar_unroll 
 05148 |          16; 
 05149 |          #else 
 05150 |           4; 
 05151 |          #endif 
 05152 |  
 05153 |          struct details 
 05154 |          { 
 05155 |             explicit details(const std::size_t& vsize, 
 05156 |                              const unsigned int loop_batch_size = global_loop_batch_size) 
 05157 |             : batch_size(loop_batch_size   ) 
 05158 |             , remainder (vsize % batch_size) 
 05159 |             , upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0))) 
 05160 |             {} 
 05161 |  
 05162 |             unsigned int batch_size; 
 05163 |             int remainder; 
 05164 |             int upper_bound; 
 05165 |          }; 
 05166 |       } 
 05167 |  
 05168 |       #ifdef exprtk_enable_debugging 
 05169 |       inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0) 
 05170 |       { 
 05171 |          if (size) 
 05172 |             exprtk_debug(("%s - addr: %p size: %d\n", 
 05173 |                           s.c_str(), 
 05174 |                           ptr, 
 05175 |                           static_cast<unsigned int>(size))); 
 05176 |          else 
 05177 |             exprtk_debug(("%s - addr: %p\n", s.c_str(), ptr)); 
 05178 |       } 
 05179 |  
 05180 |       template <typename T> 
 05181 |       inline void dump_vector(const std::string& vec_name, const T* data, const std::size_t size) 
 05182 |       { 
 05183 |          printf("----- %s (%p) -----\n", 
 05184 |                 vec_name.c_str(), 
 05185 |                 static_cast<const void*>(data)); 
 05186 |          printf("[ "); 
 05187 |          for (std::size_t i = 0; i <  size; ++i) 
 05188 |          { 
 05189 |             printf("%8.3f\t", data[i]); 
 05190 |          } 
 05191 |          printf(" ]\n"); 
 05192 |          printf("---------------------\n"); 
 05193 |       } 
 05194 |       #else 
 05195 |       inline void dump_ptr(const std::string&, const void*) {} 
 05196 |       inline void dump_ptr(const std::string&, const void*, const std::size_t) {} 
 05197 |       template <typename T> 
 05198 |       inline void dump_vector(const std::string&, const T*, const std::size_t) {} 
 05199 |       #endif 
 05200 |  
 05201 |       template <typename T> 
 05202 |       class vec_data_store 
 05203 |       { 
 05204 |       public: 
 05205 |  
 05206 |          typedef vec_data_store<T> type; 
 05207 |          typedef T* data_t; 
 05208 |  
 05209 |       private: 
 05210 |  
 05211 |          struct control_block 
 05212 |          { 
 05213 |             control_block() 
 05214 |             : ref_count(1) 
 05215 |             , size     (0) 
 05216 |             , data     (0) 
 05217 |             , destruct (true) 
 05218 |             {} 
 05219 |  
 05220 |             explicit control_block(const std::size_t& dsize) 
 05221 |             : ref_count(1    ) 
 05222 |             , size     (dsize) 
 05223 |             , data     (0    ) 
 05224 |             , destruct (true ) 
 05225 |             { create_data(); } 
 05226 |  
 05227 |             control_block(const std::size_t& dsize, data_t dptr, bool dstrct = false) 
 05228 |             : ref_count(1     ) 
 05229 |             , size     (dsize ) 
 05230 |             , data     (dptr  ) 
 05231 |             , destruct (dstrct) 
 05232 |             {} 
 05233 |  
 05234 |            ~control_block() 
 05235 |             { 
 05236 |                if (data && destruct && (0 == ref_count)) 
 05237 |                { 
 05238 |                   dump_ptr("~vec_data_store::control_block() data",data); 
 05239 |                   delete[] data; 
 05240 |                   data = reinterpret_cast<data_t>(0); 
 05241 |                } 
 05242 |             } 
 05243 |  
 05244 |             static inline control_block* create(const std::size_t& dsize, data_t data_ptr = data_t(0), bool dstrct = false) 
 05245 |             { 
 05246 |                if (dsize) 
 05247 |                { 
 05248 |                   if (0 == data_ptr) 
 05249 |                      return (new control_block(dsize)); 
 05250 |                   else 
 05251 |                      return (new control_block(dsize, data_ptr, dstrct)); 
 05252 |                } 
 05253 |                else 
 05254 |                   return (new control_block); 
 05255 |             } 
 05256 |  
 05257 |             static inline void destroy(control_block*& cntrl_blck) 
 05258 |             { 
 05259 |                if (cntrl_blck) 
 05260 |                { 
 05261 |                   if ( 
 05262 |                        (0 !=   cntrl_blck->ref_count) && 
 05263 |                        (0 == --cntrl_blck->ref_count) 
 05264 |                      ) 
 05265 |                   { 
 05266 |                      delete cntrl_blck; 
 05267 |                   } 
 05268 |  
 05269 |                   cntrl_blck = 0; 
 05270 |                } 
 05271 |             } 
 05272 |  
 05273 |             std::size_t ref_count; 
 05274 |             std::size_t size; 
 05275 |             data_t      data; 
 05276 |             bool        destruct; 
 05277 |  
 05278 |          private: 
 05279 |  
 05280 |             control_block(const control_block&) exprtk_delete; 
 05281 |             control_block& operator=(const control_block&) exprtk_delete; 
 05282 |  
 05283 |             inline void create_data() 
 05284 |             { 
 05285 |                destruct = true; 
 05286 |                data     = new T[size]; 
 05287 |                std::fill_n(data, size, T(0)); 
 05288 |                dump_ptr("control_block::create_data() - data", data, size); 
 05289 |             } 
 05290 |          }; 
 05291 |  
 05292 |       public: 
 05293 |  
 05294 |          vec_data_store() 
 05295 |          : control_block_(control_block::create(0)) 
 05296 |          {} 
 05297 |  
 05298 |          explicit vec_data_store(const std::size_t& size) 
 05299 |          : control_block_(control_block::create(size,reinterpret_cast<data_t>(0),true)) 
 05300 |          {} 
 05301 |  
 05302 |          vec_data_store(const std::size_t& size, data_t data, bool dstrct = false) 
 05303 |          : control_block_(control_block::create(size, data, dstrct)) 
 05304 |          {} 
 05305 |  
 05306 |          vec_data_store(const type& vds) 
 05307 |          { 
 05308 |             control_block_ = vds.control_block_; 
 05309 |             control_block_->ref_count++; 
 05310 |          } 
 05311 |  
 05312 |         ~vec_data_store() 
 05313 |          { 
 05314 |             control_block::destroy(control_block_); 
 05315 |          } 
 05316 |  
 05317 |          type& operator=(const type& vds) 
 05318 |          { 
 05319 |             if (this != &vds) 
 05320 |             { 
 05321 |                const std::size_t final_size = min_size(control_block_, vds.control_block_); 
 05322 |  
 05323 |                vds.control_block_->size = final_size; 
 05324 |                    control_block_->size = final_size; 
 05325 |  
 05326 |                if (control_block_->destruct || (0 == control_block_->data)) 
 05327 |                { 
 05328 |                   control_block::destroy(control_block_); 
 05329 |  
 05330 |                   control_block_ = vds.control_block_; 
 05331 |                   control_block_->ref_count++; 
 05332 |                } 
 05333 |             } 
 05334 |  
 05335 |             return (*this); 
 05336 |          } 
 05337 |  
 05338 |          inline data_t data() 
 05339 |          { 
 05340 |             return control_block_->data; 
 05341 |          } 
 05342 |  
 05343 |          inline data_t data() const 
 05344 |          { 
 05345 |             return control_block_->data; 
 05346 |          } 
 05347 |  
 05348 |          inline std::size_t size() const 
 05349 |          { 
 05350 |             return control_block_->size; 
 05351 |          } 
 05352 |  
 05353 |          inline data_t& ref() 
 05354 |          { 
 05355 |             return control_block_->data; 
 05356 |          } 
 05357 |  
 05358 |          inline void dump() const 
 05359 |          { 
 05360 |             #ifdef exprtk_enable_debugging 
 05361 |             exprtk_debug(("size: %d\taddress:%p\tdestruct:%c\n", 
 05362 |                           size(), 
 05363 |                           data(), 
 05364 |                           (control_block_->destruct ? 'T' : 'F'))); 
 05365 |  
 05366 |             for (std::size_t i = 0; i < size(); ++i) 
 05367 |             { 
 05368 |                if (5 == i) 
 05369 |                   exprtk_debug(("\n")); 
 05370 |  
 05371 |                exprtk_debug(("%15.10f ", data()[i])); 
 05372 |             } 
 05373 |             exprtk_debug(("\n")); 
 05374 |             #endif 
 05375 |          } 
 05376 |  
 05377 |          static inline void match_sizes(type& vds0, type& vds1) 
 05378 |          { 
 05379 |             const std::size_t size = min_size(vds0.control_block_,vds1.control_block_); 
 05380 |             vds0.control_block_->size = size; 
 05381 |             vds1.control_block_->size = size; 
 05382 |          } 
 05383 |  
 05384 |       private: 
 05385 |  
 05386 |          static inline std::size_t min_size(const control_block* cb0, const control_block* cb1) 
 05387 |          { 
 05388 |             const std::size_t size0 = cb0->size; 
 05389 |             const std::size_t size1 = cb1->size; 
 05390 |  
 05391 |             if (size0 && size1) 
 05392 |                return std::min(size0,size1); 
 05393 |             else 
 05394 |                return (size0) ? size0 : size1; 
 05395 |          } 
 05396 |  
 05397 |          control_block* control_block_; 
 05398 |       }; 
 05399 |  
 05400 |       namespace numeric 
 05401 |       { 
 05402 |          namespace details 
 05403 |          { 
 05404 |             template <typename T> 
 05405 |             inline T process_impl(const operator_type operation, const T arg) 
 05406 |             { 
 05407 |                switch (operation) 
 05408 |                { 
 05409 |                   case e_abs   : return numeric::abs  (arg); 
 05410 |                   case e_acos  : return numeric::acos (arg); 
 05411 |                   case e_acosh : return numeric::acosh(arg); 
 05412 |                   case e_asin  : return numeric::asin (arg); 
 05413 |                   case e_asinh : return numeric::asinh(arg); 
 05414 |                   case e_atan  : return numeric::atan (arg); 
 05415 |                   case e_atanh : return numeric::atanh(arg); 
 05416 |                   case e_ceil  : return numeric::ceil (arg); 
 05417 |                   case e_cos   : return numeric::cos  (arg); 
 05418 |                   case e_cosh  : return numeric::cosh (arg); 
 05419 |                   case e_exp   : return numeric::exp  (arg); 
 05420 |                   case e_expm1 : return numeric::expm1(arg); 
 05421 |                   case e_floor : return numeric::floor(arg); 
 05422 |                   case e_log   : return numeric::log  (arg); 
 05423 |                   case e_log10 : return numeric::log10(arg); 
 05424 |                   case e_log2  : return numeric::log2 (arg); 
 05425 |                   case e_log1p : return numeric::log1p(arg); 
 05426 |                   case e_neg   : return numeric::neg  (arg); 
 05427 |                   case e_pos   : return numeric::pos  (arg); 
 05428 |                   case e_round : return numeric::round(arg); 
 05429 |                   case e_sin   : return numeric::sin  (arg); 
 05430 |                   case e_sinc  : return numeric::sinc (arg); 
 05431 |                   case e_sinh  : return numeric::sinh (arg); 
 05432 |                   case e_sqrt  : return numeric::sqrt (arg); 
 05433 |                   case e_tan   : return numeric::tan  (arg); 
 05434 |                   case e_tanh  : return numeric::tanh (arg); 
 05435 |                   case e_cot   : return numeric::cot  (arg); 
 05436 |                   case e_sec   : return numeric::sec  (arg); 
 05437 |                   case e_csc   : return numeric::csc  (arg); 
 05438 |                   case e_r2d   : return numeric::r2d  (arg); 
 05439 |                   case e_d2r   : return numeric::d2r  (arg); 
 05440 |                   case e_d2g   : return numeric::d2g  (arg); 
 05441 |                   case e_g2d   : return numeric::g2d  (arg); 
 05442 |                   case e_notl  : return numeric::notl (arg); 
 05443 |                   case e_sgn   : return numeric::sgn  (arg); 
 05444 |                   case e_erf   : return numeric::erf  (arg); 
 05445 |                   case e_erfc  : return numeric::erfc (arg); 
 05446 |                   case e_ncdf  : return numeric::ncdf (arg); 
 05447 |                   case e_frac  : return numeric::frac (arg); 
 05448 |                   case e_trunc : return numeric::trunc(arg); 
 05449 |  
 05450 |                   default      : exprtk_debug(("numeric::details::process_impl<T> - Invalid unary operation.\n")); 
 05451 |                                  return std::numeric_limits<T>::quiet_NaN(); 
 05452 |                } 
 05453 |             } 
 05454 |  
 05455 |             template <typename T> 
 05456 |             inline T process_impl(const operator_type operation, const T arg0, const T arg1) 
 05457 |             { 
 05458 |                switch (operation) 
 05459 |                { 
 05460 |                   case e_add    : return (arg0 + arg1); 
 05461 |                   case e_sub    : return (arg0 - arg1); 
 05462 |                   case e_mul    : return (arg0 * arg1); 
 05463 |                   case e_div    : return (arg0 / arg1); 
 05464 |                   case e_mod    : return modulus<T>(arg0,arg1); 
 05465 |                   case e_pow    : return pow<T>(arg0,arg1); 
 05466 |                   case e_atan2  : return atan2<T>(arg0,arg1); 
 05467 |                   case e_min    : return std::min<T>(arg0,arg1); 
 05468 |                   case e_max    : return std::max<T>(arg0,arg1); 
 05469 |                   case e_logn   : return logn<T>(arg0,arg1); 
 05470 |                   case e_lt     : return (arg0 <  arg1) ? T(1) : T(0); 
 05471 |                   case e_lte    : return (arg0 <= arg1) ? T(1) : T(0); 
 05472 |                   case e_eq     : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0); 
 05473 |                   case e_ne     : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0); 
 05474 |                   case e_gte    : return (arg0 >= arg1) ? T(1) : T(0); 
 05475 |                   case e_gt     : return (arg0 >  arg1) ? T(1) : T(0); 
 05476 |                   case e_and    : return and_opr <T>(arg0,arg1); 
 05477 |                   case e_nand   : return nand_opr<T>(arg0,arg1); 
 05478 |                   case e_or     : return or_opr  <T>(arg0,arg1); 
 05479 |                   case e_nor    : return nor_opr <T>(arg0,arg1); 
 05480 |                   case e_xor    : return xor_opr <T>(arg0,arg1); 
 05481 |                   case e_xnor   : return xnor_opr<T>(arg0,arg1); 
 05482 |                   case e_root   : return root    <T>(arg0,arg1); 
 05483 |                   case e_roundn : return roundn  <T>(arg0,arg1); 
 05484 |                   case e_equal  : return equal   <T>(arg0,arg1); 
 05485 |                   case e_nequal : return nequal  <T>(arg0,arg1); 
 05486 |                   case e_hypot  : return hypot   <T>(arg0,arg1); 
 05487 |                   case e_shr    : return shr     <T>(arg0,arg1); 
 05488 |                   case e_shl    : return shl     <T>(arg0,arg1); 
 05489 |  
 05490 |                   default       : exprtk_debug(("numeric::details::process_impl<T> - Invalid binary operation.\n")); 
 05491 |                                   return std::numeric_limits<T>::quiet_NaN(); 
 05492 |                } 
 05493 |             } 
 05494 |  
 05495 |             template <typename T> 
 05496 |             inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag) 
 05497 |             { 
 05498 |                switch (operation) 
 05499 |                { 
 05500 |                   case e_add    : return (arg0 + arg1); 
 05501 |                   case e_sub    : return (arg0 - arg1); 
 05502 |                   case e_mul    : return (arg0 * arg1); 
 05503 |                   case e_div    : return (arg0 / arg1); 
 05504 |                   case e_mod    : return arg0 % arg1; 
 05505 |                   case e_pow    : return pow<T>(arg0,arg1); 
 05506 |                   case e_min    : return std::min<T>(arg0,arg1); 
 05507 |                   case e_max    : return std::max<T>(arg0,arg1); 
 05508 |                   case e_logn   : return logn<T>(arg0,arg1); 
 05509 |                   case e_lt     : return (arg0 <  arg1) ? T(1) : T(0); 
 05510 |                   case e_lte    : return (arg0 <= arg1) ? T(1) : T(0); 
 05511 |                   case e_eq     : return (arg0 == arg1) ? T(1) : T(0); 
 05512 |                   case e_ne     : return (arg0 != arg1) ? T(1) : T(0); 
 05513 |                   case e_gte    : return (arg0 >= arg1) ? T(1) : T(0); 
 05514 |                   case e_gt     : return (arg0 >  arg1) ? T(1) : T(0); 
 05515 |                   case e_and    : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0); 
 05516 |                   case e_nand   : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1); 
 05517 |                   case e_or     : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0); 
 05518 |                   case e_nor    : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1); 
 05519 |                   case e_xor    : return arg0 ^ arg1; 
 05520 |                   case e_xnor   : return !(arg0 ^ arg1); 
 05521 |                   case e_root   : return root<T>(arg0,arg1); 
 05522 |                   case e_equal  : return arg0 == arg1; 
 05523 |                   case e_nequal : return arg0 != arg1; 
 05524 |                   case e_hypot  : return hypot<T>(arg0,arg1); 
 05525 |                   case e_shr    : return arg0 >> arg1; 
 05526 |                   case e_shl    : return arg0 << arg1; 
 05527 |  
 05528 |                   default       : exprtk_debug(("numeric::details::process_impl<IntType> - Invalid binary operation.\n")); 
 05529 |                                   return std::numeric_limits<T>::quiet_NaN(); 
 05530 |                } 
 05531 |             } 
 05532 |          } 
 05533 |  
 05534 |          template <typename T> 
 05535 |          inline T process(const operator_type operation, const T arg) 
 05536 |          { 
 05537 |             return exprtk::details::numeric::details::process_impl(operation,arg); 
 05538 |          } 
 05539 |  
 05540 |          template <typename T> 
 05541 |          inline T process(const operator_type operation, const T arg0, const T arg1) 
 05542 |          { 
 05543 |             return exprtk::details::numeric::details::process_impl(operation, arg0, arg1); 
 05544 |          } 
 05545 |       } 
 05546 |  
 05547 |       template <typename Node> 
 05548 |       struct node_collector_interface 
 05549 |       { 
 05550 |          typedef Node* node_ptr_t; 
 05551 |          typedef Node** node_pp_t; 
 05552 |          typedef std::vector<node_pp_t> noderef_list_t; 
 05553 |  
 05554 |          virtual ~node_collector_interface() 
 05555 |          {} 
 05556 |  
 05557 |          virtual void collect_nodes(noderef_list_t&) 
 05558 |          {} 
 05559 |       }; 
 05560 |  
 05561 |       template <typename Node> 
 05562 |       struct node_depth_base; 
 05563 |  
 05564 |       template <typename T> 
 05565 |       class expression_node : public node_collector_interface<expression_node<T> > 
 05566 |                             , public node_depth_base<expression_node<T> > 
 05567 |       { 
 05568 |       public: 
 05569 |  
 05570 |          enum node_type 
 05571 |          { 
 05572 |             e_none          , e_null          , e_constant    , e_unary        , 
 05573 |             e_binary        , e_binary_ext    , e_trinary     , e_quaternary   , 
 05574 |             e_vararg        , e_conditional   , e_while       , e_repeat       , 
 05575 |             e_for           , e_switch        , e_mswitch     , e_return       , 
 05576 |             e_retenv        , e_variable      , e_stringvar   , e_stringconst  , 
 05577 |             e_stringvarrng  , e_cstringvarrng , e_strgenrange , e_strconcat    , 
 05578 |             e_stringvarsize , e_strswap       , e_stringsize  , e_stringvararg , 
 05579 |             e_function      , e_vafunction    , e_genfunction , e_strfunction  , 
 05580 |             e_strcondition  , e_strccondition , e_add         , e_sub          , 
 05581 |             e_mul           , e_div           , e_mod         , e_pow          , 
 05582 |             e_lt            , e_lte           , e_gt          , e_gte          , 
 05583 |             e_eq            , e_ne            , e_and         , e_nand         , 
 05584 |             e_or            , e_nor           , e_xor         , e_xnor         , 
 05585 |             e_in            , e_like          , e_ilike       , e_inranges     , 
 05586 |             e_ipow          , e_ipowinv       , e_abs         , e_acos         , 
 05587 |             e_acosh         , e_asin          , e_asinh       , e_atan         , 
 05588 |             e_atanh         , e_ceil          , e_cos         , e_cosh         , 
 05589 |             e_exp           , e_expm1         , e_floor       , e_log          , 
 05590 |             e_log10         , e_log2          , e_log1p       , e_neg          , 
 05591 |             e_pos           , e_round         , e_sin         , e_sinc         , 
 05592 |             e_sinh          , e_sqrt          , e_tan         , e_tanh         , 
 05593 |             e_cot           , e_sec           , e_csc         , e_r2d          , 
 05594 |             e_d2r           , e_d2g           , e_g2d         , e_notl         , 
 05595 |             e_sgn           , e_erf           , e_erfc        , e_ncdf         , 
 05596 |             e_frac          , e_trunc         , e_uvouv       , e_vov          , 
 05597 |             e_cov           , e_voc           , e_vob         , e_bov          , 
 05598 |             e_cob           , e_boc           , e_vovov       , e_vovoc        , 
 05599 |             e_vocov         , e_covov         , e_covoc       , e_vovovov      , 
 05600 |             e_vovovoc       , e_vovocov       , e_vocovov     , e_covovov      , 
 05601 |             e_covocov       , e_vocovoc       , e_covovoc     , e_vococov      , 
 05602 |             e_sf3ext        , e_sf4ext        , e_nulleq      , e_strass       , 
 05603 |             e_vector        , e_vecsize       , e_vecelem     , e_veccelem     , 
 05604 |             e_vecelemrtc    , e_veccelemrtc   , e_rbvecelem   , e_rbvecelemrtc , 
 05605 |             e_rbveccelem    , e_rbveccelemrtc , e_vecinit     , e_vecvalass    , 
 05606 |             e_vecvecass     , e_vecopvalass   , e_vecopvecass , e_vecfunc      , 
 05607 |             e_vecvecswap    , e_vecvecineq    , e_vecvalineq  , e_valvecineq   , 
 05608 |             e_vecvecarith   , e_vecvalarith   , e_valvecarith , e_vecunaryop   , 
 05609 |             e_vecondition   , e_break         , e_continue    , e_swap         , 
 05610 |             e_assert 
 05611 |          }; 
 05612 |  
 05613 |          typedef T value_type; 
 05614 |          typedef expression_node<T>* expression_ptr; 
 05615 |          typedef node_collector_interface<expression_node<T> > nci_t; 
 05616 |          typedef typename nci_t::noderef_list_t noderef_list_t; 
 05617 |          typedef node_depth_base<expression_node<T> > ndb_t; 
 05618 |  
 05619 |          virtual ~expression_node() 
 05620 |          {} 
 05621 |  
 05622 |          inline virtual T value() const 
 05623 |          { 
 05624 |             return std::numeric_limits<T>::quiet_NaN(); 
 05625 |          } 
 05626 |  
 05627 |          inline virtual expression_node<T>* branch(const std::size_t& index = 0) const 
 05628 |          { 
 05629 |             return reinterpret_cast<expression_ptr>(index * 0); 
 05630 |          } 
 05631 |  
 05632 |          inline virtual node_type type() const 
 05633 |          { 
 05634 |             return e_none; 
 05635 |          } 
 05636 |  
 05637 |          inline virtual bool valid() const 
 05638 |          { 
 05639 |             return true; 
 05640 |          } 
 05641 |       }; // class expression_node 
 05642 |  
 05643 |       template <typename T> 
 05644 |       inline bool is_generally_string_node(const expression_node<T>* node); 
 05645 |  
 05646 |       inline bool is_true(const double v) 
 05647 |       { 
 05648 |          return std::not_equal_to<double>()(0.0,v); 
 05649 |       } 
 05650 |  
 05651 |       inline bool is_true(const long double v) 
 05652 |       { 
 05653 |          return std::not_equal_to<long double>()(0.0L,v); 
 05654 |       } 
 05655 |  
 05656 |       inline bool is_true(const float v) 
 05657 |       { 
 05658 |          return std::not_equal_to<float>()(0.0f,v); 
 05659 |       } 
 05660 |  
 05661 |       template <typename T> 
 05662 |       inline bool is_true(const expression_node<T>* node) 
 05663 |       { 
 05664 |          return std::not_equal_to<T>()(T(0),node->value()); 
 05665 |       } 
 05666 |  
 05667 |       template <typename T> 
 05668 |       inline bool is_true(const std::pair<expression_node<T>*,bool>& node) 
 05669 |       { 
 05670 |          return std::not_equal_to<T>()(T(0),node.first->value()); 
 05671 |       } 
 05672 |  
 05673 |       template <typename T> 
 05674 |       inline bool is_false(const expression_node<T>* node) 
 05675 |       { 
 05676 |          return std::equal_to<T>()(T(0),node->value()); 
 05677 |       } 
 05678 |  
 05679 |       template <typename T> 
 05680 |       inline bool is_false(const std::pair<expression_node<T>*,bool>& node) 
 05681 |       { 
 05682 |          return std::equal_to<T>()(T(0),node.first->value()); 
 05683 |       } 
 05684 |  
 05685 |       template <typename T> 
 05686 |       inline bool is_literal_node(const expression_node<T>* node) 
 05687 |       { 
 05688 |          return node && (details::expression_node<T>::e_constant == node->type()); 
 05689 |       } 
 05690 |  
 05691 |       template <typename T> 
 05692 |       inline bool is_unary_node(const expression_node<T>* node) 
 05693 |       { 
 05694 |          return node && (details::expression_node<T>::e_unary == node->type()); 
 05695 |       } 
 05696 |  
 05697 |       template <typename T> 
 05698 |       inline bool is_neg_unary_node(const expression_node<T>* node) 
 05699 |       { 
 05700 |          return node && (details::expression_node<T>::e_neg == node->type()); 
 05701 |       } 
 05702 |  
 05703 |       template <typename T> 
 05704 |       inline bool is_binary_node(const expression_node<T>* node) 
 05705 |       { 
 05706 |          return node && (details::expression_node<T>::e_binary == node->type()); 
 05707 |       } 
 05708 |  
 05709 |       template <typename T> 
 05710 |       inline bool is_variable_node(const expression_node<T>* node) 
 05711 |       { 
 05712 |          return node && (details::expression_node<T>::e_variable == node->type()); 
 05713 |       } 
 05714 |  
 05715 |       template <typename T> 
 05716 |       inline bool is_ivariable_node(const expression_node<T>* node) 
 05717 |       { 
 05718 |          return node && 
 05719 |                 ( 
 05720 |                   details::expression_node<T>::e_variable      == node->type() || 
 05721 |                   details::expression_node<T>::e_vecelem       == node->type() || 
 05722 |                   details::expression_node<T>::e_veccelem      == node->type() || 
 05723 |                   details::expression_node<T>::e_vecelemrtc    == node->type() || 
 05724 |                   details::expression_node<T>::e_veccelemrtc   == node->type() || 
 05725 |                   details::expression_node<T>::e_rbvecelem     == node->type() || 
 05726 |                   details::expression_node<T>::e_rbveccelem    == node->type() || 
 05727 |                   details::expression_node<T>::e_rbvecelemrtc  == node->type() || 
 05728 |                   details::expression_node<T>::e_rbveccelemrtc == node->type() 
 05729 |                 ); 
 05730 |       } 
 05731 |  
 05732 |       template <typename T> 
 05733 |       inline bool is_vector_elem_node(const expression_node<T>* node) 
 05734 |       { 
 05735 |          return node && (details::expression_node<T>::e_vecelem == node->type()); 
 05736 |       } 
 05737 |  
 05738 |       template <typename T> 
 05739 |       inline bool is_vector_celem_node(const expression_node<T>* node) 
 05740 |       { 
 05741 |          return node && (details::expression_node<T>::e_veccelem == node->type()); 
 05742 |       } 
 05743 |  
 05744 |       template <typename T> 
 05745 |       inline bool is_vector_elem_rtc_node(const expression_node<T>* node) 
 05746 |       { 
 05747 |          return node && (details::expression_node<T>::e_vecelemrtc == node->type()); 
 05748 |       } 
 05749 |  
 05750 |       template <typename T> 
 05751 |       inline bool is_vector_celem_rtc_node(const expression_node<T>* node) 
 05752 |       { 
 05753 |          return node && (details::expression_node<T>::e_veccelemrtc == node->type()); 
 05754 |       } 
 05755 |  
 05756 |       template <typename T> 
 05757 |       inline bool is_rebasevector_elem_node(const expression_node<T>* node) 
 05758 |       { 
 05759 |          return node && (details::expression_node<T>::e_rbvecelem == node->type()); 
 05760 |       } 
 05761 |  
 05762 |       template <typename T> 
 05763 |       inline bool is_rebasevector_elem_rtc_node(const expression_node<T>* node) 
 05764 |       { 
 05765 |          return node && (details::expression_node<T>::e_rbvecelemrtc == node->type()); 
 05766 |       } 
 05767 |  
 05768 |       template <typename T> 
 05769 |       inline bool is_rebasevector_celem_rtc_node(const expression_node<T>* node) 
 05770 |       { 
 05771 |          return node && (details::expression_node<T>::e_rbveccelemrtc == node->type()); 
 05772 |       } 
 05773 |  
 05774 |       template <typename T> 
 05775 |       inline bool is_rebasevector_celem_node(const expression_node<T>* node) 
 05776 |       { 
 05777 |          return node && (details::expression_node<T>::e_rbveccelem == node->type()); 
 05778 |       } 
 05779 |  
 05780 |       template <typename T> 
 05781 |       inline bool is_vector_node(const expression_node<T>* node) 
 05782 |       { 
 05783 |          return node && (details::expression_node<T>::e_vector == node->type()); 
 05784 |       } 
 05785 |  
 05786 |       template <typename T> 
 05787 |       inline bool is_ivector_node(const expression_node<T>* node) 
 05788 |       { 
 05789 |          if (node) 
 05790 |          { 
 05791 |             switch (node->type()) 
 05792 |             { 
 05793 |                case details::expression_node<T>::e_vector      : 
 05794 |                case details::expression_node<T>::e_vecvalass   : 
 05795 |                case details::expression_node<T>::e_vecvecass   : 
 05796 |                case details::expression_node<T>::e_vecopvalass : 
 05797 |                case details::expression_node<T>::e_vecopvecass : 
 05798 |                case details::expression_node<T>::e_vecvecswap  : 
 05799 |                case details::expression_node<T>::e_vecvecarith : 
 05800 |                case details::expression_node<T>::e_vecvalarith : 
 05801 |                case details::expression_node<T>::e_valvecarith : 
 05802 |                case details::expression_node<T>::e_vecunaryop  : 
 05803 |                case details::expression_node<T>::e_vecondition : return true; 
 05804 |                default                                         : return false; 
 05805 |             } 
 05806 |          } 
 05807 |          else 
 05808 |             return false; 
 05809 |       } 
 05810 |  
 05811 |       template <typename T> 
 05812 |       inline bool is_constant_node(const expression_node<T>* node) 
 05813 |       { 
 05814 |          return node && 
 05815 |          ( 
 05816 |            details::expression_node<T>::e_constant    == node->type() || 
 05817 |            details::expression_node<T>::e_stringconst == node->type() 
 05818 |          ); 
 05819 |       } 
 05820 |  
 05821 |       template <typename T> 
 05822 |       inline bool is_null_node(const expression_node<T>* node) 
 05823 |       { 
 05824 |          return node && (details::expression_node<T>::e_null == node->type()); 
 05825 |       } 
 05826 |  
 05827 |       template <typename T> 
 05828 |       inline bool is_break_node(const expression_node<T>* node) 
 05829 |       { 
 05830 |          return node && (details::expression_node<T>::e_break == node->type()); 
 05831 |       } 
 05832 |  
 05833 |       template <typename T> 
 05834 |       inline bool is_continue_node(const expression_node<T>* node) 
 05835 |       { 
 05836 |          return node && (details::expression_node<T>::e_continue == node->type()); 
 05837 |       } 
 05838 |  
 05839 |       template <typename T> 
 05840 |       inline bool is_swap_node(const expression_node<T>* node) 
 05841 |       { 
 05842 |          return node && (details::expression_node<T>::e_swap == node->type()); 
 05843 |       } 
 05844 |  
 05845 |       template <typename T> 
 05846 |       inline bool is_function(const expression_node<T>* node) 
 05847 |       { 
 05848 |          return node && (details::expression_node<T>::e_function == node->type()); 
 05849 |       } 
 05850 |  
 05851 |       template <typename T> 
 05852 |       inline bool is_vararg_node(const expression_node<T>* node) 
 05853 |       { 
 05854 |          return node && (details::expression_node<T>::e_vararg == node->type()); 
 05855 |       } 
 05856 |  
 05857 |       template <typename T> 
 05858 |       inline bool is_return_node(const expression_node<T>* node) 
 05859 |       { 
 05860 |          return node && (details::expression_node<T>::e_return == node->type()); 
 05861 |       } 
 05862 |  
 05863 |       template <typename T> class unary_node; 
 05864 |  
 05865 |       template <typename T> 
 05866 |       inline bool is_negate_node(const expression_node<T>* node) 
 05867 |       { 
 05868 |          if (node && is_unary_node(node)) 
 05869 |          { 
 05870 |             return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation()); 
 05871 |          } 
 05872 |          else 
 05873 |             return false; 
 05874 |       } 
 05875 |  
 05876 |       template <typename T> 
 05877 |       inline bool is_assert_node(const expression_node<T>* node) 
 05878 |       { 
 05879 |          return node && (details::expression_node<T>::e_assert == node->type()); 
 05880 |       } 
 05881 |  
 05882 |       template <typename T> 
 05883 |       inline bool branch_deletable(const expression_node<T>* node) 
 05884 |       { 
 05885 |          return (0 != node)             && 
 05886 |                 !is_variable_node(node) && 
 05887 |                 !is_string_node  (node) ; 
 05888 |       } 
 05889 |  
 05890 |       template <std::size_t N, typename T> 
 05891 |       inline bool all_nodes_valid(expression_node<T>* const (&b)[N]) 
 05892 |       { 
 05893 |          for (std::size_t i = 0; i < N; ++i) 
 05894 |          { 
 05895 |             if (0 == b[i]) return false; 
 05896 |          } 
 05897 |  
 05898 |          return true; 
 05899 |       } 
 05900 |  
 05901 |       template <typename T, 
 05902 |                 typename Allocator, 
 05903 |                 template <typename, typename> class Sequence> 
 05904 |       inline bool all_nodes_valid(const Sequence<expression_node<T>*,Allocator>& b) 
 05905 |       { 
 05906 |          for (std::size_t i = 0; i < b.size(); ++i) 
 05907 |          { 
 05908 |             if (0 == b[i]) return false; 
 05909 |          } 
 05910 |  
 05911 |          return true; 
 05912 |       } 
 05913 |  
 05914 |       template <std::size_t N, typename T> 
 05915 |       inline bool all_nodes_variables(expression_node<T>* const (&b)[N]) 
 05916 |       { 
 05917 |          for (std::size_t i = 0; i < N; ++i) 
 05918 |          { 
 05919 |             if (0 == b[i]) 
 05920 |                return false; 
 05921 |             else if (!is_variable_node(b[i])) 
 05922 |                return false; 
 05923 |          } 
 05924 |  
 05925 |          return true; 
 05926 |       } 
 05927 |  
 05928 |       template <typename T, 
 05929 |                 typename Allocator, 
 05930 |                 template <typename, typename> class Sequence> 
 05931 |       inline bool all_nodes_variables(const Sequence<expression_node<T>*,Allocator>& b) 
 05932 |       { 
 05933 |          for (std::size_t i = 0; i < b.size(); ++i) 
 05934 |          { 
 05935 |             if (0 == b[i]) 
 05936 |                return false; 
 05937 |             else if (!is_variable_node(b[i])) 
 05938 |                return false; 
 05939 |          } 
 05940 |  
 05941 |          return true; 
 05942 |       } 
 05943 |  
 05944 |       template <typename Node> 
 05945 |       class node_collection_destructor 
 05946 |       { 
 05947 |       public: 
 05948 |  
 05949 |          typedef node_collector_interface<Node> nci_t; 
 05950 |  
 05951 |          typedef typename nci_t::node_ptr_t     node_ptr_t; 
 05952 |          typedef typename nci_t::node_pp_t      node_pp_t; 
 05953 |          typedef typename nci_t::noderef_list_t noderef_list_t; 
 05954 |  
 05955 |          static void delete_nodes(node_ptr_t& root) 
 05956 |          { 
 05957 |             std::vector<node_pp_t> node_delete_list; 
 05958 |             node_delete_list.reserve(1000); 
 05959 |  
 05960 |             collect_nodes(root, node_delete_list); 
 05961 |  
 05962 |             for (std::size_t i = 0; i < node_delete_list.size(); ++i) 
 05963 |             { 
 05964 |                node_ptr_t& node = *node_delete_list[i]; 
 05965 |                exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", reinterpret_cast<void*>(node))); 
 05966 |                delete node; 
 05967 |                node = reinterpret_cast<node_ptr_t>(0); 
 05968 |             } 
 05969 |          } 
 05970 |  
 05971 |       private: 
 05972 |  
 05973 |          static void collect_nodes(node_ptr_t& root, noderef_list_t& node_delete_list) 
 05974 |          { 
 05975 |             std::deque<node_ptr_t> node_list; 
 05976 |             node_list.push_back(root); 
 05977 |             node_delete_list.push_back(&root); 
 05978 |  
 05979 |             noderef_list_t child_node_delete_list; 
 05980 |             child_node_delete_list.reserve(1000); 
 05981 |  
 05982 |             while (!node_list.empty()) 
 05983 |             { 
 05984 |                node_list.front()->collect_nodes(child_node_delete_list); 
 05985 |  
 05986 |                if (!child_node_delete_list.empty()) 
 05987 |                { 
 05988 |                   for (std::size_t i = 0; i < child_node_delete_list.size(); ++i) 
 05989 |                   { 
 05990 |                      node_pp_t& node = child_node_delete_list[i]; 
 05991 |  
 05992 |                      if (0 == (*node)) 
 05993 |                      { 
 05994 |                         exprtk_debug(("ncd::collect_nodes() - null node encountered.\n")); 
 05995 |                      } 
 05996 |  
 05997 |                      node_list.push_back(*node); 
 05998 |                   } 
 05999 |  
 06000 |                   node_delete_list.insert( 
 06001 |                      node_delete_list.end(), 
 06002 |                      child_node_delete_list.begin(), child_node_delete_list.end()); 
 06003 |  
 06004 |                   child_node_delete_list.clear(); 
 06005 |                } 
 06006 |  
 06007 |                node_list.pop_front(); 
 06008 |             } 
 06009 |  
 06010 |             std::reverse(node_delete_list.begin(), node_delete_list.end()); 
 06011 |          } 
 06012 |       }; 
 06013 |  
 06014 |       template <typename NodeAllocator, typename T, std::size_t N> 
 06015 |       inline void free_all_nodes(NodeAllocator& node_allocator, expression_node<T>* (&b)[N]) 
 06016 |       { 
 06017 |          for (std::size_t i = 0; i < N; ++i) 
 06018 |          { 
 06019 |             free_node(node_allocator,b[i]); 
 06020 |          } 
 06021 |       } 
 06022 |  
 06023 |       template <typename NodeAllocator, 
 06024 |                 typename T, 
 06025 |                 typename Allocator, 
 06026 |                 template <typename, typename> class Sequence> 
 06027 |       inline void free_all_nodes(NodeAllocator& node_allocator, Sequence<expression_node<T>*,Allocator>& b) 
 06028 |       { 
 06029 |          for (std::size_t i = 0; i < b.size(); ++i) 
 06030 |          { 
 06031 |             free_node(node_allocator,b[i]); 
 06032 |          } 
 06033 |  
 06034 |          b.clear(); 
 06035 |       } 
 06036 |  
 06037 |       template <typename NodeAllocator, typename T> 
 06038 |       inline void free_node(NodeAllocator&, expression_node<T>*& node) 
 06039 |       { 
 06040 |          if ((0 == node) || is_variable_node(node) || is_string_node(node)) 
 06041 |          { 
 06042 |             return; 
 06043 |          } 
 06044 |  
 06045 |          node_collection_destructor<expression_node<T> > 
 06046 |             ::delete_nodes(node); 
 06047 |       } 
 06048 |  
 06049 |       template <typename T> 
 06050 |       inline void destroy_node(expression_node<T>*& node) 
 06051 |       { 
 06052 |          if (0 != node) 
 06053 |          { 
 06054 |             node_collection_destructor<expression_node<T> > 
 06055 |                ::delete_nodes(node); 
 06056 |          } 
 06057 |       } 
 06058 |  
 06059 |       template <typename Node> 
 06060 |       struct node_depth_base 
 06061 |       { 
 06062 |          typedef Node* node_ptr_t; 
 06063 |          typedef std::pair<node_ptr_t,bool> nb_pair_t; 
 06064 |  
 06065 |          node_depth_base() 
 06066 |          : depth_set(false) 
 06067 |          , depth(0) 
 06068 |          {} 
 06069 |  
 06070 |          virtual ~node_depth_base() 
 06071 |          {} 
 06072 |  
 06073 |          virtual std::size_t node_depth() const { return 1; } 
 06074 |  
 06075 |          std::size_t compute_node_depth(const Node* const& node) const 
 06076 |          { 
 06077 |             if (!depth_set) 
 06078 |             { 
 06079 |                depth = 1 + (node ? node->node_depth() : 0); 
 06080 |                depth_set = true; 
 06081 |             } 
 06082 |  
 06083 |             return depth; 
 06084 |          } 
 06085 |  
 06086 |          std::size_t compute_node_depth(const nb_pair_t& branch) const 
 06087 |          { 
 06088 |             if (!depth_set) 
 06089 |             { 
 06090 |                depth = 1 + (branch.first ? branch.first->node_depth() : 0); 
 06091 |                depth_set = true; 
 06092 |             } 
 06093 |  
 06094 |             return depth; 
 06095 |          } 
 06096 |  
 06097 |          template <std::size_t N> 
 06098 |          std::size_t compute_node_depth(const nb_pair_t (&branch)[N]) const 
 06099 |          { 
 06100 |             if (!depth_set) 
 06101 |             { 
 06102 |                depth = 0; 
 06103 |  
 06104 |                for (std::size_t i = 0; i < N; ++i) 
 06105 |                { 
 06106 |                   if (branch[i].first) 
 06107 |                   { 
 06108 |                      depth = std::max(depth,branch[i].first->node_depth()); 
 06109 |                   } 
 06110 |                } 
 06111 |  
 06112 |                depth += 1; 
 06113 |                depth_set = true; 
 06114 |             } 
 06115 |  
 06116 |             return depth; 
 06117 |          } 
 06118 |  
 06119 |          template <typename BranchType> 
 06120 |          std::size_t max_node_depth(const BranchType& n0, const BranchType& n1) const 
 06121 |          { 
 06122 |             return std::max(compute_node_depth(n0), compute_node_depth(n1)); 
 06123 |          } 
 06124 |  
 06125 |          template <typename BranchType> 
 06126 |          std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, const BranchType& n2) const 
 06127 |          { 
 06128 |             return std::max(compute_node_depth(n0), 
 06129 |                    std::max(compute_node_depth(n1), compute_node_depth(n2))); 
 06130 |          } 
 06131 |  
 06132 |          template <typename BranchType> 
 06133 |          std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, 
 06134 |                                     const BranchType& n2, const BranchType& n3) const 
 06135 |          { 
 06136 |             return std::max( 
 06137 |                      std::max(compute_node_depth(n0), compute_node_depth(n1)), 
 06138 |                      std::max(compute_node_depth(n2), compute_node_depth(n3))); 
 06139 |          } 
 06140 |  
 06141 |          template <typename BranchType> 
 06142 |          std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1) const 
 06143 |          { 
 06144 |             if (!depth_set) 
 06145 |             { 
 06146 |                depth = 1 + max_node_depth(n0, n1); 
 06147 |                depth_set = true; 
 06148 |             } 
 06149 |  
 06150 |             return depth; 
 06151 |          } 
 06152 |  
 06153 |          template <typename BranchType> 
 06154 |          std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1, 
 06155 |                                         const BranchType& n2) const 
 06156 |          { 
 06157 |             if (!depth_set) 
 06158 |             { 
 06159 |                depth = 1 + max_node_depth(n0, n1, n2); 
 06160 |                depth_set = true; 
 06161 |             } 
 06162 |  
 06163 |             return depth; 
 06164 |          } 
 06165 |  
 06166 |          template <typename BranchType> 
 06167 |          std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1, 
 06168 |                                         const BranchType& n2, const BranchType& n3) const 
 06169 |          { 
 06170 |             if (!depth_set) 
 06171 |             { 
 06172 |                depth = 1 + max_node_depth(n0, n1, n2, n3); 
 06173 |                depth_set = true; 
 06174 |             } 
 06175 |  
 06176 |             return depth; 
 06177 |          } 
 06178 |  
 06179 |          template <typename Allocator, 
 06180 |                    template <typename, typename> class Sequence> 
 06181 |          std::size_t compute_node_depth(const Sequence<node_ptr_t, Allocator>& branch_list) const 
 06182 |          { 
 06183 |             if (!depth_set) 
 06184 |             { 
 06185 |                for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06186 |                { 
 06187 |                   if (branch_list[i]) 
 06188 |                   { 
 06189 |                      depth = std::max(depth, compute_node_depth(branch_list[i])); 
 06190 |                   } 
 06191 |                } 
 06192 |  
 06193 |                depth_set = true; 
 06194 |             } 
 06195 |  
 06196 |             return depth; 
 06197 |          } 
 06198 |  
 06199 |          template <typename Allocator, 
 06200 |                    template <typename, typename> class Sequence> 
 06201 |          std::size_t compute_node_depth(const Sequence<nb_pair_t,Allocator>& branch_list) const 
 06202 |          { 
 06203 |             if (!depth_set) 
 06204 |             { 
 06205 |                for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06206 |                { 
 06207 |                   if (branch_list[i].first) 
 06208 |                   { 
 06209 |                      depth = std::max(depth, compute_node_depth(branch_list[i].first)); 
 06210 |                   } 
 06211 |                } 
 06212 |  
 06213 |                depth_set = true; 
 06214 |             } 
 06215 |  
 06216 |             return depth; 
 06217 |          } 
 06218 |  
 06219 |          mutable bool depth_set; 
 06220 |          mutable std::size_t depth; 
 06221 |  
 06222 |          template <typename NodeSequence> 
 06223 |          void collect(node_ptr_t const& node, 
 06224 |                       const bool deletable, 
 06225 |                       NodeSequence& delete_node_list) const 
 06226 |          { 
 06227 |             if ((0 != node) && deletable) 
 06228 |             { 
 06229 |                delete_node_list.push_back(const_cast<node_ptr_t*>(&node)); 
 06230 |             } 
 06231 |          } 
 06232 |  
 06233 |          template <typename NodeSequence> 
 06234 |          void collect(const nb_pair_t& branch, 
 06235 |                       NodeSequence& delete_node_list) const 
 06236 |          { 
 06237 |             collect(branch.first, branch.second, delete_node_list); 
 06238 |          } 
 06239 |  
 06240 |          template <typename NodeSequence> 
 06241 |          void collect(Node*& node, 
 06242 |                       NodeSequence& delete_node_list) const 
 06243 |          { 
 06244 |             collect(node, branch_deletable(node), delete_node_list); 
 06245 |          } 
 06246 |  
 06247 |          template <std::size_t N, typename NodeSequence> 
 06248 |          void collect(const nb_pair_t(&branch)[N], 
 06249 |                       NodeSequence& delete_node_list) const 
 06250 |          { 
 06251 |             for (std::size_t i = 0; i < N; ++i) 
 06252 |             { 
 06253 |                collect(branch[i].first, branch[i].second, delete_node_list); 
 06254 |             } 
 06255 |          } 
 06256 |  
 06257 |          template <typename Allocator, 
 06258 |                    template <typename, typename> class Sequence, 
 06259 |                    typename NodeSequence> 
 06260 |          void collect(const Sequence<nb_pair_t, Allocator>& branch, 
 06261 |                       NodeSequence& delete_node_list) const 
 06262 |          { 
 06263 |             for (std::size_t i = 0; i < branch.size(); ++i) 
 06264 |             { 
 06265 |                collect(branch[i].first, branch[i].second, delete_node_list); 
 06266 |             } 
 06267 |          } 
 06268 |  
 06269 |          template <typename Allocator, 
 06270 |                    template <typename, typename> class Sequence, 
 06271 |                    typename NodeSequence> 
 06272 |          void collect(const Sequence<node_ptr_t, Allocator>& branch_list, 
 06273 |                       NodeSequence& delete_node_list) const 
 06274 |          { 
 06275 |             for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06276 |             { 
 06277 |                collect(branch_list[i], branch_deletable(branch_list[i]), delete_node_list); 
 06278 |             } 
 06279 |          } 
 06280 |  
 06281 |          template <typename Boolean, 
 06282 |                    typename AllocatorT, 
 06283 |                    typename AllocatorB, 
 06284 |                    template <typename, typename> class Sequence, 
 06285 |                    typename NodeSequence> 
 06286 |          void collect(const Sequence<node_ptr_t, AllocatorT>& branch_list, 
 06287 |                       const Sequence<Boolean, AllocatorB>& branch_deletable_list, 
 06288 |                       NodeSequence& delete_node_list) const 
 06289 |          { 
 06290 |             for (std::size_t i = 0; i < branch_list.size(); ++i) 
 06291 |             { 
 06292 |                collect(branch_list[i], branch_deletable_list[i], delete_node_list); 
 06293 |             } 
 06294 |          } 
 06295 |       }; 
 06296 |  
 06297 |       template <typename Type> 
 06298 |       class vector_holder 
 06299 |       { 
 06300 |       private: 
 06301 |  
 06302 |          typedef Type value_type; 
 06303 |          typedef value_type* value_ptr; 
 06304 |          typedef const value_ptr const_value_ptr; 
 06305 |          typedef vector_holder<Type> vector_holder_t; 
 06306 |  
 06307 |          class vector_holder_base 
 06308 |          { 
 06309 |          public: 
 06310 |  
 06311 |             virtual ~vector_holder_base() 
 06312 |             {} 
 06313 |  
 06314 |             inline value_ptr operator[](const std::size_t& index) const 
 06315 |             { 
 06316 |                return value_at(index); 
 06317 |             } 
 06318 |  
 06319 |             inline std::size_t size() const 
 06320 |             { 
 06321 |                return vector_size(); 
 06322 |             } 
 06323 |  
 06324 |             inline std::size_t base_size() const 
 06325 |             { 
 06326 |                return vector_base_size(); 
 06327 |             } 
 06328 |  
 06329 |             inline value_ptr data() const 
 06330 |             { 
 06331 |                return value_at(0); 
 06332 |             } 
 06333 |  
 06334 |             virtual inline bool rebaseable() const 
 06335 |             { 
 06336 |                return false; 
 06337 |             } 
 06338 |  
 06339 |             virtual void set_ref(value_ptr*) 
 06340 |             {} 
 06341 |  
 06342 |             virtual void remove_ref(value_ptr*) 
 06343 |             {} 
 06344 |  
 06345 |             virtual vector_view<Type>* rebaseable_instance() 
 06346 |             { 
 06347 |                return reinterpret_cast<vector_view<Type>*>(0); 
 06348 |             } 
 06349 |  
 06350 |          protected: 
 06351 |  
 06352 |             virtual value_ptr value_at(const std::size_t&) const = 0; 
 06353 |             virtual std::size_t vector_size()              const = 0; 
 06354 |             virtual std::size_t vector_base_size()         const = 0; 
 06355 |          }; 
 06356 |  
 06357 |          class array_vector_impl exprtk_final : public vector_holder_base 
 06358 |          { 
 06359 |          public: 
 06360 |  
 06361 |             array_vector_impl(const Type* vec, const std::size_t& vec_size) 
 06362 |             : vec_(vec) 
 06363 |             , size_(vec_size) 
 06364 |             {} 
 06365 |  
 06366 |          protected: 
 06367 |  
 06368 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06369 |             { 
 06370 |                assert(index < size_); 
 06371 |                return const_cast<const_value_ptr>(vec_ + index); 
 06372 |             } 
 06373 |  
 06374 |             std::size_t vector_size() const exprtk_override 
 06375 |             { 
 06376 |                return size_; 
 06377 |             } 
 06378 |  
 06379 |             std::size_t vector_base_size() const exprtk_override 
 06380 |             { 
 06381 |                return vector_size(); 
 06382 |             } 
 06383 |  
 06384 |          private: 
 06385 |  
 06386 |             array_vector_impl(const array_vector_impl&) exprtk_delete; 
 06387 |             array_vector_impl& operator=(const array_vector_impl&) exprtk_delete; 
 06388 |  
 06389 |             const Type* vec_; 
 06390 |             const std::size_t size_; 
 06391 |          }; 
 06392 |  
 06393 |          template <typename Allocator, 
 06394 |                    template <typename, typename> class Sequence> 
 06395 |          class sequence_vector_impl exprtk_final : public vector_holder_base 
 06396 |          { 
 06397 |          public: 
 06398 |  
 06399 |             typedef Sequence<Type,Allocator> sequence_t; 
 06400 |  
 06401 |             explicit sequence_vector_impl(sequence_t& seq) 
 06402 |             : sequence_(seq) 
 06403 |             {} 
 06404 |  
 06405 |          protected: 
 06406 |  
 06407 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06408 |             { 
 06409 |                assert(index < sequence_.size()); 
 06410 |                return (&sequence_[index]); 
 06411 |             } 
 06412 |  
 06413 |             std::size_t vector_size() const exprtk_override 
 06414 |             { 
 06415 |                return sequence_.size(); 
 06416 |             } 
 06417 |  
 06418 |             std::size_t vector_base_size() const exprtk_override 
 06419 |             { 
 06420 |                return vector_size(); 
 06421 |             } 
 06422 |  
 06423 |          private: 
 06424 |  
 06425 |             sequence_vector_impl(const sequence_vector_impl&) exprtk_delete; 
 06426 |             sequence_vector_impl& operator=(const sequence_vector_impl&) exprtk_delete; 
 06427 |  
 06428 |             sequence_t& sequence_; 
 06429 |          }; 
 06430 |  
 06431 |          class vector_view_impl exprtk_final : public vector_holder_base 
 06432 |          { 
 06433 |          public: 
 06434 |  
 06435 |             typedef exprtk::vector_view<Type> vector_view_t; 
 06436 |  
 06437 |             vector_view_impl(vector_view_t& vec_view) 
 06438 |             : vec_view_(vec_view) 
 06439 |             { 
 06440 |                assert(vec_view_.size() > 0); 
 06441 |             } 
 06442 |  
 06443 |             void set_ref(value_ptr* ref) exprtk_override 
 06444 |             { 
 06445 |                vec_view_.set_ref(ref); 
 06446 |             } 
 06447 |  
 06448 |             void remove_ref(value_ptr* ref) exprtk_override 
 06449 |             { 
 06450 |                vec_view_.remove_ref(ref); 
 06451 |             } 
 06452 |  
 06453 |             bool rebaseable() const exprtk_override 
 06454 |             { 
 06455 |                return true; 
 06456 |             } 
 06457 |  
 06458 |             vector_view<Type>* rebaseable_instance() exprtk_override 
 06459 |             { 
 06460 |                return &vec_view_; 
 06461 |             } 
 06462 |  
 06463 |          protected: 
 06464 |  
 06465 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06466 |             { 
 06467 |                assert(index < vec_view_.size()); 
 06468 |                return (&vec_view_[index]); 
 06469 |             } 
 06470 |  
 06471 |             std::size_t vector_size() const exprtk_override 
 06472 |             { 
 06473 |                return vec_view_.size(); 
 06474 |             } 
 06475 |  
 06476 |             std::size_t vector_base_size() const exprtk_override 
 06477 |             { 
 06478 |                return vec_view_.base_size(); 
 06479 |             } 
 06480 |  
 06481 |          private: 
 06482 |  
 06483 |             vector_view_impl(const vector_view_impl&) exprtk_delete; 
 06484 |             vector_view_impl& operator=(const vector_view_impl&) exprtk_delete; 
 06485 |  
 06486 |             vector_view_t& vec_view_; 
 06487 |          }; 
 06488 |  
 06489 |          class resizable_vector_impl exprtk_final : public vector_holder_base 
 06490 |          { 
 06491 |          public: 
 06492 |  
 06493 |             resizable_vector_impl(vector_holder& vec_view_holder, 
 06494 |                                   const Type* vec, 
 06495 |                                   const std::size_t& vec_size) 
 06496 |             : vec_(vec) 
 06497 |             , size_(vec_size) 
 06498 |             , vec_view_holder_(*vec_view_holder.rebaseable_instance()) 
 06499 |             { 
 06500 |                assert(vec_view_holder.rebaseable_instance()); 
 06501 |                assert(size_ <= vector_base_size()); 
 06502 |             } 
 06503 |  
 06504 |             virtual ~resizable_vector_impl() 
 06505 |             {} 
 06506 |  
 06507 |          protected: 
 06508 |  
 06509 |             value_ptr value_at(const std::size_t& index) const exprtk_override 
 06510 |             { 
 06511 |                assert(index < vector_size()); 
 06512 |                return const_cast<const_value_ptr>(vec_ + index); 
 06513 |             } 
 06514 |  
 06515 |             std::size_t vector_size() const exprtk_override 
 06516 |             { 
 06517 |                return vec_view_holder_.size(); 
 06518 |             } 
 06519 |  
 06520 |             std::size_t vector_base_size() const exprtk_override 
 06521 |             { 
 06522 |                return vec_view_holder_.base_size(); 
 06523 |             } 
 06524 |  
 06525 |             bool rebaseable() const exprtk_override 
 06526 |             { 
 06527 |                return true; 
 06528 |             } 
 06529 |  
 06530 |             virtual vector_view<Type>* rebaseable_instance() exprtk_override 
 06531 |             { 
 06532 |                return &vec_view_holder_; 
 06533 |             } 
 06534 |  
 06535 |          private: 
 06536 |  
 06537 |             resizable_vector_impl(const resizable_vector_impl&) exprtk_delete; 
 06538 |             resizable_vector_impl& operator=(const resizable_vector_impl&) exprtk_delete; 
 06539 |  
 06540 |             const Type* vec_; 
 06541 |             const std::size_t size_; 
 06542 |             vector_view<Type>& vec_view_holder_; 
 06543 |          }; 
 06544 |  
 06545 |       public: 
 06546 |  
 06547 |          typedef typename details::vec_data_store<Type> vds_t; 
 06548 |  
 06549 |          vector_holder(Type* vec, const std::size_t& vec_size) 
 06550 |          : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size)) 
 06551 |          {} 
 06552 |  
 06553 |          explicit vector_holder(const vds_t& vds) 
 06554 |          : vector_holder_base_(new(buffer)array_vector_impl(vds.data(),vds.size())) 
 06555 |          {} 
 06556 |  
 06557 |          template <typename Allocator> 
 06558 |          explicit vector_holder(std::vector<Type,Allocator>& vec) 
 06559 |          : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec)) 
 06560 |          {} 
 06561 |  
 06562 |          explicit vector_holder(exprtk::vector_view<Type>& vec) 
 06563 |          : vector_holder_base_(new(buffer)vector_view_impl(vec)) 
 06564 |          {} 
 06565 |  
 06566 |          explicit vector_holder(vector_holder_t& vec_holder, const vds_t& vds) 
 06567 |          : vector_holder_base_(new(buffer)resizable_vector_impl(vec_holder, vds.data(), vds.size())) 
 06568 |          {} 
 06569 |  
 06570 |          inline value_ptr operator[](const std::size_t& index) const 
 06571 |          { 
 06572 |             return (*vector_holder_base_)[index]; 
 06573 |          } 
 06574 |  
 06575 |          inline std::size_t size() const 
 06576 |          { 
 06577 |             return vector_holder_base_->size(); 
 06578 |          } 
 06579 |  
 06580 |          inline std::size_t base_size() const 
 06581 |          { 
 06582 |             return vector_holder_base_->base_size(); 
 06583 |          } 
 06584 |  
 06585 |          inline value_ptr data() const 
 06586 |          { 
 06587 |             return vector_holder_base_->data(); 
 06588 |          } 
 06589 |  
 06590 |          void set_ref(value_ptr* ref) 
 06591 |          { 
 06592 |             if (rebaseable()) 
 06593 |             { 
 06594 |                vector_holder_base_->set_ref(ref); 
 06595 |             } 
 06596 |          } 
 06597 |  
 06598 |          void remove_ref(value_ptr* ref) 
 06599 |          { 
 06600 |             if (rebaseable()) 
 06601 |             { 
 06602 |                vector_holder_base_->remove_ref(ref); 
 06603 |             } 
 06604 |          } 
 06605 |  
 06606 |          bool rebaseable() const 
 06607 |          { 
 06608 |             return vector_holder_base_->rebaseable(); 
 06609 |          } 
 06610 |  
 06611 |          vector_view<Type>* rebaseable_instance() 
 06612 |          { 
 06613 |             return vector_holder_base_->rebaseable_instance(); 
 06614 |          } 
 06615 |  
 06616 |       private: 
 06617 |  
 06618 |          vector_holder(const vector_holder<Type>&) exprtk_delete; 
 06619 |          vector_holder<Type>& operator=(const vector_holder<Type>&) exprtk_delete; 
 06620 |  
 06621 |          mutable vector_holder_base* vector_holder_base_; 
 06622 |          uchar_t buffer[64]; 
 06623 |       }; 
 06624 |  
 06625 |       template <typename T> 
 06626 |       class null_node exprtk_final : public expression_node<T> 
 06627 |       { 
 06628 |       public: 
 06629 |  
 06630 |          inline T value() const exprtk_override 
 06631 |          { 
 06632 |             return std::numeric_limits<T>::quiet_NaN(); 
 06633 |          } 
 06634 |  
 06635 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06636 |          { 
 06637 |             return expression_node<T>::e_null; 
 06638 |          } 
 06639 |       }; 
 06640 |  
 06641 |       template <typename T, std::size_t N> 
 06642 |       inline void construct_branch_pair(std::pair<expression_node<T>*,bool> (&branch)[N], 
 06643 |                                         expression_node<T>* b, 
 06644 |                                         const std::size_t& index) 
 06645 |       { 
 06646 |          if (b && (index < N)) 
 06647 |          { 
 06648 |             branch[index] = std::make_pair(b,branch_deletable(b)); 
 06649 |          } 
 06650 |       } 
 06651 |  
 06652 |       template <typename T> 
 06653 |       inline void construct_branch_pair(std::pair<expression_node<T>*,bool>& branch, expression_node<T>* b) 
 06654 |       { 
 06655 |          if (b) 
 06656 |          { 
 06657 |             branch = std::make_pair(b,branch_deletable(b)); 
 06658 |          } 
 06659 |       } 
 06660 |  
 06661 |       template <std::size_t N, typename T> 
 06662 |       inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N], 
 06663 |                                 expression_node<T>* b0, 
 06664 |                                 expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0), 
 06665 |                                 expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0), 
 06666 |                                 expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0), 
 06667 |                                 expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0), 
 06668 |                                 expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0), 
 06669 |                                 expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0), 
 06670 |                                 expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0), 
 06671 |                                 expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0), 
 06672 |                                 expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0)) 
 06673 |       { 
 06674 |          construct_branch_pair(branch, b0, 0); 
 06675 |          construct_branch_pair(branch, b1, 1); 
 06676 |          construct_branch_pair(branch, b2, 2); 
 06677 |          construct_branch_pair(branch, b3, 3); 
 06678 |          construct_branch_pair(branch, b4, 4); 
 06679 |          construct_branch_pair(branch, b5, 5); 
 06680 |          construct_branch_pair(branch, b6, 6); 
 06681 |          construct_branch_pair(branch, b7, 7); 
 06682 |          construct_branch_pair(branch, b8, 8); 
 06683 |          construct_branch_pair(branch, b9, 9); 
 06684 |       } 
 06685 |  
 06686 |       template <typename T> 
 06687 |       class null_eq_node exprtk_final : public expression_node<T> 
 06688 |       { 
 06689 |       public: 
 06690 |  
 06691 |          typedef expression_node<T>* expression_ptr; 
 06692 |          typedef std::pair<expression_ptr,bool> branch_t; 
 06693 |  
 06694 |          explicit null_eq_node(expression_ptr branch, const bool equality = true) 
 06695 |          : equality_(equality) 
 06696 |          { 
 06697 |             construct_branch_pair(branch_, branch); 
 06698 |             assert(valid()); 
 06699 |          } 
 06700 |  
 06701 |          inline T value() const exprtk_override 
 06702 |          { 
 06703 |             const T v = branch_.first->value(); 
 06704 |             const bool result = details::numeric::is_nan(v); 
 06705 |  
 06706 |             if (result) 
 06707 |                return equality_ ? T(1) : T(0); 
 06708 |             else 
 06709 |                return equality_ ? T(0) : T(1); 
 06710 |          } 
 06711 |  
 06712 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06713 |          { 
 06714 |             return expression_node<T>::e_nulleq; 
 06715 |          } 
 06716 |  
 06717 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06718 |          { 
 06719 |             return branch_.first; 
 06720 |          } 
 06721 |  
 06722 |          inline bool valid() const exprtk_override 
 06723 |          { 
 06724 |             return branch_.first; 
 06725 |          } 
 06726 |  
 06727 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 06728 |          { 
 06729 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 06730 |          } 
 06731 |  
 06732 |          std::size_t node_depth() const exprtk_override 
 06733 |          { 
 06734 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 06735 |          } 
 06736 |  
 06737 |       private: 
 06738 |  
 06739 |          bool equality_; 
 06740 |          branch_t branch_; 
 06741 |       }; 
 06742 |  
 06743 |       template <typename T> 
 06744 |       class literal_node exprtk_final : public expression_node<T> 
 06745 |       { 
 06746 |       public: 
 06747 |  
 06748 |          explicit literal_node(const T& v) 
 06749 |          : value_(v) 
 06750 |          {} 
 06751 |  
 06752 |          inline T value() const exprtk_override 
 06753 |          { 
 06754 |             return value_; 
 06755 |          } 
 06756 |  
 06757 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06758 |          { 
 06759 |             return expression_node<T>::e_constant; 
 06760 |          } 
 06761 |  
 06762 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06763 |          { 
 06764 |             return reinterpret_cast<expression_node<T>*>(0); 
 06765 |          } 
 06766 |  
 06767 |       private: 
 06768 |  
 06769 |          literal_node(const literal_node<T>&) exprtk_delete; 
 06770 |          literal_node<T>& operator=(const literal_node<T>&) exprtk_delete; 
 06771 |  
 06772 |          const T value_; 
 06773 |       }; 
 06774 |  
 06775 |       template <typename T> 
 06776 |       struct range_pack; 
 06777 |  
 06778 |       template <typename T> 
 06779 |       struct range_data_type; 
 06780 |  
 06781 |       template <typename T> 
 06782 |       class range_interface 
 06783 |       { 
 06784 |       public: 
 06785 |  
 06786 |          typedef range_pack<T> range_t; 
 06787 |  
 06788 |          virtual ~range_interface() 
 06789 |          {} 
 06790 |  
 06791 |          virtual range_t& range_ref() = 0; 
 06792 |  
 06793 |          virtual const range_t& range_ref() const = 0; 
 06794 |       }; 
 06795 |  
 06796 |       #ifndef exprtk_disable_string_capabilities 
 06797 |       template <typename T> 
 06798 |       class string_base_node 
 06799 |       { 
 06800 |       public: 
 06801 |  
 06802 |          typedef range_data_type<T> range_data_type_t; 
 06803 |  
 06804 |          virtual ~string_base_node() 
 06805 |          {} 
 06806 |  
 06807 |          virtual std::string str () const = 0; 
 06808 |  
 06809 |          virtual char_cptr   base() const = 0; 
 06810 |  
 06811 |          virtual std::size_t size() const = 0; 
 06812 |       }; 
 06813 |  
 06814 |       template <typename T> 
 06815 |       class string_literal_node exprtk_final 
 06816 |                                 : public expression_node <T> 
 06817 |                                 , public string_base_node<T> 
 06818 |                                 , public range_interface <T> 
 06819 |       { 
 06820 |       public: 
 06821 |  
 06822 |          typedef range_pack<T> range_t; 
 06823 |  
 06824 |          explicit string_literal_node(const std::string& v) 
 06825 |          : value_(v) 
 06826 |          { 
 06827 |             rp_.n0_c = std::make_pair<bool,std::size_t>(true, 0); 
 06828 |             rp_.n1_c = std::make_pair<bool,std::size_t>(true, v.size()); 
 06829 |             rp_.cache.first  = rp_.n0_c.second; 
 06830 |             rp_.cache.second = rp_.n1_c.second; 
 06831 |          } 
 06832 |  
 06833 |          inline T value() const exprtk_override 
 06834 |          { 
 06835 |             return std::numeric_limits<T>::quiet_NaN(); 
 06836 |          } 
 06837 |  
 06838 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06839 |          { 
 06840 |             return expression_node<T>::e_stringconst; 
 06841 |          } 
 06842 |  
 06843 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06844 |          { 
 06845 |             return reinterpret_cast<expression_node<T>*>(0); 
 06846 |          } 
 06847 |  
 06848 |          std::string str() const exprtk_override 
 06849 |          { 
 06850 |             return value_; 
 06851 |          } 
 06852 |  
 06853 |          char_cptr base() const exprtk_override 
 06854 |          { 
 06855 |             return value_.data(); 
 06856 |          } 
 06857 |  
 06858 |          std::size_t size() const exprtk_override 
 06859 |          { 
 06860 |             return value_.size(); 
 06861 |          } 
 06862 |  
 06863 |          range_t& range_ref() exprtk_override 
 06864 |          { 
 06865 |             return rp_; 
 06866 |          } 
 06867 |  
 06868 |          const range_t& range_ref() const exprtk_override 
 06869 |          { 
 06870 |             return rp_; 
 06871 |          } 
 06872 |  
 06873 |       private: 
 06874 |  
 06875 |          string_literal_node(const string_literal_node<T>&) exprtk_delete; 
 06876 |          string_literal_node<T>& operator=(const string_literal_node<T>&) exprtk_delete; 
 06877 |  
 06878 |          const std::string value_; 
 06879 |          range_t rp_; 
 06880 |       }; 
 06881 |       #endif 
 06882 |  
 06883 |       template <typename T> 
 06884 |       class unary_node : public expression_node<T> 
 06885 |       { 
 06886 |       public: 
 06887 |  
 06888 |          typedef expression_node<T>* expression_ptr; 
 06889 |          typedef std::pair<expression_ptr,bool> branch_t; 
 06890 |  
 06891 |          unary_node(const operator_type& opr, expression_ptr branch) 
 06892 |          : operation_(opr) 
 06893 |          { 
 06894 |             construct_branch_pair(branch_,branch); 
 06895 |             assert(valid()); 
 06896 |          } 
 06897 |  
 06898 |          inline T value() const exprtk_override 
 06899 |          { 
 06900 |             return numeric::process<T> 
 06901 |                      (operation_,branch_.first->value()); 
 06902 |          } 
 06903 |  
 06904 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06905 |          { 
 06906 |             return expression_node<T>::e_unary; 
 06907 |          } 
 06908 |  
 06909 |          inline operator_type operation() 
 06910 |          { 
 06911 |             return operation_; 
 06912 |          } 
 06913 |  
 06914 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 06915 |          { 
 06916 |             return branch_.first; 
 06917 |          } 
 06918 |  
 06919 |          inline bool valid() const exprtk_override 
 06920 |          { 
 06921 |             return branch_.first && branch_.first->valid(); 
 06922 |          } 
 06923 |  
 06924 |          inline void release() 
 06925 |          { 
 06926 |             branch_.second = false; 
 06927 |          } 
 06928 |  
 06929 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 06930 |          { 
 06931 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 06932 |          } 
 06933 |  
 06934 |          std::size_t node_depth() const exprtk_final 
 06935 |          { 
 06936 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 06937 |          } 
 06938 |  
 06939 |       private: 
 06940 |  
 06941 |          operator_type operation_; 
 06942 |          branch_t branch_; 
 06943 |       }; 
 06944 |  
 06945 |       template <typename T> 
 06946 |       class binary_node : public expression_node<T> 
 06947 |       { 
 06948 |       public: 
 06949 |  
 06950 |          typedef expression_node<T>* expression_ptr; 
 06951 |          typedef std::pair<expression_ptr,bool> branch_t; 
 06952 |  
 06953 |          binary_node(const operator_type& opr, 
 06954 |                      expression_ptr branch0, 
 06955 |                      expression_ptr branch1) 
 06956 |          : operation_(opr) 
 06957 |          { 
 06958 |             init_branches<2>(branch_, branch0, branch1); 
 06959 |             assert(valid()); 
 06960 |          } 
 06961 |  
 06962 |          inline T value() const exprtk_override 
 06963 |          { 
 06964 |             return numeric::process<T> 
 06965 |                    ( 
 06966 |                       operation_, 
 06967 |                       branch_[0].first->value(), 
 06968 |                       branch_[1].first->value() 
 06969 |                    ); 
 06970 |          } 
 06971 |  
 06972 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 06973 |          { 
 06974 |             return expression_node<T>::e_binary; 
 06975 |          } 
 06976 |  
 06977 |          inline operator_type operation() 
 06978 |          { 
 06979 |             return operation_; 
 06980 |          } 
 06981 |  
 06982 |          inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override 
 06983 |          { 
 06984 |             assert(index < 2); 
 06985 |             return branch_[index].first; 
 06986 |          } 
 06987 |  
 06988 |          inline bool valid() const exprtk_override 
 06989 |          { 
 06990 |             return 
 06991 |                branch_[0].first && branch_[0].first->valid() && 
 06992 |                branch_[1].first && branch_[1].first->valid() ; 
 06993 |          } 
 06994 |  
 06995 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 06996 |          { 
 06997 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 06998 |          } 
 06999 |  
 07000 |          std::size_t node_depth() const exprtk_final 
 07001 |          { 
 07002 |             return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_); 
 07003 |          } 
 07004 |  
 07005 |       private: 
 07006 |  
 07007 |          operator_type operation_; 
 07008 |          branch_t branch_[2]; 
 07009 |       }; 
 07010 |  
 07011 |       template <typename T, typename Operation> 
 07012 |       class binary_ext_node exprtk_final : public expression_node<T> 
 07013 |       { 
 07014 |       public: 
 07015 |  
 07016 |          typedef expression_node<T>* expression_ptr; 
 07017 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07018 |  
 07019 |          binary_ext_node(expression_ptr branch0, expression_ptr branch1) 
 07020 |          { 
 07021 |             init_branches<2>(branch_, branch0, branch1); 
 07022 |             assert(valid()); 
 07023 |          } 
 07024 |  
 07025 |          inline T value() const exprtk_override 
 07026 |          { 
 07027 |             const T arg0 = branch_[0].first->value(); 
 07028 |             const T arg1 = branch_[1].first->value(); 
 07029 |             return Operation::process(arg0,arg1); 
 07030 |          } 
 07031 |  
 07032 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07033 |          { 
 07034 |             return expression_node<T>::e_binary_ext; 
 07035 |          } 
 07036 |  
 07037 |          inline operator_type operation() 
 07038 |          { 
 07039 |             return Operation::operation(); 
 07040 |          } 
 07041 |  
 07042 |          inline expression_node<T>* branch(const std::size_t& index = 0) const exprtk_override 
 07043 |          { 
 07044 |             assert(index < 2); 
 07045 |             return branch_[index].first; 
 07046 |          } 
 07047 |  
 07048 |          inline bool valid() const exprtk_override 
 07049 |          { 
 07050 |             return 
 07051 |                branch_[0].first && branch_[0].first->valid() && 
 07052 |                branch_[1].first && branch_[1].first->valid() ; 
 07053 |          } 
 07054 |  
 07055 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07056 |          { 
 07057 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 07058 |          } 
 07059 |  
 07060 |          std::size_t node_depth() const exprtk_override 
 07061 |          { 
 07062 |             return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_); 
 07063 |          } 
 07064 |  
 07065 |       protected: 
 07066 |  
 07067 |          branch_t branch_[2]; 
 07068 |       }; 
 07069 |  
 07070 |       template <typename T> 
 07071 |       class trinary_node : public expression_node<T> 
 07072 |       { 
 07073 |       public: 
 07074 |  
 07075 |          typedef expression_node<T>* expression_ptr; 
 07076 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07077 |  
 07078 |          trinary_node(const operator_type& opr, 
 07079 |                       expression_ptr branch0, 
 07080 |                       expression_ptr branch1, 
 07081 |                       expression_ptr branch2) 
 07082 |          : operation_(opr) 
 07083 |          { 
 07084 |             init_branches<3>(branch_, branch0, branch1, branch2); 
 07085 |             assert(valid()); 
 07086 |          } 
 07087 |  
 07088 |          inline T value() const exprtk_override 
 07089 |          { 
 07090 |             const T arg0 = branch_[0].first->value(); 
 07091 |             const T arg1 = branch_[1].first->value(); 
 07092 |             const T arg2 = branch_[2].first->value(); 
 07093 |  
 07094 |             switch (operation_) 
 07095 |             { 
 07096 |                case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1)); 
 07097 |  
 07098 |                case e_clamp   : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1); 
 07099 |  
 07100 |                case e_iclamp  : if ((arg1 <= arg0) || (arg1 >= arg2)) 
 07101 |                                    return arg1; 
 07102 |                                 else 
 07103 |                                    return ((T(2) * arg1  <= (arg2 + arg0)) ? arg0 : arg2); 
 07104 |  
 07105 |                default        : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n")); 
 07106 |                                 return std::numeric_limits<T>::quiet_NaN(); 
 07107 |             } 
 07108 |          } 
 07109 |  
 07110 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07111 |          { 
 07112 |             return expression_node<T>::e_trinary; 
 07113 |          } 
 07114 |  
 07115 |          inline bool valid() const exprtk_override 
 07116 |          { 
 07117 |             return 
 07118 |                branch_[0].first && branch_[0].first->valid() && 
 07119 |                branch_[1].first && branch_[1].first->valid() && 
 07120 |                branch_[2].first && branch_[2].first->valid() ; 
 07121 |          } 
 07122 |  
 07123 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07124 |          { 
 07125 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 07126 |          } 
 07127 |  
 07128 |          std::size_t node_depth() const exprtk_override exprtk_final 
 07129 |          { 
 07130 |             return expression_node<T>::ndb_t::template compute_node_depth<3>(branch_); 
 07131 |          } 
 07132 |  
 07133 |       protected: 
 07134 |  
 07135 |          operator_type operation_; 
 07136 |          branch_t branch_[3]; 
 07137 |       }; 
 07138 |  
 07139 |       template <typename T> 
 07140 |       class quaternary_node : public expression_node<T> 
 07141 |       { 
 07142 |       public: 
 07143 |  
 07144 |          typedef expression_node<T>* expression_ptr; 
 07145 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07146 |  
 07147 |          quaternary_node(const operator_type& opr, 
 07148 |                          expression_ptr branch0, 
 07149 |                          expression_ptr branch1, 
 07150 |                          expression_ptr branch2, 
 07151 |                          expression_ptr branch3) 
 07152 |          : operation_(opr) 
 07153 |          { 
 07154 |             init_branches<4>(branch_, branch0, branch1, branch2, branch3); 
 07155 |          } 
 07156 |  
 07157 |          inline T value() const exprtk_override 
 07158 |          { 
 07159 |             return std::numeric_limits<T>::quiet_NaN(); 
 07160 |          } 
 07161 |  
 07162 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07163 |          { 
 07164 |             return expression_node<T>::e_quaternary; 
 07165 |          } 
 07166 |  
 07167 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07168 |          { 
 07169 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 07170 |          } 
 07171 |  
 07172 |          std::size_t node_depth() const exprtk_override exprtk_final 
 07173 |          { 
 07174 |             return expression_node<T>::ndb_t::template compute_node_depth<4>(branch_); 
 07175 |          } 
 07176 |  
 07177 |          inline bool valid() const exprtk_override 
 07178 |          { 
 07179 |             return 
 07180 |                branch_[0].first && branch_[0].first->valid() && 
 07181 |                branch_[1].first && branch_[1].first->valid() && 
 07182 |                branch_[2].first && branch_[2].first->valid() && 
 07183 |                branch_[3].first && branch_[3].first->valid() ; 
 07184 |          } 
 07185 |  
 07186 |       protected: 
 07187 |  
 07188 |          operator_type operation_; 
 07189 |          branch_t branch_[4]; 
 07190 |       }; 
 07191 |  
 07192 |       template <typename T> 
 07193 |       class conditional_node exprtk_final : public expression_node<T> 
 07194 |       { 
 07195 |       public: 
 07196 |  
 07197 |          typedef expression_node<T>* expression_ptr; 
 07198 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07199 |  
 07200 |          conditional_node(expression_ptr condition, 
 07201 |                           expression_ptr consequent, 
 07202 |                           expression_ptr alternative) 
 07203 |          { 
 07204 |             construct_branch_pair(condition_  , condition  ); 
 07205 |             construct_branch_pair(consequent_ , consequent ); 
 07206 |             construct_branch_pair(alternative_, alternative); 
 07207 |             assert(valid()); 
 07208 |          } 
 07209 |  
 07210 |          inline T value() const exprtk_override 
 07211 |          { 
 07212 |             if (is_true(condition_)) 
 07213 |                return consequent_.first->value(); 
 07214 |             else 
 07215 |                return alternative_.first->value(); 
 07216 |          } 
 07217 |  
 07218 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07219 |          { 
 07220 |             return expression_node<T>::e_conditional; 
 07221 |          } 
 07222 |  
 07223 |          inline bool valid() const exprtk_override 
 07224 |          { 
 07225 |             return 
 07226 |                condition_  .first && condition_  .first->valid() && 
 07227 |                consequent_ .first && consequent_ .first->valid() && 
 07228 |                alternative_.first && alternative_.first->valid() ; 
 07229 |          } 
 07230 |  
 07231 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07232 |          { 
 07233 |             expression_node<T>::ndb_t::collect(condition_   , node_delete_list); 
 07234 |             expression_node<T>::ndb_t::collect(consequent_  , node_delete_list); 
 07235 |             expression_node<T>::ndb_t::collect(alternative_ , node_delete_list); 
 07236 |          } 
 07237 |  
 07238 |          std::size_t node_depth() const exprtk_override 
 07239 |          { 
 07240 |             return expression_node<T>::ndb_t::compute_node_depth 
 07241 |                (condition_, consequent_, alternative_); 
 07242 |          } 
 07243 |  
 07244 |       private: 
 07245 |  
 07246 |          branch_t condition_; 
 07247 |          branch_t consequent_; 
 07248 |          branch_t alternative_; 
 07249 |       }; 
 07250 |  
 07251 |       template <typename T> 
 07252 |       class cons_conditional_node exprtk_final : public expression_node<T> 
 07253 |       { 
 07254 |       public: 
 07255 |  
 07256 |          // Consequent only conditional statement node 
 07257 |          typedef expression_node<T>* expression_ptr; 
 07258 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07259 |  
 07260 |          cons_conditional_node(expression_ptr condition, 
 07261 |                                expression_ptr consequent) 
 07262 |          { 
 07263 |             construct_branch_pair(condition_ , condition ); 
 07264 |             construct_branch_pair(consequent_, consequent); 
 07265 |             assert(valid()); 
 07266 |          } 
 07267 |  
 07268 |          inline T value() const exprtk_override 
 07269 |          { 
 07270 |             if (is_true(condition_)) 
 07271 |                return consequent_.first->value(); 
 07272 |             else 
 07273 |                return std::numeric_limits<T>::quiet_NaN(); 
 07274 |          } 
 07275 |  
 07276 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07277 |          { 
 07278 |             return expression_node<T>::e_conditional; 
 07279 |          } 
 07280 |  
 07281 |          inline bool valid() const exprtk_override 
 07282 |          { 
 07283 |             return 
 07284 |                condition_ .first && condition_ .first->valid() && 
 07285 |                consequent_.first && consequent_.first->valid() ; 
 07286 |          } 
 07287 |  
 07288 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07289 |          { 
 07290 |             expression_node<T>::ndb_t::collect(condition_  , node_delete_list); 
 07291 |             expression_node<T>::ndb_t::collect(consequent_ , node_delete_list); 
 07292 |          } 
 07293 |  
 07294 |          std::size_t node_depth() const exprtk_override 
 07295 |          { 
 07296 |             return expression_node<T>::ndb_t:: 
 07297 |                compute_node_depth(condition_, consequent_); 
 07298 |          } 
 07299 |  
 07300 |       private: 
 07301 |  
 07302 |          branch_t condition_; 
 07303 |          branch_t consequent_; 
 07304 |       }; 
 07305 |  
 07306 |       #ifndef exprtk_disable_break_continue 
 07307 |       template <typename T> 
 07308 |       class break_exception 
 07309 |       { 
 07310 |       public: 
 07311 |  
 07312 |          explicit break_exception(const T& v) 
 07313 |          : value(v) 
 07314 |          {} 
 07315 |  
 07316 |          T value; 
 07317 |       }; 
 07318 |  
 07319 |       class continue_exception {}; 
 07320 |  
 07321 |       template <typename T> 
 07322 |       class break_node exprtk_final : public expression_node<T> 
 07323 |       { 
 07324 |       public: 
 07325 |  
 07326 |          typedef expression_node<T>* expression_ptr; 
 07327 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07328 |  
 07329 |          explicit break_node(expression_ptr ret = expression_ptr(0)) 
 07330 |          { 
 07331 |             construct_branch_pair(return_, ret); 
 07332 |          } 
 07333 |  
 07334 |          inline T value() const exprtk_override 
 07335 |          { 
 07336 |             const T result = return_.first ? 
 07337 |                              return_.first->value() : 
 07338 |                              std::numeric_limits<T>::quiet_NaN(); 
 07339 |  
 07340 |             throw break_exception<T>(result); 
 07341 |  
 07342 |             #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 07343 |             return std::numeric_limits<T>::quiet_NaN(); 
 07344 |             #endif 
 07345 |          } 
 07346 |  
 07347 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07348 |          { 
 07349 |             return expression_node<T>::e_break; 
 07350 |          } 
 07351 |  
 07352 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07353 |          { 
 07354 |             expression_node<T>::ndb_t::collect(return_, node_delete_list); 
 07355 |          } 
 07356 |  
 07357 |          std::size_t node_depth() const exprtk_override 
 07358 |          { 
 07359 |             return expression_node<T>::ndb_t::compute_node_depth(return_); 
 07360 |          } 
 07361 |  
 07362 |       private: 
 07363 |  
 07364 |          branch_t return_; 
 07365 |       }; 
 07366 |  
 07367 |       template <typename T> 
 07368 |       class continue_node exprtk_final : public expression_node<T> 
 07369 |       { 
 07370 |       public: 
 07371 |  
 07372 |          inline T value() const exprtk_override 
 07373 |          { 
 07374 |             throw continue_exception(); 
 07375 |             #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 07376 |             return std::numeric_limits<T>::quiet_NaN(); 
 07377 |             #endif 
 07378 |          } 
 07379 |  
 07380 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07381 |          { 
 07382 |             return expression_node<T>::e_break; 
 07383 |          } 
 07384 |       }; 
 07385 |       #endif 
 07386 |  
 07387 |       struct loop_runtime_checker 
 07388 |       { 
 07389 |          loop_runtime_checker(loop_runtime_check_ptr loop_runtime_check, 
 07390 |                               loop_runtime_check::loop_types lp_typ = loop_runtime_check::e_invalid) 
 07391 |          : iteration_count_(0) 
 07392 |          , loop_runtime_check_(loop_runtime_check) 
 07393 |          , max_loop_iterations_(loop_runtime_check_->max_loop_iterations) 
 07394 |          , loop_type_(lp_typ) 
 07395 |          { 
 07396 |             assert(loop_runtime_check_); 
 07397 |          } 
 07398 |  
 07399 |          inline void reset(const _uint64_t initial_value = 0) const 
 07400 |          { 
 07401 |             iteration_count_ = initial_value; 
 07402 |          } 
 07403 |  
 07404 |          inline bool check() const 
 07405 |          { 
 07406 |             assert(loop_runtime_check_); 
 07407 |  
 07408 |             if ( 
 07409 |                  (++iteration_count_ <= max_loop_iterations_) && 
 07410 |                  loop_runtime_check_->check() 
 07411 |                ) 
 07412 |             { 
 07413 |                return true; 
 07414 |             } 
 07415 |  
 07416 |             loop_runtime_check::violation_context ctxt; 
 07417 |             ctxt.loop      = loop_type_; 
 07418 |             ctxt.violation = loop_runtime_check::e_iteration_count; 
 07419 |  
 07420 |             loop_runtime_check_->handle_runtime_violation(ctxt); 
 07421 |  
 07422 |             return false; 
 07423 |          } 
 07424 |  
 07425 |          bool valid() const 
 07426 |          { 
 07427 |             return 0 != loop_runtime_check_; 
 07428 |          } 
 07429 |  
 07430 |          mutable _uint64_t iteration_count_; 
 07431 |          mutable loop_runtime_check_ptr loop_runtime_check_; 
 07432 |          const details::_uint64_t& max_loop_iterations_; 
 07433 |          loop_runtime_check::loop_types loop_type_; 
 07434 |       }; 
 07435 |  
 07436 |       template <typename T> 
 07437 |       class while_loop_node : public expression_node<T> 
 07438 |       { 
 07439 |       public: 
 07440 |  
 07441 |          typedef expression_node<T>* expression_ptr; 
 07442 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07443 |  
 07444 |          while_loop_node(expression_ptr condition, 
 07445 |                          expression_ptr loop_body) 
 07446 |          { 
 07447 |             construct_branch_pair(condition_, condition); 
 07448 |             construct_branch_pair(loop_body_, loop_body); 
 07449 |             assert(valid()); 
 07450 |          } 
 07451 |  
 07452 |          inline T value() const exprtk_override 
 07453 |          { 
 07454 |             T result = T(0); 
 07455 |  
 07456 |             while (is_true(condition_)) 
 07457 |             { 
 07458 |                result = loop_body_.first->value(); 
 07459 |             } 
 07460 |  
 07461 |             return result; 
 07462 |          } 
 07463 |  
 07464 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07465 |          { 
 07466 |             return expression_node<T>::e_while; 
 07467 |          } 
 07468 |  
 07469 |          inline bool valid() const exprtk_override 
 07470 |          { 
 07471 |             return 
 07472 |                condition_.first && condition_.first->valid() && 
 07473 |                loop_body_.first && loop_body_.first->valid() ; 
 07474 |          } 
 07475 |  
 07476 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07477 |          { 
 07478 |             expression_node<T>::ndb_t::collect(condition_ , node_delete_list); 
 07479 |             expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list); 
 07480 |          } 
 07481 |  
 07482 |          std::size_t node_depth() const exprtk_override 
 07483 |          { 
 07484 |             return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_); 
 07485 |          } 
 07486 |  
 07487 |       protected: 
 07488 |  
 07489 |          branch_t condition_; 
 07490 |          branch_t loop_body_; 
 07491 |       }; 
 07492 |  
 07493 |       template <typename T> 
 07494 |       class while_loop_rtc_node exprtk_final 
 07495 |                                 : public while_loop_node<T> 
 07496 |                                 , public loop_runtime_checker 
 07497 |       { 
 07498 |       public: 
 07499 |  
 07500 |          typedef while_loop_node<T>  parent_t; 
 07501 |          typedef expression_node<T>* expression_ptr; 
 07502 |  
 07503 |          while_loop_rtc_node(expression_ptr condition, 
 07504 |                              expression_ptr loop_body, 
 07505 |                              loop_runtime_check_ptr loop_rt_chk) 
 07506 |          : parent_t(condition, loop_body) 
 07507 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop) 
 07508 |          { 
 07509 |             assert(valid()); 
 07510 |          } 
 07511 |  
 07512 |          inline T value() const exprtk_override 
 07513 |          { 
 07514 |  
 07515 |             T result = T(0); 
 07516 |  
 07517 |             loop_runtime_checker::reset(); 
 07518 |  
 07519 |             while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07520 |             { 
 07521 |                result = parent_t::loop_body_.first->value(); 
 07522 |             } 
 07523 |  
 07524 |             return result; 
 07525 |          } 
 07526 |  
 07527 |          using parent_t::valid; 
 07528 |  
 07529 |          bool valid() const exprtk_override exprtk_final 
 07530 |          { 
 07531 |             return parent_t::valid() && 
 07532 |                    loop_runtime_checker::valid(); 
 07533 |          } 
 07534 |       }; 
 07535 |  
 07536 |       template <typename T> 
 07537 |       class repeat_until_loop_node : public expression_node<T> 
 07538 |       { 
 07539 |       public: 
 07540 |  
 07541 |          typedef expression_node<T>* expression_ptr; 
 07542 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07543 |  
 07544 |          repeat_until_loop_node(expression_ptr condition, 
 07545 |                                 expression_ptr loop_body) 
 07546 |          { 
 07547 |             construct_branch_pair(condition_, condition); 
 07548 |             construct_branch_pair(loop_body_, loop_body); 
 07549 |             assert(valid()); 
 07550 |          } 
 07551 |  
 07552 |          inline T value() const exprtk_override 
 07553 |          { 
 07554 |             T result = T(0); 
 07555 |  
 07556 |             do 
 07557 |             { 
 07558 |                result = loop_body_.first->value(); 
 07559 |             } 
 07560 |             while (is_false(condition_.first)); 
 07561 |  
 07562 |             return result; 
 07563 |          } 
 07564 |  
 07565 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07566 |          { 
 07567 |             return expression_node<T>::e_repeat; 
 07568 |          } 
 07569 |  
 07570 |          inline bool valid() const exprtk_override 
 07571 |          { 
 07572 |             return 
 07573 |                condition_.first && condition_.first->valid() && 
 07574 |                loop_body_.first && loop_body_.first->valid() ; 
 07575 |          } 
 07576 |  
 07577 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07578 |          { 
 07579 |             expression_node<T>::ndb_t::collect(condition_ , node_delete_list); 
 07580 |             expression_node<T>::ndb_t::collect(loop_body_ , node_delete_list); 
 07581 |          } 
 07582 |  
 07583 |          std::size_t node_depth() const exprtk_override 
 07584 |          { 
 07585 |             return expression_node<T>::ndb_t::compute_node_depth(condition_, loop_body_); 
 07586 |          } 
 07587 |  
 07588 |       protected: 
 07589 |  
 07590 |          branch_t condition_; 
 07591 |          branch_t loop_body_; 
 07592 |       }; 
 07593 |  
 07594 |       template <typename T> 
 07595 |       class repeat_until_loop_rtc_node exprtk_final 
 07596 |                                        : public repeat_until_loop_node<T> 
 07597 |                                        , public loop_runtime_checker 
 07598 |       { 
 07599 |       public: 
 07600 |  
 07601 |          typedef repeat_until_loop_node<T> parent_t; 
 07602 |          typedef expression_node<T>*       expression_ptr; 
 07603 |  
 07604 |          repeat_until_loop_rtc_node(expression_ptr condition, 
 07605 |                                     expression_ptr loop_body, 
 07606 |                                     loop_runtime_check_ptr loop_rt_chk) 
 07607 |          : parent_t(condition, loop_body) 
 07608 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop) 
 07609 |          { 
 07610 |             assert(valid()); 
 07611 |          } 
 07612 |  
 07613 |          inline T value() const exprtk_override 
 07614 |          { 
 07615 |             T result = T(0); 
 07616 |  
 07617 |             loop_runtime_checker::reset(1); 
 07618 |  
 07619 |             do 
 07620 |             { 
 07621 |                result = parent_t::loop_body_.first->value(); 
 07622 |             } 
 07623 |             while (is_false(parent_t::condition_.first) && loop_runtime_checker::check()); 
 07624 |  
 07625 |             return result; 
 07626 |          } 
 07627 |  
 07628 |          using parent_t::valid; 
 07629 |  
 07630 |          inline bool valid() const exprtk_override exprtk_final 
 07631 |          { 
 07632 |             return parent_t::valid() && 
 07633 |                    loop_runtime_checker::valid(); 
 07634 |          } 
 07635 |       }; 
 07636 |  
 07637 |       template <typename T> 
 07638 |       class for_loop_node : public expression_node<T> 
 07639 |       { 
 07640 |       public: 
 07641 |  
 07642 |          typedef expression_node<T>* expression_ptr; 
 07643 |          typedef std::pair<expression_ptr,bool> branch_t; 
 07644 |  
 07645 |          for_loop_node(expression_ptr initialiser, 
 07646 |                        expression_ptr condition, 
 07647 |                        expression_ptr incrementor, 
 07648 |                        expression_ptr loop_body) 
 07649 |          { 
 07650 |             construct_branch_pair(initialiser_, initialiser); 
 07651 |             construct_branch_pair(condition_  , condition  ); 
 07652 |             construct_branch_pair(incrementor_, incrementor); 
 07653 |             construct_branch_pair(loop_body_  , loop_body  ); 
 07654 |             assert(valid()); 
 07655 |          } 
 07656 |  
 07657 |          inline T value() const exprtk_override 
 07658 |          { 
 07659 |             T result = T(0); 
 07660 |  
 07661 |             if (initialiser_.first) 
 07662 |                initialiser_.first->value(); 
 07663 |  
 07664 |             if (incrementor_.first) 
 07665 |             { 
 07666 |                while (is_true(condition_)) 
 07667 |                { 
 07668 |                   result = loop_body_.first->value(); 
 07669 |                   incrementor_.first->value(); 
 07670 |                } 
 07671 |             } 
 07672 |             else 
 07673 |             { 
 07674 |                while (is_true(condition_)) 
 07675 |                { 
 07676 |                   result = loop_body_.first->value(); 
 07677 |                } 
 07678 |             } 
 07679 |  
 07680 |             return result; 
 07681 |          } 
 07682 |  
 07683 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 07684 |          { 
 07685 |             return expression_node<T>::e_for; 
 07686 |          } 
 07687 |  
 07688 |          inline bool valid() const exprtk_override 
 07689 |          { 
 07690 |             return condition_.first && loop_body_.first; 
 07691 |          } 
 07692 |  
 07693 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 07694 |          { 
 07695 |             expression_node<T>::ndb_t::collect(initialiser_ , node_delete_list); 
 07696 |             expression_node<T>::ndb_t::collect(condition_   , node_delete_list); 
 07697 |             expression_node<T>::ndb_t::collect(incrementor_ , node_delete_list); 
 07698 |             expression_node<T>::ndb_t::collect(loop_body_   , node_delete_list); 
 07699 |          } 
 07700 |  
 07701 |          std::size_t node_depth() const exprtk_override 
 07702 |          { 
 07703 |             return expression_node<T>::ndb_t::compute_node_depth 
 07704 |                (initialiser_, condition_, incrementor_, loop_body_); 
 07705 |          } 
 07706 |  
 07707 |       protected: 
 07708 |  
 07709 |          branch_t initialiser_; 
 07710 |          branch_t condition_  ; 
 07711 |          branch_t incrementor_; 
 07712 |          branch_t loop_body_  ; 
 07713 |       }; 
 07714 |  
 07715 |       template <typename T> 
 07716 |       class for_loop_rtc_node exprtk_final 
 07717 |                               : public for_loop_node<T> 
 07718 |                               , public loop_runtime_checker 
 07719 |       { 
 07720 |       public: 
 07721 |  
 07722 |          typedef for_loop_node<T>    parent_t; 
 07723 |          typedef expression_node<T>* expression_ptr; 
 07724 |  
 07725 |          for_loop_rtc_node(expression_ptr initialiser, 
 07726 |                            expression_ptr condition, 
 07727 |                            expression_ptr incrementor, 
 07728 |                            expression_ptr loop_body, 
 07729 |                            loop_runtime_check_ptr loop_rt_chk) 
 07730 |          : parent_t(initialiser, condition, incrementor, loop_body) 
 07731 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop) 
 07732 |          { 
 07733 |             assert(valid()); 
 07734 |          } 
 07735 |  
 07736 |          inline T value() const exprtk_override 
 07737 |          { 
 07738 |             T result = T(0); 
 07739 |  
 07740 |             loop_runtime_checker::reset(); 
 07741 |  
 07742 |             if (parent_t::initialiser_.first) 
 07743 |                parent_t::initialiser_.first->value(); 
 07744 |  
 07745 |             if (parent_t::incrementor_.first) 
 07746 |             { 
 07747 |                while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07748 |                { 
 07749 |                   result = parent_t::loop_body_.first->value(); 
 07750 |                   parent_t::incrementor_.first->value(); 
 07751 |                } 
 07752 |             } 
 07753 |             else 
 07754 |             { 
 07755 |                while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07756 |                { 
 07757 |                   result = parent_t::loop_body_.first->value(); 
 07758 |                } 
 07759 |             } 
 07760 |  
 07761 |             return result; 
 07762 |          } 
 07763 |  
 07764 |          using parent_t::valid; 
 07765 |  
 07766 |          inline bool valid() const exprtk_override exprtk_final 
 07767 |          { 
 07768 |             return parent_t::valid() && 
 07769 |                    loop_runtime_checker::valid(); 
 07770 |          } 
 07771 |       }; 
 07772 |  
 07773 |       #ifndef exprtk_disable_break_continue 
 07774 |       template <typename T> 
 07775 |       class while_loop_bc_node : public while_loop_node<T> 
 07776 |       { 
 07777 |       public: 
 07778 |  
 07779 |          typedef while_loop_node<T>  parent_t; 
 07780 |          typedef expression_node<T>* expression_ptr; 
 07781 |  
 07782 |          while_loop_bc_node(expression_ptr condition, 
 07783 |                             expression_ptr loop_body) 
 07784 |          : parent_t(condition, loop_body) 
 07785 |          { 
 07786 |             assert(parent_t::valid()); 
 07787 |          } 
 07788 |  
 07789 |          inline T value() const exprtk_override 
 07790 |          { 
 07791 |             T result = T(0); 
 07792 |  
 07793 |             while (is_true(parent_t::condition_)) 
 07794 |             { 
 07795 |                try 
 07796 |                { 
 07797 |                   result = parent_t::loop_body_.first->value(); 
 07798 |                } 
 07799 |                catch(const break_exception<T>& e) 
 07800 |                { 
 07801 |                   return e.value; 
 07802 |                } 
 07803 |                catch(const continue_exception&) 
 07804 |                {} 
 07805 |             } 
 07806 |  
 07807 |             return result; 
 07808 |          } 
 07809 |       }; 
 07810 |  
 07811 |       template <typename T> 
 07812 |       class while_loop_bc_rtc_node exprtk_final 
 07813 |                                    : public while_loop_bc_node<T> 
 07814 |                                    , public loop_runtime_checker 
 07815 |       { 
 07816 |       public: 
 07817 |  
 07818 |          typedef while_loop_bc_node<T> parent_t; 
 07819 |          typedef expression_node<T>*   expression_ptr; 
 07820 |  
 07821 |          while_loop_bc_rtc_node(expression_ptr condition, 
 07822 |                                 expression_ptr loop_body, 
 07823 |                                 loop_runtime_check_ptr loop_rt_chk) 
 07824 |          : parent_t(condition, loop_body) 
 07825 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop) 
 07826 |          { 
 07827 |             assert(valid()); 
 07828 |          } 
 07829 |  
 07830 |          inline T value() const exprtk_override 
 07831 |          { 
 07832 |             T result = T(0); 
 07833 |  
 07834 |             loop_runtime_checker::reset(); 
 07835 |  
 07836 |             while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 07837 |             { 
 07838 |                try 
 07839 |                { 
 07840 |                   result = parent_t::loop_body_.first->value(); 
 07841 |                } 
 07842 |                catch(const break_exception<T>& e) 
 07843 |                { 
 07844 |                   return e.value; 
 07845 |                } 
 07846 |                catch(const continue_exception&) 
 07847 |                {} 
 07848 |             } 
 07849 |  
 07850 |             return result; 
 07851 |          } 
 07852 |  
 07853 |          using parent_t::valid; 
 07854 |  
 07855 |          inline bool valid() const exprtk_override exprtk_final 
 07856 |          { 
 07857 |             return parent_t::valid() && 
 07858 |                    loop_runtime_checker::valid(); 
 07859 |          } 
 07860 |       }; 
 07861 |  
 07862 |       template <typename T> 
 07863 |       class repeat_until_loop_bc_node : public repeat_until_loop_node<T> 
 07864 |       { 
 07865 |       public: 
 07866 |  
 07867 |          typedef repeat_until_loop_node<T> parent_t; 
 07868 |          typedef expression_node<T>*       expression_ptr; 
 07869 |  
 07870 |          repeat_until_loop_bc_node(expression_ptr condition, 
 07871 |                                    expression_ptr loop_body) 
 07872 |          : parent_t(condition, loop_body) 
 07873 |          { 
 07874 |             assert(parent_t::valid()); 
 07875 |          } 
 07876 |  
 07877 |          inline T value() const exprtk_override 
 07878 |          { 
 07879 |             T result = T(0); 
 07880 |  
 07881 |             do 
 07882 |             { 
 07883 |                try 
 07884 |                { 
 07885 |                   result = parent_t::loop_body_.first->value(); 
 07886 |                } 
 07887 |                catch(const break_exception<T>& e) 
 07888 |                { 
 07889 |                   return e.value; 
 07890 |                } 
 07891 |                catch(const continue_exception&) 
 07892 |                {} 
 07893 |             } 
 07894 |             while (is_false(parent_t::condition_.first)); 
 07895 |  
 07896 |             return result; 
 07897 |          } 
 07898 |       }; 
 07899 |  
 07900 |       template <typename T> 
 07901 |       class repeat_until_loop_bc_rtc_node exprtk_final 
 07902 |                                           : public repeat_until_loop_bc_node<T> 
 07903 |                                           , public loop_runtime_checker 
 07904 |       { 
 07905 |       public: 
 07906 |  
 07907 |          typedef repeat_until_loop_bc_node<T> parent_t; 
 07908 |          typedef expression_node<T>*          expression_ptr; 
 07909 |  
 07910 |          repeat_until_loop_bc_rtc_node(expression_ptr condition, 
 07911 |                                        expression_ptr loop_body, 
 07912 |                                        loop_runtime_check_ptr loop_rt_chk) 
 07913 |          : parent_t(condition, loop_body) 
 07914 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop) 
 07915 |          { 
 07916 |             assert(valid()); 
 07917 |          } 
 07918 |  
 07919 |          inline T value() const exprtk_override 
 07920 |          { 
 07921 |             T result = T(0); 
 07922 |  
 07923 |             loop_runtime_checker::reset(); 
 07924 |  
 07925 |             do 
 07926 |             { 
 07927 |                try 
 07928 |                { 
 07929 |                   result = parent_t::loop_body_.first->value(); 
 07930 |                } 
 07931 |                catch(const break_exception<T>& e) 
 07932 |                { 
 07933 |                   return e.value; 
 07934 |                } 
 07935 |                catch(const continue_exception&) 
 07936 |                {} 
 07937 |             } 
 07938 |             while (is_false(parent_t::condition_.first) && loop_runtime_checker::check()); 
 07939 |  
 07940 |             return result; 
 07941 |          } 
 07942 |  
 07943 |          using parent_t::valid; 
 07944 |  
 07945 |          inline bool valid() const exprtk_override exprtk_final 
 07946 |          { 
 07947 |             return parent_t::valid() && 
 07948 |                    loop_runtime_checker::valid(); 
 07949 |          } 
 07950 |       }; 
 07951 |  
 07952 |       template <typename T> 
 07953 |       class for_loop_bc_node : public for_loop_node<T> 
 07954 |       { 
 07955 |       public: 
 07956 |  
 07957 |          typedef for_loop_node<T>    parent_t; 
 07958 |          typedef expression_node<T>* expression_ptr; 
 07959 |  
 07960 |          for_loop_bc_node(expression_ptr initialiser, 
 07961 |                           expression_ptr condition, 
 07962 |                           expression_ptr incrementor, 
 07963 |                           expression_ptr loop_body) 
 07964 |          : parent_t(initialiser, condition, incrementor, loop_body) 
 07965 |          { 
 07966 |             assert(parent_t::valid()); 
 07967 |          } 
 07968 |  
 07969 |          inline T value() const exprtk_override 
 07970 |          { 
 07971 |             T result = T(0); 
 07972 |  
 07973 |             if (parent_t::initialiser_.first) 
 07974 |                parent_t::initialiser_.first->value(); 
 07975 |  
 07976 |             if (parent_t::incrementor_.first) 
 07977 |             { 
 07978 |                while (is_true(parent_t::condition_)) 
 07979 |                { 
 07980 |                   try 
 07981 |                   { 
 07982 |                      result = parent_t::loop_body_.first->value(); 
 07983 |                   } 
 07984 |                   catch(const break_exception<T>& e) 
 07985 |                   { 
 07986 |                      return e.value; 
 07987 |                   } 
 07988 |                   catch(const continue_exception&) 
 07989 |                   {} 
 07990 |  
 07991 |                   parent_t::incrementor_.first->value(); 
 07992 |                } 
 07993 |             } 
 07994 |             else 
 07995 |             { 
 07996 |                while (is_true(parent_t::condition_)) 
 07997 |                { 
 07998 |                   try 
 07999 |                   { 
 08000 |                      result = parent_t::loop_body_.first->value(); 
 08001 |                   } 
 08002 |                   catch(const break_exception<T>& e) 
 08003 |                   { 
 08004 |                      return e.value; 
 08005 |                   } 
 08006 |                   catch(const continue_exception&) 
 08007 |                   {} 
 08008 |                } 
 08009 |             } 
 08010 |  
 08011 |             return result; 
 08012 |          } 
 08013 |       }; 
 08014 |  
 08015 |       template <typename T> 
 08016 |       class for_loop_bc_rtc_node exprtk_final 
 08017 |                                  : public for_loop_bc_node<T> 
 08018 |                                  , public loop_runtime_checker 
 08019 |       { 
 08020 |       public: 
 08021 |  
 08022 |          typedef for_loop_bc_node<T> parent_t; 
 08023 |          typedef expression_node<T>* expression_ptr; 
 08024 |  
 08025 |          for_loop_bc_rtc_node(expression_ptr initialiser, 
 08026 |                               expression_ptr condition, 
 08027 |                               expression_ptr incrementor, 
 08028 |                               expression_ptr loop_body, 
 08029 |                               loop_runtime_check_ptr loop_rt_chk) 
 08030 |          : parent_t(initialiser, condition, incrementor, loop_body) 
 08031 |          , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop) 
 08032 |          { 
 08033 |             assert(valid()); 
 08034 |          } 
 08035 |  
 08036 |          inline T value() const exprtk_override 
 08037 |          { 
 08038 |             T result = T(0); 
 08039 |  
 08040 |             loop_runtime_checker::reset(); 
 08041 |  
 08042 |             if (parent_t::initialiser_.first) 
 08043 |                parent_t::initialiser_.first->value(); 
 08044 |  
 08045 |             if (parent_t::incrementor_.first) 
 08046 |             { 
 08047 |                while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 08048 |                { 
 08049 |                   try 
 08050 |                   { 
 08051 |                      result = parent_t::loop_body_.first->value(); 
 08052 |                   } 
 08053 |                   catch(const break_exception<T>& e) 
 08054 |                   { 
 08055 |                      return e.value; 
 08056 |                   } 
 08057 |                   catch(const continue_exception&) 
 08058 |                   {} 
 08059 |  
 08060 |                   parent_t::incrementor_.first->value(); 
 08061 |                } 
 08062 |             } 
 08063 |             else 
 08064 |             { 
 08065 |                while (is_true(parent_t::condition_) && loop_runtime_checker::check()) 
 08066 |                { 
 08067 |                   try 
 08068 |                   { 
 08069 |                      result = parent_t::loop_body_.first->value(); 
 08070 |                   } 
 08071 |                   catch(const break_exception<T>& e) 
 08072 |                   { 
 08073 |                      return e.value; 
 08074 |                   } 
 08075 |                   catch(const continue_exception&) 
 08076 |                   {} 
 08077 |                } 
 08078 |             } 
 08079 |  
 08080 |             return result; 
 08081 |          } 
 08082 |  
 08083 |          using parent_t::valid; 
 08084 |  
 08085 |          inline bool valid() const exprtk_override exprtk_final 
 08086 |          { 
 08087 |             return parent_t::valid() && 
 08088 |                    loop_runtime_checker::valid(); 
 08089 |          } 
 08090 |       }; 
 08091 |       #endif 
 08092 |  
 08093 |       template <typename T> 
 08094 |       class switch_node : public expression_node<T> 
 08095 |       { 
 08096 |       public: 
 08097 |  
 08098 |          typedef expression_node<T>* expression_ptr; 
 08099 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08100 |  
 08101 |          template <typename Allocator, 
 08102 |                    template <typename, typename> class Sequence> 
 08103 |          explicit switch_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 08104 |          { 
 08105 |             if (1 != (arg_list.size() & 1)) 
 08106 |                return; 
 08107 |  
 08108 |             arg_list_.resize(arg_list.size()); 
 08109 |  
 08110 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 08111 |             { 
 08112 |                if (arg_list[i] && arg_list[i]->valid()) 
 08113 |                { 
 08114 |                   construct_branch_pair(arg_list_[i], arg_list[i]); 
 08115 |                } 
 08116 |                else 
 08117 |                { 
 08118 |                   arg_list_.clear(); 
 08119 |                   return; 
 08120 |                } 
 08121 |             } 
 08122 |  
 08123 |             assert(valid()); 
 08124 |          } 
 08125 |  
 08126 |          inline T value() const exprtk_override 
 08127 |          { 
 08128 |             const std::size_t upper_bound = (arg_list_.size() - 1); 
 08129 |  
 08130 |             for (std::size_t i = 0; i < upper_bound; i += 2) 
 08131 |             { 
 08132 |                expression_ptr condition  = arg_list_[i    ].first; 
 08133 |                expression_ptr consequent = arg_list_[i + 1].first; 
 08134 |  
 08135 |                if (is_true(condition)) 
 08136 |                { 
 08137 |                   return consequent->value(); 
 08138 |                } 
 08139 |             } 
 08140 |  
 08141 |             return arg_list_[upper_bound].first->value(); 
 08142 |          } 
 08143 |  
 08144 |          inline typename expression_node<T>::node_type type() const exprtk_override exprtk_final 
 08145 |          { 
 08146 |             return expression_node<T>::e_switch; 
 08147 |          } 
 08148 |  
 08149 |          inline bool valid() const exprtk_override 
 08150 |          { 
 08151 |             return !arg_list_.empty(); 
 08152 |          } 
 08153 |  
 08154 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08155 |          { 
 08156 |             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list); 
 08157 |          } 
 08158 |  
 08159 |          std::size_t node_depth() const exprtk_override exprtk_final 
 08160 |          { 
 08161 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 08162 |          } 
 08163 |  
 08164 |       protected: 
 08165 |  
 08166 |          std::vector<branch_t> arg_list_; 
 08167 |       }; 
 08168 |  
 08169 |       template <typename T, typename Switch_N> 
 08170 |       class switch_n_node exprtk_final : public switch_node<T> 
 08171 |       { 
 08172 |       public: 
 08173 |  
 08174 |          typedef expression_node<T>* expression_ptr; 
 08175 |  
 08176 |          template <typename Allocator, 
 08177 |                    template <typename, typename> class Sequence> 
 08178 |          explicit switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 08179 |          : switch_node<T>(arg_list) 
 08180 |          {} 
 08181 |  
 08182 |          inline T value() const exprtk_override 
 08183 |          { 
 08184 |             return Switch_N::process(switch_node<T>::arg_list_); 
 08185 |          } 
 08186 |       }; 
 08187 |  
 08188 |       template <typename T> 
 08189 |       class multi_switch_node exprtk_final : public expression_node<T> 
 08190 |       { 
 08191 |       public: 
 08192 |  
 08193 |          typedef expression_node<T>* expression_ptr; 
 08194 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08195 |  
 08196 |          template <typename Allocator, 
 08197 |                    template <typename, typename> class Sequence> 
 08198 |          explicit multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 08199 |          { 
 08200 |             if (0 != (arg_list.size() & 1)) 
 08201 |                return; 
 08202 |  
 08203 |             arg_list_.resize(arg_list.size()); 
 08204 |  
 08205 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 08206 |             { 
 08207 |                if (arg_list[i] && arg_list[i]->valid()) 
 08208 |                { 
 08209 |                   construct_branch_pair(arg_list_[i], arg_list[i]); 
 08210 |                } 
 08211 |                else 
 08212 |                { 
 08213 |                   arg_list_.clear(); 
 08214 |                   return; 
 08215 |                } 
 08216 |             } 
 08217 |  
 08218 |             assert(valid()); 
 08219 |          } 
 08220 |  
 08221 |          inline T value() const exprtk_override 
 08222 |          { 
 08223 |             const std::size_t upper_bound = (arg_list_.size() - 1); 
 08224 |  
 08225 |             T result = T(0); 
 08226 |  
 08227 |             for (std::size_t i = 0; i < upper_bound; i += 2) 
 08228 |             { 
 08229 |                expression_ptr condition  = arg_list_[i    ].first; 
 08230 |                expression_ptr consequent = arg_list_[i + 1].first; 
 08231 |  
 08232 |                if (is_true(condition)) 
 08233 |                { 
 08234 |                   result = consequent->value(); 
 08235 |                } 
 08236 |             } 
 08237 |  
 08238 |             return result; 
 08239 |          } 
 08240 |  
 08241 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08242 |          { 
 08243 |             return expression_node<T>::e_mswitch; 
 08244 |          } 
 08245 |  
 08246 |          inline bool valid() const exprtk_override 
 08247 |          { 
 08248 |             return !arg_list_.empty() && (0 == (arg_list_.size() % 2)); 
 08249 |          } 
 08250 |  
 08251 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08252 |          { 
 08253 |             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list); 
 08254 |          } 
 08255 |  
 08256 |          std::size_t node_depth() const exprtk_override exprtk_final 
 08257 |          { 
 08258 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 08259 |          } 
 08260 |  
 08261 |       private: 
 08262 |  
 08263 |          std::vector<branch_t> arg_list_; 
 08264 |       }; 
 08265 |  
 08266 |       template <typename T> 
 08267 |       class ivariable 
 08268 |       { 
 08269 |       public: 
 08270 |  
 08271 |          virtual ~ivariable() 
 08272 |          {} 
 08273 |  
 08274 |          virtual T& ref() = 0; 
 08275 |          virtual const T& ref() const = 0; 
 08276 |       }; 
 08277 |  
 08278 |       template <typename T> 
 08279 |       class variable_node exprtk_final 
 08280 |                           : public expression_node<T> 
 08281 |                           , public ivariable      <T> 
 08282 |       { 
 08283 |       public: 
 08284 |  
 08285 |          static T null_value; 
 08286 |  
 08287 |          explicit variable_node() 
 08288 |          : value_(&null_value) 
 08289 |          {} 
 08290 |  
 08291 |          explicit variable_node(T& v) 
 08292 |          : value_(&v) 
 08293 |          {} 
 08294 |  
 08295 |          inline bool operator <(const variable_node<T>& v) const 
 08296 |          { 
 08297 |             return this < (&v); 
 08298 |          } 
 08299 |  
 08300 |          inline T value() const exprtk_override 
 08301 |          { 
 08302 |             return (*value_); 
 08303 |          } 
 08304 |  
 08305 |          inline T& ref() exprtk_override 
 08306 |          { 
 08307 |             return (*value_); 
 08308 |          } 
 08309 |  
 08310 |          inline const T& ref() const exprtk_override 
 08311 |          { 
 08312 |             return (*value_); 
 08313 |          } 
 08314 |  
 08315 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08316 |          { 
 08317 |             return expression_node<T>::e_variable; 
 08318 |          } 
 08319 |  
 08320 |       private: 
 08321 |  
 08322 |          T* value_; 
 08323 |       }; 
 08324 |  
 08325 |       template <typename T> 
 08326 |       T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN()); 
 08327 |  
 08328 |       template <typename T> 
 08329 |       struct range_pack 
 08330 |       { 
 08331 |          typedef expression_node<T>*           expression_node_ptr; 
 08332 |          typedef std::pair<std::size_t,std::size_t> cached_range_t; 
 08333 |  
 08334 |          range_pack() 
 08335 |          : n0_e (std::make_pair(false,expression_node_ptr(0))) 
 08336 |          , n1_e (std::make_pair(false,expression_node_ptr(0))) 
 08337 |          , n0_c (std::make_pair(false,0)) 
 08338 |          , n1_c (std::make_pair(false,0)) 
 08339 |          , cache(std::make_pair(0,0)) 
 08340 |          {} 
 08341 |  
 08342 |          void clear() 
 08343 |          { 
 08344 |             n0_e  = std::make_pair(false,expression_node_ptr(0)); 
 08345 |             n1_e  = std::make_pair(false,expression_node_ptr(0)); 
 08346 |             n0_c  = std::make_pair(false,0); 
 08347 |             n1_c  = std::make_pair(false,0); 
 08348 |             cache = std::make_pair(0,0); 
 08349 |          } 
 08350 |  
 08351 |          void free() 
 08352 |          { 
 08353 |             if (n0_e.first && n0_e.second) 
 08354 |             { 
 08355 |                n0_e.first = false; 
 08356 |  
 08357 |                if ( 
 08358 |                     !is_variable_node(n0_e.second) && 
 08359 |                     !is_string_node  (n0_e.second) 
 08360 |                   ) 
 08361 |                { 
 08362 |                   destroy_node(n0_e.second); 
 08363 |                } 
 08364 |             } 
 08365 |  
 08366 |             if (n1_e.first && n1_e.second) 
 08367 |             { 
 08368 |                n1_e.first = false; 
 08369 |  
 08370 |                if ( 
 08371 |                     !is_variable_node(n1_e.second) && 
 08372 |                     !is_string_node  (n1_e.second) 
 08373 |                   ) 
 08374 |                { 
 08375 |                   destroy_node(n1_e.second); 
 08376 |                } 
 08377 |             } 
 08378 |          } 
 08379 |  
 08380 |          bool const_range() const 
 08381 |          { 
 08382 |            return ( n0_c.first &&  n1_c.first) && 
 08383 |                   (!n0_e.first && !n1_e.first); 
 08384 |          } 
 08385 |  
 08386 |          bool var_range() const 
 08387 |          { 
 08388 |            return ( n0_e.first &&  n1_e.first) && 
 08389 |                   (!n0_c.first && !n1_c.first); 
 08390 |          } 
 08391 |  
 08392 |          bool operator() (std::size_t& r0, std::size_t& r1, 
 08393 |                           const std::size_t& size = std::numeric_limits<std::size_t>::max()) const 
 08394 |          { 
 08395 |             if (n0_c.first) 
 08396 |                r0 = n0_c.second; 
 08397 |             else if (n0_e.first) 
 08398 |             { 
 08399 |                r0 = static_cast<std::size_t>(details::numeric::to_int64(n0_e.second->value())); 
 08400 |             } 
 08401 |             else 
 08402 |                return false; 
 08403 |  
 08404 |             if (n1_c.first) 
 08405 |                r1 = n1_c.second; 
 08406 |             else if (n1_e.first) 
 08407 |             { 
 08408 |                r1 = static_cast<std::size_t>(details::numeric::to_int64(n1_e.second->value())); 
 08409 |             } 
 08410 |             else 
 08411 |                return false; 
 08412 |  
 08413 |             if ( 
 08414 |                  (std::numeric_limits<std::size_t>::max() != size) && 
 08415 |                  (std::numeric_limits<std::size_t>::max() == r1  ) 
 08416 |                ) 
 08417 |             { 
 08418 |                r1 = size; 
 08419 |             } 
 08420 |  
 08421 |             cache.first  = r0; 
 08422 |             cache.second = r1; 
 08423 |  
 08424 |             #ifndef exprtk_enable_range_runtime_checks 
 08425 |             return (r0 <= r1); 
 08426 |             #else 
 08427 |             return range_runtime_check(r0, r1, size); 
 08428 |             #endif 
 08429 |          } 
 08430 |  
 08431 |          inline std::size_t const_size() const 
 08432 |          { 
 08433 |             return (n1_c.second - n0_c.second); 
 08434 |          } 
 08435 |  
 08436 |          inline std::size_t cache_size() const 
 08437 |          { 
 08438 |             return (cache.second - cache.first); 
 08439 |          } 
 08440 |  
 08441 |          std::pair<bool,expression_node_ptr> n0_e; 
 08442 |          std::pair<bool,expression_node_ptr> n1_e; 
 08443 |          std::pair<bool,std::size_t        > n0_c; 
 08444 |          std::pair<bool,std::size_t        > n1_c; 
 08445 |          mutable cached_range_t             cache; 
 08446 |  
 08447 |          #ifdef exprtk_enable_range_runtime_checks 
 08448 |          bool range_runtime_check(const std::size_t r0, 
 08449 |                                   const std::size_t r1, 
 08450 |                                   const std::size_t size) const 
 08451 |          { 
 08452 |             if (r0 > size) 
 08453 |             { 
 08454 |                throw std::runtime_error("range error: (r0 < 0) || (r0 > size)"); 
 08455 |                #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 08456 |                return false; 
 08457 |                #endif 
 08458 |             } 
 08459 |  
 08460 |             if (r1 > size) 
 08461 |             { 
 08462 |                throw std::runtime_error("range error: (r1 < 0) || (r1 > size)"); 
 08463 |                #if !defined(_MSC_VER) && !defined(__NVCOMPILER) 
 08464 |                return false; 
 08465 |                #endif 
 08466 |             } 
 08467 |  
 08468 |             return (r0 <= r1); 
 08469 |          } 
 08470 |          #endif 
 08471 |       }; 
 08472 |  
 08473 |       template <typename T> 
 08474 |       class string_base_node; 
 08475 |  
 08476 |       template <typename T> 
 08477 |       struct range_data_type 
 08478 |       { 
 08479 |          typedef range_pack<T> range_t; 
 08480 |          typedef string_base_node<T>* strbase_ptr_t; 
 08481 |  
 08482 |          range_data_type() 
 08483 |          : range(0) 
 08484 |          , data (0) 
 08485 |          , size (0) 
 08486 |          , type_size(0) 
 08487 |          , str_node (0) 
 08488 |          {} 
 08489 |  
 08490 |          range_t*      range; 
 08491 |          void*         data; 
 08492 |          std::size_t   size; 
 08493 |          std::size_t   type_size; 
 08494 |          strbase_ptr_t str_node; 
 08495 |       }; 
 08496 |  
 08497 |       template <typename T> class vector_node; 
 08498 |  
 08499 |       template <typename T> 
 08500 |       class vector_interface 
 08501 |       { 
 08502 |       public: 
 08503 |  
 08504 |          typedef vector_node<T>*   vector_node_ptr; 
 08505 |          typedef vec_data_store<T> vds_t; 
 08506 |  
 08507 |          virtual ~vector_interface() 
 08508 |          {} 
 08509 |  
 08510 |          virtual std::size_t size     () const = 0; 
 08511 |  
 08512 |          virtual std::size_t base_size() const = 0; 
 08513 |  
 08514 |          virtual vector_node_ptr vec  () const = 0; 
 08515 |  
 08516 |          virtual vector_node_ptr vec  ()       = 0; 
 08517 |  
 08518 |          virtual       vds_t& vds     ()       = 0; 
 08519 |  
 08520 |          virtual const vds_t& vds     () const = 0; 
 08521 |  
 08522 |          virtual bool side_effect     () const { return false; } 
 08523 |       }; 
 08524 |  
 08525 |       template <typename T> 
 08526 |       class vector_node exprtk_final 
 08527 |                         : public expression_node <T> 
 08528 |                         , public vector_interface<T> 
 08529 |       { 
 08530 |       public: 
 08531 |  
 08532 |          typedef expression_node<T>* expression_ptr; 
 08533 |          typedef vector_holder<T>    vector_holder_t; 
 08534 |          typedef vector_node<T>*     vector_node_ptr; 
 08535 |          typedef vec_data_store<T>   vds_t; 
 08536 |  
 08537 |          explicit vector_node(vector_holder_t* vh) 
 08538 |          : vector_holder_(vh) 
 08539 |          , vds_((*vector_holder_).size(),(*vector_holder_)[0]) 
 08540 |          { 
 08541 |             vector_holder_->set_ref(&vds_.ref()); 
 08542 |          } 
 08543 |  
 08544 |          vector_node(const vds_t& vds, vector_holder_t* vh) 
 08545 |          : vector_holder_(vh) 
 08546 |          , vds_(vds) 
 08547 |          {} 
 08548 |  
 08549 |         ~vector_node() 
 08550 |          { 
 08551 |             assert(valid()); 
 08552 |             vector_holder_->remove_ref(&vds_.ref()); 
 08553 |          } 
 08554 |  
 08555 |          inline T value() const exprtk_override 
 08556 |          { 
 08557 |             return vds().data()[0]; 
 08558 |          } 
 08559 |  
 08560 |          vector_node_ptr vec() const exprtk_override 
 08561 |          { 
 08562 |             return const_cast<vector_node_ptr>(this); 
 08563 |          } 
 08564 |  
 08565 |          vector_node_ptr vec() exprtk_override 
 08566 |          { 
 08567 |             return this; 
 08568 |          } 
 08569 |  
 08570 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08571 |          { 
 08572 |             return expression_node<T>::e_vector; 
 08573 |          } 
 08574 |  
 08575 |          inline bool valid() const exprtk_override 
 08576 |          { 
 08577 |             return vector_holder_; 
 08578 |          } 
 08579 |  
 08580 |          std::size_t size() const exprtk_override 
 08581 |          { 
 08582 |             return vec_holder().size(); 
 08583 |          } 
 08584 |  
 08585 |          std::size_t base_size() const exprtk_override 
 08586 |          { 
 08587 |             return vec_holder().base_size(); 
 08588 |          } 
 08589 |  
 08590 |          vds_t& vds() exprtk_override 
 08591 |          { 
 08592 |             return vds_; 
 08593 |          } 
 08594 |  
 08595 |          const vds_t& vds() const exprtk_override 
 08596 |          { 
 08597 |             return vds_; 
 08598 |          } 
 08599 |  
 08600 |          inline vector_holder_t& vec_holder() 
 08601 |          { 
 08602 |             return (*vector_holder_); 
 08603 |          } 
 08604 |  
 08605 |          inline vector_holder_t& vec_holder() const 
 08606 |          { 
 08607 |             return (*vector_holder_); 
 08608 |          } 
 08609 |  
 08610 |       private: 
 08611 |  
 08612 |          vector_holder_t* vector_holder_; 
 08613 |          vds_t                      vds_; 
 08614 |       }; 
 08615 |  
 08616 |       template <typename T> 
 08617 |       class vector_size_node exprtk_final 
 08618 |                         : public expression_node <T> 
 08619 |       { 
 08620 |       public: 
 08621 |  
 08622 |          typedef expression_node<T>* expression_ptr; 
 08623 |          typedef vector_holder<T>    vector_holder_t; 
 08624 |  
 08625 |          explicit vector_size_node(vector_holder_t* vh) 
 08626 |          : vector_holder_(vh) 
 08627 |          {} 
 08628 |  
 08629 |         ~vector_size_node() 
 08630 |          { 
 08631 |             assert(valid()); 
 08632 |          } 
 08633 |  
 08634 |          inline T value() const exprtk_override 
 08635 |          { 
 08636 |             assert(vector_holder_); 
 08637 |             return static_cast<T>(vector_holder_->size()); 
 08638 |          } 
 08639 |  
 08640 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08641 |          { 
 08642 |             return expression_node<T>::e_vecsize; 
 08643 |          } 
 08644 |  
 08645 |          inline bool valid() const exprtk_override 
 08646 |          { 
 08647 |             return vector_holder_ && vector_holder_->size(); 
 08648 |          } 
 08649 |  
 08650 |          inline vector_holder_t* vec_holder() 
 08651 |          { 
 08652 |             return vector_holder_; 
 08653 |          } 
 08654 |  
 08655 |       private: 
 08656 |  
 08657 |          vector_holder_t* vector_holder_; 
 08658 |       }; 
 08659 |  
 08660 |       template <typename T> 
 08661 |       class vector_elem_node exprtk_final 
 08662 |                              : public expression_node<T> 
 08663 |                              , public ivariable      <T> 
 08664 |       { 
 08665 |       public: 
 08666 |  
 08667 |          typedef expression_node<T>*            expression_ptr; 
 08668 |          typedef vector_holder<T>               vector_holder_t; 
 08669 |          typedef vector_holder_t*               vector_holder_ptr; 
 08670 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08671 |  
 08672 |          vector_elem_node(expression_ptr vec_node, 
 08673 |                           expression_ptr index, 
 08674 |                           vector_holder_ptr vec_holder) 
 08675 |          : vector_holder_(vec_holder) 
 08676 |          , vector_base_((*vec_holder)[0]) 
 08677 |          { 
 08678 |             construct_branch_pair(vector_node_, vec_node); 
 08679 |             construct_branch_pair(index_      , index   ); 
 08680 |             assert(valid()); 
 08681 |          } 
 08682 |  
 08683 |          inline T value() const exprtk_override 
 08684 |          { 
 08685 |             return *access_vector(); 
 08686 |          } 
 08687 |  
 08688 |          inline T& ref() exprtk_override 
 08689 |          { 
 08690 |             return *access_vector(); 
 08691 |          } 
 08692 |  
 08693 |          inline const T& ref() const exprtk_override 
 08694 |          { 
 08695 |             return *access_vector(); 
 08696 |          } 
 08697 |  
 08698 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08699 |          { 
 08700 |             return expression_node<T>::e_vecelem; 
 08701 |          } 
 08702 |  
 08703 |          inline bool valid() const exprtk_override 
 08704 |          { 
 08705 |             return 
 08706 |                vector_holder_        && 
 08707 |                index_.first          && 
 08708 |                vector_node_.first    && 
 08709 |                index_.first->valid() && 
 08710 |                vector_node_.first->valid(); 
 08711 |          } 
 08712 |  
 08713 |          inline vector_holder_t& vec_holder() 
 08714 |          { 
 08715 |             return (*vector_holder_); 
 08716 |          } 
 08717 |  
 08718 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08719 |          { 
 08720 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 08721 |             expression_node<T>::ndb_t::collect(index_      , node_delete_list); 
 08722 |          } 
 08723 |  
 08724 |          std::size_t node_depth() const exprtk_override 
 08725 |          { 
 08726 |             return expression_node<T>::ndb_t::compute_node_depth 
 08727 |                (vector_node_, index_); 
 08728 |          } 
 08729 |  
 08730 |       private: 
 08731 |  
 08732 |          inline T* access_vector() const 
 08733 |          { 
 08734 |             vector_node_.first->value(); 
 08735 |             return (vector_base_ + details::numeric::to_uint64(index_.first->value())); 
 08736 |          } 
 08737 |  
 08738 |          vector_holder_ptr vector_holder_; 
 08739 |          T* vector_base_; 
 08740 |          branch_t vector_node_; 
 08741 |          branch_t index_; 
 08742 |       }; 
 08743 |  
 08744 |       template <typename T> 
 08745 |       class vector_celem_node exprtk_final 
 08746 |                               : public expression_node<T> 
 08747 |                               , public ivariable      <T> 
 08748 |       { 
 08749 |       public: 
 08750 |  
 08751 |          typedef expression_node<T>*            expression_ptr; 
 08752 |          typedef vector_holder<T>               vector_holder_t; 
 08753 |          typedef vector_holder_t*               vector_holder_ptr; 
 08754 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08755 |  
 08756 |          vector_celem_node(expression_ptr vec_node, 
 08757 |                            const std::size_t index, 
 08758 |                            vector_holder_ptr vec_holder) 
 08759 |          : index_(index) 
 08760 |          , vector_holder_(vec_holder) 
 08761 |          , vector_base_((*vec_holder)[0]) 
 08762 |          { 
 08763 |             construct_branch_pair(vector_node_, vec_node); 
 08764 |             assert(valid()); 
 08765 |          } 
 08766 |  
 08767 |          inline T value() const exprtk_override 
 08768 |          { 
 08769 |             return *access_vector(); 
 08770 |          } 
 08771 |  
 08772 |          inline T& ref() exprtk_override 
 08773 |          { 
 08774 |             return *access_vector(); 
 08775 |          } 
 08776 |  
 08777 |          inline const T& ref() const exprtk_override 
 08778 |          { 
 08779 |             return *access_vector(); 
 08780 |          } 
 08781 |  
 08782 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08783 |          { 
 08784 |             return expression_node<T>::e_veccelem; 
 08785 |          } 
 08786 |  
 08787 |          inline bool valid() const exprtk_override 
 08788 |          { 
 08789 |             return 
 08790 |                vector_holder_     && 
 08791 |                vector_node_.first && 
 08792 |                vector_node_.first->valid(); 
 08793 |          } 
 08794 |  
 08795 |          inline vector_holder_t& vec_holder() 
 08796 |          { 
 08797 |             return (*vector_holder_); 
 08798 |          } 
 08799 |  
 08800 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08801 |          { 
 08802 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 08803 |          } 
 08804 |  
 08805 |          std::size_t node_depth() const exprtk_override 
 08806 |          { 
 08807 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 08808 |          } 
 08809 |  
 08810 |       private: 
 08811 |  
 08812 |          inline T* access_vector() const 
 08813 |          { 
 08814 |             vector_node_.first->value(); 
 08815 |             return (vector_base_ + index_); 
 08816 |          } 
 08817 |  
 08818 |          const std::size_t index_; 
 08819 |          vector_holder_ptr vector_holder_; 
 08820 |          T* vector_base_; 
 08821 |          branch_t vector_node_; 
 08822 |       }; 
 08823 |  
 08824 |       template <typename T> 
 08825 |       class vector_elem_rtc_node exprtk_final 
 08826 |                                  : public expression_node<T> 
 08827 |                                  , public ivariable      <T> 
 08828 |       { 
 08829 |       public: 
 08830 |  
 08831 |          typedef expression_node<T>*            expression_ptr; 
 08832 |          typedef vector_holder<T>               vector_holder_t; 
 08833 |          typedef vector_holder_t*               vector_holder_ptr; 
 08834 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08835 |  
 08836 |          vector_elem_rtc_node(expression_ptr vec_node, 
 08837 |                               expression_ptr index, 
 08838 |                               vector_holder_ptr vec_holder, 
 08839 |                               vector_access_runtime_check_ptr vec_rt_chk) 
 08840 |          : vector_holder_(vec_holder) 
 08841 |          , vector_base_((*vec_holder)[0]) 
 08842 |          , vec_rt_chk_(vec_rt_chk) 
 08843 |          , max_vector_index_(vector_holder_->size() - 1) 
 08844 |          { 
 08845 |             construct_branch_pair(vector_node_, vec_node); 
 08846 |             construct_branch_pair(index_      , index   ); 
 08847 |             assert(valid()); 
 08848 |          } 
 08849 |  
 08850 |          inline T value() const exprtk_override 
 08851 |          { 
 08852 |             return *access_vector(); 
 08853 |          } 
 08854 |  
 08855 |          inline T& ref() exprtk_override 
 08856 |          { 
 08857 |             return *access_vector(); 
 08858 |          } 
 08859 |  
 08860 |          inline const T& ref() const exprtk_override 
 08861 |          { 
 08862 |             return *access_vector(); 
 08863 |          } 
 08864 |  
 08865 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08866 |          { 
 08867 |             return expression_node<T>::e_vecelemrtc; 
 08868 |          } 
 08869 |  
 08870 |          inline bool valid() const exprtk_override 
 08871 |          { 
 08872 |             return 
 08873 |                vector_holder_        && 
 08874 |                index_.first          && 
 08875 |                vector_node_.first    && 
 08876 |                index_.first->valid() && 
 08877 |                vector_node_.first->valid(); 
 08878 |          } 
 08879 |  
 08880 |          inline vector_holder_t& vec_holder() 
 08881 |          { 
 08882 |             return (*vector_holder_); 
 08883 |          } 
 08884 |  
 08885 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08886 |          { 
 08887 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 08888 |             expression_node<T>::ndb_t::collect(index_,       node_delete_list); 
 08889 |          } 
 08890 |  
 08891 |          std::size_t node_depth() const exprtk_override 
 08892 |          { 
 08893 |             return expression_node<T>::ndb_t::compute_node_depth 
 08894 |                (vector_node_, index_); 
 08895 |          } 
 08896 |  
 08897 |       private: 
 08898 |  
 08899 |          inline T* access_vector() const 
 08900 |          { 
 08901 |             const _uint64_t index = details::numeric::to_uint64(index_.first->value()); 
 08902 |             vector_node_.first->value(); 
 08903 |  
 08904 |             if (index <= max_vector_index_) 
 08905 |             { 
 08906 |                return (vector_holder_->data() + index); 
 08907 |             } 
 08908 |  
 08909 |             assert(vec_rt_chk_); 
 08910 |  
 08911 |             vector_access_runtime_check::violation_context context; 
 08912 |             context.base_ptr   = reinterpret_cast<void*>(vector_base_); 
 08913 |             context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size()); 
 08914 |             context.access_ptr = reinterpret_cast<void*>(vector_base_ + index); 
 08915 |             context.type_size  = sizeof(T); 
 08916 |  
 08917 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 08918 |                reinterpret_cast<T*>(context.access_ptr) : 
 08919 |                vector_base_ ; 
 08920 |          } 
 08921 |  
 08922 |          vector_holder_ptr vector_holder_; 
 08923 |          T*                vector_base_; 
 08924 |          branch_t          vector_node_; 
 08925 |          branch_t          index_; 
 08926 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 08927 |          const std::size_t max_vector_index_; 
 08928 |       }; 
 08929 |  
 08930 |       template <typename T> 
 08931 |       class vector_celem_rtc_node exprtk_final 
 08932 |                                  : public expression_node<T> 
 08933 |                                  , public ivariable      <T> 
 08934 |       { 
 08935 |       public: 
 08936 |  
 08937 |          typedef expression_node<T>*            expression_ptr; 
 08938 |          typedef vector_holder<T>               vector_holder_t; 
 08939 |          typedef vector_holder_t*               vector_holder_ptr; 
 08940 |          typedef std::pair<expression_ptr,bool> branch_t; 
 08941 |  
 08942 |          vector_celem_rtc_node(expression_ptr vec_node, 
 08943 |                                const std::size_t index, 
 08944 |                                vector_holder_ptr vec_holder, 
 08945 |                                vector_access_runtime_check_ptr vec_rt_chk) 
 08946 |          : index_(index) 
 08947 |          , max_vector_index_(vec_holder->size() - 1) 
 08948 |          , vector_holder_(vec_holder) 
 08949 |          , vector_base_((*vec_holder)[0]) 
 08950 |          , vec_rt_chk_(vec_rt_chk) 
 08951 |          { 
 08952 |             construct_branch_pair(vector_node_, vec_node); 
 08953 |             assert(valid()); 
 08954 |          } 
 08955 |  
 08956 |          inline T value() const exprtk_override 
 08957 |          { 
 08958 |             return *access_vector(); 
 08959 |          } 
 08960 |  
 08961 |          inline T& ref() exprtk_override 
 08962 |          { 
 08963 |             return *access_vector(); 
 08964 |          } 
 08965 |  
 08966 |          inline const T& ref() const exprtk_override 
 08967 |          { 
 08968 |             return *access_vector(); 
 08969 |          } 
 08970 |  
 08971 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 08972 |          { 
 08973 |             return expression_node<T>::e_veccelemrtc; 
 08974 |          } 
 08975 |  
 08976 |          inline bool valid() const exprtk_override 
 08977 |          { 
 08978 |             return 
 08979 |                vector_holder_     && 
 08980 |                vector_node_.first && 
 08981 |                vector_node_.first->valid(); 
 08982 |          } 
 08983 |  
 08984 |          inline vector_holder_t& vec_holder() 
 08985 |          { 
 08986 |             return (*vector_holder_); 
 08987 |          } 
 08988 |  
 08989 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 08990 |          { 
 08991 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 08992 |          } 
 08993 |  
 08994 |          std::size_t node_depth() const exprtk_override 
 08995 |          { 
 08996 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 08997 |          } 
 08998 |  
 08999 |       private: 
 09000 |  
 09001 |          inline T* access_vector() const 
 09002 |          { 
 09003 |             vector_node_.first->value(); 
 09004 |  
 09005 |             if (index_ <= max_vector_index_) 
 09006 |             { 
 09007 |                return (vector_holder_->data() + index_); 
 09008 |             } 
 09009 |  
 09010 |             assert(vec_rt_chk_); 
 09011 |  
 09012 |             vector_access_runtime_check::violation_context context; 
 09013 |             context.base_ptr   = reinterpret_cast<void*>(vector_base_); 
 09014 |             context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size()); 
 09015 |             context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_); 
 09016 |             context.type_size  = sizeof(T); 
 09017 |  
 09018 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 09019 |                reinterpret_cast<T*>(context.access_ptr) : 
 09020 |                vector_base_ ; 
 09021 |          } 
 09022 |  
 09023 |          const std::size_t index_; 
 09024 |          const std::size_t max_vector_index_; 
 09025 |          vector_holder_ptr vector_holder_; 
 09026 |          T*                vector_base_; 
 09027 |          branch_t          vector_node_; 
 09028 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 09029 |       }; 
 09030 |  
 09031 |       template <typename T> 
 09032 |       class rebasevector_elem_node exprtk_final 
 09033 |                                    : public expression_node<T> 
 09034 |                                    , public ivariable      <T> 
 09035 |       { 
 09036 |       public: 
 09037 |  
 09038 |          typedef expression_node<T>*            expression_ptr; 
 09039 |          typedef vector_holder<T>               vector_holder_t; 
 09040 |          typedef vector_holder_t*               vector_holder_ptr; 
 09041 |          typedef vec_data_store<T>              vds_t; 
 09042 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09043 |  
 09044 |          rebasevector_elem_node(expression_ptr vec_node, 
 09045 |                                 expression_ptr index, 
 09046 |                                 vector_holder_ptr vec_holder) 
 09047 |          : vector_holder_(vec_holder) 
 09048 |          { 
 09049 |             construct_branch_pair(vector_node_, vec_node); 
 09050 |             construct_branch_pair(index_      , index   ); 
 09051 |             assert(valid()); 
 09052 |          } 
 09053 |  
 09054 |          inline T value() const exprtk_override 
 09055 |          { 
 09056 |             return *access_vector(); 
 09057 |          } 
 09058 |  
 09059 |          inline T& ref() exprtk_override 
 09060 |          { 
 09061 |             return *access_vector(); 
 09062 |          } 
 09063 |  
 09064 |          inline const T& ref() const exprtk_override 
 09065 |          { 
 09066 |             return *access_vector(); 
 09067 |          } 
 09068 |  
 09069 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09070 |          { 
 09071 |             return expression_node<T>::e_rbvecelem; 
 09072 |          } 
 09073 |  
 09074 |          inline bool valid() const exprtk_override 
 09075 |          { 
 09076 |             return 
 09077 |                vector_holder_        && 
 09078 |                index_.first          && 
 09079 |                vector_node_.first    && 
 09080 |                index_.first->valid() && 
 09081 |                vector_node_.first->valid(); 
 09082 |          } 
 09083 |  
 09084 |          inline vector_holder_t& vec_holder() 
 09085 |          { 
 09086 |             return (*vector_holder_); 
 09087 |          } 
 09088 |  
 09089 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09090 |          { 
 09091 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09092 |             expression_node<T>::ndb_t::collect(index_,       node_delete_list); 
 09093 |          } 
 09094 |  
 09095 |          std::size_t node_depth() const exprtk_override 
 09096 |          { 
 09097 |             return expression_node<T>::ndb_t::compute_node_depth 
 09098 |                (vector_node_, index_); 
 09099 |          } 
 09100 |  
 09101 |       private: 
 09102 |  
 09103 |          inline T* access_vector() const 
 09104 |          { 
 09105 |             vector_node_.first->value(); 
 09106 |             return (vector_holder_->data() + details::numeric::to_uint64(index_.first->value())); 
 09107 |          } 
 09108 |  
 09109 |          vector_holder_ptr vector_holder_; 
 09110 |          branch_t          vector_node_; 
 09111 |          branch_t          index_; 
 09112 |       }; 
 09113 |  
 09114 |       template <typename T> 
 09115 |       class rebasevector_celem_node exprtk_final 
 09116 |                                     : public expression_node<T> 
 09117 |                                     , public ivariable      <T> 
 09118 |       { 
 09119 |       public: 
 09120 |  
 09121 |          typedef expression_node<T>* expression_ptr; 
 09122 |          typedef vector_holder<T>    vector_holder_t; 
 09123 |          typedef vector_holder_t*    vector_holder_ptr; 
 09124 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09125 |  
 09126 |          rebasevector_celem_node(expression_ptr vec_node, 
 09127 |                                  const std::size_t index, 
 09128 |                                  vector_holder_ptr vec_holder) 
 09129 |          : index_(index) 
 09130 |          , vector_holder_(vec_holder) 
 09131 |          { 
 09132 |             construct_branch_pair(vector_node_, vec_node); 
 09133 |             assert(valid()); 
 09134 |          } 
 09135 |  
 09136 |          inline T value() const exprtk_override 
 09137 |          { 
 09138 |             vector_node_.first->value(); 
 09139 |             return ref();; 
 09140 |          } 
 09141 |  
 09142 |          inline T& ref() exprtk_override 
 09143 |          { 
 09144 |             return *(vector_holder_->data() + index_); 
 09145 |          } 
 09146 |  
 09147 |          inline const T& ref() const exprtk_override 
 09148 |          { 
 09149 |             return *(vector_holder_->data() + index_); 
 09150 |          } 
 09151 |  
 09152 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09153 |          { 
 09154 |             return expression_node<T>::e_rbveccelem; 
 09155 |          } 
 09156 |  
 09157 |          inline bool valid() const exprtk_override 
 09158 |          { 
 09159 |             return 
 09160 |                vector_holder_     && 
 09161 |                vector_node_.first && 
 09162 |                vector_node_.first->valid(); 
 09163 |          } 
 09164 |  
 09165 |          inline vector_holder_t& vec_holder() 
 09166 |          { 
 09167 |             return (*vector_holder_); 
 09168 |          } 
 09169 |  
 09170 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09171 |          { 
 09172 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09173 |          } 
 09174 |  
 09175 |          std::size_t node_depth() const exprtk_override 
 09176 |          { 
 09177 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 09178 |          } 
 09179 |  
 09180 |       private: 
 09181 |  
 09182 |          const std::size_t index_; 
 09183 |          vector_holder_ptr vector_holder_; 
 09184 |          branch_t          vector_node_; 
 09185 |       }; 
 09186 |  
 09187 |       template <typename T> 
 09188 |       class rebasevector_elem_rtc_node exprtk_final 
 09189 |                                        : public expression_node<T> 
 09190 |                                        , public ivariable      <T> 
 09191 |       { 
 09192 |       public: 
 09193 |  
 09194 |          typedef expression_node<T>*            expression_ptr; 
 09195 |          typedef vector_holder<T>               vector_holder_t; 
 09196 |          typedef vector_holder_t*               vector_holder_ptr; 
 09197 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09198 |  
 09199 |          rebasevector_elem_rtc_node(expression_ptr vec_node, 
 09200 |                                     expression_ptr index, 
 09201 |                                     vector_holder_ptr vec_holder, 
 09202 |                                     vector_access_runtime_check_ptr vec_rt_chk) 
 09203 |          : vector_holder_(vec_holder) 
 09204 |          , vec_rt_chk_(vec_rt_chk) 
 09205 |          { 
 09206 |             construct_branch_pair(vector_node_, vec_node); 
 09207 |             construct_branch_pair(index_      , index   ); 
 09208 |             assert(valid()); 
 09209 |          } 
 09210 |  
 09211 |          inline T value() const exprtk_override 
 09212 |          { 
 09213 |             return *access_vector(); 
 09214 |          } 
 09215 |  
 09216 |          inline T& ref() exprtk_override 
 09217 |          { 
 09218 |             return *access_vector(); 
 09219 |          } 
 09220 |  
 09221 |          inline const T& ref() const exprtk_override 
 09222 |          { 
 09223 |             return *access_vector(); 
 09224 |          } 
 09225 |  
 09226 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09227 |          { 
 09228 |             return expression_node<T>::e_rbvecelemrtc; 
 09229 |          } 
 09230 |  
 09231 |          inline bool valid() const exprtk_override 
 09232 |          { 
 09233 |             return 
 09234 |                vector_holder_        && 
 09235 |                index_.first          && 
 09236 |                vector_node_.first    && 
 09237 |                index_.first->valid() && 
 09238 |                vector_node_.first->valid(); 
 09239 |          } 
 09240 |  
 09241 |          inline vector_holder_t& vec_holder() 
 09242 |          { 
 09243 |             return (*vector_holder_); 
 09244 |          } 
 09245 |  
 09246 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09247 |          { 
 09248 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09249 |             expression_node<T>::ndb_t::collect(index_      , node_delete_list); 
 09250 |          } 
 09251 |  
 09252 |          std::size_t node_depth() const exprtk_override 
 09253 |          { 
 09254 |             return expression_node<T>::ndb_t::compute_node_depth 
 09255 |                (vector_node_, index_); 
 09256 |          } 
 09257 |  
 09258 |       private: 
 09259 |  
 09260 |          inline T* access_vector() const 
 09261 |          { 
 09262 |             vector_node_.first->value(); 
 09263 |             const _uint64_t index = details::numeric::to_uint64(index_.first->value()); 
 09264 |  
 09265 |             if (index <= (vector_holder_->size() - 1)) 
 09266 |             { 
 09267 |                return (vector_holder_->data() + index); 
 09268 |             } 
 09269 |  
 09270 |             assert(vec_rt_chk_); 
 09271 |  
 09272 |             vector_access_runtime_check::violation_context context; 
 09273 |             context.base_ptr   = reinterpret_cast<void*>(vector_holder_->data()); 
 09274 |             context.end_ptr    = reinterpret_cast<void*>(vector_holder_->data() + vector_holder_->size()); 
 09275 |             context.access_ptr = reinterpret_cast<void*>(vector_holder_->data() + index); 
 09276 |             context.type_size  = sizeof(T); 
 09277 |  
 09278 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 09279 |                    reinterpret_cast<T*>(context.access_ptr) : 
 09280 |                    vector_holder_->data() ; 
 09281 |          } 
 09282 |  
 09283 |          vector_holder_ptr vector_holder_; 
 09284 |          branch_t          vector_node_; 
 09285 |          branch_t          index_; 
 09286 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 09287 |       }; 
 09288 |  
 09289 |       template <typename T> 
 09290 |       class rebasevector_celem_rtc_node exprtk_final 
 09291 |                                     : public expression_node<T> 
 09292 |                                     , public ivariable      <T> 
 09293 |       { 
 09294 |       public: 
 09295 |  
 09296 |          typedef expression_node<T>*            expression_ptr; 
 09297 |          typedef vector_holder<T>               vector_holder_t; 
 09298 |          typedef vector_holder_t*               vector_holder_ptr; 
 09299 |          typedef std::pair<expression_ptr,bool> branch_t; 
 09300 |  
 09301 |          rebasevector_celem_rtc_node(expression_ptr vec_node, 
 09302 |                                      const std::size_t index, 
 09303 |                                      vector_holder_ptr vec_holder, 
 09304 |                                      vector_access_runtime_check_ptr vec_rt_chk) 
 09305 |          : index_(index) 
 09306 |          , vector_holder_(vec_holder) 
 09307 |          , vector_base_((*vec_holder)[0]) 
 09308 |          , vec_rt_chk_(vec_rt_chk) 
 09309 |          { 
 09310 |             construct_branch_pair(vector_node_, vec_node); 
 09311 |             assert(valid()); 
 09312 |          } 
 09313 |  
 09314 |          inline T value() const exprtk_override 
 09315 |          { 
 09316 |             return *access_vector(); 
 09317 |          } 
 09318 |  
 09319 |          inline T& ref() exprtk_override 
 09320 |          { 
 09321 |             return *access_vector(); 
 09322 |          } 
 09323 |  
 09324 |          inline const T& ref() const exprtk_override 
 09325 |          { 
 09326 |             return *access_vector(); 
 09327 |          } 
 09328 |  
 09329 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09330 |          { 
 09331 |             return expression_node<T>::e_rbveccelemrtc; 
 09332 |          } 
 09333 |  
 09334 |          inline bool valid() const exprtk_override 
 09335 |          { 
 09336 |             return 
 09337 |                vector_holder_     && 
 09338 |                vector_node_.first && 
 09339 |                vector_node_.first->valid(); 
 09340 |          } 
 09341 |  
 09342 |          inline vector_holder_t& vec_holder() 
 09343 |          { 
 09344 |             return (*vector_holder_); 
 09345 |          } 
 09346 |  
 09347 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09348 |          { 
 09349 |             expression_node<T>::ndb_t::collect(vector_node_, node_delete_list); 
 09350 |          } 
 09351 |  
 09352 |          std::size_t node_depth() const exprtk_override 
 09353 |          { 
 09354 |             return expression_node<T>::ndb_t::compute_node_depth(vector_node_); 
 09355 |          } 
 09356 |  
 09357 |       private: 
 09358 |  
 09359 |          inline T* access_vector() const 
 09360 |          { 
 09361 |             vector_node_.first->value(); 
 09362 |  
 09363 |             if (index_ <= vector_holder_->size() - 1) 
 09364 |             { 
 09365 |                return (vector_holder_->data() + index_); 
 09366 |             } 
 09367 |  
 09368 |             assert(vec_rt_chk_); 
 09369 |  
 09370 |             vector_access_runtime_check::violation_context context; 
 09371 |             context.base_ptr   = reinterpret_cast<void*>(vector_base_); 
 09372 |             context.end_ptr    = reinterpret_cast<void*>(vector_base_ + vector_holder_->size()); 
 09373 |             context.access_ptr = reinterpret_cast<void*>(vector_base_ + index_); 
 09374 |             context.type_size  = sizeof(T); 
 09375 |  
 09376 |             return vec_rt_chk_->handle_runtime_violation(context) ? 
 09377 |                reinterpret_cast<T*>(context.access_ptr) : 
 09378 |                vector_base_ ; 
 09379 |          } 
 09380 |  
 09381 |          const std::size_t index_; 
 09382 |          vector_holder_ptr vector_holder_; 
 09383 |          T*                vector_base_; 
 09384 |          branch_t          vector_node_; 
 09385 |          vector_access_runtime_check_ptr vec_rt_chk_; 
 09386 |       }; 
 09387 |  
 09388 |       template <typename T> 
 09389 |       class vector_initialisation_node exprtk_final : public expression_node<T> 
 09390 |       { 
 09391 |       public: 
 09392 |  
 09393 |          typedef expression_node<T>* expression_ptr; 
 09394 |  
 09395 |          vector_initialisation_node(T* vector_base, 
 09396 |                                     const std::size_t& size, 
 09397 |                                     const std::vector<expression_ptr>& initialiser_list, 
 09398 |                                     const bool single_value_initialse) 
 09399 |          : vector_base_(vector_base) 
 09400 |          , initialiser_list_(initialiser_list) 
 09401 |          , size_(size) 
 09402 |          , single_value_initialse_(single_value_initialse) 
 09403 |          , zero_value_initialse_(false) 
 09404 |          , const_nonzero_literal_value_initialse_(false) 
 09405 |          , single_initialiser_value_(T(0)) 
 09406 |          { 
 09407 |             if (single_value_initialse_) 
 09408 |             { 
 09409 |                if (initialiser_list_.empty()) 
 09410 |                   zero_value_initialse_ = true; 
 09411 |                else if ( 
 09412 |                          (initialiser_list_.size() == 1) && 
 09413 |                          details::is_constant_node(initialiser_list_[0]) && 
 09414 |                          (T(0) == initialiser_list_[0]->value()) 
 09415 |                        ) 
 09416 |                { 
 09417 |                   zero_value_initialse_ = true; 
 09418 |                } 
 09419 |                else 
 09420 |                { 
 09421 |                   assert(initialiser_list_.size() == 1); 
 09422 |  
 09423 |                   if (details::is_constant_node(initialiser_list_[0])) 
 09424 |                   { 
 09425 |                      const_nonzero_literal_value_initialse_ = true; 
 09426 |                      single_initialiser_value_ = initialiser_list_[0]->value(); 
 09427 |                      assert(T(0) != single_initialiser_value_); 
 09428 |                   } 
 09429 |                } 
 09430 |             } 
 09431 |          } 
 09432 |  
 09433 |          inline T value() const exprtk_override 
 09434 |          { 
 09435 |             if (single_value_initialse_) 
 09436 |             { 
 09437 |                if (zero_value_initialse_) 
 09438 |                { 
 09439 |                   details::set_zero_value(vector_base_, size_); 
 09440 |                } 
 09441 |                else if (const_nonzero_literal_value_initialse_) 
 09442 |                { 
 09443 |                   for (std::size_t i = 0; i < size_; ++i) 
 09444 |                   { 
 09445 |                      *(vector_base_ + i) = single_initialiser_value_; 
 09446 |                   } 
 09447 |                } 
 09448 |                else 
 09449 |                { 
 09450 |                   for (std::size_t i = 0; i < size_; ++i) 
 09451 |                   { 
 09452 |                      *(vector_base_ + i) = initialiser_list_[0]->value(); 
 09453 |                   } 
 09454 |                } 
 09455 |             } 
 09456 |             else 
 09457 |             { 
 09458 |                const std::size_t initialiser_list_size = initialiser_list_.size(); 
 09459 |  
 09460 |                for (std::size_t i = 0; i < initialiser_list_size; ++i) 
 09461 |                { 
 09462 |                   *(vector_base_ + i) = initialiser_list_[i]->value(); 
 09463 |                } 
 09464 |  
 09465 |                if (initialiser_list_size < size_) 
 09466 |                { 
 09467 |                   details::set_zero_value( 
 09468 |                      vector_base_ + initialiser_list_size, 
 09469 |                      (size_ - initialiser_list_size)); 
 09470 |                } 
 09471 |             } 
 09472 |  
 09473 |             return *(vector_base_); 
 09474 |          } 
 09475 |  
 09476 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09477 |          { 
 09478 |             return expression_node<T>::e_vecinit; 
 09479 |          } 
 09480 |  
 09481 |          inline bool valid() const exprtk_override 
 09482 |          { 
 09483 |             return vector_base_; 
 09484 |          } 
 09485 |  
 09486 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09487 |          { 
 09488 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09489 |          } 
 09490 |  
 09491 |          std::size_t node_depth() const exprtk_override 
 09492 |          { 
 09493 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09494 |          } 
 09495 |  
 09496 |       private: 
 09497 |  
 09498 |          vector_initialisation_node(const vector_initialisation_node<T>&) exprtk_delete; 
 09499 |          vector_initialisation_node<T>& operator=(const vector_initialisation_node<T>&) exprtk_delete; 
 09500 |  
 09501 |          mutable T* vector_base_; 
 09502 |          std::vector<expression_ptr> initialiser_list_; 
 09503 |          const std::size_t size_; 
 09504 |          const bool single_value_initialse_; 
 09505 |          bool zero_value_initialse_; 
 09506 |          bool const_nonzero_literal_value_initialse_; 
 09507 |          T single_initialiser_value_; 
 09508 |       }; 
 09509 |  
 09510 |       template <typename T> 
 09511 |       class vector_init_zero_value_node exprtk_final : public expression_node<T> 
 09512 |       { 
 09513 |       public: 
 09514 |  
 09515 |          typedef expression_node<T>* expression_ptr; 
 09516 |  
 09517 |          vector_init_zero_value_node(T* vector_base, 
 09518 |                                      const std::size_t& size, 
 09519 |                                      const std::vector<expression_ptr>& initialiser_list) 
 09520 |          : vector_base_(vector_base) 
 09521 |          , size_(size) 
 09522 |          , initialiser_list_(initialiser_list) 
 09523 |          {} 
 09524 |  
 09525 |          inline T value() const exprtk_override 
 09526 |          { 
 09527 |             details::set_zero_value(vector_base_, size_); 
 09528 |             return *(vector_base_); 
 09529 |          } 
 09530 |  
 09531 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09532 |          { 
 09533 |             return expression_node<T>::e_vecinit; 
 09534 |          } 
 09535 |  
 09536 |          inline bool valid() const exprtk_override 
 09537 |          { 
 09538 |             return vector_base_; 
 09539 |          } 
 09540 |  
 09541 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09542 |          { 
 09543 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09544 |          } 
 09545 |  
 09546 |          std::size_t node_depth() const exprtk_override 
 09547 |          { 
 09548 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09549 |          } 
 09550 |  
 09551 |       private: 
 09552 |  
 09553 |          vector_init_zero_value_node(const vector_init_zero_value_node<T>&) exprtk_delete; 
 09554 |          vector_init_zero_value_node<T>& operator=(const vector_init_zero_value_node<T>&) exprtk_delete; 
 09555 |  
 09556 |          mutable T* vector_base_; 
 09557 |          const std::size_t size_; 
 09558 |          std::vector<expression_ptr> initialiser_list_; 
 09559 |       }; 
 09560 |  
 09561 |       template <typename T> 
 09562 |       class vector_init_single_constvalue_node exprtk_final : public expression_node<T> 
 09563 |       { 
 09564 |       public: 
 09565 |  
 09566 |          typedef expression_node<T>* expression_ptr; 
 09567 |  
 09568 |          vector_init_single_constvalue_node(T* vector_base, 
 09569 |                                             const std::size_t& size, 
 09570 |                                             const std::vector<expression_ptr>& initialiser_list) 
 09571 |          : vector_base_(vector_base) 
 09572 |          , size_(size) 
 09573 |          , initialiser_list_(initialiser_list) 
 09574 |          { 
 09575 |             single_initialiser_value_ = initialiser_list_[0]->value(); 
 09576 |             assert(valid()); 
 09577 |          } 
 09578 |  
 09579 |          inline T value() const exprtk_override 
 09580 |          { 
 09581 |             for (std::size_t i = 0; i < size_; ++i) 
 09582 |             { 
 09583 |                *(vector_base_ + i) = single_initialiser_value_; 
 09584 |             } 
 09585 |  
 09586 |             return *(vector_base_); 
 09587 |          } 
 09588 |  
 09589 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09590 |          { 
 09591 |             return expression_node<T>::e_vecinit; 
 09592 |          } 
 09593 |  
 09594 |          inline bool valid() const exprtk_override 
 09595 |          { 
 09596 |             return vector_base_ && 
 09597 |                    (initialiser_list_.size() == 1) && 
 09598 |                    (details::is_constant_node(initialiser_list_[0])) && 
 09599 |                    (single_initialiser_value_ != T(0)); 
 09600 |          } 
 09601 |  
 09602 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09603 |          { 
 09604 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09605 |          } 
 09606 |  
 09607 |          std::size_t node_depth() const exprtk_override 
 09608 |          { 
 09609 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09610 |          } 
 09611 |  
 09612 |       private: 
 09613 |  
 09614 |          vector_init_single_constvalue_node(const vector_init_single_constvalue_node<T>&) exprtk_delete; 
 09615 |          vector_init_single_constvalue_node<T>& operator=(const vector_init_single_constvalue_node<T>&) exprtk_delete; 
 09616 |  
 09617 |          mutable T* vector_base_; 
 09618 |          const std::size_t size_; 
 09619 |          std::vector<expression_ptr> initialiser_list_; 
 09620 |          T single_initialiser_value_; 
 09621 |       }; 
 09622 |  
 09623 |       template <typename T> 
 09624 |       class vector_init_single_value_node exprtk_final : public expression_node<T> 
 09625 |       { 
 09626 |       public: 
 09627 |  
 09628 |          typedef expression_node<T>* expression_ptr; 
 09629 |  
 09630 |          vector_init_single_value_node(T* vector_base, 
 09631 |                                        const std::size_t& size, 
 09632 |                                        const std::vector<expression_ptr>& initialiser_list) 
 09633 |          : vector_base_(vector_base) 
 09634 |          , size_(size) 
 09635 |          , initialiser_list_(initialiser_list) 
 09636 |          { 
 09637 |             assert(valid()); 
 09638 |          } 
 09639 |  
 09640 |          inline T value() const exprtk_override 
 09641 |          { 
 09642 |             expression_node<T>& node = *initialiser_list_[0]; 
 09643 |  
 09644 |             for (std::size_t i = 0; i < size_; ++i) 
 09645 |             { 
 09646 |                *(vector_base_ + i) = node.value(); 
 09647 |             } 
 09648 |  
 09649 |             return *(vector_base_); 
 09650 |          } 
 09651 |  
 09652 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09653 |          { 
 09654 |             return expression_node<T>::e_vecinit; 
 09655 |          } 
 09656 |  
 09657 |          inline bool valid() const exprtk_override 
 09658 |          { 
 09659 |             return vector_base_ && 
 09660 |                    (initialiser_list_.size() == 1) && 
 09661 |                    !details::is_constant_node(initialiser_list_[0]); 
 09662 |          } 
 09663 |  
 09664 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09665 |          { 
 09666 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09667 |          } 
 09668 |  
 09669 |          std::size_t node_depth() const exprtk_override 
 09670 |          { 
 09671 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09672 |          } 
 09673 |  
 09674 |       private: 
 09675 |  
 09676 |          vector_init_single_value_node(const vector_init_single_value_node<T>&) exprtk_delete; 
 09677 |          vector_init_single_value_node<T>& operator=(const vector_init_single_value_node<T>&) exprtk_delete; 
 09678 |  
 09679 |          mutable T* vector_base_; 
 09680 |          const std::size_t size_; 
 09681 |          std::vector<expression_ptr> initialiser_list_; 
 09682 |       }; 
 09683 |  
 09684 |       template <typename T> 
 09685 |       class vector_init_iota_constconst_node exprtk_final : public expression_node<T> 
 09686 |       { 
 09687 |       public: 
 09688 |  
 09689 |          typedef expression_node<T>* expression_ptr; 
 09690 |  
 09691 |          vector_init_iota_constconst_node(T* vector_base, 
 09692 |                                           const std::size_t& size, 
 09693 |                                           const std::vector<expression_ptr>& initialiser_list) 
 09694 |          : vector_base_(vector_base) 
 09695 |          , size_(size) 
 09696 |          , initialiser_list_(initialiser_list) 
 09697 |          { 
 09698 |             base_value_      = initialiser_list_[0]->value(); 
 09699 |             increment_value_ = initialiser_list_[1]->value(); 
 09700 |  
 09701 |             assert(valid()); 
 09702 |          } 
 09703 |  
 09704 |          inline T value() const exprtk_override 
 09705 |          { 
 09706 |             T value = base_value_; 
 09707 |  
 09708 |             for (std::size_t i = 0; i < size_; ++i, value += increment_value_) 
 09709 |             { 
 09710 |                *(vector_base_ + i) = value; 
 09711 |             } 
 09712 |  
 09713 |             return *(vector_base_); 
 09714 |          } 
 09715 |  
 09716 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09717 |          { 
 09718 |             return expression_node<T>::e_vecinit; 
 09719 |          } 
 09720 |  
 09721 |          inline bool valid() const exprtk_override 
 09722 |          { 
 09723 |             return vector_base_ && 
 09724 |                    (initialiser_list_.size() == 2) && 
 09725 |                    (details::is_constant_node(initialiser_list_[0])) && 
 09726 |                    (details::is_constant_node(initialiser_list_[1])) ; 
 09727 |          } 
 09728 |  
 09729 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09730 |          { 
 09731 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09732 |          } 
 09733 |  
 09734 |          std::size_t node_depth() const exprtk_override 
 09735 |          { 
 09736 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09737 |          } 
 09738 |  
 09739 |       private: 
 09740 |  
 09741 |          vector_init_iota_constconst_node(const vector_init_iota_constconst_node<T>&) exprtk_delete; 
 09742 |          vector_init_iota_constconst_node<T>& operator=(const vector_init_iota_constconst_node<T>&) exprtk_delete; 
 09743 |  
 09744 |          mutable T* vector_base_; 
 09745 |          const std::size_t size_; 
 09746 |          std::vector<expression_ptr> initialiser_list_; 
 09747 |          T base_value_; 
 09748 |          T increment_value_; 
 09749 |       }; 
 09750 |  
 09751 |       template <typename T> 
 09752 |       class vector_init_iota_constnconst_node exprtk_final : public expression_node<T> 
 09753 |       { 
 09754 |       public: 
 09755 |  
 09756 |          typedef expression_node<T>* expression_ptr; 
 09757 |  
 09758 |          vector_init_iota_constnconst_node(T* vector_base, 
 09759 |                                            const std::size_t& size, 
 09760 |                                            const std::vector<expression_ptr>& initialiser_list) 
 09761 |          : vector_base_(vector_base) 
 09762 |          , size_(size) 
 09763 |          , initialiser_list_(initialiser_list) 
 09764 |          { 
 09765 |             assert(valid()); 
 09766 |             base_value_ = initialiser_list_[0]->value(); 
 09767 |          } 
 09768 |  
 09769 |          inline T value() const exprtk_override 
 09770 |          { 
 09771 |             T value = base_value_; 
 09772 |             expression_node<T>& increment = *initialiser_list_[1]; 
 09773 |  
 09774 |             for (std::size_t i = 0; i < size_; ++i, value += increment.value()) 
 09775 |             { 
 09776 |                *(vector_base_ + i) = value; 
 09777 |             } 
 09778 |  
 09779 |             return *(vector_base_); 
 09780 |          } 
 09781 |  
 09782 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09783 |          { 
 09784 |             return expression_node<T>::e_vecinit; 
 09785 |          } 
 09786 |  
 09787 |          inline bool valid() const exprtk_override 
 09788 |          { 
 09789 |             return vector_base_ && 
 09790 |                   (initialiser_list_.size() == 2) && 
 09791 |                   ( details::is_constant_node(initialiser_list_[0])) && 
 09792 |                   (!details::is_constant_node(initialiser_list_[1])); 
 09793 |          } 
 09794 |  
 09795 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09796 |          { 
 09797 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09798 |          } 
 09799 |  
 09800 |          std::size_t node_depth() const exprtk_override 
 09801 |          { 
 09802 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09803 |          } 
 09804 |  
 09805 |       private: 
 09806 |  
 09807 |          vector_init_iota_constnconst_node(const vector_init_iota_constnconst_node<T>&) exprtk_delete; 
 09808 |          vector_init_iota_constnconst_node<T>& operator=(const vector_init_iota_constnconst_node<T>&) exprtk_delete; 
 09809 |  
 09810 |          mutable T* vector_base_; 
 09811 |          const std::size_t size_; 
 09812 |          std::vector<expression_ptr> initialiser_list_; 
 09813 |          T base_value_; 
 09814 |       }; 
 09815 |  
 09816 |       template <typename T> 
 09817 |       class vector_init_iota_nconstconst_node exprtk_final : public expression_node<T> 
 09818 |       { 
 09819 |       public: 
 09820 |  
 09821 |          typedef expression_node<T>* expression_ptr; 
 09822 |  
 09823 |          vector_init_iota_nconstconst_node(T* vector_base, 
 09824 |                                            const std::size_t& size, 
 09825 |                                            const std::vector<expression_ptr>& initialiser_list) 
 09826 |          : vector_base_(vector_base) 
 09827 |          , size_(size) 
 09828 |          , initialiser_list_(initialiser_list) 
 09829 |          { 
 09830 |             assert(valid()); 
 09831 |          } 
 09832 |  
 09833 |          inline T value() const exprtk_override 
 09834 |          { 
 09835 |             T value = initialiser_list_[0]->value(); 
 09836 |             const T increment = initialiser_list_[1]->value(); 
 09837 |  
 09838 |             for (std::size_t i = 0; i < size_; ++i, value += increment) 
 09839 |             { 
 09840 |                *(vector_base_ + i) = value; 
 09841 |             } 
 09842 |  
 09843 |             return *(vector_base_); 
 09844 |          } 
 09845 |  
 09846 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09847 |          { 
 09848 |             return expression_node<T>::e_vecinit; 
 09849 |          } 
 09850 |  
 09851 |          inline bool valid() const exprtk_override 
 09852 |          { 
 09853 |             return vector_base_ && 
 09854 |                    (initialiser_list_.size() == 2) && 
 09855 |                    (!details::is_constant_node(initialiser_list_[0])) && 
 09856 |                    (details::is_constant_node(initialiser_list_[1])); 
 09857 |          } 
 09858 |  
 09859 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09860 |          { 
 09861 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09862 |          } 
 09863 |  
 09864 |          std::size_t node_depth() const exprtk_override 
 09865 |          { 
 09866 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09867 |          } 
 09868 |  
 09869 |       private: 
 09870 |  
 09871 |          vector_init_iota_nconstconst_node(const vector_init_iota_nconstconst_node<T>&) exprtk_delete; 
 09872 |          vector_init_iota_nconstconst_node<T>& operator=(const vector_init_iota_nconstconst_node<T>&) exprtk_delete; 
 09873 |  
 09874 |          mutable T* vector_base_; 
 09875 |          const std::size_t size_; 
 09876 |          std::vector<expression_ptr> initialiser_list_; 
 09877 |       }; 
 09878 |  
 09879 |       template <typename T> 
 09880 |       class vector_init_iota_nconstnconst_node exprtk_final : public expression_node<T> 
 09881 |       { 
 09882 |       public: 
 09883 |  
 09884 |          typedef expression_node<T>* expression_ptr; 
 09885 |  
 09886 |          vector_init_iota_nconstnconst_node(T* vector_base, 
 09887 |                                             const std::size_t& size, 
 09888 |                                             const std::vector<expression_ptr>& initialiser_list) 
 09889 |          : vector_base_(vector_base) 
 09890 |          , size_(size) 
 09891 |          , initialiser_list_(initialiser_list) 
 09892 |          { 
 09893 |             assert(valid()); 
 09894 |          } 
 09895 |  
 09896 |          inline T value() const exprtk_override 
 09897 |          { 
 09898 |             T value = initialiser_list_[0]->value(); 
 09899 |             expression_node<T>& increment = *initialiser_list_[1]; 
 09900 |  
 09901 |             for (std::size_t i = 0; i < size_; ++i, value += increment.value()) 
 09902 |             { 
 09903 |                *(vector_base_ + i) = value; 
 09904 |             } 
 09905 |  
 09906 |             return *(vector_base_); 
 09907 |          } 
 09908 |  
 09909 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09910 |          { 
 09911 |             return expression_node<T>::e_vecinit; 
 09912 |          } 
 09913 |  
 09914 |          inline bool valid() const exprtk_override 
 09915 |          { 
 09916 |             return vector_base_ && 
 09917 |                    (initialiser_list_.size() == 2) && 
 09918 |                    (!details::is_constant_node(initialiser_list_[0])) && 
 09919 |                    (!details::is_constant_node(initialiser_list_[1])); 
 09920 |          } 
 09921 |  
 09922 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 09923 |          { 
 09924 |             expression_node<T>::ndb_t::collect(initialiser_list_, node_delete_list); 
 09925 |          } 
 09926 |  
 09927 |          std::size_t node_depth() const exprtk_override 
 09928 |          { 
 09929 |             return expression_node<T>::ndb_t::compute_node_depth(initialiser_list_); 
 09930 |          } 
 09931 |  
 09932 |       private: 
 09933 |  
 09934 |          vector_init_iota_nconstnconst_node(const vector_init_iota_nconstnconst_node<T>&) exprtk_delete; 
 09935 |          vector_init_iota_nconstnconst_node<T>& operator=(const vector_init_iota_nconstnconst_node<T>&) exprtk_delete; 
 09936 |  
 09937 |          mutable T* vector_base_; 
 09938 |          const std::size_t size_; 
 09939 |          std::vector<expression_ptr> initialiser_list_; 
 09940 |       }; 
 09941 |  
 09942 |       template <typename T> 
 09943 |       class swap_node exprtk_final : public expression_node<T> 
 09944 |       { 
 09945 |       public: 
 09946 |  
 09947 |          typedef expression_node<T>* expression_ptr; 
 09948 |          typedef variable_node<T>*   variable_node_ptr; 
 09949 |  
 09950 |          swap_node(variable_node_ptr var0, variable_node_ptr var1) 
 09951 |          : var0_(var0) 
 09952 |          , var1_(var1) 
 09953 |          {} 
 09954 |  
 09955 |          inline T value() const exprtk_override 
 09956 |          { 
 09957 |             std::swap(var0_->ref(),var1_->ref()); 
 09958 |             return var1_->ref(); 
 09959 |          } 
 09960 |  
 09961 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09962 |          { 
 09963 |             return expression_node<T>::e_swap; 
 09964 |          } 
 09965 |  
 09966 |       private: 
 09967 |  
 09968 |          variable_node_ptr var0_; 
 09969 |          variable_node_ptr var1_; 
 09970 |       }; 
 09971 |  
 09972 |       template <typename T> 
 09973 |       class swap_generic_node exprtk_final : public binary_node<T> 
 09974 |       { 
 09975 |       public: 
 09976 |  
 09977 |          typedef expression_node<T>* expression_ptr; 
 09978 |          typedef ivariable<T>*       ivariable_ptr; 
 09979 |  
 09980 |          swap_generic_node(expression_ptr var0, expression_ptr var1) 
 09981 |          : binary_node<T>(details::e_swap, var0, var1) 
 09982 |          , var0_(dynamic_cast<ivariable_ptr>(var0)) 
 09983 |          , var1_(dynamic_cast<ivariable_ptr>(var1)) 
 09984 |          {} 
 09985 |  
 09986 |          inline T value() const exprtk_override 
 09987 |          { 
 09988 |             std::swap(var0_->ref(),var1_->ref()); 
 09989 |             return var1_->ref(); 
 09990 |          } 
 09991 |  
 09992 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 09993 |          { 
 09994 |             return expression_node<T>::e_swap; 
 09995 |          } 
 09996 |  
 09997 |       private: 
 09998 |  
 09999 |          ivariable_ptr var0_; 
 10000 |          ivariable_ptr var1_; 
 10001 |       }; 
 10002 |  
 10003 |       template <typename T> 
 10004 |       class swap_vecvec_node exprtk_final 
 10005 |                              : public binary_node     <T> 
 10006 |                              , public vector_interface<T> 
 10007 |       { 
 10008 |       public: 
 10009 |  
 10010 |          typedef expression_node<T>* expression_ptr; 
 10011 |          typedef vector_node    <T>* vector_node_ptr; 
 10012 |          typedef vec_data_store <T>  vds_t; 
 10013 |  
 10014 |          using binary_node<T>::branch; 
 10015 |  
 10016 |          swap_vecvec_node(expression_ptr branch0, 
 10017 |                           expression_ptr branch1) 
 10018 |          : binary_node<T>(details::e_swap, branch0, branch1) 
 10019 |          , vec0_node_ptr_(0) 
 10020 |          , vec1_node_ptr_(0) 
 10021 |          , initialised_  (false) 
 10022 |          { 
 10023 |             if (is_ivector_node(branch(0))) 
 10024 |             { 
 10025 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 10026 |  
 10027 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 10028 |                { 
 10029 |                   vec0_node_ptr_ = vi->vec(); 
 10030 |                   vds()          = vi->vds(); 
 10031 |                } 
 10032 |             } 
 10033 |  
 10034 |             if (is_ivector_node(branch(1))) 
 10035 |             { 
 10036 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 10037 |  
 10038 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 10039 |                { 
 10040 |                   vec1_node_ptr_ = vi->vec(); 
 10041 |                } 
 10042 |             } 
 10043 |  
 10044 |             if (vec0_node_ptr_ && vec1_node_ptr_) 
 10045 |             { 
 10046 |                initialised_ = size() <= base_size(); 
 10047 |             } 
 10048 |  
 10049 |             assert(valid()); 
 10050 |          } 
 10051 |  
 10052 |          inline T value() const exprtk_override 
 10053 |          { 
 10054 |             binary_node<T>::branch(0)->value(); 
 10055 |             binary_node<T>::branch(1)->value(); 
 10056 |  
 10057 |             T* vec0 = vec0_node_ptr_->vds().data(); 
 10058 |             T* vec1 = vec1_node_ptr_->vds().data(); 
 10059 |  
 10060 |             assert(size() <= base_size()); 
 10061 |             const std::size_t n = size(); 
 10062 |  
 10063 |             for (std::size_t i = 0; i < n; ++i) 
 10064 |             { 
 10065 |                std::swap(vec0[i],vec1[i]); 
 10066 |             } 
 10067 |  
 10068 |             return vec1_node_ptr_->value(); 
 10069 |          } 
 10070 |  
 10071 |          vector_node_ptr vec() const exprtk_override 
 10072 |          { 
 10073 |             return vec0_node_ptr_; 
 10074 |          } 
 10075 |  
 10076 |          vector_node_ptr vec() exprtk_override 
 10077 |          { 
 10078 |             return vec0_node_ptr_; 
 10079 |          } 
 10080 |  
 10081 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10082 |          { 
 10083 |             return expression_node<T>::e_vecvecswap; 
 10084 |          } 
 10085 |  
 10086 |          inline bool valid() const exprtk_override 
 10087 |          { 
 10088 |             return initialised_ && binary_node<T>::valid(); 
 10089 |          } 
 10090 |  
 10091 |          std::size_t size() const exprtk_override 
 10092 |          { 
 10093 |             return std::min( 
 10094 |                vec0_node_ptr_->vec_holder().size(), 
 10095 |                vec1_node_ptr_->vec_holder().size()); 
 10096 |          } 
 10097 |  
 10098 |          std::size_t base_size() const exprtk_override 
 10099 |          { 
 10100 |             return std::min( 
 10101 |                vec0_node_ptr_->vec_holder().base_size(), 
 10102 |                vec1_node_ptr_->vec_holder().base_size()); 
 10103 |          } 
 10104 |  
 10105 |          vds_t& vds() exprtk_override 
 10106 |          { 
 10107 |             return vds_; 
 10108 |          } 
 10109 |  
 10110 |          const vds_t& vds() const exprtk_override 
 10111 |          { 
 10112 |             return vds_; 
 10113 |          } 
 10114 |  
 10115 |       private: 
 10116 |  
 10117 |          vector_node<T>* vec0_node_ptr_; 
 10118 |          vector_node<T>* vec1_node_ptr_; 
 10119 |          bool            initialised_; 
 10120 |          vds_t           vds_; 
 10121 |       }; 
 10122 |  
 10123 |       #ifndef exprtk_disable_string_capabilities 
 10124 |       template <typename T> 
 10125 |       class stringvar_node exprtk_final 
 10126 |                            : public expression_node <T> 
 10127 |                            , public string_base_node<T> 
 10128 |                            , public range_interface <T> 
 10129 |       { 
 10130 |       public: 
 10131 |  
 10132 |          typedef typename range_interface<T>::range_t range_t; 
 10133 |  
 10134 |          static std::string null_value; 
 10135 |  
 10136 |          explicit stringvar_node() 
 10137 |          : value_(&null_value) 
 10138 |          {} 
 10139 |  
 10140 |          explicit stringvar_node(std::string& v) 
 10141 |          : value_(&v) 
 10142 |          { 
 10143 |             rp_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10144 |             rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size()); 
 10145 |             rp_.cache.first  = rp_.n0_c.second; 
 10146 |             rp_.cache.second = rp_.n1_c.second; 
 10147 |          } 
 10148 |  
 10149 |          inline bool operator <(const stringvar_node<T>& v) const 
 10150 |          { 
 10151 |             return this < (&v); 
 10152 |          } 
 10153 |  
 10154 |          inline T value() const exprtk_override 
 10155 |          { 
 10156 |             rp_.n1_c.second  = (*value_).size(); 
 10157 |             rp_.cache.second = rp_.n1_c.second; 
 10158 |  
 10159 |             return std::numeric_limits<T>::quiet_NaN(); 
 10160 |          } 
 10161 |  
 10162 |          std::string str() const exprtk_override 
 10163 |          { 
 10164 |             return ref(); 
 10165 |          } 
 10166 |  
 10167 |          char_cptr base() const exprtk_override 
 10168 |          { 
 10169 |             return &(*value_)[0]; 
 10170 |          } 
 10171 |  
 10172 |          std::size_t size() const exprtk_override 
 10173 |          { 
 10174 |             return ref().size(); 
 10175 |          } 
 10176 |  
 10177 |          std::string& ref() 
 10178 |          { 
 10179 |             return (*value_); 
 10180 |          } 
 10181 |  
 10182 |          const std::string& ref() const 
 10183 |          { 
 10184 |             return (*value_); 
 10185 |          } 
 10186 |  
 10187 |          range_t& range_ref() exprtk_override 
 10188 |          { 
 10189 |             return rp_; 
 10190 |          } 
 10191 |  
 10192 |          const range_t& range_ref() const exprtk_override 
 10193 |          { 
 10194 |             return rp_; 
 10195 |          } 
 10196 |  
 10197 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10198 |          { 
 10199 |             return expression_node<T>::e_stringvar; 
 10200 |          } 
 10201 |  
 10202 |          void rebase(std::string& s) 
 10203 |          { 
 10204 |             value_ = &s; 
 10205 |             rp_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10206 |             rp_.n1_c = std::make_pair<bool,std::size_t>(true,value_->size() - 1); 
 10207 |             rp_.cache.first  = rp_.n0_c.second; 
 10208 |             rp_.cache.second = rp_.n1_c.second; 
 10209 |          } 
 10210 |  
 10211 |       private: 
 10212 |  
 10213 |          std::string* value_; 
 10214 |          mutable range_t rp_; 
 10215 |       }; 
 10216 |  
 10217 |       template <typename T> 
 10218 |       std::string stringvar_node<T>::null_value = std::string(""); 
 10219 |  
 10220 |       template <typename T> 
 10221 |       class string_range_node exprtk_final 
 10222 |                               : public expression_node <T> 
 10223 |                               , public string_base_node<T> 
 10224 |                               , public range_interface <T> 
 10225 |       { 
 10226 |       public: 
 10227 |  
 10228 |          typedef typename range_interface<T>::range_t range_t; 
 10229 |  
 10230 |          static std::string null_value; 
 10231 |  
 10232 |          explicit string_range_node(std::string& v, const range_t& rp) 
 10233 |          : value_(&v) 
 10234 |          , rp_(rp) 
 10235 |          {} 
 10236 |  
 10237 |          virtual ~string_range_node() 
 10238 |          { 
 10239 |             rp_.free(); 
 10240 |          } 
 10241 |  
 10242 |          inline bool operator <(const string_range_node<T>& v) const 
 10243 |          { 
 10244 |             return this < (&v); 
 10245 |          } 
 10246 |  
 10247 |          inline T value() const exprtk_override 
 10248 |          { 
 10249 |             return std::numeric_limits<T>::quiet_NaN(); 
 10250 |          } 
 10251 |  
 10252 |          inline std::string str() const exprtk_override 
 10253 |          { 
 10254 |             return (*value_); 
 10255 |          } 
 10256 |  
 10257 |          char_cptr base() const exprtk_override 
 10258 |          { 
 10259 |             return &(*value_)[0]; 
 10260 |          } 
 10261 |  
 10262 |          std::size_t size() const exprtk_override 
 10263 |          { 
 10264 |             return ref().size(); 
 10265 |          } 
 10266 |  
 10267 |          inline range_t range() const 
 10268 |          { 
 10269 |             return rp_; 
 10270 |          } 
 10271 |  
 10272 |          inline virtual std::string& ref() 
 10273 |          { 
 10274 |             return (*value_); 
 10275 |          } 
 10276 |  
 10277 |          inline virtual const std::string& ref() const 
 10278 |          { 
 10279 |             return (*value_); 
 10280 |          } 
 10281 |  
 10282 |          inline range_t& range_ref() exprtk_override 
 10283 |          { 
 10284 |             return rp_; 
 10285 |          } 
 10286 |  
 10287 |          inline const range_t& range_ref() const exprtk_override 
 10288 |          { 
 10289 |             return rp_; 
 10290 |          } 
 10291 |  
 10292 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10293 |          { 
 10294 |             return expression_node<T>::e_stringvarrng; 
 10295 |          } 
 10296 |  
 10297 |       private: 
 10298 |  
 10299 |          std::string* value_; 
 10300 |          range_t      rp_; 
 10301 |       }; 
 10302 |  
 10303 |       template <typename T> 
 10304 |       std::string string_range_node<T>::null_value = std::string(""); 
 10305 |  
 10306 |       template <typename T> 
 10307 |       class const_string_range_node exprtk_final 
 10308 |                                     : public expression_node <T> 
 10309 |                                     , public string_base_node<T> 
 10310 |                                     , public range_interface <T> 
 10311 |       { 
 10312 |       public: 
 10313 |  
 10314 |          typedef typename range_interface<T>::range_t range_t; 
 10315 |  
 10316 |          explicit const_string_range_node(const std::string& v, const range_t& rp) 
 10317 |          : value_(v) 
 10318 |          , rp_(rp) 
 10319 |          {} 
 10320 |  
 10321 |         ~const_string_range_node() 
 10322 |          { 
 10323 |             rp_.free(); 
 10324 |          } 
 10325 |  
 10326 |          inline T value() const exprtk_override 
 10327 |          { 
 10328 |             return std::numeric_limits<T>::quiet_NaN(); 
 10329 |          } 
 10330 |  
 10331 |          std::string str() const exprtk_override 
 10332 |          { 
 10333 |             return value_; 
 10334 |          } 
 10335 |  
 10336 |          char_cptr base() const exprtk_override 
 10337 |          { 
 10338 |             return value_.data(); 
 10339 |          } 
 10340 |  
 10341 |          std::size_t size() const exprtk_override 
 10342 |          { 
 10343 |             return value_.size(); 
 10344 |          } 
 10345 |  
 10346 |          range_t range() const 
 10347 |          { 
 10348 |             return rp_; 
 10349 |          } 
 10350 |  
 10351 |          range_t& range_ref() exprtk_override 
 10352 |          { 
 10353 |             return rp_; 
 10354 |          } 
 10355 |  
 10356 |          const range_t& range_ref() const exprtk_override 
 10357 |          { 
 10358 |             return rp_; 
 10359 |          } 
 10360 |  
 10361 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10362 |          { 
 10363 |             return expression_node<T>::e_cstringvarrng; 
 10364 |          } 
 10365 |  
 10366 |       private: 
 10367 |  
 10368 |          const_string_range_node(const const_string_range_node<T>&) exprtk_delete; 
 10369 |          const_string_range_node<T>& operator=(const const_string_range_node<T>&) exprtk_delete; 
 10370 |  
 10371 |          const std::string value_; 
 10372 |          range_t rp_; 
 10373 |       }; 
 10374 |  
 10375 |       template <typename T> 
 10376 |       class generic_string_range_node exprtk_final 
 10377 |                                       : public expression_node <T> 
 10378 |                                       , public string_base_node<T> 
 10379 |                                       , public range_interface <T> 
 10380 |       { 
 10381 |       public: 
 10382 |  
 10383 |          typedef expression_node <T>* expression_ptr; 
 10384 |          typedef stringvar_node  <T>* strvar_node_ptr; 
 10385 |          typedef string_base_node<T>* str_base_ptr; 
 10386 |          typedef typename range_interface<T>::range_t range_t; 
 10387 |          typedef range_t*             range_ptr; 
 10388 |          typedef range_interface<T>   irange_t; 
 10389 |          typedef irange_t*            irange_ptr; 
 10390 |          typedef std::pair<expression_ptr,bool>  branch_t; 
 10391 |  
 10392 |          generic_string_range_node(expression_ptr str_branch, const range_t& brange) 
 10393 |          : initialised_(false) 
 10394 |          , str_base_ptr_ (0) 
 10395 |          , str_range_ptr_(0) 
 10396 |          , base_range_(brange) 
 10397 |          { 
 10398 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10399 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 10400 |             range_.cache.first  = range_.n0_c.second; 
 10401 |             range_.cache.second = range_.n1_c.second; 
 10402 |  
 10403 |             construct_branch_pair(branch_, str_branch); 
 10404 |  
 10405 |             if (is_generally_string_node(branch_.first)) 
 10406 |             { 
 10407 |                str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first); 
 10408 |  
 10409 |                if (0 == str_base_ptr_) 
 10410 |                   return; 
 10411 |  
 10412 |                str_range_ptr_ = dynamic_cast<irange_ptr>(branch_.first); 
 10413 |  
 10414 |                if (0 == str_range_ptr_) 
 10415 |                   return; 
 10416 |             } 
 10417 |  
 10418 |             initialised_ = (str_base_ptr_ && str_range_ptr_); 
 10419 |             assert(valid()); 
 10420 |          } 
 10421 |  
 10422 |         ~generic_string_range_node() 
 10423 |          { 
 10424 |             base_range_.free(); 
 10425 |          } 
 10426 |  
 10427 |          inline T value() const exprtk_override 
 10428 |          { 
 10429 |             branch_.first->value(); 
 10430 |  
 10431 |             std::size_t str_r0 = 0; 
 10432 |             std::size_t str_r1 = 0; 
 10433 |  
 10434 |             std::size_t r0 = 0; 
 10435 |             std::size_t r1 = 0; 
 10436 |  
 10437 |             const range_t& range = str_range_ptr_->range_ref(); 
 10438 |  
 10439 |             const std::size_t base_str_size = str_base_ptr_->size(); 
 10440 |  
 10441 |             if ( 
 10442 |                   range      (str_r0, str_r1, base_str_size         ) && 
 10443 |                   base_range_(r0    , r1    , base_str_size - str_r0) 
 10444 |                ) 
 10445 |             { 
 10446 |                const std::size_t size = r1 - r0; 
 10447 |  
 10448 |                range_.n1_c.second  = size; 
 10449 |                range_.cache.second = range_.n1_c.second; 
 10450 |  
 10451 |                value_.assign(str_base_ptr_->base() + str_r0 + r0, size); 
 10452 |             } 
 10453 |  
 10454 |             return std::numeric_limits<T>::quiet_NaN(); 
 10455 |          } 
 10456 |  
 10457 |          std::string str() const exprtk_override 
 10458 |          { 
 10459 |             return value_; 
 10460 |          } 
 10461 |  
 10462 |          char_cptr base() const exprtk_override 
 10463 |          { 
 10464 |             return &value_[0]; 
 10465 |          } 
 10466 |  
 10467 |          std::size_t size() const exprtk_override 
 10468 |          { 
 10469 |             return value_.size(); 
 10470 |          } 
 10471 |  
 10472 |          range_t& range_ref() exprtk_override 
 10473 |          { 
 10474 |             return range_; 
 10475 |          } 
 10476 |  
 10477 |          const range_t& range_ref() const exprtk_override 
 10478 |          { 
 10479 |             return range_; 
 10480 |          } 
 10481 |  
 10482 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10483 |          { 
 10484 |             return expression_node<T>::e_strgenrange; 
 10485 |          } 
 10486 |  
 10487 |          inline bool valid() const exprtk_override 
 10488 |          { 
 10489 |             return initialised_ && branch_.first; 
 10490 |          } 
 10491 |  
 10492 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 10493 |          { 
 10494 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 10495 |          } 
 10496 |  
 10497 |          std::size_t node_depth() const exprtk_override 
 10498 |          { 
 10499 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 10500 |          } 
 10501 |  
 10502 |       private: 
 10503 |  
 10504 |          bool                initialised_; 
 10505 |          branch_t            branch_; 
 10506 |          str_base_ptr        str_base_ptr_; 
 10507 |          irange_ptr          str_range_ptr_; 
 10508 |          mutable range_t     base_range_; 
 10509 |          mutable range_t     range_; 
 10510 |          mutable std::string value_; 
 10511 |       }; 
 10512 |  
 10513 |       template <typename T> 
 10514 |       class string_concat_node exprtk_final 
 10515 |                                : public binary_node     <T> 
 10516 |                                , public string_base_node<T> 
 10517 |                                , public range_interface <T> 
 10518 |       { 
 10519 |       public: 
 10520 |  
 10521 |          typedef typename range_interface<T>::range_t range_t; 
 10522 |          typedef range_interface<T>   irange_t; 
 10523 |          typedef irange_t*            irange_ptr; 
 10524 |          typedef range_t*             range_ptr; 
 10525 |          typedef expression_node <T>* expression_ptr; 
 10526 |          typedef string_base_node<T>* str_base_ptr; 
 10527 |  
 10528 |          using binary_node<T>::branch; 
 10529 |  
 10530 |          string_concat_node(const operator_type& opr, 
 10531 |                             expression_ptr branch0, 
 10532 |                             expression_ptr branch1) 
 10533 |          : binary_node<T>(opr, branch0, branch1) 
 10534 |          , initialised_(false) 
 10535 |          , str0_base_ptr_ (0) 
 10536 |          , str1_base_ptr_ (0) 
 10537 |          , str0_range_ptr_(0) 
 10538 |          , str1_range_ptr_(0) 
 10539 |          { 
 10540 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 10541 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 10542 |  
 10543 |             range_.cache.first  = range_.n0_c.second; 
 10544 |             range_.cache.second = range_.n1_c.second; 
 10545 |  
 10546 |             if (is_generally_string_node(branch(0))) 
 10547 |             { 
 10548 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 10549 |  
 10550 |                if (0 == str0_base_ptr_) 
 10551 |                   return; 
 10552 |  
 10553 |                str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0)); 
 10554 |  
 10555 |                if (0 == str0_range_ptr_) 
 10556 |                   return; 
 10557 |             } 
 10558 |  
 10559 |             if (is_generally_string_node(branch(1))) 
 10560 |             { 
 10561 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 10562 |  
 10563 |                if (0 == str1_base_ptr_) 
 10564 |                   return; 
 10565 |  
 10566 |                str1_range_ptr_ = dynamic_cast<irange_ptr>(branch(1)); 
 10567 |  
 10568 |                if (0 == str1_range_ptr_) 
 10569 |                   return; 
 10570 |             } 
 10571 |  
 10572 |             initialised_ = str0_base_ptr_  && 
 10573 |                            str1_base_ptr_  && 
 10574 |                            str0_range_ptr_ && 
 10575 |                            str1_range_ptr_ ; 
 10576 |  
 10577 |             assert(valid()); 
 10578 |          } 
 10579 |  
 10580 |          inline T value() const exprtk_override 
 10581 |          { 
 10582 |             branch(0)->value(); 
 10583 |             branch(1)->value(); 
 10584 |  
 10585 |             std::size_t str0_r0 = 0; 
 10586 |             std::size_t str0_r1 = 0; 
 10587 |  
 10588 |             std::size_t str1_r0 = 0; 
 10589 |             std::size_t str1_r1 = 0; 
 10590 |  
 10591 |             const range_t& range0 = str0_range_ptr_->range_ref(); 
 10592 |             const range_t& range1 = str1_range_ptr_->range_ref(); 
 10593 |  
 10594 |             if ( 
 10595 |                   range0(str0_r0, str0_r1, str0_base_ptr_->size()) && 
 10596 |                   range1(str1_r0, str1_r1, str1_base_ptr_->size()) 
 10597 |                ) 
 10598 |             { 
 10599 |                const std::size_t size0 = (str0_r1 - str0_r0); 
 10600 |                const std::size_t size1 = (str1_r1 - str1_r0); 
 10601 |  
 10602 |                value_.assign(str0_base_ptr_->base() + str0_r0, size0); 
 10603 |                value_.append(str1_base_ptr_->base() + str1_r0, size1); 
 10604 |  
 10605 |                range_.n1_c.second  = value_.size(); 
 10606 |                range_.cache.second = range_.n1_c.second; 
 10607 |             } 
 10608 |  
 10609 |             return std::numeric_limits<T>::quiet_NaN(); 
 10610 |          } 
 10611 |  
 10612 |          std::string str() const exprtk_override 
 10613 |          { 
 10614 |             return value_; 
 10615 |          } 
 10616 |  
 10617 |          char_cptr base() const exprtk_override 
 10618 |          { 
 10619 |             return &value_[0]; 
 10620 |          } 
 10621 |  
 10622 |          std::size_t size() const exprtk_override 
 10623 |          { 
 10624 |             return value_.size(); 
 10625 |          } 
 10626 |  
 10627 |          range_t& range_ref() exprtk_override 
 10628 |          { 
 10629 |             return range_; 
 10630 |          } 
 10631 |  
 10632 |          const range_t& range_ref() const exprtk_override 
 10633 |          { 
 10634 |             return range_; 
 10635 |          } 
 10636 |  
 10637 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10638 |          { 
 10639 |             return expression_node<T>::e_strconcat; 
 10640 |          } 
 10641 |  
 10642 |          inline bool valid() const exprtk_override 
 10643 |          { 
 10644 |             return initialised_ && binary_node<T>::valid(); 
 10645 |          } 
 10646 |  
 10647 |       private: 
 10648 |  
 10649 |          bool                initialised_; 
 10650 |          str_base_ptr        str0_base_ptr_; 
 10651 |          str_base_ptr        str1_base_ptr_; 
 10652 |          irange_ptr          str0_range_ptr_; 
 10653 |          irange_ptr          str1_range_ptr_; 
 10654 |          mutable range_t     range_; 
 10655 |          mutable std::string value_; 
 10656 |       }; 
 10657 |  
 10658 |       template <typename T> 
 10659 |       class swap_string_node exprtk_final 
 10660 |                              : public binary_node     <T> 
 10661 |                              , public string_base_node<T> 
 10662 |                              , public range_interface <T> 
 10663 |       { 
 10664 |       public: 
 10665 |  
 10666 |          typedef typename range_interface<T>::range_t range_t; 
 10667 |          typedef range_t*             range_ptr; 
 10668 |          typedef range_interface<T>   irange_t; 
 10669 |          typedef irange_t*            irange_ptr; 
 10670 |          typedef expression_node <T>* expression_ptr; 
 10671 |          typedef stringvar_node  <T>* strvar_node_ptr; 
 10672 |          typedef string_base_node<T>* str_base_ptr; 
 10673 |  
 10674 |          using binary_node<T>::branch; 
 10675 |  
 10676 |          swap_string_node(expression_ptr branch0, expression_ptr branch1) 
 10677 |          : binary_node<T>(details::e_swap, branch0, branch1) 
 10678 |          , initialised_(false) 
 10679 |          , str0_node_ptr_(0) 
 10680 |          , str1_node_ptr_(0) 
 10681 |          { 
 10682 |             if (is_string_node(branch(0))) 
 10683 |             { 
 10684 |                str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0)); 
 10685 |             } 
 10686 |  
 10687 |             if (is_string_node(branch(1))) 
 10688 |             { 
 10689 |                str1_node_ptr_ = static_cast<strvar_node_ptr>(branch(1)); 
 10690 |             } 
 10691 |  
 10692 |             initialised_ = (str0_node_ptr_ && str1_node_ptr_); 
 10693 |             assert(valid()); 
 10694 |          } 
 10695 |  
 10696 |          inline T value() const exprtk_override 
 10697 |          { 
 10698 |             branch(0)->value(); 
 10699 |             branch(1)->value(); 
 10700 |  
 10701 |             std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref()); 
 10702 |  
 10703 |             return std::numeric_limits<T>::quiet_NaN(); 
 10704 |          } 
 10705 |  
 10706 |          std::string str() const exprtk_override 
 10707 |          { 
 10708 |             return str0_node_ptr_->str(); 
 10709 |          } 
 10710 |  
 10711 |          char_cptr base() const exprtk_override 
 10712 |          { 
 10713 |            return str0_node_ptr_->base(); 
 10714 |          } 
 10715 |  
 10716 |          std::size_t size() const exprtk_override 
 10717 |          { 
 10718 |             return str0_node_ptr_->size(); 
 10719 |          } 
 10720 |  
 10721 |          range_t& range_ref() exprtk_override 
 10722 |          { 
 10723 |             return str0_node_ptr_->range_ref(); 
 10724 |          } 
 10725 |  
 10726 |          const range_t& range_ref() const exprtk_override 
 10727 |          { 
 10728 |             return str0_node_ptr_->range_ref(); 
 10729 |          } 
 10730 |  
 10731 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10732 |          { 
 10733 |             return expression_node<T>::e_strswap; 
 10734 |          } 
 10735 |  
 10736 |          inline bool valid() const exprtk_override 
 10737 |          { 
 10738 |             return initialised_ && binary_node<T>::valid(); 
 10739 |          } 
 10740 |  
 10741 |       private: 
 10742 |  
 10743 |          bool initialised_; 
 10744 |          strvar_node_ptr str0_node_ptr_; 
 10745 |          strvar_node_ptr str1_node_ptr_; 
 10746 |       }; 
 10747 |  
 10748 |       template <typename T> 
 10749 |       class swap_genstrings_node exprtk_final : public binary_node<T> 
 10750 |       { 
 10751 |       public: 
 10752 |  
 10753 |          typedef typename range_interface<T>::range_t range_t; 
 10754 |          typedef range_t*             range_ptr; 
 10755 |          typedef range_interface<T>   irange_t; 
 10756 |          typedef irange_t*            irange_ptr; 
 10757 |          typedef expression_node <T>* expression_ptr; 
 10758 |          typedef string_base_node<T>* str_base_ptr; 
 10759 |  
 10760 |          using binary_node<T>::branch; 
 10761 |  
 10762 |          swap_genstrings_node(expression_ptr branch0, 
 10763 |                               expression_ptr branch1) 
 10764 |          : binary_node<T>(details::e_default, branch0, branch1) 
 10765 |          , str0_base_ptr_ (0) 
 10766 |          , str1_base_ptr_ (0) 
 10767 |          , str0_range_ptr_(0) 
 10768 |          , str1_range_ptr_(0) 
 10769 |          , initialised_(false) 
 10770 |          { 
 10771 |             if (is_generally_string_node(branch(0))) 
 10772 |             { 
 10773 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 10774 |  
 10775 |                if (0 == str0_base_ptr_) 
 10776 |                   return; 
 10777 |  
 10778 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(0)); 
 10779 |  
 10780 |                if (0 == range) 
 10781 |                   return; 
 10782 |  
 10783 |                str0_range_ptr_ = &(range->range_ref()); 
 10784 |             } 
 10785 |  
 10786 |             if (is_generally_string_node(branch(1))) 
 10787 |             { 
 10788 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 10789 |  
 10790 |                if (0 == str1_base_ptr_) 
 10791 |                   return; 
 10792 |  
 10793 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 10794 |  
 10795 |                if (0 == range) 
 10796 |                   return; 
 10797 |  
 10798 |                str1_range_ptr_ = &(range->range_ref()); 
 10799 |             } 
 10800 |  
 10801 |             initialised_ = str0_base_ptr_  && 
 10802 |                            str1_base_ptr_  && 
 10803 |                            str0_range_ptr_ && 
 10804 |                            str1_range_ptr_ ; 
 10805 |  
 10806 |             assert(valid()); 
 10807 |          } 
 10808 |  
 10809 |          inline T value() const exprtk_override 
 10810 |          { 
 10811 |             branch(0)->value(); 
 10812 |             branch(1)->value(); 
 10813 |  
 10814 |             std::size_t str0_r0 = 0; 
 10815 |             std::size_t str0_r1 = 0; 
 10816 |  
 10817 |             std::size_t str1_r0 = 0; 
 10818 |             std::size_t str1_r1 = 0; 
 10819 |  
 10820 |             const range_t& range0 = (*str0_range_ptr_); 
 10821 |             const range_t& range1 = (*str1_range_ptr_); 
 10822 |  
 10823 |             if ( 
 10824 |                   range0(str0_r0, str0_r1, str0_base_ptr_->size()) && 
 10825 |                   range1(str1_r0, str1_r1, str1_base_ptr_->size()) 
 10826 |                ) 
 10827 |             { 
 10828 |                const std::size_t size0    = range0.cache_size(); 
 10829 |                const std::size_t size1    = range1.cache_size(); 
 10830 |                const std::size_t max_size = std::min(size0,size1); 
 10831 |  
 10832 |                char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0); 
 10833 |                char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0); 
 10834 |  
 10835 |                loop_unroll::details lud(max_size); 
 10836 |                char_cptr upper_bound = s0 + lud.upper_bound; 
 10837 |  
 10838 |                while (s0 < upper_bound) 
 10839 |                { 
 10840 |                   #define exprtk_loop(N)   \ 
 10841 |                   std::swap(s0[N], s1[N]); \ 
 10842 |  
 10843 |                   exprtk_loop( 0) exprtk_loop( 1) 
 10844 |                   exprtk_loop( 2) exprtk_loop( 3) 
 10845 |                   #ifndef exprtk_disable_superscalar_unroll 
 10846 |                   exprtk_loop( 4) exprtk_loop( 5) 
 10847 |                   exprtk_loop( 6) exprtk_loop( 7) 
 10848 |                   exprtk_loop( 8) exprtk_loop( 9) 
 10849 |                   exprtk_loop(10) exprtk_loop(11) 
 10850 |                   exprtk_loop(12) exprtk_loop(13) 
 10851 |                   exprtk_loop(14) exprtk_loop(15) 
 10852 |                   #endif 
 10853 |  
 10854 |                   s0 += lud.batch_size; 
 10855 |                   s1 += lud.batch_size; 
 10856 |                } 
 10857 |  
 10858 |                int i = 0; 
 10859 |  
 10860 |                switch (lud.remainder) 
 10861 |                { 
 10862 |                   #define case_stmt(N)                       \ 
 10863 |                   case N : { std::swap(s0[i], s1[i]); ++i; } \ 
 10864 |                   exprtk_fallthrough                         \ 
 10865 |  
 10866 |                   #ifndef exprtk_disable_superscalar_unroll 
 10867 |                   case_stmt(15) case_stmt(14) 
 10868 |                   case_stmt(13) case_stmt(12) 
 10869 |                   case_stmt(11) case_stmt(10) 
 10870 |                   case_stmt( 9) case_stmt( 8) 
 10871 |                   case_stmt( 7) case_stmt( 6) 
 10872 |                   case_stmt( 5) case_stmt( 4) 
 10873 |                   #endif 
 10874 |                   case_stmt( 3) case_stmt( 2) 
 10875 |                   case_stmt( 1) 
 10876 |                   default: break; 
 10877 |                } 
 10878 |  
 10879 |                #undef exprtk_loop 
 10880 |                #undef case_stmt 
 10881 |             } 
 10882 |  
 10883 |             return std::numeric_limits<T>::quiet_NaN(); 
 10884 |          } 
 10885 |  
 10886 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10887 |          { 
 10888 |             return expression_node<T>::e_strswap; 
 10889 |          } 
 10890 |  
 10891 |          inline bool valid() const exprtk_override 
 10892 |          { 
 10893 |             return initialised_ && binary_node<T>::valid(); 
 10894 |          } 
 10895 |  
 10896 |       private: 
 10897 |  
 10898 |          swap_genstrings_node(const swap_genstrings_node<T>&) exprtk_delete; 
 10899 |          swap_genstrings_node<T>& operator=(const swap_genstrings_node<T>&) exprtk_delete; 
 10900 |  
 10901 |          str_base_ptr str0_base_ptr_; 
 10902 |          str_base_ptr str1_base_ptr_; 
 10903 |          range_ptr    str0_range_ptr_; 
 10904 |          range_ptr    str1_range_ptr_; 
 10905 |          bool         initialised_; 
 10906 |       }; 
 10907 |  
 10908 |       template <typename T> 
 10909 |       class stringvar_size_node exprtk_final : public expression_node<T> 
 10910 |       { 
 10911 |       public: 
 10912 |  
 10913 |          static const std::string null_value; 
 10914 |  
 10915 |          explicit stringvar_size_node() 
 10916 |          : value_(&null_value) 
 10917 |          {} 
 10918 |  
 10919 |          explicit stringvar_size_node(std::string& v) 
 10920 |          : value_(&v) 
 10921 |          {} 
 10922 |  
 10923 |          inline T value() const exprtk_override 
 10924 |          { 
 10925 |             return T((*value_).size()); 
 10926 |          } 
 10927 |  
 10928 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10929 |          { 
 10930 |             return expression_node<T>::e_stringvarsize; 
 10931 |          } 
 10932 |  
 10933 |       private: 
 10934 |  
 10935 |          const std::string* value_; 
 10936 |       }; 
 10937 |  
 10938 |       template <typename T> 
 10939 |       const std::string stringvar_size_node<T>::null_value = std::string(""); 
 10940 |  
 10941 |       template <typename T> 
 10942 |       class string_size_node exprtk_final : public expression_node<T> 
 10943 |       { 
 10944 |       public: 
 10945 |  
 10946 |          typedef expression_node <T>* expression_ptr; 
 10947 |          typedef string_base_node<T>* str_base_ptr; 
 10948 |          typedef std::pair<expression_ptr,bool>  branch_t; 
 10949 |  
 10950 |          explicit string_size_node(expression_ptr branch) 
 10951 |          : str_base_ptr_(0) 
 10952 |          { 
 10953 |             construct_branch_pair(branch_, branch); 
 10954 |  
 10955 |             if (is_generally_string_node(branch_.first)) 
 10956 |             { 
 10957 |                str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_.first); 
 10958 |             } 
 10959 |  
 10960 |             assert(valid()); 
 10961 |          } 
 10962 |  
 10963 |          inline T value() const exprtk_override 
 10964 |          { 
 10965 |             branch_.first->value(); 
 10966 |             return T(str_base_ptr_->size()); 
 10967 |          } 
 10968 |  
 10969 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 10970 |          { 
 10971 |             return expression_node<T>::e_stringsize; 
 10972 |          } 
 10973 |  
 10974 |          inline bool valid() const exprtk_override 
 10975 |          { 
 10976 |             return str_base_ptr_; 
 10977 |          } 
 10978 |  
 10979 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 10980 |          { 
 10981 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 10982 |          } 
 10983 |  
 10984 |          std::size_t node_depth() const exprtk_override 
 10985 |          { 
 10986 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 10987 |          } 
 10988 |  
 10989 |       private: 
 10990 |  
 10991 |          branch_t     branch_; 
 10992 |          str_base_ptr str_base_ptr_; 
 10993 |       }; 
 10994 |  
 10995 |       struct asn_assignment 
 10996 |       { 
 10997 |          static inline void execute(std::string& s, char_cptr data, const std::size_t size) 
 10998 |          { s.assign(data,size); } 
 10999 |       }; 
 11000 |  
 11001 |       struct asn_addassignment 
 11002 |       { 
 11003 |          static inline void execute(std::string& s, char_cptr data, const std::size_t size) 
 11004 |          { s.append(data,size); } 
 11005 |       }; 
 11006 |  
 11007 |       template <typename T, typename AssignmentProcess = asn_assignment> 
 11008 |       class assignment_string_node exprtk_final 
 11009 |                                    : public binary_node     <T> 
 11010 |                                    , public string_base_node<T> 
 11011 |                                    , public range_interface <T> 
 11012 |       { 
 11013 |       public: 
 11014 |  
 11015 |          typedef typename range_interface<T>::range_t range_t; 
 11016 |          typedef range_t*             range_ptr; 
 11017 |          typedef range_interface <T>  irange_t; 
 11018 |          typedef irange_t*            irange_ptr; 
 11019 |          typedef expression_node <T>* expression_ptr; 
 11020 |          typedef stringvar_node  <T>* strvar_node_ptr; 
 11021 |          typedef string_base_node<T>* str_base_ptr; 
 11022 |  
 11023 |          using binary_node<T>::branch; 
 11024 |  
 11025 |          assignment_string_node(const operator_type& opr, 
 11026 |                                 expression_ptr branch0, 
 11027 |                                 expression_ptr branch1) 
 11028 |          : binary_node<T>(opr, branch0, branch1) 
 11029 |          , initialised_(false) 
 11030 |          , str0_base_ptr_ (0) 
 11031 |          , str1_base_ptr_ (0) 
 11032 |          , str0_node_ptr_ (0) 
 11033 |          , str1_range_ptr_(0) 
 11034 |          { 
 11035 |             if (is_string_node(branch(0))) 
 11036 |             { 
 11037 |                str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0)); 
 11038 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 11039 |             } 
 11040 |  
 11041 |             if (is_generally_string_node(branch(1))) 
 11042 |             { 
 11043 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 11044 |  
 11045 |                if (0 == str1_base_ptr_) 
 11046 |                   return; 
 11047 |  
 11048 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 11049 |  
 11050 |                if (0 == range) 
 11051 |                   return; 
 11052 |  
 11053 |                str1_range_ptr_ = &(range->range_ref()); 
 11054 |             } 
 11055 |  
 11056 |             initialised_ = str0_base_ptr_  && 
 11057 |                            str1_base_ptr_  && 
 11058 |                            str0_node_ptr_  && 
 11059 |                            str1_range_ptr_ ; 
 11060 |  
 11061 |             assert(valid()); 
 11062 |          } 
 11063 |  
 11064 |          inline T value() const exprtk_override 
 11065 |          { 
 11066 |             branch(1)->value(); 
 11067 |  
 11068 |             std::size_t r0 = 0; 
 11069 |             std::size_t r1 = 0; 
 11070 |  
 11071 |             const range_t& range = (*str1_range_ptr_); 
 11072 |  
 11073 |             if (range(r0, r1, str1_base_ptr_->size())) 
 11074 |             { 
 11075 |                AssignmentProcess::execute( 
 11076 |                   str0_node_ptr_->ref(), 
 11077 |                   str1_base_ptr_->base() + r0, (r1 - r0)); 
 11078 |  
 11079 |                branch(0)->value(); 
 11080 |             } 
 11081 |  
 11082 |             return std::numeric_limits<T>::quiet_NaN(); 
 11083 |          } 
 11084 |  
 11085 |          std::string str() const exprtk_override 
 11086 |          { 
 11087 |             return str0_node_ptr_->str(); 
 11088 |          } 
 11089 |  
 11090 |          char_cptr base() const exprtk_override 
 11091 |          { 
 11092 |            return str0_node_ptr_->base(); 
 11093 |          } 
 11094 |  
 11095 |          std::size_t size() const exprtk_override 
 11096 |          { 
 11097 |             return str0_node_ptr_->size(); 
 11098 |          } 
 11099 |  
 11100 |          range_t& range_ref() exprtk_override 
 11101 |          { 
 11102 |             return str0_node_ptr_->range_ref(); 
 11103 |          } 
 11104 |  
 11105 |          const range_t& range_ref() const exprtk_override 
 11106 |          { 
 11107 |             return str0_node_ptr_->range_ref(); 
 11108 |          } 
 11109 |  
 11110 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11111 |          { 
 11112 |             return expression_node<T>::e_strass; 
 11113 |          } 
 11114 |  
 11115 |          inline bool valid() const exprtk_override 
 11116 |          { 
 11117 |             return initialised_ && binary_node<T>::valid(); 
 11118 |          } 
 11119 |  
 11120 |       private: 
 11121 |  
 11122 |          bool            initialised_; 
 11123 |          str_base_ptr    str0_base_ptr_; 
 11124 |          str_base_ptr    str1_base_ptr_; 
 11125 |          strvar_node_ptr str0_node_ptr_; 
 11126 |          range_ptr       str1_range_ptr_; 
 11127 |       }; 
 11128 |  
 11129 |       template <typename T, typename AssignmentProcess = asn_assignment> 
 11130 |       class assignment_string_range_node exprtk_final 
 11131 |                                          : public binary_node     <T> 
 11132 |                                          , public string_base_node<T> 
 11133 |                                          , public range_interface <T> 
 11134 |       { 
 11135 |       public: 
 11136 |  
 11137 |          typedef typename range_interface<T>::range_t range_t; 
 11138 |          typedef range_t*              range_ptr; 
 11139 |          typedef range_interface  <T>  irange_t; 
 11140 |          typedef irange_t*             irange_ptr; 
 11141 |          typedef expression_node  <T>* expression_ptr; 
 11142 |          typedef stringvar_node   <T>* strvar_node_ptr; 
 11143 |          typedef string_range_node<T>* str_rng_node_ptr; 
 11144 |          typedef string_base_node <T>* str_base_ptr; 
 11145 |  
 11146 |          using binary_node<T>::branch; 
 11147 |  
 11148 |          assignment_string_range_node(const operator_type& opr, 
 11149 |                                       expression_ptr branch0, 
 11150 |                                       expression_ptr branch1) 
 11151 |          : binary_node<T>(opr, branch0, branch1) 
 11152 |          , initialised_(false) 
 11153 |          , str0_base_ptr_    (0) 
 11154 |          , str1_base_ptr_    (0) 
 11155 |          , str0_rng_node_ptr_(0) 
 11156 |          , str0_range_ptr_   (0) 
 11157 |          , str1_range_ptr_   (0) 
 11158 |          { 
 11159 |             if (is_string_range_node(branch(0))) 
 11160 |             { 
 11161 |                str0_rng_node_ptr_ = static_cast<str_rng_node_ptr>(branch(0)); 
 11162 |                str0_base_ptr_     = dynamic_cast<str_base_ptr>(branch(0)); 
 11163 |                irange_ptr range   = dynamic_cast<irange_ptr>(branch(0)); 
 11164 |  
 11165 |                if (0 == range) 
 11166 |                   return; 
 11167 |  
 11168 |                str0_range_ptr_ = &(range->range_ref()); 
 11169 |             } 
 11170 |  
 11171 |             if (is_generally_string_node(branch(1))) 
 11172 |             { 
 11173 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 11174 |  
 11175 |                if (0 == str1_base_ptr_) 
 11176 |                   return; 
 11177 |  
 11178 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 11179 |  
 11180 |                if (0 == range) 
 11181 |                   return; 
 11182 |  
 11183 |                str1_range_ptr_ = &(range->range_ref()); 
 11184 |             } 
 11185 |  
 11186 |             initialised_ = str0_base_ptr_     && 
 11187 |                            str1_base_ptr_     && 
 11188 |                            str0_rng_node_ptr_ && 
 11189 |                            str0_range_ptr_    && 
 11190 |                            str1_range_ptr_    ; 
 11191 |  
 11192 |             assert(valid()); 
 11193 |          } 
 11194 |  
 11195 |          inline T value() const exprtk_override 
 11196 |          { 
 11197 |             branch(0)->value(); 
 11198 |             branch(1)->value(); 
 11199 |  
 11200 |             std::size_t s0_r0 = 0; 
 11201 |             std::size_t s0_r1 = 0; 
 11202 |  
 11203 |             std::size_t s1_r0 = 0; 
 11204 |             std::size_t s1_r1 = 0; 
 11205 |  
 11206 |             const range_t& range0 = (*str0_range_ptr_); 
 11207 |             const range_t& range1 = (*str1_range_ptr_); 
 11208 |  
 11209 |             if ( 
 11210 |                   range0(s0_r0, s0_r1, str0_base_ptr_->size()) && 
 11211 |                   range1(s1_r0, s1_r1, str1_base_ptr_->size()) 
 11212 |                ) 
 11213 |             { 
 11214 |                const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0)); 
 11215 |  
 11216 |                std::copy( 
 11217 |                   str1_base_ptr_->base() + s1_r0, 
 11218 |                   str1_base_ptr_->base() + s1_r0 + size, 
 11219 |                   const_cast<char_ptr>(base() + s0_r0)); 
 11220 |             } 
 11221 |  
 11222 |             return std::numeric_limits<T>::quiet_NaN(); 
 11223 |          } 
 11224 |  
 11225 |          std::string str() const exprtk_override 
 11226 |          { 
 11227 |             return str0_base_ptr_->str(); 
 11228 |          } 
 11229 |  
 11230 |          char_cptr base() const exprtk_override 
 11231 |          { 
 11232 |             return str0_base_ptr_->base(); 
 11233 |          } 
 11234 |  
 11235 |          std::size_t size() const exprtk_override 
 11236 |          { 
 11237 |             return str0_base_ptr_->size(); 
 11238 |          } 
 11239 |  
 11240 |          range_t& range_ref() exprtk_override 
 11241 |          { 
 11242 |             return str0_rng_node_ptr_->range_ref(); 
 11243 |          } 
 11244 |  
 11245 |          const range_t& range_ref() const exprtk_override 
 11246 |          { 
 11247 |             return str0_rng_node_ptr_->range_ref(); 
 11248 |          } 
 11249 |  
 11250 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11251 |          { 
 11252 |             return expression_node<T>::e_strass; 
 11253 |          } 
 11254 |  
 11255 |          inline bool valid() const exprtk_override 
 11256 |          { 
 11257 |             return initialised_ && binary_node<T>::valid(); 
 11258 |          } 
 11259 |  
 11260 |       private: 
 11261 |  
 11262 |          bool             initialised_; 
 11263 |          str_base_ptr     str0_base_ptr_; 
 11264 |          str_base_ptr     str1_base_ptr_; 
 11265 |          str_rng_node_ptr str0_rng_node_ptr_; 
 11266 |          range_ptr        str0_range_ptr_; 
 11267 |          range_ptr        str1_range_ptr_; 
 11268 |       }; 
 11269 |  
 11270 |       template <typename T> 
 11271 |       class conditional_string_node exprtk_final 
 11272 |                                     : public trinary_node    <T> 
 11273 |                                     , public string_base_node<T> 
 11274 |                                     , public range_interface <T> 
 11275 |       { 
 11276 |       public: 
 11277 |  
 11278 |          typedef typename range_interface<T>::range_t range_t; 
 11279 |          typedef range_t*             range_ptr; 
 11280 |          typedef range_interface <T>  irange_t; 
 11281 |          typedef irange_t*            irange_ptr; 
 11282 |          typedef expression_node <T>* expression_ptr; 
 11283 |          typedef string_base_node<T>* str_base_ptr; 
 11284 |  
 11285 |          conditional_string_node(expression_ptr condition, 
 11286 |                                  expression_ptr consequent, 
 11287 |                                  expression_ptr alternative) 
 11288 |          : trinary_node<T>(details::e_default, consequent, alternative, condition) 
 11289 |          , initialised_(false) 
 11290 |          , str0_base_ptr_ (0) 
 11291 |          , str1_base_ptr_ (0) 
 11292 |          , str0_range_ptr_(0) 
 11293 |          , str1_range_ptr_(0) 
 11294 |          , condition_  (condition  ) 
 11295 |          , consequent_ (consequent ) 
 11296 |          , alternative_(alternative) 
 11297 |          { 
 11298 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 11299 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 11300 |  
 11301 |             range_.cache.first  = range_.n0_c.second; 
 11302 |             range_.cache.second = range_.n1_c.second; 
 11303 |  
 11304 |             if (is_generally_string_node(trinary_node<T>::branch_[0].first)) 
 11305 |             { 
 11306 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[0].first); 
 11307 |  
 11308 |                if (0 == str0_base_ptr_) 
 11309 |                   return; 
 11310 |  
 11311 |                str0_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[0].first); 
 11312 |  
 11313 |                if (0 == str0_range_ptr_) 
 11314 |                   return; 
 11315 |             } 
 11316 |  
 11317 |             if (is_generally_string_node(trinary_node<T>::branch_[1].first)) 
 11318 |             { 
 11319 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[1].first); 
 11320 |  
 11321 |                if (0 == str1_base_ptr_) 
 11322 |                   return; 
 11323 |  
 11324 |                str1_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[1].first); 
 11325 |  
 11326 |                if (0 == str1_range_ptr_) 
 11327 |                   return; 
 11328 |             } 
 11329 |  
 11330 |             initialised_ = str0_base_ptr_  && 
 11331 |                            str1_base_ptr_  && 
 11332 |                            str0_range_ptr_ && 
 11333 |                            str1_range_ptr_ ; 
 11334 |  
 11335 |             assert(valid()); 
 11336 |          } 
 11337 |  
 11338 |          inline T value() const exprtk_override 
 11339 |          { 
 11340 |             std::size_t r0 = 0; 
 11341 |             std::size_t r1 = 0; 
 11342 |  
 11343 |             if (is_true(condition_)) 
 11344 |             { 
 11345 |                consequent_->value(); 
 11346 |  
 11347 |                const range_t& range = str0_range_ptr_->range_ref(); 
 11348 |  
 11349 |                if (range(r0, r1, str0_base_ptr_->size())) 
 11350 |                { 
 11351 |                   const std::size_t size = (r1 - r0); 
 11352 |  
 11353 |                   value_.assign(str0_base_ptr_->base() + r0, size); 
 11354 |  
 11355 |                   range_.n1_c.second  = value_.size(); 
 11356 |                   range_.cache.second = range_.n1_c.second; 
 11357 |  
 11358 |                   return T(1); 
 11359 |                } 
 11360 |             } 
 11361 |             else 
 11362 |             { 
 11363 |                alternative_->value(); 
 11364 |  
 11365 |                const range_t& range = str1_range_ptr_->range_ref(); 
 11366 |  
 11367 |                if (range(r0, r1, str1_base_ptr_->size())) 
 11368 |                { 
 11369 |                   const std::size_t size = (r1 - r0); 
 11370 |  
 11371 |                   value_.assign(str1_base_ptr_->base() + r0, size); 
 11372 |  
 11373 |                   range_.n1_c.second  = value_.size(); 
 11374 |                   range_.cache.second = range_.n1_c.second; 
 11375 |  
 11376 |                   return T(0); 
 11377 |                } 
 11378 |             } 
 11379 |  
 11380 |             return std::numeric_limits<T>::quiet_NaN(); 
 11381 |          } 
 11382 |  
 11383 |          std::string str() const exprtk_override 
 11384 |          { 
 11385 |             return value_; 
 11386 |          } 
 11387 |  
 11388 |          char_cptr base() const exprtk_override 
 11389 |          { 
 11390 |             return &value_[0]; 
 11391 |          } 
 11392 |  
 11393 |          std::size_t size() const exprtk_override 
 11394 |          { 
 11395 |             return value_.size(); 
 11396 |          } 
 11397 |  
 11398 |          range_t& range_ref() exprtk_override 
 11399 |          { 
 11400 |             return range_; 
 11401 |          } 
 11402 |  
 11403 |          const range_t& range_ref() const exprtk_override 
 11404 |          { 
 11405 |             return range_; 
 11406 |          } 
 11407 |  
 11408 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11409 |          { 
 11410 |             return expression_node<T>::e_strcondition; 
 11411 |          } 
 11412 |  
 11413 |          inline bool valid() const exprtk_override 
 11414 |          { 
 11415 |             return 
 11416 |                initialised_                         && 
 11417 |                condition_  && condition_  ->valid() && 
 11418 |                consequent_ && consequent_ ->valid() && 
 11419 |                alternative_&& alternative_->valid() ; 
 11420 |          } 
 11421 |  
 11422 |       private: 
 11423 |  
 11424 |          bool initialised_; 
 11425 |          str_base_ptr str0_base_ptr_; 
 11426 |          str_base_ptr str1_base_ptr_; 
 11427 |          irange_ptr   str0_range_ptr_; 
 11428 |          irange_ptr   str1_range_ptr_; 
 11429 |          mutable range_t     range_; 
 11430 |          mutable std::string value_; 
 11431 |  
 11432 |          expression_ptr condition_; 
 11433 |          expression_ptr consequent_; 
 11434 |          expression_ptr alternative_; 
 11435 |       }; 
 11436 |  
 11437 |       template <typename T> 
 11438 |       class cons_conditional_str_node exprtk_final 
 11439 |                                       : public binary_node     <T> 
 11440 |                                       , public string_base_node<T> 
 11441 |                                       , public range_interface <T> 
 11442 |       { 
 11443 |       public: 
 11444 |  
 11445 |          typedef typename range_interface<T>::range_t range_t; 
 11446 |          typedef range_t*             range_ptr; 
 11447 |          typedef range_interface <T>  irange_t; 
 11448 |          typedef irange_t*            irange_ptr; 
 11449 |          typedef expression_node <T>* expression_ptr; 
 11450 |          typedef string_base_node<T>* str_base_ptr; 
 11451 |  
 11452 |          using binary_node<T>::branch; 
 11453 |  
 11454 |          cons_conditional_str_node(expression_ptr condition, 
 11455 |                                    expression_ptr consequent) 
 11456 |          : binary_node<T>(details::e_default, consequent, condition) 
 11457 |          , initialised_(false) 
 11458 |          , str0_base_ptr_ (0) 
 11459 |          , str0_range_ptr_(0) 
 11460 |          , condition_ (condition ) 
 11461 |          , consequent_(consequent) 
 11462 |          { 
 11463 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 11464 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 11465 |  
 11466 |             range_.cache.first  = range_.n0_c.second; 
 11467 |             range_.cache.second = range_.n1_c.second; 
 11468 |  
 11469 |             if (is_generally_string_node(branch(0))) 
 11470 |             { 
 11471 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 11472 |  
 11473 |                if (0 == str0_base_ptr_) 
 11474 |                   return; 
 11475 |  
 11476 |                str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0)); 
 11477 |  
 11478 |                if (0 == str0_range_ptr_) 
 11479 |                   return; 
 11480 |             } 
 11481 |  
 11482 |             initialised_ = str0_base_ptr_ && str0_range_ptr_ ; 
 11483 |             assert(valid()); 
 11484 |          } 
 11485 |  
 11486 |          inline T value() const exprtk_override 
 11487 |          { 
 11488 |             if (is_true(condition_)) 
 11489 |             { 
 11490 |                consequent_->value(); 
 11491 |  
 11492 |                const range_t& range = str0_range_ptr_->range_ref(); 
 11493 |  
 11494 |                std::size_t r0 = 0; 
 11495 |                std::size_t r1 = 0; 
 11496 |  
 11497 |                if (range(r0, r1, str0_base_ptr_->size())) 
 11498 |                { 
 11499 |                   const std::size_t size = (r1 - r0); 
 11500 |  
 11501 |                   value_.assign(str0_base_ptr_->base() + r0, size); 
 11502 |  
 11503 |                   range_.n1_c.second  = value_.size(); 
 11504 |                   range_.cache.second = range_.n1_c.second; 
 11505 |  
 11506 |                   return T(1); 
 11507 |                } 
 11508 |             } 
 11509 |  
 11510 |             return std::numeric_limits<T>::quiet_NaN(); 
 11511 |          } 
 11512 |  
 11513 |          std::string str() const 
 11514 |          { 
 11515 |             return value_; 
 11516 |          } 
 11517 |  
 11518 |          char_cptr base() const 
 11519 |          { 
 11520 |             return &value_[0]; 
 11521 |          } 
 11522 |  
 11523 |          std::size_t size() const 
 11524 |          { 
 11525 |             return value_.size(); 
 11526 |          } 
 11527 |  
 11528 |          range_t& range_ref() 
 11529 |          { 
 11530 |             return range_; 
 11531 |          } 
 11532 |  
 11533 |          const range_t& range_ref() const 
 11534 |          { 
 11535 |             return range_; 
 11536 |          } 
 11537 |  
 11538 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11539 |          { 
 11540 |             return expression_node<T>::e_strccondition; 
 11541 |          } 
 11542 |  
 11543 |          inline bool valid() const exprtk_override 
 11544 |          { 
 11545 |             return 
 11546 |                initialised_                         && 
 11547 |                condition_  && condition_  ->valid() && 
 11548 |                consequent_ && consequent_ ->valid() ; 
 11549 |          } 
 11550 |  
 11551 |       private: 
 11552 |  
 11553 |          bool initialised_; 
 11554 |          str_base_ptr str0_base_ptr_; 
 11555 |          irange_ptr   str0_range_ptr_; 
 11556 |          mutable range_t     range_; 
 11557 |          mutable std::string value_; 
 11558 |  
 11559 |          expression_ptr condition_; 
 11560 |          expression_ptr consequent_; 
 11561 |       }; 
 11562 |  
 11563 |       template <typename T, typename VarArgFunction> 
 11564 |       class str_vararg_node exprtk_final 
 11565 |                             : public expression_node <T> 
 11566 |                             , public string_base_node<T> 
 11567 |                             , public range_interface <T> 
 11568 |       { 
 11569 |       public: 
 11570 |  
 11571 |          typedef typename range_interface<T>::range_t range_t; 
 11572 |          typedef range_t*             range_ptr; 
 11573 |          typedef range_interface <T>  irange_t; 
 11574 |          typedef irange_t*            irange_ptr; 
 11575 |          typedef expression_node <T>* expression_ptr; 
 11576 |          typedef string_base_node<T>* str_base_ptr; 
 11577 |          typedef std::pair<expression_ptr,bool> branch_t; 
 11578 |  
 11579 |          template <typename Allocator, 
 11580 |                    template <typename, typename> class Sequence> 
 11581 |          explicit str_vararg_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 11582 |          : initialised_(false) 
 11583 |          , str_base_ptr_ (0) 
 11584 |          , str_range_ptr_(0) 
 11585 |          { 
 11586 |             construct_branch_pair(final_node_, const_cast<expression_ptr>(arg_list.back())); 
 11587 |  
 11588 |             if (0 == final_node_.first) 
 11589 |                return; 
 11590 |             else if (!is_generally_string_node(final_node_.first)) 
 11591 |                return; 
 11592 |  
 11593 |             str_base_ptr_ = dynamic_cast<str_base_ptr>(final_node_.first); 
 11594 |  
 11595 |             if (0 == str_base_ptr_) 
 11596 |                return; 
 11597 |  
 11598 |             str_range_ptr_ = dynamic_cast<irange_ptr>(final_node_.first); 
 11599 |  
 11600 |             if (0 == str_range_ptr_) 
 11601 |                return; 
 11602 |  
 11603 |             if (arg_list.size() > 1) 
 11604 |             { 
 11605 |                const std::size_t arg_list_size = arg_list.size() - 1; 
 11606 |  
 11607 |                arg_list_.resize(arg_list_size); 
 11608 |  
 11609 |                for (std::size_t i = 0; i < arg_list_size; ++i) 
 11610 |                { 
 11611 |                   if (arg_list[i] && arg_list[i]->valid()) 
 11612 |                   { 
 11613 |                      construct_branch_pair(arg_list_[i], arg_list[i]); 
 11614 |                   } 
 11615 |                   else 
 11616 |                   { 
 11617 |                      arg_list_.clear(); 
 11618 |                      return; 
 11619 |                   } 
 11620 |                } 
 11621 |  
 11622 |                initialised_ = true; 
 11623 |             } 
 11624 |  
 11625 |             initialised_ &= str_base_ptr_ && str_range_ptr_; 
 11626 |             assert(valid()); 
 11627 |          } 
 11628 |  
 11629 |          inline T value() const exprtk_override 
 11630 |          { 
 11631 |             if (!arg_list_.empty()) 
 11632 |             { 
 11633 |                VarArgFunction::process(arg_list_); 
 11634 |             } 
 11635 |  
 11636 |             final_node_.first->value(); 
 11637 |  
 11638 |             return std::numeric_limits<T>::quiet_NaN(); 
 11639 |          } 
 11640 |  
 11641 |          std::string str() const exprtk_override 
 11642 |          { 
 11643 |             return str_base_ptr_->str(); 
 11644 |          } 
 11645 |  
 11646 |          char_cptr base() const exprtk_override 
 11647 |          { 
 11648 |             return str_base_ptr_->base(); 
 11649 |          } 
 11650 |  
 11651 |          std::size_t size() const exprtk_override 
 11652 |          { 
 11653 |             return str_base_ptr_->size(); 
 11654 |          } 
 11655 |  
 11656 |          range_t& range_ref() exprtk_override 
 11657 |          { 
 11658 |             return str_range_ptr_->range_ref(); 
 11659 |          } 
 11660 |  
 11661 |          const range_t& range_ref() const exprtk_override 
 11662 |          { 
 11663 |             return str_range_ptr_->range_ref(); 
 11664 |          } 
 11665 |  
 11666 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11667 |          { 
 11668 |             return expression_node<T>::e_stringvararg; 
 11669 |          } 
 11670 |  
 11671 |          inline bool valid() const exprtk_override 
 11672 |          { 
 11673 |             return 
 11674 |                initialised_ && 
 11675 |                final_node_.first && final_node_.first->valid(); 
 11676 |          } 
 11677 |  
 11678 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 11679 |          { 
 11680 |             expression_node<T>::ndb_t::collect(final_node_ , node_delete_list); 
 11681 |             expression_node<T>::ndb_t::collect(arg_list_   , node_delete_list); 
 11682 |          } 
 11683 |  
 11684 |          std::size_t node_depth() const exprtk_override 
 11685 |          { 
 11686 |             return std::max( 
 11687 |                expression_node<T>::ndb_t::compute_node_depth(final_node_), 
 11688 |                expression_node<T>::ndb_t::compute_node_depth(arg_list_  )); 
 11689 |          } 
 11690 |  
 11691 |       private: 
 11692 |  
 11693 |          bool                  initialised_; 
 11694 |          branch_t              final_node_; 
 11695 |          str_base_ptr          str_base_ptr_; 
 11696 |          irange_ptr            str_range_ptr_; 
 11697 |          std::vector<branch_t> arg_list_; 
 11698 |       }; 
 11699 |       #endif 
 11700 |  
 11701 |       template <typename T> 
 11702 |       class assert_node exprtk_final : public expression_node<T> 
 11703 |       { 
 11704 |       public: 
 11705 |  
 11706 |          typedef expression_node<T>* expression_ptr; 
 11707 |          typedef std::pair<expression_ptr,bool> branch_t; 
 11708 |          typedef string_base_node<T>* str_base_ptr; 
 11709 |          typedef assert_check::assert_context assert_context_t; 
 11710 |  
 11711 |          assert_node(expression_ptr   assert_condition_node, 
 11712 |                      expression_ptr   assert_message_node, 
 11713 |                      assert_check_ptr assert_check, 
 11714 |                      assert_context_t context) 
 11715 |          : assert_message_str_base_(0) 
 11716 |          , assert_check_(assert_check) 
 11717 |          , context_(context) 
 11718 |          { 
 11719 |             construct_branch_pair(assert_condition_node_, assert_condition_node); 
 11720 |             construct_branch_pair(assert_message_node_  , assert_message_node  ); 
 11721 |  
 11722 |             #ifndef exprtk_disable_string_capabilities 
 11723 |             if ( 
 11724 |                   assert_message_node_.first && 
 11725 |                   details::is_generally_string_node(assert_message_node_.first) 
 11726 |                ) 
 11727 |             { 
 11728 |                assert_message_str_base_ = dynamic_cast<str_base_ptr>(assert_message_node_.first); 
 11729 |             } 
 11730 |             #endif 
 11731 |  
 11732 |             assert(valid()); 
 11733 |          } 
 11734 |  
 11735 |          inline T value() const exprtk_override 
 11736 |          { 
 11737 |             if (details::is_true(assert_condition_node_.first->value())) 
 11738 |             { 
 11739 |                return T(1); 
 11740 |             } 
 11741 |  
 11742 |             #ifndef exprtk_disable_string_capabilities 
 11743 |             if (assert_message_node_.first) 
 11744 |             { 
 11745 |                assert_message_node_.first->value(); 
 11746 |                assert(assert_message_str_base_); 
 11747 |                context_.message = assert_message_str_base_->str(); 
 11748 |             } 
 11749 |             #endif 
 11750 |  
 11751 |             assert_check_->handle_assert(context_); 
 11752 |             return T(0); 
 11753 |          } 
 11754 |  
 11755 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 11756 |          { 
 11757 |             return expression_node<T>::e_assert; 
 11758 |          } 
 11759 |  
 11760 |          inline bool valid() const exprtk_override 
 11761 |          { 
 11762 |             return ( 
 11763 |                      assert_check_ && 
 11764 |                      assert_condition_node_.first && 
 11765 |                      assert_condition_node_.first->valid() 
 11766 |                    ) && 
 11767 |                    ( 
 11768 |                      (0 == assert_message_node_.first) || 
 11769 |                      ( 
 11770 |                        assert_message_node_.first && 
 11771 |                        assert_message_str_base_   && 
 11772 |                        assert_message_node_.first->valid() && 
 11773 |                        details::is_generally_string_node(assert_message_node_.first) 
 11774 |                      ) 
 11775 |                    ); 
 11776 |          } 
 11777 |  
 11778 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 11779 |          { 
 11780 |             expression_node<T>::ndb_t::collect(assert_condition_node_, node_delete_list); 
 11781 |             expression_node<T>::ndb_t::collect(assert_message_node_  , node_delete_list); 
 11782 |          } 
 11783 |  
 11784 |          std::size_t node_depth() const exprtk_override 
 11785 |          { 
 11786 |             return expression_node<T>::ndb_t::compute_node_depth 
 11787 |                (assert_condition_node_, assert_message_node_); 
 11788 |          } 
 11789 |  
 11790 |       private: 
 11791 |  
 11792 |          branch_t         assert_condition_node_; 
 11793 |          branch_t         assert_message_node_; 
 11794 |          str_base_ptr     assert_message_str_base_; 
 11795 |          assert_check_ptr assert_check_; 
 11796 |          mutable assert_context_t context_; 
 11797 |       }; 
 11798 |  
 11799 |       template <typename T, std::size_t N> 
 11800 |       inline T axn(const T a, const T x) 
 11801 |       { 
 11802 |          // a*x^n 
 11803 |          return a * exprtk::details::numeric::fast_exp<T,N>::result(x); 
 11804 |       } 
 11805 |  
 11806 |       template <typename T, std::size_t N> 
 11807 |       inline T axnb(const T a, const T x, const T b) 
 11808 |       { 
 11809 |          // a*x^n+b 
 11810 |          return a * exprtk::details::numeric::fast_exp<T,N>::result(x) + b; 
 11811 |       } 
 11812 |  
 11813 |       template <typename T> 
 11814 |       struct sf_base 
 11815 |       { 
 11816 |          typedef typename details::functor_t<T>::Type Type; 
 11817 |          typedef typename details::functor_t<T> functor_t; 
 11818 |          typedef typename functor_t::qfunc_t quaternary_functor_t; 
 11819 |          typedef typename functor_t::tfunc_t trinary_functor_t; 
 11820 |          typedef typename functor_t::bfunc_t binary_functor_t; 
 11821 |          typedef typename functor_t::ufunc_t unary_functor_t; 
 11822 |       }; 
 11823 |  
 11824 |       #define define_sfop3(NN, OP0, OP1)                 \ 
 11825 |       template <typename T>                              \ 
 11826 |       struct sf##NN##_op : public sf_base<T>             \ 
 11827 |       {                                                  \ 
 11828 |          typedef typename sf_base<T>::Type const Type;   \ 
 11829 |          static inline T process(Type x, Type y, Type z) \ 
 11830 |          {                                               \ 
 11831 |             return (OP0);                                \ 
 11832 |          }                                               \ 
 11833 |          static inline std::string id()                  \ 
 11834 |          {                                               \ 
 11835 |             return (OP1);                                \ 
 11836 |          }                                               \ 
 11837 |       };                                                 \ 
 11838 |  
 11839 |       define_sfop3(00,(x + y) / z       ,"(t+t)/t") 
 11840 |       define_sfop3(01,(x + y) * z       ,"(t+t)*t") 
 11841 |       define_sfop3(02,(x + y) - z       ,"(t+t)-t") 
 11842 |       define_sfop3(03,(x + y) + z       ,"(t+t)+t") 
 11843 |       define_sfop3(04,(x - y) + z       ,"(t-t)+t") 
 11844 |       define_sfop3(05,(x - y) / z       ,"(t-t)/t") 
 11845 |       define_sfop3(06,(x - y) * z       ,"(t-t)*t") 
 11846 |       define_sfop3(07,(x * y) + z       ,"(t*t)+t") 
 11847 |       define_sfop3(08,(x * y) - z       ,"(t*t)-t") 
 11848 |       define_sfop3(09,(x * y) / z       ,"(t*t)/t") 
 11849 |       define_sfop3(10,(x * y) * z       ,"(t*t)*t") 
 11850 |       define_sfop3(11,(x / y) + z       ,"(t/t)+t") 
 11851 |       define_sfop3(12,(x / y) - z       ,"(t/t)-t") 
 11852 |       define_sfop3(13,(x / y) / z       ,"(t/t)/t") 
 11853 |       define_sfop3(14,(x / y) * z       ,"(t/t)*t") 
 11854 |       define_sfop3(15,x / (y + z)       ,"t/(t+t)") 
 11855 |       define_sfop3(16,x / (y - z)       ,"t/(t-t)") 
 11856 |       define_sfop3(17,x / (y * z)       ,"t/(t*t)") 
 11857 |       define_sfop3(18,x / (y / z)       ,"t/(t/t)") 
 11858 |       define_sfop3(19,x * (y + z)       ,"t*(t+t)") 
 11859 |       define_sfop3(20,x * (y - z)       ,"t*(t-t)") 
 11860 |       define_sfop3(21,x * (y * z)       ,"t*(t*t)") 
 11861 |       define_sfop3(22,x * (y / z)       ,"t*(t/t)") 
 11862 |       define_sfop3(23,x - (y + z)       ,"t-(t+t)") 
 11863 |       define_sfop3(24,x - (y - z)       ,"t-(t-t)") 
 11864 |       define_sfop3(25,x - (y / z)       ,"t-(t/t)") 
 11865 |       define_sfop3(26,x - (y * z)       ,"t-(t*t)") 
 11866 |       define_sfop3(27,x + (y * z)       ,"t+(t*t)") 
 11867 |       define_sfop3(28,x + (y / z)       ,"t+(t/t)") 
 11868 |       define_sfop3(29,x + (y + z)       ,"t+(t+t)") 
 11869 |       define_sfop3(30,x + (y - z)       ,"t+(t-t)") 
 11870 |       define_sfop3(31,(axnb<T,2>(x,y,z)),"       ") 
 11871 |       define_sfop3(32,(axnb<T,3>(x,y,z)),"       ") 
 11872 |       define_sfop3(33,(axnb<T,4>(x,y,z)),"       ") 
 11873 |       define_sfop3(34,(axnb<T,5>(x,y,z)),"       ") 
 11874 |       define_sfop3(35,(axnb<T,6>(x,y,z)),"       ") 
 11875 |       define_sfop3(36,(axnb<T,7>(x,y,z)),"       ") 
 11876 |       define_sfop3(37,(axnb<T,8>(x,y,z)),"       ") 
 11877 |       define_sfop3(38,(axnb<T,9>(x,y,z)),"       ") 
 11878 |       define_sfop3(39,x * numeric::log(y)   + z,"") 
 11879 |       define_sfop3(40,x * numeric::log(y)   - z,"") 
 11880 |       define_sfop3(41,x * numeric::log10(y) + z,"") 
 11881 |       define_sfop3(42,x * numeric::log10(y) - z,"") 
 11882 |       define_sfop3(43,x * numeric::sin(y) + z  ,"") 
 11883 |       define_sfop3(44,x * numeric::sin(y) - z  ,"") 
 11884 |       define_sfop3(45,x * numeric::cos(y) + z  ,"") 
 11885 |       define_sfop3(46,x * numeric::cos(y) - z  ,"") 
 11886 |       define_sfop3(47,details::is_true(x) ? y : z,"") 
 11887 |  
 11888 |       #define define_sfop4(NN, OP0, OP1)                         \ 
 11889 |       template <typename T>                                      \ 
 11890 |       struct sf##NN##_op : public sf_base<T>                     \ 
 11891 |       {                                                          \ 
 11892 |          typedef typename sf_base<T>::Type const Type;           \ 
 11893 |          static inline T process(Type x, Type y, Type z, Type w) \ 
 11894 |          {                                                       \ 
 11895 |             return (OP0);                                        \ 
 11896 |          }                                                       \ 
 11897 |          static inline std::string id()                          \ 
 11898 |          {                                                       \ 
 11899 |             return (OP1);                                        \ 
 11900 |          }                                                       \ 
 11901 |       };                                                         \ 
 11902 |  
 11903 |       define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)") 
 11904 |       define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)") 
 11905 |       define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)") 
 11906 |       define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)") 
 11907 |       define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)") 
 11908 |       define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)") 
 11909 |       define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)") 
 11910 |       define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)") 
 11911 |       define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)") 
 11912 |       define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)") 
 11913 |       define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)") 
 11914 |       define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)") 
 11915 |       define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)") 
 11916 |       define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)") 
 11917 |       define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)") 
 11918 |       define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)") 
 11919 |       define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)") 
 11920 |       define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t") 
 11921 |       define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t") 
 11922 |       define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t") 
 11923 |       define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t") 
 11924 |       define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t") 
 11925 |       define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t") 
 11926 |       define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t") 
 11927 |       define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t") 
 11928 |       define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)") 
 11929 |       define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)") 
 11930 |       define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)") 
 11931 |       define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)") 
 11932 |       define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)") 
 11933 |       define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)") 
 11934 |       define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)") 
 11935 |       define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))") 
 11936 |       define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))") 
 11937 |       define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))") 
 11938 |       define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))") 
 11939 |  
 11940 |       define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"") 
 11941 |       define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"") 
 11942 |       define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"") 
 11943 |       define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"") 
 11944 |       define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"") 
 11945 |       define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"") 
 11946 |       define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"") 
 11947 |       define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"") 
 11948 |       define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"") 
 11949 |       define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"") 
 11950 |       define_sfop4(94,((x <  y) ? z : w),"") 
 11951 |       define_sfop4(95,((x <= y) ? z : w),"") 
 11952 |       define_sfop4(96,((x >  y) ? z : w),"") 
 11953 |       define_sfop4(97,((x >= y) ? z : w),"") 
 11954 |       define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"") 
 11955 |       define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"") 
 11956 |  
 11957 |       define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)") 
 11958 |       define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)") 
 11959 |       define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)") 
 11960 |       define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)") 
 11961 |       define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)") 
 11962 |       define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)") 
 11963 |       define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)") 
 11964 |       define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)") 
 11965 |       define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)") 
 11966 |       define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)") 
 11967 |       define_sfop4(ext10,((x + y) + (z + w)),"(t+t)+(t+t)") 
 11968 |       define_sfop4(ext11,((x + y) * (z - w)),"(t+t)*(t-t)") 
 11969 |       define_sfop4(ext12,((x + y) / (z - w)),"(t+t)/(t-t)") 
 11970 |       define_sfop4(ext13,((x - y) - (z + w)),"(t-t)-(t+t)") 
 11971 |       define_sfop4(ext14,((x - y) + (z + w)),"(t-t)+(t+t)") 
 11972 |       define_sfop4(ext15,((x - y) * (z + w)),"(t-t)*(t+t)") 
 11973 |       define_sfop4(ext16,((x - y) / (z + w)),"(t-t)/(t+t)") 
 11974 |       define_sfop4(ext17,((x * y) - (z + w)),"(t*t)-(t+t)") 
 11975 |       define_sfop4(ext18,((x / y) - (z + w)),"(t/t)-(t+t)") 
 11976 |       define_sfop4(ext19,((x * y) + (z + w)),"(t*t)+(t+t)") 
 11977 |       define_sfop4(ext20,((x / y) + (z + w)),"(t/t)+(t+t)") 
 11978 |       define_sfop4(ext21,((x * y) + (z - w)),"(t*t)+(t-t)") 
 11979 |       define_sfop4(ext22,((x / y) + (z - w)),"(t/t)+(t-t)") 
 11980 |       define_sfop4(ext23,((x * y) - (z - w)),"(t*t)-(t-t)") 
 11981 |       define_sfop4(ext24,((x / y) - (z - w)),"(t/t)-(t-t)") 
 11982 |       define_sfop4(ext25,((x + y) * (z * w)),"(t+t)*(t*t)") 
 11983 |       define_sfop4(ext26,((x + y) * (z / w)),"(t+t)*(t/t)") 
 11984 |       define_sfop4(ext27,((x + y) / (z * w)),"(t+t)/(t*t)") 
 11985 |       define_sfop4(ext28,((x + y) / (z / w)),"(t+t)/(t/t)") 
 11986 |       define_sfop4(ext29,((x - y) / (z * w)),"(t-t)/(t*t)") 
 11987 |       define_sfop4(ext30,((x - y) / (z / w)),"(t-t)/(t/t)") 
 11988 |       define_sfop4(ext31,((x - y) * (z * w)),"(t-t)*(t*t)") 
 11989 |       define_sfop4(ext32,((x - y) * (z / w)),"(t-t)*(t/t)") 
 11990 |       define_sfop4(ext33,((x * y) * (z + w)),"(t*t)*(t+t)") 
 11991 |       define_sfop4(ext34,((x / y) * (z + w)),"(t/t)*(t+t)") 
 11992 |       define_sfop4(ext35,((x * y) / (z + w)),"(t*t)/(t+t)") 
 11993 |       define_sfop4(ext36,((x / y) / (z + w)),"(t/t)/(t+t)") 
 11994 |       define_sfop4(ext37,((x * y) / (z - w)),"(t*t)/(t-t)") 
 11995 |       define_sfop4(ext38,((x / y) / (z - w)),"(t/t)/(t-t)") 
 11996 |       define_sfop4(ext39,((x * y) * (z - w)),"(t*t)*(t-t)") 
 11997 |       define_sfop4(ext40,((x * y) / (z * w)),"(t*t)/(t*t)") 
 11998 |       define_sfop4(ext41,((x / y) * (z / w)),"(t/t)*(t/t)") 
 11999 |       define_sfop4(ext42,((x / y) * (z - w)),"(t/t)*(t-t)") 
 12000 |       define_sfop4(ext43,((x * y) * (z * w)),"(t*t)*(t*t)") 
 12001 |       define_sfop4(ext44,(x + (y * (z / w))),"t+(t*(t/t))") 
 12002 |       define_sfop4(ext45,(x - (y * (z / w))),"t-(t*(t/t))") 
 12003 |       define_sfop4(ext46,(x + (y / (z * w))),"t+(t/(t*t))") 
 12004 |       define_sfop4(ext47,(x - (y / (z * w))),"t-(t/(t*t))") 
 12005 |       define_sfop4(ext48,(((x - y) - z) * w),"((t-t)-t)*t") 
 12006 |       define_sfop4(ext49,(((x - y) - z) / w),"((t-t)-t)/t") 
 12007 |       define_sfop4(ext50,(((x - y) + z) * w),"((t-t)+t)*t") 
 12008 |       define_sfop4(ext51,(((x - y) + z) / w),"((t-t)+t)/t") 
 12009 |       define_sfop4(ext52,((x + (y - z)) * w),"(t+(t-t))*t") 
 12010 |       define_sfop4(ext53,((x + (y - z)) / w),"(t+(t-t))/t") 
 12011 |       define_sfop4(ext54,((x + y) / (z + w)),"(t+t)/(t+t)") 
 12012 |       define_sfop4(ext55,((x - y) / (z - w)),"(t-t)/(t-t)") 
 12013 |       define_sfop4(ext56,((x + y) * (z + w)),"(t+t)*(t+t)") 
 12014 |       define_sfop4(ext57,((x - y) * (z - w)),"(t-t)*(t-t)") 
 12015 |       define_sfop4(ext58,((x - y) + (z - w)),"(t-t)+(t-t)") 
 12016 |       define_sfop4(ext59,((x - y) - (z - w)),"(t-t)-(t-t)") 
 12017 |       define_sfop4(ext60,((x / y) + (z * w)),"(t/t)+(t*t)") 
 12018 |       define_sfop4(ext61,(((x * y) * z) / w),"((t*t)*t)/t") 
 12019 |  
 12020 |       #undef define_sfop3 
 12021 |       #undef define_sfop4 
 12022 |  
 12023 |       template <typename T, typename SpecialFunction> 
 12024 |       class sf3_node exprtk_final : public trinary_node<T> 
 12025 |       { 
 12026 |       public: 
 12027 |  
 12028 |          typedef expression_node<T>* expression_ptr; 
 12029 |  
 12030 |          sf3_node(const operator_type& opr, 
 12031 |                   expression_ptr branch0, 
 12032 |                   expression_ptr branch1, 
 12033 |                   expression_ptr branch2) 
 12034 |          : trinary_node<T>(opr, branch0, branch1, branch2) 
 12035 |          {} 
 12036 |  
 12037 |          inline T value() const exprtk_override 
 12038 |          { 
 12039 |             const T x = trinary_node<T>::branch_[0].first->value(); 
 12040 |             const T y = trinary_node<T>::branch_[1].first->value(); 
 12041 |             const T z = trinary_node<T>::branch_[2].first->value(); 
 12042 |  
 12043 |             return SpecialFunction::process(x, y, z); 
 12044 |          } 
 12045 |       }; 
 12046 |  
 12047 |       template <typename T, typename SpecialFunction> 
 12048 |       class sf4_node exprtk_final : public quaternary_node<T> 
 12049 |       { 
 12050 |       public: 
 12051 |  
 12052 |          typedef expression_node<T>* expression_ptr; 
 12053 |  
 12054 |          sf4_node(const operator_type& opr, 
 12055 |                   expression_ptr branch0, 
 12056 |                   expression_ptr branch1, 
 12057 |                   expression_ptr branch2, 
 12058 |                   expression_ptr branch3) 
 12059 |          : quaternary_node<T>(opr, branch0, branch1, branch2, branch3) 
 12060 |          {} 
 12061 |  
 12062 |          inline T value() const exprtk_override 
 12063 |          { 
 12064 |             const T x = quaternary_node<T>::branch_[0].first->value(); 
 12065 |             const T y = quaternary_node<T>::branch_[1].first->value(); 
 12066 |             const T z = quaternary_node<T>::branch_[2].first->value(); 
 12067 |             const T w = quaternary_node<T>::branch_[3].first->value(); 
 12068 |  
 12069 |             return SpecialFunction::process(x, y, z, w); 
 12070 |          } 
 12071 |       }; 
 12072 |  
 12073 |       template <typename T, typename SpecialFunction> 
 12074 |       class sf3_var_node exprtk_final : public expression_node<T> 
 12075 |       { 
 12076 |       public: 
 12077 |  
 12078 |          typedef expression_node<T>* expression_ptr; 
 12079 |  
 12080 |          sf3_var_node(const T& v0, const T& v1, const T& v2) 
 12081 |          : v0_(v0) 
 12082 |          , v1_(v1) 
 12083 |          , v2_(v2) 
 12084 |          {} 
 12085 |  
 12086 |          inline T value() const exprtk_override 
 12087 |          { 
 12088 |             return SpecialFunction::process(v0_, v1_, v2_); 
 12089 |          } 
 12090 |  
 12091 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12092 |          { 
 12093 |             return expression_node<T>::e_trinary; 
 12094 |          } 
 12095 |  
 12096 |       private: 
 12097 |  
 12098 |          sf3_var_node(const sf3_var_node<T,SpecialFunction>&) exprtk_delete; 
 12099 |          sf3_var_node<T,SpecialFunction>& operator=(const sf3_var_node<T,SpecialFunction>&) exprtk_delete; 
 12100 |  
 12101 |          const T& v0_; 
 12102 |          const T& v1_; 
 12103 |          const T& v2_; 
 12104 |       }; 
 12105 |  
 12106 |       template <typename T, typename SpecialFunction> 
 12107 |       class sf4_var_node exprtk_final : public expression_node<T> 
 12108 |       { 
 12109 |       public: 
 12110 |  
 12111 |          typedef expression_node<T>* expression_ptr; 
 12112 |  
 12113 |          sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3) 
 12114 |          : v0_(v0) 
 12115 |          , v1_(v1) 
 12116 |          , v2_(v2) 
 12117 |          , v3_(v3) 
 12118 |          {} 
 12119 |  
 12120 |          inline T value() const exprtk_override 
 12121 |          { 
 12122 |             return SpecialFunction::process(v0_, v1_, v2_, v3_); 
 12123 |          } 
 12124 |  
 12125 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12126 |          { 
 12127 |             return expression_node<T>::e_trinary; 
 12128 |          } 
 12129 |  
 12130 |       private: 
 12131 |  
 12132 |          sf4_var_node(const sf4_var_node<T,SpecialFunction>&) exprtk_delete; 
 12133 |          sf4_var_node<T,SpecialFunction>& operator=(const sf4_var_node<T,SpecialFunction>&) exprtk_delete; 
 12134 |  
 12135 |          const T& v0_; 
 12136 |          const T& v1_; 
 12137 |          const T& v2_; 
 12138 |          const T& v3_; 
 12139 |       }; 
 12140 |  
 12141 |       template <typename T, typename VarArgFunction> 
 12142 |       class vararg_node exprtk_final : public expression_node<T> 
 12143 |       { 
 12144 |       public: 
 12145 |  
 12146 |          typedef expression_node<T>* expression_ptr; 
 12147 |          typedef std::pair<expression_ptr,bool> branch_t; 
 12148 |  
 12149 |          template <typename Allocator, 
 12150 |                    template <typename, typename> class Sequence> 
 12151 |          explicit vararg_node(const Sequence<expression_ptr,Allocator>& arg_list) 
 12152 |          : initialised_(false) 
 12153 |          { 
 12154 |             arg_list_.resize(arg_list.size()); 
 12155 |  
 12156 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 12157 |             { 
 12158 |                if (arg_list[i] && arg_list[i]->valid()) 
 12159 |                { 
 12160 |                   construct_branch_pair(arg_list_[i],arg_list[i]); 
 12161 |                } 
 12162 |                else 
 12163 |                { 
 12164 |                   arg_list_.clear(); 
 12165 |                   return; 
 12166 |                } 
 12167 |             } 
 12168 |  
 12169 |             initialised_ = (arg_list_.size() == arg_list.size()); 
 12170 |             assert(valid()); 
 12171 |          } 
 12172 |  
 12173 |          inline T value() const exprtk_override 
 12174 |          { 
 12175 |             return VarArgFunction::process(arg_list_); 
 12176 |          } 
 12177 |  
 12178 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12179 |          { 
 12180 |             return expression_node<T>::e_vararg; 
 12181 |          } 
 12182 |  
 12183 |          inline bool valid() const exprtk_override 
 12184 |          { 
 12185 |             return initialised_; 
 12186 |          } 
 12187 |  
 12188 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 12189 |          { 
 12190 |             expression_node<T>::ndb_t::collect(arg_list_, node_delete_list); 
 12191 |          } 
 12192 |  
 12193 |          std::size_t node_depth() const exprtk_override 
 12194 |          { 
 12195 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 12196 |          } 
 12197 |  
 12198 |          std::size_t size() const 
 12199 |          { 
 12200 |             return arg_list_.size(); 
 12201 |          } 
 12202 |  
 12203 |          expression_ptr operator[](const std::size_t& index) const 
 12204 |          { 
 12205 |             return arg_list_[index].first; 
 12206 |          } 
 12207 |  
 12208 |       private: 
 12209 |  
 12210 |          std::vector<branch_t> arg_list_; 
 12211 |          bool initialised_; 
 12212 |       }; 
 12213 |  
 12214 |       template <typename T, typename VarArgFunction> 
 12215 |       class vararg_varnode exprtk_final : public expression_node<T> 
 12216 |       { 
 12217 |       public: 
 12218 |  
 12219 |          typedef expression_node<T>* expression_ptr; 
 12220 |  
 12221 |          template <typename Allocator, 
 12222 |                    template <typename, typename> class Sequence> 
 12223 |          explicit vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list) 
 12224 |          : initialised_(false) 
 12225 |          { 
 12226 |             arg_list_.resize(arg_list.size()); 
 12227 |  
 12228 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 12229 |             { 
 12230 |                if (arg_list[i] && arg_list[i]->valid() && is_variable_node(arg_list[i])) 
 12231 |                { 
 12232 |                   variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]); 
 12233 |                   arg_list_[i] = (&var_node_ptr->ref()); 
 12234 |                } 
 12235 |                else 
 12236 |                { 
 12237 |                   arg_list_.clear(); 
 12238 |                   return; 
 12239 |                } 
 12240 |             } 
 12241 |  
 12242 |             initialised_ = (arg_list.size() == arg_list_.size()); 
 12243 |             assert(valid()); 
 12244 |          } 
 12245 |  
 12246 |          inline T value() const exprtk_override 
 12247 |          { 
 12248 |             return VarArgFunction::process(arg_list_); 
 12249 |          } 
 12250 |  
 12251 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12252 |          { 
 12253 |             return expression_node<T>::e_vararg; 
 12254 |          } 
 12255 |  
 12256 |          inline bool valid() const exprtk_override 
 12257 |          { 
 12258 |             return initialised_; 
 12259 |          } 
 12260 |  
 12261 |       private: 
 12262 |  
 12263 |          std::vector<const T*> arg_list_; 
 12264 |          bool initialised_; 
 12265 |       }; 
 12266 |  
 12267 |       template <typename T, typename VecFunction> 
 12268 |       class vectorize_node exprtk_final : public expression_node<T> 
 12269 |       { 
 12270 |       public: 
 12271 |  
 12272 |          typedef expression_node<T>* expression_ptr; 
 12273 |          typedef std::pair<expression_ptr,bool> branch_t; 
 12274 |  
 12275 |          explicit vectorize_node(const expression_ptr v) 
 12276 |          : ivec_ptr_(0) 
 12277 |          { 
 12278 |             construct_branch_pair(v_, v); 
 12279 |  
 12280 |             if (is_ivector_node(v_.first)) 
 12281 |             { 
 12282 |                ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v_.first); 
 12283 |             } 
 12284 |          } 
 12285 |  
 12286 |          inline T value() const exprtk_override 
 12287 |          { 
 12288 |             v_.first->value(); 
 12289 |             return VecFunction::process(ivec_ptr_); 
 12290 |          } 
 12291 |  
 12292 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12293 |          { 
 12294 |             return expression_node<T>::e_vecfunc; 
 12295 |          } 
 12296 |  
 12297 |          inline bool valid() const exprtk_override 
 12298 |          { 
 12299 |             return ivec_ptr_ && v_.first && v_.first->valid(); 
 12300 |          } 
 12301 |  
 12302 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 12303 |          { 
 12304 |             expression_node<T>::ndb_t::collect(v_, node_delete_list); 
 12305 |          } 
 12306 |  
 12307 |          std::size_t node_depth() const exprtk_override 
 12308 |          { 
 12309 |             return expression_node<T>::ndb_t::compute_node_depth(v_); 
 12310 |          } 
 12311 |  
 12312 |       private: 
 12313 |  
 12314 |          vector_interface<T>* ivec_ptr_; 
 12315 |          branch_t                    v_; 
 12316 |       }; 
 12317 |  
 12318 |       template <typename T> 
 12319 |       class assignment_node exprtk_final : public binary_node<T> 
 12320 |       { 
 12321 |       public: 
 12322 |  
 12323 |          typedef expression_node<T>* expression_ptr; 
 12324 |          using binary_node<T>::branch; 
 12325 |  
 12326 |          assignment_node(const operator_type& opr, 
 12327 |                          expression_ptr branch0, 
 12328 |                          expression_ptr branch1) 
 12329 |          : binary_node<T>(opr, branch0, branch1) 
 12330 |          , var_node_ptr_(0) 
 12331 |          { 
 12332 |             if (is_variable_node(branch(0))) 
 12333 |             { 
 12334 |                var_node_ptr_ = static_cast<variable_node<T>*>(branch(0)); 
 12335 |             } 
 12336 |          } 
 12337 |  
 12338 |          inline T value() const exprtk_override 
 12339 |          { 
 12340 |             T& result = var_node_ptr_->ref(); 
 12341 |                result = branch(1)->value(); 
 12342 |  
 12343 |             return result; 
 12344 |          } 
 12345 |  
 12346 |          inline bool valid() const exprtk_override 
 12347 |          { 
 12348 |             return var_node_ptr_ && binary_node<T>::valid(); 
 12349 |          } 
 12350 |  
 12351 |       private: 
 12352 |  
 12353 |          variable_node<T>* var_node_ptr_; 
 12354 |       }; 
 12355 |  
 12356 |       template <typename T> 
 12357 |       class assignment_vec_elem_node exprtk_final : public binary_node<T> 
 12358 |       { 
 12359 |       public: 
 12360 |  
 12361 |          typedef expression_node<T>* expression_ptr; 
 12362 |          using binary_node<T>::branch; 
 12363 |  
 12364 |          assignment_vec_elem_node(const operator_type& opr, 
 12365 |                                   expression_ptr branch0, 
 12366 |                                   expression_ptr branch1) 
 12367 |          : binary_node<T>(opr, branch0, branch1) 
 12368 |          , vec_node_ptr_(0) 
 12369 |          { 
 12370 |             if (is_vector_elem_node(branch(0))) 
 12371 |             { 
 12372 |                vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0)); 
 12373 |             } 
 12374 |  
 12375 |             assert(valid()); 
 12376 |          } 
 12377 |  
 12378 |          inline T value() const exprtk_override 
 12379 |          { 
 12380 |             T& result = vec_node_ptr_->ref(); 
 12381 |                result = branch(1)->value(); 
 12382 |  
 12383 |             return result; 
 12384 |          } 
 12385 |  
 12386 |          inline bool valid() const exprtk_override 
 12387 |          { 
 12388 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12389 |          } 
 12390 |  
 12391 |       private: 
 12392 |  
 12393 |          vector_elem_node<T>* vec_node_ptr_; 
 12394 |       }; 
 12395 |  
 12396 |       template <typename T> 
 12397 |       class assignment_vec_elem_rtc_node exprtk_final : public binary_node<T> 
 12398 |       { 
 12399 |       public: 
 12400 |  
 12401 |          typedef expression_node<T>* expression_ptr; 
 12402 |          using binary_node<T>::branch; 
 12403 |  
 12404 |          assignment_vec_elem_rtc_node(const operator_type& opr, 
 12405 |                                       expression_ptr branch0, 
 12406 |                                       expression_ptr branch1) 
 12407 |          : binary_node<T>(opr, branch0, branch1) 
 12408 |          , vec_node_ptr_(0) 
 12409 |          { 
 12410 |             if (is_vector_elem_rtc_node(branch(0))) 
 12411 |             { 
 12412 |                vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0)); 
 12413 |             } 
 12414 |  
 12415 |             assert(valid()); 
 12416 |          } 
 12417 |  
 12418 |          inline T value() const exprtk_override 
 12419 |          { 
 12420 |             T& result = vec_node_ptr_->ref(); 
 12421 |                result = branch(1)->value(); 
 12422 |  
 12423 |             return result; 
 12424 |          } 
 12425 |  
 12426 |          inline bool valid() const exprtk_override 
 12427 |          { 
 12428 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12429 |          } 
 12430 |  
 12431 |       private: 
 12432 |  
 12433 |          vector_elem_rtc_node<T>* vec_node_ptr_; 
 12434 |       }; 
 12435 |  
 12436 |       template <typename T> 
 12437 |       class assignment_rebasevec_elem_node exprtk_final : public binary_node<T> 
 12438 |       { 
 12439 |       public: 
 12440 |  
 12441 |          typedef expression_node<T>* expression_ptr; 
 12442 |          using expression_node<T>::branch; 
 12443 |  
 12444 |          assignment_rebasevec_elem_node(const operator_type& opr, 
 12445 |                                         expression_ptr branch0, 
 12446 |                                         expression_ptr branch1) 
 12447 |          : binary_node<T>(opr, branch0, branch1) 
 12448 |          , rbvec_node_ptr_(0) 
 12449 |          { 
 12450 |             if (is_rebasevector_elem_node(branch(0))) 
 12451 |             { 
 12452 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0)); 
 12453 |             } 
 12454 |  
 12455 |             assert(valid()); 
 12456 |          } 
 12457 |  
 12458 |          inline T value() const exprtk_override 
 12459 |          { 
 12460 |             T& result = rbvec_node_ptr_->ref(); 
 12461 |                result = branch(1)->value(); 
 12462 |  
 12463 |             return result; 
 12464 |          } 
 12465 |  
 12466 |          inline bool valid() const exprtk_override 
 12467 |          { 
 12468 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 12469 |          } 
 12470 |  
 12471 |       private: 
 12472 |  
 12473 |          rebasevector_elem_node<T>* rbvec_node_ptr_; 
 12474 |       }; 
 12475 |  
 12476 |       template <typename T> 
 12477 |       class assignment_rebasevec_elem_rtc_node exprtk_final : public binary_node<T> 
 12478 |       { 
 12479 |       public: 
 12480 |  
 12481 |          typedef expression_node<T>* expression_ptr; 
 12482 |          using expression_node<T>::branch; 
 12483 |  
 12484 |          assignment_rebasevec_elem_rtc_node(const operator_type& opr, 
 12485 |                                             expression_ptr branch0, 
 12486 |                                             expression_ptr branch1) 
 12487 |          : binary_node<T>(opr, branch0, branch1) 
 12488 |          , rbvec_node_ptr_(0) 
 12489 |          { 
 12490 |             if (is_rebasevector_elem_rtc_node(branch(0))) 
 12491 |             { 
 12492 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0)); 
 12493 |             } 
 12494 |  
 12495 |             assert(valid()); 
 12496 |          } 
 12497 |  
 12498 |          inline T value() const exprtk_override 
 12499 |          { 
 12500 |             T& result = rbvec_node_ptr_->ref(); 
 12501 |                result = branch(1)->value(); 
 12502 |  
 12503 |             return result; 
 12504 |          } 
 12505 |  
 12506 |          inline bool valid() const exprtk_override 
 12507 |          { 
 12508 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 12509 |          } 
 12510 |  
 12511 |       private: 
 12512 |  
 12513 |          rebasevector_elem_rtc_node<T>* rbvec_node_ptr_; 
 12514 |       }; 
 12515 |  
 12516 |       template <typename T> 
 12517 |       class assignment_rebasevec_celem_node exprtk_final : public binary_node<T> 
 12518 |       { 
 12519 |       public: 
 12520 |  
 12521 |          typedef expression_node<T>* expression_ptr; 
 12522 |          using binary_node<T>::branch; 
 12523 |  
 12524 |          assignment_rebasevec_celem_node(const operator_type& opr, 
 12525 |                                          expression_ptr branch0, 
 12526 |                                          expression_ptr branch1) 
 12527 |          : binary_node<T>(opr, branch0, branch1) 
 12528 |          , rbvec_node_ptr_(0) 
 12529 |          { 
 12530 |             if (is_rebasevector_celem_node(branch(0))) 
 12531 |             { 
 12532 |                rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0)); 
 12533 |             } 
 12534 |  
 12535 |             assert(valid()); 
 12536 |          } 
 12537 |  
 12538 |          inline T value() const exprtk_override 
 12539 |          { 
 12540 |             T& result = rbvec_node_ptr_->ref(); 
 12541 |                result = branch(1)->value(); 
 12542 |  
 12543 |             return result; 
 12544 |          } 
 12545 |  
 12546 |          inline bool valid() const exprtk_override 
 12547 |          { 
 12548 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 12549 |          } 
 12550 |  
 12551 |       private: 
 12552 |  
 12553 |          rebasevector_celem_node<T>* rbvec_node_ptr_; 
 12554 |       }; 
 12555 |  
 12556 |       template <typename T> 
 12557 |       class assignment_vec_node exprtk_final 
 12558 |                                 : public binary_node     <T> 
 12559 |                                 , public vector_interface<T> 
 12560 |       { 
 12561 |       public: 
 12562 |  
 12563 |          typedef expression_node<T>* expression_ptr; 
 12564 |          typedef vector_node<T>*     vector_node_ptr; 
 12565 |          typedef vec_data_store<T>   vds_t; 
 12566 |  
 12567 |          using binary_node<T>::branch; 
 12568 |  
 12569 |          assignment_vec_node(const operator_type& opr, 
 12570 |                              expression_ptr branch0, 
 12571 |                              expression_ptr branch1) 
 12572 |          : binary_node<T>(opr, branch0, branch1) 
 12573 |          , vec_node_ptr_(0) 
 12574 |          { 
 12575 |             if (is_vector_node(branch(0))) 
 12576 |             { 
 12577 |                vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 12578 |                vds()         = vec_node_ptr_->vds(); 
 12579 |             } 
 12580 |  
 12581 |             assert(valid()); 
 12582 |          } 
 12583 |  
 12584 |          inline T value() const exprtk_override 
 12585 |          { 
 12586 |             const T v = branch(1)->value(); 
 12587 |  
 12588 |             T* vec = vds().data(); 
 12589 |  
 12590 |             loop_unroll::details lud(size()); 
 12591 |             const T* upper_bound = vec + lud.upper_bound; 
 12592 |  
 12593 |             while (vec < upper_bound) 
 12594 |             { 
 12595 |                #define exprtk_loop(N) \ 
 12596 |                vec[N] = v;            \ 
 12597 |  
 12598 |                exprtk_loop( 0) exprtk_loop( 1) 
 12599 |                exprtk_loop( 2) exprtk_loop( 3) 
 12600 |                #ifndef exprtk_disable_superscalar_unroll 
 12601 |                exprtk_loop( 4) exprtk_loop( 5) 
 12602 |                exprtk_loop( 6) exprtk_loop( 7) 
 12603 |                exprtk_loop( 8) exprtk_loop( 9) 
 12604 |                exprtk_loop(10) exprtk_loop(11) 
 12605 |                exprtk_loop(12) exprtk_loop(13) 
 12606 |                exprtk_loop(14) exprtk_loop(15) 
 12607 |                #endif 
 12608 |  
 12609 |                vec += lud.batch_size; 
 12610 |             } 
 12611 |  
 12612 |             switch (lud.remainder) 
 12613 |             { 
 12614 |                #define case_stmt(N) \ 
 12615 |                case N : *vec++ = v; \ 
 12616 |                exprtk_fallthrough   \ 
 12617 |  
 12618 |                #ifndef exprtk_disable_superscalar_unroll 
 12619 |                case_stmt(15) case_stmt(14) 
 12620 |                case_stmt(13) case_stmt(12) 
 12621 |                case_stmt(11) case_stmt(10) 
 12622 |                case_stmt( 9) case_stmt( 8) 
 12623 |                case_stmt( 7) case_stmt( 6) 
 12624 |                case_stmt( 5) case_stmt( 4) 
 12625 |                #endif 
 12626 |                case_stmt( 3) case_stmt( 2) 
 12627 |                case 1 : *vec++ = v; 
 12628 |             } 
 12629 |  
 12630 |             #undef exprtk_loop 
 12631 |             #undef case_stmt 
 12632 |  
 12633 |             return vec_node_ptr_->value(); 
 12634 |          } 
 12635 |  
 12636 |          vector_node_ptr vec() const exprtk_override 
 12637 |          { 
 12638 |             return vec_node_ptr_; 
 12639 |          } 
 12640 |  
 12641 |          vector_node_ptr vec() exprtk_override 
 12642 |          { 
 12643 |             return vec_node_ptr_; 
 12644 |          } 
 12645 |  
 12646 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12647 |          { 
 12648 |             return expression_node<T>::e_vecvalass; 
 12649 |          } 
 12650 |  
 12651 |          inline bool valid() const exprtk_override 
 12652 |          { 
 12653 |             return 
 12654 |                vec_node_ptr_ && 
 12655 |                (vds().size() <= vec_node_ptr_->vec_holder().base_size()) && 
 12656 |                binary_node<T>::valid(); 
 12657 |          } 
 12658 |  
 12659 |          std::size_t size() const exprtk_override 
 12660 |          { 
 12661 |             return vec_node_ptr_->vec_holder().size(); 
 12662 |          } 
 12663 |  
 12664 |          std::size_t base_size() const exprtk_override 
 12665 |          { 
 12666 |             return vec_node_ptr_->vec_holder().base_size(); 
 12667 |          } 
 12668 |  
 12669 |          vds_t& vds() exprtk_override 
 12670 |          { 
 12671 |             return vds_; 
 12672 |          } 
 12673 |  
 12674 |          const vds_t& vds() const exprtk_override 
 12675 |          { 
 12676 |             return vds_; 
 12677 |          } 
 12678 |  
 12679 |       private: 
 12680 |  
 12681 |          vector_node<T>* vec_node_ptr_; 
 12682 |          vds_t           vds_; 
 12683 |       }; 
 12684 |  
 12685 |       template <typename T> 
 12686 |       class assignment_vecvec_node exprtk_final 
 12687 |                                    : public binary_node     <T> 
 12688 |                                    , public vector_interface<T> 
 12689 |       { 
 12690 |       public: 
 12691 |  
 12692 |          typedef expression_node<T>* expression_ptr; 
 12693 |          typedef vector_node<T>*     vector_node_ptr; 
 12694 |          typedef vec_data_store<T>   vds_t; 
 12695 |  
 12696 |          using binary_node<T>::branch; 
 12697 |  
 12698 |          assignment_vecvec_node(const operator_type& opr, 
 12699 |                                 expression_ptr branch0, 
 12700 |                                 expression_ptr branch1) 
 12701 |          : binary_node<T>(opr, branch0, branch1) 
 12702 |          , vec0_node_ptr_(0) 
 12703 |          , vec1_node_ptr_(0) 
 12704 |          , initialised_(false) 
 12705 |          , src_is_ivec_(false) 
 12706 |          { 
 12707 |             if (is_vector_node(branch(0))) 
 12708 |             { 
 12709 |                vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 12710 |                vds()          = vec0_node_ptr_->vds(); 
 12711 |             } 
 12712 |  
 12713 |             if (is_vector_node(branch(1))) 
 12714 |             { 
 12715 |                vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1)); 
 12716 |                vds_t::match_sizes(vds(),vec1_node_ptr_->vds()); 
 12717 |             } 
 12718 |             else if (is_ivector_node(branch(1))) 
 12719 |             { 
 12720 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 12721 |  
 12722 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 12723 |                { 
 12724 |                   vec1_node_ptr_ = vi->vec(); 
 12725 |  
 12726 |                   if (!vi->side_effect()) 
 12727 |                   { 
 12728 |                      vi->vds()    = vds(); 
 12729 |                      src_is_ivec_ = true; 
 12730 |                   } 
 12731 |                   else 
 12732 |                      vds_t::match_sizes(vds(),vi->vds()); 
 12733 |                } 
 12734 |             } 
 12735 |  
 12736 |             initialised_ = 
 12737 |                vec0_node_ptr_               && 
 12738 |                vec1_node_ptr_               && 
 12739 |                (size() <= base_size())      && 
 12740 |                (vds_.size() <= base_size()) && 
 12741 |                binary_node<T>::valid(); 
 12742 |  
 12743 |             assert(valid()); 
 12744 |          } 
 12745 |  
 12746 |          inline T value() const exprtk_override 
 12747 |          { 
 12748 |             branch(1)->value(); 
 12749 |  
 12750 |             if (src_is_ivec_) 
 12751 |                return vec0_node_ptr_->value(); 
 12752 |  
 12753 |             T* vec0 = vec0_node_ptr_->vds().data(); 
 12754 |             T* vec1 = vec1_node_ptr_->vds().data(); 
 12755 |  
 12756 |             loop_unroll::details lud(size()); 
 12757 |             const T* upper_bound = vec0 + lud.upper_bound; 
 12758 |  
 12759 |             while (vec0 < upper_bound) 
 12760 |             { 
 12761 |                #define exprtk_loop(N) \ 
 12762 |                vec0[N] = vec1[N];     \ 
 12763 |  
 12764 |                exprtk_loop( 0) exprtk_loop( 1) 
 12765 |                exprtk_loop( 2) exprtk_loop( 3) 
 12766 |                #ifndef exprtk_disable_superscalar_unroll 
 12767 |                exprtk_loop( 4) exprtk_loop( 5) 
 12768 |                exprtk_loop( 6) exprtk_loop( 7) 
 12769 |                exprtk_loop( 8) exprtk_loop( 9) 
 12770 |                exprtk_loop(10) exprtk_loop(11) 
 12771 |                exprtk_loop(12) exprtk_loop(13) 
 12772 |                exprtk_loop(14) exprtk_loop(15) 
 12773 |                #endif 
 12774 |  
 12775 |                vec0 += lud.batch_size; 
 12776 |                vec1 += lud.batch_size; 
 12777 |             } 
 12778 |  
 12779 |             switch (lud.remainder) 
 12780 |             { 
 12781 |                #define case_stmt(N,fall_through) \ 
 12782 |                case N : *vec0++ = *vec1++;       \ 
 12783 |                fall_through                      \ 
 12784 |  
 12785 |                #ifndef exprtk_disable_superscalar_unroll 
 12786 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 12787 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 12788 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 12789 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 12790 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 12791 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 12792 |                #endif 
 12793 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 12794 |                case_stmt( 1, (void)0;) 
 12795 |             } 
 12796 |  
 12797 |             #undef exprtk_loop 
 12798 |             #undef case_stmt 
 12799 |  
 12800 |             return vec0_node_ptr_->value(); 
 12801 |          } 
 12802 |  
 12803 |          vector_node_ptr vec() exprtk_override 
 12804 |          { 
 12805 |             return vec0_node_ptr_; 
 12806 |          } 
 12807 |  
 12808 |          vector_node_ptr vec() const exprtk_override 
 12809 |          { 
 12810 |             return vec0_node_ptr_; 
 12811 |          } 
 12812 |  
 12813 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 12814 |          { 
 12815 |             return expression_node<T>::e_vecvecass; 
 12816 |          } 
 12817 |  
 12818 |          inline bool valid() const exprtk_override 
 12819 |          { 
 12820 |             return initialised_; 
 12821 |          } 
 12822 |  
 12823 |          std::size_t size() const exprtk_override 
 12824 |          { 
 12825 |             return std::min( 
 12826 |                vec0_node_ptr_->vec_holder().size(), 
 12827 |                vec1_node_ptr_->vec_holder().size()); 
 12828 |          } 
 12829 |  
 12830 |          std::size_t base_size() const exprtk_override 
 12831 |          { 
 12832 |             return std::min( 
 12833 |                vec0_node_ptr_->vec_holder().base_size(), 
 12834 |                vec1_node_ptr_->vec_holder().base_size()); 
 12835 |          } 
 12836 |  
 12837 |          vds_t& vds() exprtk_override 
 12838 |          { 
 12839 |             return vds_; 
 12840 |          } 
 12841 |  
 12842 |          const vds_t& vds() const exprtk_override 
 12843 |          { 
 12844 |             return vds_; 
 12845 |          } 
 12846 |  
 12847 |       private: 
 12848 |  
 12849 |          vector_node<T>* vec0_node_ptr_; 
 12850 |          vector_node<T>* vec1_node_ptr_; 
 12851 |          bool            initialised_; 
 12852 |          bool            src_is_ivec_; 
 12853 |          vds_t           vds_; 
 12854 |       }; 
 12855 |  
 12856 |       template <typename T, typename Operation> 
 12857 |       class assignment_op_node exprtk_final : public binary_node<T> 
 12858 |       { 
 12859 |       public: 
 12860 |  
 12861 |          typedef expression_node<T>* expression_ptr; 
 12862 |          using binary_node<T>::branch; 
 12863 |  
 12864 |          assignment_op_node(const operator_type& opr, 
 12865 |                             expression_ptr branch0, 
 12866 |                             expression_ptr branch1) 
 12867 |          : binary_node<T>(opr, branch0, branch1) 
 12868 |          , var_node_ptr_(0) 
 12869 |          { 
 12870 |             if (is_variable_node(branch(0))) 
 12871 |             { 
 12872 |                var_node_ptr_ = static_cast<variable_node<T>*>(branch(0)); 
 12873 |             } 
 12874 |  
 12875 |             assert(valid()); 
 12876 |          } 
 12877 |  
 12878 |          inline T value() const exprtk_override 
 12879 |          { 
 12880 |             T& v = var_node_ptr_->ref(); 
 12881 |             v = Operation::process(v,branch(1)->value()); 
 12882 |  
 12883 |             return v; 
 12884 |          } 
 12885 |  
 12886 |          inline bool valid() const exprtk_override 
 12887 |          { 
 12888 |             return var_node_ptr_ && binary_node<T>::valid(); 
 12889 |          } 
 12890 |  
 12891 |       private: 
 12892 |  
 12893 |          variable_node<T>* var_node_ptr_; 
 12894 |       }; 
 12895 |  
 12896 |       template <typename T, typename Operation> 
 12897 |       class assignment_vec_elem_op_node exprtk_final : public binary_node<T> 
 12898 |       { 
 12899 |       public: 
 12900 |  
 12901 |          typedef expression_node<T>* expression_ptr; 
 12902 |          using binary_node<T>::branch; 
 12903 |  
 12904 |          assignment_vec_elem_op_node(const operator_type& opr, 
 12905 |                                      expression_ptr branch0, 
 12906 |                                      expression_ptr branch1) 
 12907 |          : binary_node<T>(opr, branch0, branch1) 
 12908 |          , vec_node_ptr_(0) 
 12909 |          { 
 12910 |             if (is_vector_elem_node(branch(0))) 
 12911 |             { 
 12912 |                vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0)); 
 12913 |             } 
 12914 |  
 12915 |             assert(valid()); 
 12916 |          } 
 12917 |  
 12918 |          inline T value() const exprtk_override 
 12919 |          { 
 12920 |             T& v = vec_node_ptr_->ref(); 
 12921 |                v = Operation::process(v,branch(1)->value()); 
 12922 |  
 12923 |             return v; 
 12924 |          } 
 12925 |  
 12926 |          inline bool valid() const exprtk_override 
 12927 |          { 
 12928 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12929 |          } 
 12930 |  
 12931 |       private: 
 12932 |  
 12933 |          vector_elem_node<T>* vec_node_ptr_; 
 12934 |       }; 
 12935 |  
 12936 |       template <typename T, typename Operation> 
 12937 |       class assignment_vec_elem_op_rtc_node exprtk_final : public binary_node<T> 
 12938 |       { 
 12939 |       public: 
 12940 |  
 12941 |          typedef expression_node<T>* expression_ptr; 
 12942 |          using binary_node<T>::branch; 
 12943 |  
 12944 |          assignment_vec_elem_op_rtc_node(const operator_type& opr, 
 12945 |                                          expression_ptr branch0, 
 12946 |                                          expression_ptr branch1) 
 12947 |          : binary_node<T>(opr, branch0, branch1) 
 12948 |          , vec_node_ptr_(0) 
 12949 |          { 
 12950 |             if (is_vector_elem_rtc_node(branch(0))) 
 12951 |             { 
 12952 |                vec_node_ptr_ = static_cast<vector_elem_rtc_node<T>*>(branch(0)); 
 12953 |             } 
 12954 |  
 12955 |             assert(valid()); 
 12956 |          } 
 12957 |  
 12958 |          inline T value() const exprtk_override 
 12959 |          { 
 12960 |             T& v = vec_node_ptr_->ref(); 
 12961 |                v = Operation::process(v,branch(1)->value()); 
 12962 |  
 12963 |             return v; 
 12964 |          } 
 12965 |  
 12966 |          inline bool valid() const exprtk_override 
 12967 |          { 
 12968 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 12969 |          } 
 12970 |  
 12971 |       private: 
 12972 |  
 12973 |          vector_elem_rtc_node<T>* vec_node_ptr_; 
 12974 |       }; 
 12975 |  
 12976 |       template <typename T, typename Operation> 
 12977 |       class assignment_vec_celem_op_rtc_node exprtk_final : public binary_node<T> 
 12978 |       { 
 12979 |       public: 
 12980 |  
 12981 |          typedef expression_node<T>* expression_ptr; 
 12982 |          using binary_node<T>::branch; 
 12983 |  
 12984 |          assignment_vec_celem_op_rtc_node(const operator_type& opr, 
 12985 |                                           expression_ptr branch0, 
 12986 |                                           expression_ptr branch1) 
 12987 |          : binary_node<T>(opr, branch0, branch1) 
 12988 |          , vec_node_ptr_(0) 
 12989 |          { 
 12990 |             if (is_vector_celem_rtc_node(branch(0))) 
 12991 |             { 
 12992 |                vec_node_ptr_ = static_cast<vector_celem_rtc_node<T>*>(branch(0)); 
 12993 |             } 
 12994 |  
 12995 |             assert(valid()); 
 12996 |          } 
 12997 |  
 12998 |          inline T value() const exprtk_override 
 12999 |          { 
 13000 |             T& v = vec_node_ptr_->ref(); 
 13001 |                v = Operation::process(v,branch(1)->value()); 
 13002 |  
 13003 |             return v; 
 13004 |          } 
 13005 |  
 13006 |          inline bool valid() const exprtk_override 
 13007 |          { 
 13008 |             return vec_node_ptr_ && binary_node<T>::valid(); 
 13009 |          } 
 13010 |  
 13011 |       private: 
 13012 |  
 13013 |          vector_celem_rtc_node<T>* vec_node_ptr_; 
 13014 |       }; 
 13015 |  
 13016 |       template <typename T, typename Operation> 
 13017 |       class assignment_rebasevec_elem_op_node exprtk_final : public binary_node<T> 
 13018 |       { 
 13019 |       public: 
 13020 |  
 13021 |          typedef expression_node<T>* expression_ptr; 
 13022 |          using binary_node<T>::branch; 
 13023 |  
 13024 |          assignment_rebasevec_elem_op_node(const operator_type& opr, 
 13025 |                                            expression_ptr branch0, 
 13026 |                                            expression_ptr branch1) 
 13027 |          : binary_node<T>(opr, branch0, branch1) 
 13028 |          , rbvec_node_ptr_(0) 
 13029 |          { 
 13030 |             if (is_rebasevector_elem_node(branch(0))) 
 13031 |             { 
 13032 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0)); 
 13033 |             } 
 13034 |  
 13035 |             assert(valid()); 
 13036 |          } 
 13037 |  
 13038 |          inline T value() const exprtk_override 
 13039 |          { 
 13040 |             T& v = rbvec_node_ptr_->ref(); 
 13041 |                v = Operation::process(v,branch(1)->value()); 
 13042 |  
 13043 |             return v; 
 13044 |          } 
 13045 |  
 13046 |          inline bool valid() const exprtk_override 
 13047 |          { 
 13048 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13049 |          } 
 13050 |  
 13051 |       private: 
 13052 |  
 13053 |          rebasevector_elem_node<T>* rbvec_node_ptr_; 
 13054 |       }; 
 13055 |  
 13056 |       template <typename T, typename Operation> 
 13057 |       class assignment_rebasevec_celem_op_node exprtk_final : public binary_node<T> 
 13058 |       { 
 13059 |       public: 
 13060 |  
 13061 |          typedef expression_node<T>* expression_ptr; 
 13062 |          using binary_node<T>::branch; 
 13063 |  
 13064 |          assignment_rebasevec_celem_op_node(const operator_type& opr, 
 13065 |                                             expression_ptr branch0, 
 13066 |                                             expression_ptr branch1) 
 13067 |          : binary_node<T>(opr, branch0, branch1) 
 13068 |          , rbvec_node_ptr_(0) 
 13069 |          { 
 13070 |             if (is_rebasevector_celem_node(branch(0))) 
 13071 |             { 
 13072 |                rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0)); 
 13073 |             } 
 13074 |  
 13075 |             assert(valid()); 
 13076 |          } 
 13077 |  
 13078 |          inline T value() const exprtk_override 
 13079 |          { 
 13080 |             T& v = rbvec_node_ptr_->ref(); 
 13081 |                v = Operation::process(v,branch(1)->value()); 
 13082 |  
 13083 |             return v; 
 13084 |          } 
 13085 |  
 13086 |          inline bool valid() const exprtk_override 
 13087 |          { 
 13088 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13089 |          } 
 13090 |  
 13091 |       private: 
 13092 |  
 13093 |          rebasevector_celem_node<T>* rbvec_node_ptr_; 
 13094 |       }; 
 13095 |  
 13096 |       template <typename T, typename Operation> 
 13097 |       class assignment_rebasevec_elem_op_rtc_node exprtk_final : public binary_node<T> 
 13098 |       { 
 13099 |       public: 
 13100 |  
 13101 |          typedef expression_node<T>* expression_ptr; 
 13102 |          using binary_node<T>::branch; 
 13103 |  
 13104 |          assignment_rebasevec_elem_op_rtc_node(const operator_type& opr, 
 13105 |                                                expression_ptr branch0, 
 13106 |                                                expression_ptr branch1) 
 13107 |          : binary_node<T>(opr, branch0, branch1) 
 13108 |          , rbvec_node_ptr_(0) 
 13109 |          { 
 13110 |             if (is_rebasevector_elem_rtc_node(branch(0))) 
 13111 |             { 
 13112 |                rbvec_node_ptr_ = static_cast<rebasevector_elem_rtc_node<T>*>(branch(0)); 
 13113 |             } 
 13114 |  
 13115 |             assert(valid()); 
 13116 |          } 
 13117 |  
 13118 |          inline T value() const exprtk_override 
 13119 |          { 
 13120 |             T& v = rbvec_node_ptr_->ref(); 
 13121 |                v = Operation::process(v,branch(1)->value()); 
 13122 |  
 13123 |             return v; 
 13124 |          } 
 13125 |  
 13126 |          inline bool valid() const exprtk_override 
 13127 |          { 
 13128 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13129 |          } 
 13130 |  
 13131 |       private: 
 13132 |  
 13133 |          rebasevector_elem_rtc_node<T>* rbvec_node_ptr_; 
 13134 |       }; 
 13135 |  
 13136 |       template <typename T, typename Operation> 
 13137 |       class assignment_rebasevec_celem_op_rtc_node exprtk_final : public binary_node<T> 
 13138 |       { 
 13139 |       public: 
 13140 |  
 13141 |          typedef expression_node<T>* expression_ptr; 
 13142 |          using binary_node<T>::branch; 
 13143 |  
 13144 |          assignment_rebasevec_celem_op_rtc_node(const operator_type& opr, 
 13145 |                                                 expression_ptr branch0, 
 13146 |                                                 expression_ptr branch1) 
 13147 |          : binary_node<T>(opr, branch0, branch1) 
 13148 |          , rbvec_node_ptr_(0) 
 13149 |          { 
 13150 |             if (is_rebasevector_celem_rtc_node(branch(0))) 
 13151 |             { 
 13152 |                rbvec_node_ptr_ = static_cast<rebasevector_celem_rtc_node<T>*>(branch(0)); 
 13153 |             } 
 13154 |  
 13155 |             assert(valid()); 
 13156 |          } 
 13157 |  
 13158 |          inline T value() const exprtk_override 
 13159 |          { 
 13160 |             T& v = rbvec_node_ptr_->ref(); 
 13161 |                v = Operation::process(v,branch(1)->value()); 
 13162 |  
 13163 |             return v; 
 13164 |          } 
 13165 |  
 13166 |          inline bool valid() const exprtk_override 
 13167 |          { 
 13168 |             return rbvec_node_ptr_ && binary_node<T>::valid(); 
 13169 |          } 
 13170 |  
 13171 |       private: 
 13172 |  
 13173 |          rebasevector_celem_rtc_node<T>* rbvec_node_ptr_; 
 13174 |       }; 
 13175 |  
 13176 |       template <typename T, typename Operation> 
 13177 |       class assignment_vec_op_node exprtk_final 
 13178 |                                    : public binary_node     <T> 
 13179 |                                    , public vector_interface<T> 
 13180 |       { 
 13181 |       public: 
 13182 |  
 13183 |          typedef expression_node<T>* expression_ptr; 
 13184 |          typedef vector_node<T>*     vector_node_ptr; 
 13185 |          typedef vec_data_store<T>   vds_t; 
 13186 |  
 13187 |          using binary_node<T>::branch; 
 13188 |  
 13189 |          assignment_vec_op_node(const operator_type& opr, 
 13190 |                                 expression_ptr branch0, 
 13191 |                                 expression_ptr branch1) 
 13192 |          : binary_node<T>(opr, branch0, branch1) 
 13193 |          , vec_node_ptr_(0) 
 13194 |          { 
 13195 |             if (is_vector_node(branch(0))) 
 13196 |             { 
 13197 |                vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 13198 |                vds()         = vec_node_ptr_->vds(); 
 13199 |             } 
 13200 |  
 13201 |             assert(valid()); 
 13202 |          } 
 13203 |  
 13204 |          inline T value() const exprtk_override 
 13205 |          { 
 13206 |             const T v = branch(1)->value(); 
 13207 |  
 13208 |             T* vec = vds().data(); 
 13209 |  
 13210 |             loop_unroll::details lud(size()); 
 13211 |             const T* upper_bound = vec + lud.upper_bound; 
 13212 |  
 13213 |             while (vec < upper_bound) 
 13214 |             { 
 13215 |                #define exprtk_loop(N)       \ 
 13216 |                Operation::assign(vec[N],v); \ 
 13217 |  
 13218 |                exprtk_loop( 0) exprtk_loop( 1) 
 13219 |                exprtk_loop( 2) exprtk_loop( 3) 
 13220 |                #ifndef exprtk_disable_superscalar_unroll 
 13221 |                exprtk_loop( 4) exprtk_loop( 5) 
 13222 |                exprtk_loop( 6) exprtk_loop( 7) 
 13223 |                exprtk_loop( 8) exprtk_loop( 9) 
 13224 |                exprtk_loop(10) exprtk_loop(11) 
 13225 |                exprtk_loop(12) exprtk_loop(13) 
 13226 |                exprtk_loop(14) exprtk_loop(15) 
 13227 |                #endif 
 13228 |  
 13229 |                vec += lud.batch_size; 
 13230 |             } 
 13231 |  
 13232 |             switch (lud.remainder) 
 13233 |             { 
 13234 |                #define case_stmt(N,fall_through)     \ 
 13235 |                case N : Operation::assign(*vec++,v); \ 
 13236 |                fall_through                          \ 
 13237 |  
 13238 |                #ifndef exprtk_disable_superscalar_unroll 
 13239 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 13240 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 13241 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 13242 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 13243 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 13244 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 13245 |                #endif 
 13246 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 13247 |                case_stmt( 1, (void)0;) 
 13248 |             } 
 13249 |  
 13250 |             #undef exprtk_loop 
 13251 |             #undef case_stmt 
 13252 |  
 13253 |             return vec_node_ptr_->value(); 
 13254 |          } 
 13255 |  
 13256 |          vector_node_ptr vec() const exprtk_override 
 13257 |          { 
 13258 |             return vec_node_ptr_; 
 13259 |          } 
 13260 |  
 13261 |          vector_node_ptr vec() exprtk_override 
 13262 |          { 
 13263 |             return vec_node_ptr_; 
 13264 |          } 
 13265 |  
 13266 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13267 |          { 
 13268 |             return expression_node<T>::e_vecopvalass; 
 13269 |          } 
 13270 |  
 13271 |          inline bool valid() const exprtk_override 
 13272 |          { 
 13273 |             return 
 13274 |                vec_node_ptr_           && 
 13275 |                (size() <= base_size()) && 
 13276 |                binary_node<T>::valid() ; 
 13277 |          } 
 13278 |  
 13279 |          std::size_t size() const exprtk_override 
 13280 |          { 
 13281 |             return vec_node_ptr_->vec_holder().size(); 
 13282 |          } 
 13283 |  
 13284 |          std::size_t base_size() const exprtk_override 
 13285 |          { 
 13286 |             return vec_node_ptr_->vec_holder().base_size(); 
 13287 |          } 
 13288 |  
 13289 |          vds_t& vds() exprtk_override 
 13290 |          { 
 13291 |             return vds_; 
 13292 |          } 
 13293 |  
 13294 |          const vds_t& vds() const exprtk_override 
 13295 |          { 
 13296 |             return vds_; 
 13297 |          } 
 13298 |  
 13299 |          bool side_effect() const exprtk_override 
 13300 |          { 
 13301 |             return true; 
 13302 |          } 
 13303 |  
 13304 |       private: 
 13305 |  
 13306 |          vector_node<T>* vec_node_ptr_; 
 13307 |          vds_t           vds_; 
 13308 |       }; 
 13309 |  
 13310 |       template <typename T, typename Operation> 
 13311 |       class assignment_vecvec_op_node exprtk_final 
 13312 |                                       : public binary_node     <T> 
 13313 |                                       , public vector_interface<T> 
 13314 |       { 
 13315 |       public: 
 13316 |  
 13317 |          typedef expression_node<T>* expression_ptr; 
 13318 |          typedef vector_node<T>*     vector_node_ptr; 
 13319 |          typedef vec_data_store<T>   vds_t; 
 13320 |  
 13321 |          using binary_node<T>::branch; 
 13322 |  
 13323 |          assignment_vecvec_op_node(const operator_type& opr, 
 13324 |                                    expression_ptr branch0, 
 13325 |                                    expression_ptr branch1) 
 13326 |          : binary_node<T>(opr, branch0, branch1) 
 13327 |          , vec0_node_ptr_(0) 
 13328 |          , vec1_node_ptr_(0) 
 13329 |          , initialised_(false) 
 13330 |          { 
 13331 |             if (is_vector_node(branch(0))) 
 13332 |             { 
 13333 |                vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); 
 13334 |                vds()          = vec0_node_ptr_->vds(); 
 13335 |             } 
 13336 |  
 13337 |             if (is_vector_node(branch(1))) 
 13338 |             { 
 13339 |                vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1)); 
 13340 |                vec1_node_ptr_->vds() = vds(); 
 13341 |             } 
 13342 |             else if (is_ivector_node(branch(1))) 
 13343 |             { 
 13344 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13345 |  
 13346 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 13347 |                { 
 13348 |                   vec1_node_ptr_ = vi->vec(); 
 13349 |                   vec1_node_ptr_->vds() = vi->vds(); 
 13350 |                } 
 13351 |                else 
 13352 |                   vds_t::match_sizes(vds(),vec1_node_ptr_->vds()); 
 13353 |             } 
 13354 |  
 13355 |             initialised_ = 
 13356 |                vec0_node_ptr_          && 
 13357 |                vec1_node_ptr_          && 
 13358 |                (size() <= base_size()) && 
 13359 |                binary_node<T>::valid(); 
 13360 |  
 13361 |             assert(valid()); 
 13362 |          } 
 13363 |  
 13364 |          inline T value() const exprtk_override 
 13365 |          { 
 13366 |             branch(0)->value(); 
 13367 |             branch(1)->value(); 
 13368 |  
 13369 |                   T* vec0 = vec0_node_ptr_->vds().data(); 
 13370 |             const T* vec1 = vec1_node_ptr_->vds().data(); 
 13371 |  
 13372 |             loop_unroll::details lud(size()); 
 13373 |             const T* upper_bound = vec0 + lud.upper_bound; 
 13374 |  
 13375 |             while (vec0 < upper_bound) 
 13376 |             { 
 13377 |                #define exprtk_loop(N)                          \ 
 13378 |                vec0[N] = Operation::process(vec0[N], vec1[N]); \ 
 13379 |  
 13380 |                exprtk_loop( 0) exprtk_loop( 1) 
 13381 |                exprtk_loop( 2) exprtk_loop( 3) 
 13382 |                #ifndef exprtk_disable_superscalar_unroll 
 13383 |                exprtk_loop( 4) exprtk_loop( 5) 
 13384 |                exprtk_loop( 6) exprtk_loop( 7) 
 13385 |                exprtk_loop( 8) exprtk_loop( 9) 
 13386 |                exprtk_loop(10) exprtk_loop(11) 
 13387 |                exprtk_loop(12) exprtk_loop(13) 
 13388 |                exprtk_loop(14) exprtk_loop(15) 
 13389 |                #endif 
 13390 |  
 13391 |                vec0 += lud.batch_size; 
 13392 |                vec1 += lud.batch_size; 
 13393 |             } 
 13394 |  
 13395 |             int i = 0; 
 13396 |  
 13397 |             switch (lud.remainder) 
 13398 |             { 
 13399 |                #define case_stmt(N,fall_through)                                 \ 
 13400 |                case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ 
 13401 |                fall_through                                                      \ 
 13402 |  
 13403 |                #ifndef exprtk_disable_superscalar_unroll 
 13404 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 13405 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 13406 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 13407 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 13408 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 13409 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 13410 |                #endif 
 13411 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 13412 |                case_stmt( 1, (void)0;) 
 13413 |             } 
 13414 |  
 13415 |             #undef exprtk_loop 
 13416 |             #undef case_stmt 
 13417 |  
 13418 |             return vec0_node_ptr_->value(); 
 13419 |          } 
 13420 |  
 13421 |          vector_node_ptr vec() const exprtk_override 
 13422 |          { 
 13423 |             return vec0_node_ptr_; 
 13424 |          } 
 13425 |  
 13426 |          vector_node_ptr vec() exprtk_override 
 13427 |          { 
 13428 |             return vec0_node_ptr_; 
 13429 |          } 
 13430 |  
 13431 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13432 |          { 
 13433 |             return expression_node<T>::e_vecopvecass; 
 13434 |          } 
 13435 |  
 13436 |          inline bool valid() const exprtk_override 
 13437 |          { 
 13438 |             return initialised_; 
 13439 |          } 
 13440 |  
 13441 |          std::size_t size() const exprtk_override 
 13442 |          { 
 13443 |             return std::min( 
 13444 |                vec0_node_ptr_->vec_holder().size(), 
 13445 |                vec1_node_ptr_->vec_holder().size()); 
 13446 |          } 
 13447 |  
 13448 |          std::size_t base_size() const exprtk_override 
 13449 |          { 
 13450 |             return std::min( 
 13451 |                vec0_node_ptr_->vec_holder().base_size(), 
 13452 |                vec1_node_ptr_->vec_holder().base_size()); 
 13453 |          } 
 13454 |  
 13455 |          vds_t& vds() exprtk_override 
 13456 |          { 
 13457 |             return vds_; 
 13458 |          } 
 13459 |  
 13460 |          const vds_t& vds() const exprtk_override 
 13461 |          { 
 13462 |             return vds_; 
 13463 |          } 
 13464 |  
 13465 |          bool side_effect() const exprtk_override 
 13466 |          { 
 13467 |             return true; 
 13468 |          } 
 13469 |  
 13470 |       private: 
 13471 |  
 13472 |          vector_node<T>* vec0_node_ptr_; 
 13473 |          vector_node<T>* vec1_node_ptr_; 
 13474 |          bool            initialised_; 
 13475 |          vds_t           vds_; 
 13476 |       }; 
 13477 |  
 13478 |       template <typename T> 
 13479 |       struct memory_context_t 
 13480 |       { 
 13481 |          typedef vector_node<T>*  vector_node_ptr; 
 13482 |          typedef vector_holder<T> vector_holder_t; 
 13483 |          typedef vector_holder_t* vector_holder_ptr; 
 13484 |  
 13485 |          memory_context_t() 
 13486 |          : temp_(0) 
 13487 |          , temp_vec_node_(0) 
 13488 |          {} 
 13489 |  
 13490 |          void clear() 
 13491 |          { 
 13492 |             delete temp_vec_node_; 
 13493 |             delete temp_; 
 13494 |          } 
 13495 |  
 13496 |          vector_holder_ptr temp_; 
 13497 |          vector_node_ptr   temp_vec_node_; 
 13498 |       }; 
 13499 |  
 13500 |       template <typename T> 
 13501 |       inline memory_context_t<T> make_memory_context(vector_holder<T>& vec_holder, 
 13502 |                                                      vec_data_store<T>& vds) 
 13503 |       { 
 13504 |          memory_context_t<T> result_ctxt; 
 13505 |          result_ctxt.temp_  = (vec_holder.rebaseable()) ? 
 13506 |                               new vector_holder<T>(vec_holder,vds) : 
 13507 |                               new vector_holder<T>(vds) ; 
 13508 |          result_ctxt.temp_vec_node_ = new vector_node  <T>(vds,result_ctxt.temp_); 
 13509 |          return result_ctxt; 
 13510 |       } 
 13511 |  
 13512 |       template <typename T> 
 13513 |       inline memory_context_t<T> make_memory_context(vector_holder<T>& vec_holder0, 
 13514 |                                                      vector_holder<T>& vec_holder1, 
 13515 |                                                      vec_data_store<T>& vds) 
 13516 |       { 
 13517 |          memory_context_t<T> result_ctxt; 
 13518 |  
 13519 |          if (!vec_holder0.rebaseable() && !vec_holder1.rebaseable()) 
 13520 |             result_ctxt.temp_ = new vector_holder<T>(vds); 
 13521 |          else if (vec_holder0.rebaseable() && !vec_holder1.rebaseable()) 
 13522 |             result_ctxt.temp_ = new vector_holder<T>(vec_holder0,vds); 
 13523 |          else if (!vec_holder0.rebaseable() && vec_holder1.rebaseable()) 
 13524 |             result_ctxt.temp_ = new vector_holder<T>(vec_holder1,vds); 
 13525 |          else 
 13526 |          { 
 13527 |             result_ctxt.temp_ = (vec_holder0.base_size() >= vec_holder1.base_size()) ? 
 13528 |                                 new vector_holder<T>(vec_holder0, vds) : 
 13529 |                                 new vector_holder<T>(vec_holder1, vds) ; 
 13530 |          } 
 13531 |  
 13532 |          result_ctxt.temp_vec_node_ = new vector_node <T>(vds,result_ctxt.temp_); 
 13533 |          return result_ctxt; 
 13534 |       } 
 13535 |  
 13536 |       template <typename T, typename Operation> 
 13537 |       class vec_binop_vecvec_node exprtk_final 
 13538 |                                   : public binary_node     <T> 
 13539 |                                   , public vector_interface<T> 
 13540 |       { 
 13541 |       public: 
 13542 |  
 13543 |          typedef expression_node<T>* expression_ptr; 
 13544 |          typedef vector_node<T>*     vector_node_ptr; 
 13545 |          typedef vector_holder<T>    vector_holder_t; 
 13546 |          typedef vector_holder_t*    vector_holder_ptr; 
 13547 |          typedef vec_data_store<T>   vds_t; 
 13548 |          typedef memory_context_t<T> memory_context; 
 13549 |  
 13550 |          using binary_node<T>::branch; 
 13551 |  
 13552 |          vec_binop_vecvec_node(const operator_type& opr, 
 13553 |                                expression_ptr branch0, 
 13554 |                                expression_ptr branch1) 
 13555 |          : binary_node<T>(opr, branch0, branch1) 
 13556 |          , vec0_node_ptr_(0) 
 13557 |          , vec1_node_ptr_(0) 
 13558 |          , initialised_(false) 
 13559 |          { 
 13560 |             bool v0_is_ivec = false; 
 13561 |             bool v1_is_ivec = false; 
 13562 |  
 13563 |             if (is_vector_node(branch(0))) 
 13564 |             { 
 13565 |                vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); 
 13566 |             } 
 13567 |             else if (is_ivector_node(branch(0))) 
 13568 |             { 
 13569 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13570 |  
 13571 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 13572 |                { 
 13573 |                   vec0_node_ptr_ = vi->vec(); 
 13574 |                   v0_is_ivec     = true; 
 13575 |                } 
 13576 |             } 
 13577 |  
 13578 |             if (is_vector_node(branch(1))) 
 13579 |             { 
 13580 |                vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1)); 
 13581 |             } 
 13582 |             else if (is_ivector_node(branch(1))) 
 13583 |             { 
 13584 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13585 |  
 13586 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 13587 |                { 
 13588 |                   vec1_node_ptr_ = vi->vec(); 
 13589 |                   v1_is_ivec     = true; 
 13590 |                } 
 13591 |             } 
 13592 |  
 13593 |             if (vec0_node_ptr_ && vec1_node_ptr_) 
 13594 |             { 
 13595 |                vector_holder<T>& vec0 = vec0_node_ptr_->vec_holder(); 
 13596 |                vector_holder<T>& vec1 = vec1_node_ptr_->vec_holder(); 
 13597 |  
 13598 |                if (v0_is_ivec && (vec0.base_size() <= vec1.base_size())) 
 13599 |                { 
 13600 |                   vds_ = vds_t(vec0_node_ptr_->vds()); 
 13601 |                } 
 13602 |                else if (v1_is_ivec && (vec1.base_size() <= vec0.base_size())) 
 13603 |                { 
 13604 |                   vds_ = vds_t(vec1_node_ptr_->vds()); 
 13605 |                } 
 13606 |                else 
 13607 |                { 
 13608 |                   vds_ = vds_t(std::min(vec0.base_size(),vec1.base_size())); 
 13609 |                } 
 13610 |  
 13611 |                memory_context_ = make_memory_context(vec0, vec1, vds()); 
 13612 |  
 13613 |                initialised_ = 
 13614 |                   (size() <= base_size()) && 
 13615 |                   binary_node<T>::valid(); 
 13616 |             } 
 13617 |  
 13618 |             assert(valid()); 
 13619 |          } 
 13620 |  
 13621 |         ~vec_binop_vecvec_node() 
 13622 |          { 
 13623 |             memory_context_.clear(); 
 13624 |          } 
 13625 |  
 13626 |          inline T value() const exprtk_override 
 13627 |          { 
 13628 |             branch(0)->value(); 
 13629 |             branch(1)->value(); 
 13630 |  
 13631 |             const T* vec0 = vec0_node_ptr_->vds().data(); 
 13632 |             const T* vec1 = vec1_node_ptr_->vds().data(); 
 13633 |                   T* vec2 = vds().data(); 
 13634 |  
 13635 |             loop_unroll::details lud(size()); 
 13636 |             const T* upper_bound = vec2 + lud.upper_bound; 
 13637 |  
 13638 |             while (vec2 < upper_bound) 
 13639 |             { 
 13640 |                #define exprtk_loop(N)                          \ 
 13641 |                vec2[N] = Operation::process(vec0[N], vec1[N]); \ 
 13642 |  
 13643 |                exprtk_loop( 0) exprtk_loop( 1) 
 13644 |                exprtk_loop( 2) exprtk_loop( 3) 
 13645 |                #ifndef exprtk_disable_superscalar_unroll 
 13646 |                exprtk_loop( 4) exprtk_loop( 5) 
 13647 |                exprtk_loop( 6) exprtk_loop( 7) 
 13648 |                exprtk_loop( 8) exprtk_loop( 9) 
 13649 |                exprtk_loop(10) exprtk_loop(11) 
 13650 |                exprtk_loop(12) exprtk_loop(13) 
 13651 |                exprtk_loop(14) exprtk_loop(15) 
 13652 |                #endif 
 13653 |  
 13654 |                vec0 += lud.batch_size; 
 13655 |                vec1 += lud.batch_size; 
 13656 |                vec2 += lud.batch_size; 
 13657 |             } 
 13658 |  
 13659 |             int i = 0; 
 13660 |  
 13661 |             switch (lud.remainder) 
 13662 |             { 
 13663 |                #define case_stmt(N)                                              \ 
 13664 |                case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ 
 13665 |                exprtk_fallthrough                                                \ 
 13666 |  
 13667 |                #ifndef exprtk_disable_superscalar_unroll 
 13668 |                case_stmt(15) case_stmt(14) 
 13669 |                case_stmt(13) case_stmt(12) 
 13670 |                case_stmt(11) case_stmt(10) 
 13671 |                case_stmt( 9) case_stmt( 8) 
 13672 |                case_stmt( 7) case_stmt( 6) 
 13673 |                case_stmt( 5) case_stmt( 4) 
 13674 |                #endif 
 13675 |                case_stmt( 3) case_stmt( 2) 
 13676 |                case_stmt( 1) 
 13677 |                default: break; 
 13678 |             } 
 13679 |  
 13680 |             #undef exprtk_loop 
 13681 |             #undef case_stmt 
 13682 |  
 13683 |             return (vds().data())[0]; 
 13684 |          } 
 13685 |  
 13686 |          vector_node_ptr vec() const exprtk_override 
 13687 |          { 
 13688 |             return memory_context_.temp_vec_node_; 
 13689 |          } 
 13690 |  
 13691 |          vector_node_ptr vec() exprtk_override 
 13692 |          { 
 13693 |             return memory_context_.temp_vec_node_; 
 13694 |          } 
 13695 |  
 13696 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13697 |          { 
 13698 |             return expression_node<T>::e_vecvecarith; 
 13699 |          } 
 13700 |  
 13701 |          inline bool valid() const exprtk_override 
 13702 |          { 
 13703 |             return initialised_; 
 13704 |          } 
 13705 |  
 13706 |          std::size_t size() const exprtk_override 
 13707 |          { 
 13708 |             return std::min( 
 13709 |                vec0_node_ptr_->vec_holder().size(), 
 13710 |                vec1_node_ptr_->vec_holder().size()); 
 13711 |          } 
 13712 |  
 13713 |          std::size_t base_size() const exprtk_override 
 13714 |          { 
 13715 |             return std::min( 
 13716 |                vec0_node_ptr_->vec_holder().base_size(), 
 13717 |                vec1_node_ptr_->vec_holder().base_size()); 
 13718 |          } 
 13719 |  
 13720 |          vds_t& vds() exprtk_override 
 13721 |          { 
 13722 |             return vds_; 
 13723 |          } 
 13724 |  
 13725 |          const vds_t& vds() const exprtk_override 
 13726 |          { 
 13727 |             return vds_; 
 13728 |          } 
 13729 |  
 13730 |       private: 
 13731 |  
 13732 |          vector_node_ptr vec0_node_ptr_; 
 13733 |          vector_node_ptr vec1_node_ptr_; 
 13734 |          bool            initialised_; 
 13735 |          vds_t           vds_; 
 13736 |          memory_context  memory_context_; 
 13737 |       }; 
 13738 |  
 13739 |       template <typename T, typename Operation> 
 13740 |       class vec_binop_vecval_node exprtk_final 
 13741 |                                   : public binary_node     <T> 
 13742 |                                   , public vector_interface<T> 
 13743 |       { 
 13744 |       public: 
 13745 |  
 13746 |          typedef expression_node<T>* expression_ptr; 
 13747 |          typedef vector_node<T>*     vector_node_ptr; 
 13748 |          typedef vector_holder<T>    vector_holder_t; 
 13749 |          typedef vector_holder_t*    vector_holder_ptr; 
 13750 |          typedef vec_data_store<T>   vds_t; 
 13751 |          typedef memory_context_t<T> memory_context; 
 13752 |  
 13753 |          using binary_node<T>::branch; 
 13754 |  
 13755 |          vec_binop_vecval_node(const operator_type& opr, 
 13756 |                                expression_ptr branch0, 
 13757 |                                expression_ptr branch1) 
 13758 |          : binary_node<T>(opr, branch0, branch1) 
 13759 |          , vec0_node_ptr_(0) 
 13760 |          { 
 13761 |             bool v0_is_ivec = false; 
 13762 |  
 13763 |             if (is_vector_node(branch(0))) 
 13764 |             { 
 13765 |                vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); 
 13766 |             } 
 13767 |             else if (is_ivector_node(branch(0))) 
 13768 |             { 
 13769 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13770 |  
 13771 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 13772 |                { 
 13773 |                   vec0_node_ptr_ = vi->vec(); 
 13774 |                   v0_is_ivec     = true; 
 13775 |                } 
 13776 |             } 
 13777 |  
 13778 |             if (vec0_node_ptr_) 
 13779 |             { 
 13780 |                if (v0_is_ivec) 
 13781 |                   vds() = vec0_node_ptr_->vds(); 
 13782 |                else 
 13783 |                   vds() = vds_t(vec0_node_ptr_->base_size()); 
 13784 |  
 13785 |                memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds()); 
 13786 |             } 
 13787 |  
 13788 |             assert(valid()); 
 13789 |          } 
 13790 |  
 13791 |         ~vec_binop_vecval_node() 
 13792 |          { 
 13793 |             memory_context_.clear(); 
 13794 |          } 
 13795 |  
 13796 |          inline T value() const exprtk_override 
 13797 |          { 
 13798 |                         branch(0)->value(); 
 13799 |             const T v = branch(1)->value(); 
 13800 |  
 13801 |             const T* vec0 = vec0_node_ptr_->vds().data(); 
 13802 |                   T* vec1 = vds().data(); 
 13803 |  
 13804 |             loop_unroll::details lud(size()); 
 13805 |             const T* upper_bound = vec0 + lud.upper_bound; 
 13806 |  
 13807 |             while (vec0 < upper_bound) 
 13808 |             { 
 13809 |                #define exprtk_loop(N)                    \ 
 13810 |                vec1[N] = Operation::process(vec0[N], v); \ 
 13811 |  
 13812 |                exprtk_loop( 0) exprtk_loop( 1) 
 13813 |                exprtk_loop( 2) exprtk_loop( 3) 
 13814 |                #ifndef exprtk_disable_superscalar_unroll 
 13815 |                exprtk_loop( 4) exprtk_loop( 5) 
 13816 |                exprtk_loop( 6) exprtk_loop( 7) 
 13817 |                exprtk_loop( 8) exprtk_loop( 9) 
 13818 |                exprtk_loop(10) exprtk_loop(11) 
 13819 |                exprtk_loop(12) exprtk_loop(13) 
 13820 |                exprtk_loop(14) exprtk_loop(15) 
 13821 |                #endif 
 13822 |  
 13823 |                vec0 += lud.batch_size; 
 13824 |                vec1 += lud.batch_size; 
 13825 |             } 
 13826 |  
 13827 |             int i = 0; 
 13828 |  
 13829 |             switch (lud.remainder) 
 13830 |             { 
 13831 |                #define case_stmt(N,fall_through)                           \ 
 13832 |                case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \ 
 13833 |                fall_through                                                \ 
 13834 |  
 13835 |                #ifndef exprtk_disable_superscalar_unroll 
 13836 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 13837 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 13838 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 13839 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 13840 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 13841 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 13842 |                #endif 
 13843 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 13844 |                case_stmt( 1, (void)0;) 
 13845 |             } 
 13846 |  
 13847 |             #undef exprtk_loop 
 13848 |             #undef case_stmt 
 13849 |  
 13850 |             return (vds().data())[0]; 
 13851 |          } 
 13852 |  
 13853 |          vector_node_ptr vec() const exprtk_override 
 13854 |          { 
 13855 |             return memory_context_.temp_vec_node_; 
 13856 |          } 
 13857 |  
 13858 |          vector_node_ptr vec() exprtk_override 
 13859 |          { 
 13860 |             return memory_context_.temp_vec_node_; 
 13861 |          } 
 13862 |  
 13863 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 13864 |          { 
 13865 |             return expression_node<T>::e_vecvalarith; 
 13866 |          } 
 13867 |  
 13868 |          inline bool valid() const exprtk_override 
 13869 |          { 
 13870 |             return 
 13871 |                vec0_node_ptr_          && 
 13872 |                (size() <= base_size()) && 
 13873 |                binary_node<T>::valid(); 
 13874 |          } 
 13875 |  
 13876 |          std::size_t size() const exprtk_override 
 13877 |          { 
 13878 |             return vec0_node_ptr_->size(); 
 13879 |          } 
 13880 |  
 13881 |          std::size_t base_size() const exprtk_override 
 13882 |          { 
 13883 |             return vec0_node_ptr_->vec_holder().base_size(); 
 13884 |          } 
 13885 |  
 13886 |          vds_t& vds() exprtk_override 
 13887 |          { 
 13888 |             return vds_; 
 13889 |          } 
 13890 |  
 13891 |          const vds_t& vds() const exprtk_override 
 13892 |          { 
 13893 |             return vds_; 
 13894 |          } 
 13895 |  
 13896 |       private: 
 13897 |  
 13898 |          vector_node_ptr   vec0_node_ptr_; 
 13899 |          vds_t             vds_; 
 13900 |          memory_context    memory_context_; 
 13901 |       }; 
 13902 |  
 13903 |       template <typename T, typename Operation> 
 13904 |       class vec_binop_valvec_node exprtk_final 
 13905 |                                   : public binary_node     <T> 
 13906 |                                   , public vector_interface<T> 
 13907 |       { 
 13908 |       public: 
 13909 |  
 13910 |          typedef expression_node<T>* expression_ptr; 
 13911 |          typedef vector_node<T>*     vector_node_ptr; 
 13912 |          typedef vector_holder<T>    vector_holder_t; 
 13913 |          typedef vector_holder_t*    vector_holder_ptr; 
 13914 |          typedef vec_data_store<T>   vds_t; 
 13915 |          typedef memory_context_t<T> memory_context; 
 13916 |  
 13917 |          using binary_node<T>::branch; 
 13918 |  
 13919 |          vec_binop_valvec_node(const operator_type& opr, 
 13920 |                                expression_ptr branch0, 
 13921 |                                expression_ptr branch1) 
 13922 |          : binary_node<T>(opr, branch0, branch1) 
 13923 |          , vec1_node_ptr_(0) 
 13924 |          { 
 13925 |             bool v1_is_ivec = false; 
 13926 |  
 13927 |             if (is_vector_node(branch(1))) 
 13928 |             { 
 13929 |                vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1)); 
 13930 |             } 
 13931 |             else if (is_ivector_node(branch(1))) 
 13932 |             { 
 13933 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 13934 |  
 13935 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) 
 13936 |                { 
 13937 |                   vec1_node_ptr_ = vi->vec(); 
 13938 |                   v1_is_ivec     = true; 
 13939 |                } 
 13940 |             } 
 13941 |  
 13942 |             if (vec1_node_ptr_) 
 13943 |             { 
 13944 |                if (v1_is_ivec) 
 13945 |                   vds() = vec1_node_ptr_->vds(); 
 13946 |                else 
 13947 |                   vds() = vds_t(vec1_node_ptr_->base_size()); 
 13948 |  
 13949 |                memory_context_ = make_memory_context(vec1_node_ptr_->vec_holder(), vds()); 
 13950 |             } 
 13951 |  
 13952 |             assert(valid()); 
 13953 |          } 
 13954 |  
 13955 |         ~vec_binop_valvec_node() 
 13956 |          { 
 13957 |             memory_context_.clear(); 
 13958 |          } 
 13959 |  
 13960 |          inline T value() const exprtk_override 
 13961 |          { 
 13962 |             const T v = branch(0)->value(); 
 13963 |                         branch(1)->value(); 
 13964 |  
 13965 |                   T* vec0 = vds().data(); 
 13966 |             const T* vec1 = vec1_node_ptr_->vds().data(); 
 13967 |  
 13968 |             loop_unroll::details lud(size()); 
 13969 |             const T* upper_bound = vec0 + lud.upper_bound; 
 13970 |  
 13971 |             while (vec0 < upper_bound) 
 13972 |             { 
 13973 |                #define exprtk_loop(N)                    \ 
 13974 |                vec0[N] = Operation::process(v, vec1[N]); \ 
 13975 |  
 13976 |                exprtk_loop( 0) exprtk_loop( 1) 
 13977 |                exprtk_loop( 2) exprtk_loop( 3) 
 13978 |                #ifndef exprtk_disable_superscalar_unroll 
 13979 |                exprtk_loop( 4) exprtk_loop( 5) 
 13980 |                exprtk_loop( 6) exprtk_loop( 7) 
 13981 |                exprtk_loop( 8) exprtk_loop( 9) 
 13982 |                exprtk_loop(10) exprtk_loop(11) 
 13983 |                exprtk_loop(12) exprtk_loop(13) 
 13984 |                exprtk_loop(14) exprtk_loop(15) 
 13985 |                #endif 
 13986 |  
 13987 |                vec0 += lud.batch_size; 
 13988 |                vec1 += lud.batch_size; 
 13989 |             } 
 13990 |  
 13991 |             int i = 0; 
 13992 |  
 13993 |             switch (lud.remainder) 
 13994 |             { 
 13995 |                #define case_stmt(N,fall_through)                           \ 
 13996 |                case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \ 
 13997 |                fall_through                                                \ 
 13998 |  
 13999 |                #ifndef exprtk_disable_superscalar_unroll 
 14000 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 14001 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 14002 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 14003 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 14004 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 14005 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 14006 |                #endif 
 14007 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 14008 |                case_stmt( 1, (void)0;) 
 14009 |             } 
 14010 |  
 14011 |             #undef exprtk_loop 
 14012 |             #undef case_stmt 
 14013 |  
 14014 |             return (vds().data())[0]; 
 14015 |          } 
 14016 |  
 14017 |          vector_node_ptr vec() const exprtk_override 
 14018 |          { 
 14019 |             return memory_context_.temp_vec_node_; 
 14020 |          } 
 14021 |  
 14022 |          vector_node_ptr vec() exprtk_override 
 14023 |          { 
 14024 |             return memory_context_.temp_vec_node_; 
 14025 |          } 
 14026 |  
 14027 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14028 |          { 
 14029 |             return expression_node<T>::e_vecvalarith; 
 14030 |          } 
 14031 |  
 14032 |          inline bool valid() const exprtk_override 
 14033 |          { 
 14034 |             return 
 14035 |                vec1_node_ptr_               && 
 14036 |                (size() <= base_size())      && 
 14037 |                (vds_.size() <= base_size()) && 
 14038 |                binary_node<T>::valid(); 
 14039 |          } 
 14040 |  
 14041 |          std::size_t size() const exprtk_override 
 14042 |          { 
 14043 |             return vec1_node_ptr_->vec_holder().size(); 
 14044 |          } 
 14045 |  
 14046 |          std::size_t base_size() const exprtk_override 
 14047 |          { 
 14048 |             return vec1_node_ptr_->vec_holder().base_size(); 
 14049 |          } 
 14050 |  
 14051 |          vds_t& vds() exprtk_override 
 14052 |          { 
 14053 |             return vds_; 
 14054 |          } 
 14055 |  
 14056 |          const vds_t& vds() const exprtk_override 
 14057 |          { 
 14058 |             return vds_; 
 14059 |          } 
 14060 |  
 14061 |       private: 
 14062 |  
 14063 |          vector_node_ptr   vec1_node_ptr_; 
 14064 |          vds_t             vds_; 
 14065 |          memory_context    memory_context_; 
 14066 |       }; 
 14067 |  
 14068 |       template <typename T, typename Operation> 
 14069 |       class unary_vector_node exprtk_final 
 14070 |                               : public unary_node      <T> 
 14071 |                               , public vector_interface<T> 
 14072 |       { 
 14073 |       public: 
 14074 |  
 14075 |          typedef expression_node<T>* expression_ptr; 
 14076 |          typedef vector_node<T>*     vector_node_ptr; 
 14077 |          typedef vector_holder<T>    vector_holder_t; 
 14078 |          typedef vector_holder_t*    vector_holder_ptr; 
 14079 |          typedef vec_data_store<T>   vds_t; 
 14080 |          typedef memory_context_t<T> memory_context; 
 14081 |  
 14082 |          using expression_node<T>::branch; 
 14083 |  
 14084 |          unary_vector_node(const operator_type& opr, expression_ptr branch0) 
 14085 |          : unary_node<T>(opr, branch0) 
 14086 |          , vec0_node_ptr_(0) 
 14087 |          { 
 14088 |             bool vec0_is_ivec = false; 
 14089 |  
 14090 |             if (is_vector_node(branch(0))) 
 14091 |             { 
 14092 |                vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); 
 14093 |             } 
 14094 |             else if (is_ivector_node(branch(0))) 
 14095 |             { 
 14096 |                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 14097 |  
 14098 |                if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) 
 14099 |                { 
 14100 |                   vec0_node_ptr_ = vi->vec(); 
 14101 |                   vec0_is_ivec   = true; 
 14102 |                } 
 14103 |             } 
 14104 |  
 14105 |             if (vec0_node_ptr_) 
 14106 |             { 
 14107 |                if (vec0_is_ivec) 
 14108 |                   vds_ = vec0_node_ptr_->vds(); 
 14109 |                else 
 14110 |                   vds_ = vds_t(vec0_node_ptr_->base_size()); 
 14111 |  
 14112 |                memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds()); 
 14113 |             } 
 14114 |  
 14115 |             assert(valid()); 
 14116 |          } 
 14117 |  
 14118 |         ~unary_vector_node() 
 14119 |          { 
 14120 |             memory_context_.clear(); 
 14121 |          } 
 14122 |  
 14123 |          inline T value() const exprtk_override 
 14124 |          { 
 14125 |             branch()->value(); 
 14126 |  
 14127 |             const T* vec0 = vec0_node_ptr_->vds().data(); 
 14128 |                   T* vec1 = vds().data(); 
 14129 |  
 14130 |             loop_unroll::details lud(size()); 
 14131 |             const T* upper_bound = vec0 + lud.upper_bound; 
 14132 |  
 14133 |             while (vec0 < upper_bound) 
 14134 |             { 
 14135 |                #define exprtk_loop(N)                 \ 
 14136 |                vec1[N] = Operation::process(vec0[N]); \ 
 14137 |  
 14138 |                exprtk_loop( 0) exprtk_loop( 1) 
 14139 |                exprtk_loop( 2) exprtk_loop( 3) 
 14140 |                #ifndef exprtk_disable_superscalar_unroll 
 14141 |                exprtk_loop( 4) exprtk_loop( 5) 
 14142 |                exprtk_loop( 6) exprtk_loop( 7) 
 14143 |                exprtk_loop( 8) exprtk_loop( 9) 
 14144 |                exprtk_loop(10) exprtk_loop(11) 
 14145 |                exprtk_loop(12) exprtk_loop(13) 
 14146 |                exprtk_loop(14) exprtk_loop(15) 
 14147 |                #endif 
 14148 |  
 14149 |                vec0 += lud.batch_size; 
 14150 |                vec1 += lud.batch_size; 
 14151 |             } 
 14152 |  
 14153 |             int i = 0; 
 14154 |  
 14155 |             switch (lud.remainder) 
 14156 |             { 
 14157 |                #define case_stmt(N)                                     \ 
 14158 |                case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \ 
 14159 |                exprtk_fallthrough                                       \ 
 14160 |  
 14161 |                #ifndef exprtk_disable_superscalar_unroll 
 14162 |                case_stmt(15) case_stmt(14) 
 14163 |                case_stmt(13) case_stmt(12) 
 14164 |                case_stmt(11) case_stmt(10) 
 14165 |                case_stmt( 9) case_stmt( 8) 
 14166 |                case_stmt( 7) case_stmt( 6) 
 14167 |                case_stmt( 5) case_stmt( 4) 
 14168 |                #endif 
 14169 |                case_stmt( 3) case_stmt( 2) 
 14170 |                case_stmt( 1) 
 14171 |                default: break; 
 14172 |             } 
 14173 |  
 14174 |             #undef exprtk_loop 
 14175 |             #undef case_stmt 
 14176 |  
 14177 |             return (vds().data())[0]; 
 14178 |          } 
 14179 |  
 14180 |          vector_node_ptr vec() const exprtk_override 
 14181 |          { 
 14182 |             return memory_context_.temp_vec_node_; 
 14183 |          } 
 14184 |  
 14185 |          vector_node_ptr vec() exprtk_override 
 14186 |          { 
 14187 |             return memory_context_.temp_vec_node_; 
 14188 |          } 
 14189 |  
 14190 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14191 |          { 
 14192 |             return expression_node<T>::e_vecunaryop; 
 14193 |          } 
 14194 |  
 14195 |          inline bool valid() const exprtk_override 
 14196 |          { 
 14197 |             return vec0_node_ptr_ && unary_node<T>::valid(); 
 14198 |          } 
 14199 |  
 14200 |          std::size_t size() const exprtk_override 
 14201 |          { 
 14202 |             return vec0_node_ptr_->vec_holder().size(); 
 14203 |          } 
 14204 |  
 14205 |          std::size_t base_size() const exprtk_override 
 14206 |          { 
 14207 |             return vec0_node_ptr_->vec_holder().base_size(); 
 14208 |          } 
 14209 |  
 14210 |          vds_t& vds() exprtk_override 
 14211 |          { 
 14212 |             return vds_; 
 14213 |          } 
 14214 |  
 14215 |          const vds_t& vds() const exprtk_override 
 14216 |          { 
 14217 |             return vds_; 
 14218 |          } 
 14219 |  
 14220 |       private: 
 14221 |  
 14222 |          vector_node_ptr vec0_node_ptr_; 
 14223 |          vds_t           vds_; 
 14224 |          memory_context  memory_context_; 
 14225 |       }; 
 14226 |  
 14227 |       template <typename T> 
 14228 |       class conditional_vector_node exprtk_final 
 14229 |                                     : public expression_node <T> 
 14230 |                                     , public vector_interface<T> 
 14231 |       { 
 14232 |       public: 
 14233 |  
 14234 |          typedef expression_node <T>* expression_ptr; 
 14235 |          typedef vector_interface<T>* vec_interface_ptr; 
 14236 |          typedef vector_node     <T>* vector_node_ptr; 
 14237 |          typedef vector_holder   <T>  vector_holder_t; 
 14238 |          typedef vector_holder_t*     vector_holder_ptr; 
 14239 |          typedef vec_data_store  <T>  vds_t; 
 14240 |          typedef memory_context_t<T> memory_context; 
 14241 |          typedef std::pair<expression_ptr,bool> branch_t; 
 14242 |  
 14243 |          conditional_vector_node(expression_ptr condition, 
 14244 |                                  expression_ptr consequent, 
 14245 |                                  expression_ptr alternative) 
 14246 |          : consequent_node_ptr_ (0) 
 14247 |          , alternative_node_ptr_(0) 
 14248 |          , temp_vec_node_       (0) 
 14249 |          , temp_                (0) 
 14250 |          , result_vec_size_     (0) 
 14251 |          , initialised_         (false) 
 14252 |          { 
 14253 |             construct_branch_pair(condition_  , condition  ); 
 14254 |             construct_branch_pair(consequent_ , consequent ); 
 14255 |             construct_branch_pair(alternative_, alternative); 
 14256 |  
 14257 |             if (details::is_ivector_node(consequent_.first)) 
 14258 |             { 
 14259 |                vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(consequent_.first); 
 14260 |  
 14261 |                if (0 != ivec_ptr) 
 14262 |                { 
 14263 |                   consequent_node_ptr_ = ivec_ptr->vec(); 
 14264 |                } 
 14265 |             } 
 14266 |  
 14267 |             if (details::is_ivector_node(alternative_.first)) 
 14268 |             { 
 14269 |                vec_interface_ptr ivec_ptr = dynamic_cast<vec_interface_ptr>(alternative_.first); 
 14270 |  
 14271 |                if (0 != ivec_ptr) 
 14272 |                { 
 14273 |                   alternative_node_ptr_ = ivec_ptr->vec(); 
 14274 |                } 
 14275 |             } 
 14276 |  
 14277 |             if (consequent_node_ptr_ && alternative_node_ptr_) 
 14278 |             { 
 14279 |                const std::size_t vec_size = 
 14280 |                   std::max(consequent_node_ptr_ ->vec_holder().base_size(), 
 14281 |                            alternative_node_ptr_->vec_holder().base_size()); 
 14282 |  
 14283 |                vds_            = vds_t(vec_size); 
 14284 |                memory_context_ = make_memory_context( 
 14285 |                   consequent_node_ptr_ ->vec_holder(), 
 14286 |                   alternative_node_ptr_->vec_holder(), 
 14287 |                   vds()); 
 14288 |  
 14289 |                initialised_ = (vec_size > 0); 
 14290 |             } 
 14291 |  
 14292 |             assert(initialised_); 
 14293 |          } 
 14294 |  
 14295 |         ~conditional_vector_node() 
 14296 |          { 
 14297 |             memory_context_.clear(); 
 14298 |          } 
 14299 |  
 14300 |          inline T value() const exprtk_override 
 14301 |          { 
 14302 |             T result = T(0); 
 14303 |             T* source_vector = 0; 
 14304 |             T* result_vector = vds().data(); 
 14305 |  
 14306 |             if (is_true(condition_)) 
 14307 |             { 
 14308 |                result           = consequent_.first->value(); 
 14309 |                source_vector    = consequent_node_ptr_->vds().data(); 
 14310 |                result_vec_size_ = consequent_node_ptr_->size(); 
 14311 |             } 
 14312 |             else 
 14313 |             { 
 14314 |                result           = alternative_.first->value(); 
 14315 |                source_vector    = alternative_node_ptr_->vds().data(); 
 14316 |                result_vec_size_ = alternative_node_ptr_->size(); 
 14317 |             } 
 14318 |  
 14319 |             for (std::size_t i = 0; i < result_vec_size_; ++i) 
 14320 |             { 
 14321 |                result_vector[i] = source_vector[i]; 
 14322 |             } 
 14323 |  
 14324 |             return result; 
 14325 |          } 
 14326 |  
 14327 |          vector_node_ptr vec() const exprtk_override 
 14328 |          { 
 14329 |             return memory_context_.temp_vec_node_; 
 14330 |          } 
 14331 |  
 14332 |          vector_node_ptr vec() exprtk_override 
 14333 |          { 
 14334 |             return memory_context_.temp_vec_node_; 
 14335 |          } 
 14336 |  
 14337 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14338 |          { 
 14339 |             return expression_node<T>::e_vecondition; 
 14340 |          } 
 14341 |  
 14342 |          inline bool valid() const exprtk_override 
 14343 |          { 
 14344 |             return 
 14345 |                initialised_                                      && 
 14346 |                condition_  .first && condition_  .first->valid() && 
 14347 |                consequent_ .first && consequent_ .first->valid() && 
 14348 |                alternative_.first && alternative_.first->valid() && 
 14349 |                size() <= base_size(); 
 14350 |          } 
 14351 |  
 14352 |          std::size_t size() const exprtk_override 
 14353 |          { 
 14354 |             return result_vec_size_; 
 14355 |          } 
 14356 |  
 14357 |          std::size_t base_size() const exprtk_override 
 14358 |          { 
 14359 |             return std::min( 
 14360 |                consequent_node_ptr_ ->vec_holder().base_size(), 
 14361 |                alternative_node_ptr_->vec_holder().base_size()); 
 14362 |          } 
 14363 |  
 14364 |          vds_t& vds() exprtk_override 
 14365 |          { 
 14366 |             return vds_; 
 14367 |          } 
 14368 |  
 14369 |          const vds_t& vds() const exprtk_override 
 14370 |          { 
 14371 |             return vds_; 
 14372 |          } 
 14373 |  
 14374 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14375 |          { 
 14376 |             expression_node<T>::ndb_t::collect(condition_   , node_delete_list); 
 14377 |             expression_node<T>::ndb_t::collect(consequent_  , node_delete_list); 
 14378 |             expression_node<T>::ndb_t::collect(alternative_ , node_delete_list); 
 14379 |          } 
 14380 |  
 14381 |          std::size_t node_depth() const exprtk_override 
 14382 |          { 
 14383 |             return expression_node<T>::ndb_t::compute_node_depth 
 14384 |                (condition_, consequent_, alternative_); 
 14385 |          } 
 14386 |  
 14387 |       private: 
 14388 |  
 14389 |          branch_t            condition_; 
 14390 |          branch_t            consequent_; 
 14391 |          branch_t            alternative_; 
 14392 |          vector_node_ptr     consequent_node_ptr_; 
 14393 |          vector_node_ptr     alternative_node_ptr_; 
 14394 |          vector_node_ptr     temp_vec_node_; 
 14395 |          vector_holder_ptr   temp_; 
 14396 |          vds_t               vds_; 
 14397 |          mutable std::size_t result_vec_size_; 
 14398 |          bool                initialised_; 
 14399 |          memory_context      memory_context_; 
 14400 |       }; 
 14401 |  
 14402 |       template <typename T> 
 14403 |       class scand_node exprtk_final : public binary_node<T> 
 14404 |       { 
 14405 |       public: 
 14406 |  
 14407 |          typedef expression_node<T>* expression_ptr; 
 14408 |          using binary_node<T>::branch; 
 14409 |  
 14410 |          scand_node(const operator_type& opr, 
 14411 |                     expression_ptr branch0, 
 14412 |                     expression_ptr branch1) 
 14413 |          : binary_node<T>(opr, branch0, branch1) 
 14414 |          { 
 14415 |             assert(binary_node<T>::valid()); 
 14416 |          } 
 14417 |  
 14418 |          inline T value() const exprtk_override 
 14419 |          { 
 14420 |             return ( 
 14421 |                      std::not_equal_to<T>() 
 14422 |                         (T(0),branch(0)->value()) && 
 14423 |                      std::not_equal_to<T>() 
 14424 |                         (T(0),branch(1)->value()) 
 14425 |                    ) ? T(1) : T(0); 
 14426 |          } 
 14427 |       }; 
 14428 |  
 14429 |       template <typename T> 
 14430 |       class scor_node exprtk_final : public binary_node<T> 
 14431 |       { 
 14432 |       public: 
 14433 |  
 14434 |          typedef expression_node<T>* expression_ptr; 
 14435 |          using binary_node<T>::branch; 
 14436 |  
 14437 |          scor_node(const operator_type& opr, 
 14438 |                    expression_ptr branch0, 
 14439 |                    expression_ptr branch1) 
 14440 |          : binary_node<T>(opr, branch0, branch1) 
 14441 |          { 
 14442 |             assert(binary_node<T>::valid()); 
 14443 |          } 
 14444 |  
 14445 |          inline T value() const exprtk_override 
 14446 |          { 
 14447 |             return ( 
 14448 |                      std::not_equal_to<T>() 
 14449 |                         (T(0),branch(0)->value()) || 
 14450 |                      std::not_equal_to<T>() 
 14451 |                         (T(0),branch(1)->value()) 
 14452 |                    ) ? T(1) : T(0); 
 14453 |          } 
 14454 |       }; 
 14455 |  
 14456 |       template <typename T, typename IFunction, std::size_t N> 
 14457 |       class function_N_node exprtk_final : public expression_node<T> 
 14458 |       { 
 14459 |       public: 
 14460 |  
 14461 |          // Function of N parameters. 
 14462 |          typedef expression_node<T>* expression_ptr; 
 14463 |          typedef std::pair<expression_ptr,bool> branch_t; 
 14464 |          typedef IFunction ifunction; 
 14465 |  
 14466 |          explicit function_N_node(ifunction* func) 
 14467 |          : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)) 
 14468 |          , parameter_count_(func->param_count) 
 14469 |          , initialised_(false) 
 14470 |          {} 
 14471 |  
 14472 |          template <std::size_t NumBranches> 
 14473 |          bool init_branches(expression_ptr (&b)[NumBranches]) 
 14474 |          { 
 14475 |             // Needed for incompetent and broken msvc compiler versions 
 14476 |             #ifdef _MSC_VER 
 14477 |              #pragma warning(push) 
 14478 |              #pragma warning(disable: 4127) 
 14479 |             #endif 
 14480 |  
 14481 |             if (N != NumBranches) 
 14482 |             { 
 14483 |                return false; 
 14484 |             } 
 14485 |  
 14486 |             for (std::size_t i = 0; i < NumBranches; ++i) 
 14487 |             { 
 14488 |                if (b[i] && b[i]->valid()) 
 14489 |                   branch_[i] = std::make_pair(b[i],branch_deletable(b[i])); 
 14490 |                else 
 14491 |                   return false; 
 14492 |             } 
 14493 |  
 14494 |             initialised_ = function_; 
 14495 |             assert(valid()); 
 14496 |             return initialised_; 
 14497 |  
 14498 |             #ifdef _MSC_VER 
 14499 |              #pragma warning(pop) 
 14500 |             #endif 
 14501 |          } 
 14502 |  
 14503 |          inline bool operator <(const function_N_node<T,IFunction,N>& fn) const 
 14504 |          { 
 14505 |             return this < (&fn); 
 14506 |          } 
 14507 |  
 14508 |          inline T value() const exprtk_override 
 14509 |          { 
 14510 |             // Needed for incompetent and broken msvc compiler versions 
 14511 |             #ifdef _MSC_VER 
 14512 |              #pragma warning(push) 
 14513 |              #pragma warning(disable: 4127) 
 14514 |             #endif 
 14515 |  
 14516 |             T v[N]; 
 14517 |             evaluate_branches<T,N>::execute(v,branch_); 
 14518 |             return invoke<T,N>::execute(*function_,v); 
 14519 |  
 14520 |             #ifdef _MSC_VER 
 14521 |              #pragma warning(pop) 
 14522 |             #endif 
 14523 |          } 
 14524 |  
 14525 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14526 |          { 
 14527 |             return expression_node<T>::e_function; 
 14528 |          } 
 14529 |  
 14530 |          inline bool valid() const exprtk_override 
 14531 |          { 
 14532 |             return initialised_; 
 14533 |          } 
 14534 |  
 14535 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14536 |          { 
 14537 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 14538 |          } 
 14539 |  
 14540 |          std::size_t node_depth() const exprtk_override 
 14541 |          { 
 14542 |             return expression_node<T>::ndb_t::template compute_node_depth<N>(branch_); 
 14543 |          } 
 14544 |  
 14545 |          template <typename T_, std::size_t BranchCount> 
 14546 |          struct evaluate_branches 
 14547 |          { 
 14548 |             static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount]) 
 14549 |             { 
 14550 |                for (std::size_t i = 0; i < BranchCount; ++i) 
 14551 |                { 
 14552 |                   v[i] = b[i].first->value(); 
 14553 |                } 
 14554 |             } 
 14555 |          }; 
 14556 |  
 14557 |          template <typename T_> 
 14558 |          struct evaluate_branches <T_,6> 
 14559 |          { 
 14560 |             static inline void execute(T_ (&v)[6], const branch_t (&b)[6]) 
 14561 |             { 
 14562 |                v[0] = b[0].first->value(); 
 14563 |                v[1] = b[1].first->value(); 
 14564 |                v[2] = b[2].first->value(); 
 14565 |                v[3] = b[3].first->value(); 
 14566 |                v[4] = b[4].first->value(); 
 14567 |                v[5] = b[5].first->value(); 
 14568 |             } 
 14569 |          }; 
 14570 |  
 14571 |          template <typename T_> 
 14572 |          struct evaluate_branches <T_,5> 
 14573 |          { 
 14574 |             static inline void execute(T_ (&v)[5], const branch_t (&b)[5]) 
 14575 |             { 
 14576 |                v[0] = b[0].first->value(); 
 14577 |                v[1] = b[1].first->value(); 
 14578 |                v[2] = b[2].first->value(); 
 14579 |                v[3] = b[3].first->value(); 
 14580 |                v[4] = b[4].first->value(); 
 14581 |             } 
 14582 |          }; 
 14583 |  
 14584 |          template <typename T_> 
 14585 |          struct evaluate_branches <T_,4> 
 14586 |          { 
 14587 |             static inline void execute(T_ (&v)[4], const branch_t (&b)[4]) 
 14588 |             { 
 14589 |                v[0] = b[0].first->value(); 
 14590 |                v[1] = b[1].first->value(); 
 14591 |                v[2] = b[2].first->value(); 
 14592 |                v[3] = b[3].first->value(); 
 14593 |             } 
 14594 |          }; 
 14595 |  
 14596 |          template <typename T_> 
 14597 |          struct evaluate_branches <T_,3> 
 14598 |          { 
 14599 |             static inline void execute(T_ (&v)[3], const branch_t (&b)[3]) 
 14600 |             { 
 14601 |                v[0] = b[0].first->value(); 
 14602 |                v[1] = b[1].first->value(); 
 14603 |                v[2] = b[2].first->value(); 
 14604 |             } 
 14605 |          }; 
 14606 |  
 14607 |          template <typename T_> 
 14608 |          struct evaluate_branches <T_,2> 
 14609 |          { 
 14610 |             static inline void execute(T_ (&v)[2], const branch_t (&b)[2]) 
 14611 |             { 
 14612 |                v[0] = b[0].first->value(); 
 14613 |                v[1] = b[1].first->value(); 
 14614 |             } 
 14615 |          }; 
 14616 |  
 14617 |          template <typename T_> 
 14618 |          struct evaluate_branches <T_,1> 
 14619 |          { 
 14620 |             static inline void execute(T_ (&v)[1], const branch_t (&b)[1]) 
 14621 |             { 
 14622 |                v[0] = b[0].first->value(); 
 14623 |             } 
 14624 |          }; 
 14625 |  
 14626 |          template <typename T_, std::size_t ParamCount> 
 14627 |          struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } }; 
 14628 |  
 14629 |          template <typename T_> 
 14630 |          struct invoke<T_,20> 
 14631 |          { 
 14632 |             static inline T_ execute(ifunction& f, T_ (&v)[20]) 
 14633 |             { 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]); } 
 14634 |          }; 
 14635 |  
 14636 |          template <typename T_> 
 14637 |          struct invoke<T_,19> 
 14638 |          { 
 14639 |             static inline T_ execute(ifunction& f, T_ (&v)[19]) 
 14640 |             { 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]); } 
 14641 |          }; 
 14642 |  
 14643 |          template <typename T_> 
 14644 |          struct invoke<T_,18> 
 14645 |          { 
 14646 |             static inline T_ execute(ifunction& f, T_ (&v)[18]) 
 14647 |             { 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]); } 
 14648 |          }; 
 14649 |  
 14650 |          template <typename T_> 
 14651 |          struct invoke<T_,17> 
 14652 |          { 
 14653 |             static inline T_ execute(ifunction& f, T_ (&v)[17]) 
 14654 |             { 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]); } 
 14655 |          }; 
 14656 |  
 14657 |          template <typename T_> 
 14658 |          struct invoke<T_,16> 
 14659 |          { 
 14660 |             static inline T_ execute(ifunction& f, T_ (&v)[16]) 
 14661 |             { 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]); } 
 14662 |          }; 
 14663 |  
 14664 |          template <typename T_> 
 14665 |          struct invoke<T_,15> 
 14666 |          { 
 14667 |             static inline T_ execute(ifunction& f, T_ (&v)[15]) 
 14668 |             { 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]); } 
 14669 |          }; 
 14670 |  
 14671 |          template <typename T_> 
 14672 |          struct invoke<T_,14> 
 14673 |          { 
 14674 |             static inline T_ execute(ifunction& f, T_ (&v)[14]) 
 14675 |             { 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]); } 
 14676 |          }; 
 14677 |  
 14678 |          template <typename T_> 
 14679 |          struct invoke<T_,13> 
 14680 |          { 
 14681 |             static inline T_ execute(ifunction& f, T_ (&v)[13]) 
 14682 |             { 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]); } 
 14683 |          }; 
 14684 |  
 14685 |          template <typename T_> 
 14686 |          struct invoke<T_,12> 
 14687 |          { 
 14688 |             static inline T_ execute(ifunction& f, T_ (&v)[12]) 
 14689 |             { 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]); } 
 14690 |          }; 
 14691 |  
 14692 |          template <typename T_> 
 14693 |          struct invoke<T_,11> 
 14694 |          { 
 14695 |             static inline T_ execute(ifunction& f, T_ (&v)[11]) 
 14696 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10]); } 
 14697 |          }; 
 14698 |  
 14699 |          template <typename T_> 
 14700 |          struct invoke<T_,10> 
 14701 |          { 
 14702 |             static inline T_ execute(ifunction& f, T_ (&v)[10]) 
 14703 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]); } 
 14704 |          }; 
 14705 |  
 14706 |          template <typename T_> 
 14707 |          struct invoke<T_,9> 
 14708 |          { 
 14709 |             static inline T_ execute(ifunction& f, T_ (&v)[9]) 
 14710 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); } 
 14711 |          }; 
 14712 |  
 14713 |          template <typename T_> 
 14714 |          struct invoke<T_,8> 
 14715 |          { 
 14716 |             static inline T_ execute(ifunction& f, T_ (&v)[8]) 
 14717 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); } 
 14718 |          }; 
 14719 |  
 14720 |          template <typename T_> 
 14721 |          struct invoke<T_,7> 
 14722 |          { 
 14723 |             static inline T_ execute(ifunction& f, T_ (&v)[7]) 
 14724 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5], v[6]); } 
 14725 |          }; 
 14726 |  
 14727 |          template <typename T_> 
 14728 |          struct invoke<T_,6> 
 14729 |          { 
 14730 |             static inline T_ execute(ifunction& f, T_ (&v)[6]) 
 14731 |             { return f(v[0], v[1], v[2], v[3], v[4], v[5]); } 
 14732 |          }; 
 14733 |  
 14734 |          template <typename T_> 
 14735 |          struct invoke<T_,5> 
 14736 |          { 
 14737 |             static inline T_ execute(ifunction& f, T_ (&v)[5]) 
 14738 |             { return f(v[0], v[1], v[2], v[3], v[4]); } 
 14739 |          }; 
 14740 |  
 14741 |          template <typename T_> 
 14742 |          struct invoke<T_,4> 
 14743 |          { 
 14744 |             static inline T_ execute(ifunction& f, T_ (&v)[4]) 
 14745 |             { return f(v[0], v[1], v[2], v[3]); } 
 14746 |          }; 
 14747 |  
 14748 |          template <typename T_> 
 14749 |          struct invoke<T_,3> 
 14750 |          { 
 14751 |             static inline T_ execute(ifunction& f, T_ (&v)[3]) 
 14752 |             { return f(v[0], v[1], v[2]); } 
 14753 |          }; 
 14754 |  
 14755 |          template <typename T_> 
 14756 |          struct invoke<T_,2> 
 14757 |          { 
 14758 |             static inline T_ execute(ifunction& f, T_ (&v)[2]) 
 14759 |             { return f(v[0], v[1]); } 
 14760 |          }; 
 14761 |  
 14762 |          template <typename T_> 
 14763 |          struct invoke<T_,1> 
 14764 |          { 
 14765 |             static inline T_ execute(ifunction& f, T_ (&v)[1]) 
 14766 |             { return f(v[0]); } 
 14767 |          }; 
 14768 |  
 14769 |       private: 
 14770 |  
 14771 |          ifunction*  function_; 
 14772 |          std::size_t parameter_count_; 
 14773 |          branch_t    branch_[N]; 
 14774 |          bool        initialised_; 
 14775 |       }; 
 14776 |  
 14777 |       template <typename T, typename IFunction> 
 14778 |       class function_N_node<T,IFunction,0> exprtk_final : public expression_node<T> 
 14779 |       { 
 14780 |       public: 
 14781 |  
 14782 |          typedef expression_node<T>* expression_ptr; 
 14783 |          typedef IFunction ifunction; 
 14784 |  
 14785 |          explicit function_N_node(ifunction* func) 
 14786 |          : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0)) 
 14787 |          { 
 14788 |             assert(valid()); 
 14789 |          } 
 14790 |  
 14791 |          inline bool operator <(const function_N_node<T,IFunction,0>& fn) const 
 14792 |          { 
 14793 |             return this < (&fn); 
 14794 |          } 
 14795 |  
 14796 |          inline T value() const exprtk_override 
 14797 |          { 
 14798 |             return (*function_)(); 
 14799 |          } 
 14800 |  
 14801 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14802 |          { 
 14803 |             return expression_node<T>::e_function; 
 14804 |          } 
 14805 |  
 14806 |          inline bool valid() const exprtk_override 
 14807 |          { 
 14808 |             return function_; 
 14809 |          } 
 14810 |  
 14811 |       private: 
 14812 |  
 14813 |          ifunction* function_; 
 14814 |       }; 
 14815 |  
 14816 |       template <typename T, typename VarArgFunction> 
 14817 |       class vararg_function_node exprtk_final : public expression_node<T> 
 14818 |       { 
 14819 |       public: 
 14820 |  
 14821 |          typedef expression_node<T>* expression_ptr; 
 14822 |  
 14823 |          vararg_function_node(VarArgFunction*  func, 
 14824 |                               const std::vector<expression_ptr>& arg_list) 
 14825 |          : function_(func) 
 14826 |          , arg_list_(arg_list) 
 14827 |          { 
 14828 |             value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN()); 
 14829 |             assert(valid()); 
 14830 |          } 
 14831 |  
 14832 |          inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const 
 14833 |          { 
 14834 |             return this < (&fn); 
 14835 |          } 
 14836 |  
 14837 |          inline T value() const exprtk_override 
 14838 |          { 
 14839 |             populate_value_list(); 
 14840 |             return (*function_)(value_list_); 
 14841 |          } 
 14842 |  
 14843 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 14844 |          { 
 14845 |             return expression_node<T>::e_vafunction; 
 14846 |          } 
 14847 |  
 14848 |          inline bool valid() const exprtk_override 
 14849 |          { 
 14850 |             return function_; 
 14851 |          } 
 14852 |  
 14853 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14854 |          { 
 14855 |             for (std::size_t i = 0; i < arg_list_.size(); ++i) 
 14856 |             { 
 14857 |                if (arg_list_[i] && !details::is_variable_node(arg_list_[i])) 
 14858 |                { 
 14859 |                   node_delete_list.push_back(&arg_list_[i]); 
 14860 |                } 
 14861 |             } 
 14862 |          } 
 14863 |  
 14864 |          std::size_t node_depth() const exprtk_override 
 14865 |          { 
 14866 |             return expression_node<T>::ndb_t::compute_node_depth(arg_list_); 
 14867 |          } 
 14868 |  
 14869 |       private: 
 14870 |  
 14871 |          inline void populate_value_list() const 
 14872 |          { 
 14873 |             for (std::size_t i = 0; i < arg_list_.size(); ++i) 
 14874 |             { 
 14875 |                value_list_[i] = arg_list_[i]->value(); 
 14876 |             } 
 14877 |          } 
 14878 |  
 14879 |          VarArgFunction* function_; 
 14880 |          std::vector<expression_ptr> arg_list_; 
 14881 |          mutable std::vector<T> value_list_; 
 14882 |       }; 
 14883 |  
 14884 |       template <typename T, typename GenericFunction> 
 14885 |       class generic_function_node : public expression_node<T> 
 14886 |       { 
 14887 |       public: 
 14888 |  
 14889 |          typedef type_store<T>       type_store_t; 
 14890 |          typedef expression_node<T>* expression_ptr; 
 14891 |          typedef variable_node<T>    variable_node_t; 
 14892 |          typedef vector_node<T>      vector_node_t; 
 14893 |          typedef variable_node_t*    variable_node_ptr_t; 
 14894 |          typedef vector_node_t*      vector_node_ptr_t; 
 14895 |          typedef range_interface<T>  range_interface_t; 
 14896 |          typedef range_data_type<T>  range_data_type_t; 
 14897 |          typedef typename range_interface<T>::range_t range_t; 
 14898 |  
 14899 |          typedef std::pair<expression_ptr,bool> branch_t; 
 14900 |          typedef vector_holder<T>* vh_t; 
 14901 |          typedef vector_view<T>*   vecview_t; 
 14902 |  
 14903 |          typedef std::vector<T>                 tmp_vs_t; 
 14904 |          typedef std::vector<type_store_t>      typestore_list_t; 
 14905 |          typedef std::vector<range_data_type_t> range_list_t; 
 14906 |  
 14907 |          explicit generic_function_node(const std::vector<expression_ptr>& arg_list, 
 14908 |                                         GenericFunction* func = reinterpret_cast<GenericFunction*>(0)) 
 14909 |          : function_(func) 
 14910 |          , arg_list_(arg_list) 
 14911 |          {} 
 14912 |  
 14913 |          virtual ~generic_function_node() 
 14914 |          { 
 14915 |             for (std::size_t i = 0; i < vv_list_.size(); ++i) 
 14916 |             { 
 14917 |                vecview_t& vv = vv_list_[i]; 
 14918 |                if (vv && typestore_list_[i].vec_data) 
 14919 |                { 
 14920 |                   vv->remove_ref(&typestore_list_[i].vec_data); 
 14921 |                   typestore_list_[i].vec_data = 0; 
 14922 |                } 
 14923 |             } 
 14924 |          } 
 14925 |  
 14926 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 14927 |          { 
 14928 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 14929 |          } 
 14930 |  
 14931 |          std::size_t node_depth() const exprtk_override exprtk_final 
 14932 |          { 
 14933 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 14934 |          } 
 14935 |  
 14936 |          virtual bool init_branches() 
 14937 |          { 
 14938 |             expr_as_vec1_store_.resize(arg_list_.size(), T(0)               ); 
 14939 |             typestore_list_    .resize(arg_list_.size(), type_store_t()     ); 
 14940 |             range_list_        .resize(arg_list_.size(), range_data_type_t()); 
 14941 |             branch_            .resize(arg_list_.size(), branch_t(reinterpret_cast<expression_ptr>(0),false)); 
 14942 |             vv_list_           .resize(arg_list_.size(), vecview_t(0)); 
 14943 |  
 14944 |             for (std::size_t i = 0; i < arg_list_.size(); ++i) 
 14945 |             { 
 14946 |                type_store_t& ts = typestore_list_[i]; 
 14947 |  
 14948 |                if (0 == arg_list_[i]) 
 14949 |                   return false; 
 14950 |                else if (is_ivector_node(arg_list_[i])) 
 14951 |                { 
 14952 |                   vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); 
 14953 |  
 14954 |                   if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i]))) 
 14955 |                      return false; 
 14956 |  
 14957 |                   ts.size = vi->size(); 
 14958 |                   ts.data = vi->vds().data(); 
 14959 |                   ts.type = type_store_t::e_vector; 
 14960 |  
 14961 |                   if ( 
 14962 |                        vi->vec()->vec_holder().rebaseable() && 
 14963 |                        vi->vec()->vec_holder().rebaseable_instance() 
 14964 |                      ) 
 14965 |                   { 
 14966 |                      vv_list_[i] = vi->vec()->vec_holder().rebaseable_instance(); 
 14967 |                      vv_list_[i]->set_ref(&ts.vec_data); 
 14968 |                   } 
 14969 |                } 
 14970 |                #ifndef exprtk_disable_string_capabilities 
 14971 |                else if (is_generally_string_node(arg_list_[i])) 
 14972 |                { 
 14973 |                   string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0); 
 14974 |  
 14975 |                   if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i]))) 
 14976 |                      return false; 
 14977 |  
 14978 |                   ts.size = sbn->size(); 
 14979 |                   ts.data = reinterpret_cast<void*>(const_cast<char_ptr>(sbn->base())); 
 14980 |                   ts.type = type_store_t::e_string; 
 14981 |  
 14982 |                   range_list_[i].data      = ts.data; 
 14983 |                   range_list_[i].size      = ts.size; 
 14984 |                   range_list_[i].type_size = sizeof(char); 
 14985 |                   range_list_[i].str_node  = sbn; 
 14986 |  
 14987 |                   range_interface_t* ri = reinterpret_cast<range_interface_t*>(0); 
 14988 |  
 14989 |                   if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i]))) 
 14990 |                      return false; 
 14991 |  
 14992 |                   const range_t& rp = ri->range_ref(); 
 14993 |  
 14994 |                   if ( 
 14995 |                        rp.const_range() && 
 14996 |                        is_const_string_range_node(arg_list_[i]) 
 14997 |                      ) 
 14998 |                   { 
 14999 |                      ts.size = rp.const_size(); 
 15000 |                      ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second; 
 15001 |                      range_list_[i].range = reinterpret_cast<range_t*>(0); 
 15002 |                   } 
 15003 |                   else 
 15004 |                   { 
 15005 |                      range_list_[i].range = &(ri->range_ref()); 
 15006 |                      range_param_list_.push_back(i); 
 15007 |                   } 
 15008 |                } 
 15009 |                #endif 
 15010 |                else if (is_variable_node(arg_list_[i])) 
 15011 |                { 
 15012 |                   variable_node_ptr_t var = variable_node_ptr_t(0); 
 15013 |  
 15014 |                   if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i]))) 
 15015 |                      return false; 
 15016 |  
 15017 |                   ts.size = 1; 
 15018 |                   ts.data = &var->ref(); 
 15019 |                   ts.type = type_store_t::e_scalar; 
 15020 |                } 
 15021 |                else 
 15022 |                { 
 15023 |                   ts.size = 1; 
 15024 |                   ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]); 
 15025 |                   ts.type = type_store_t::e_scalar; 
 15026 |                } 
 15027 |  
 15028 |                branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i])); 
 15029 |             } 
 15030 |  
 15031 |             return true; 
 15032 |          } 
 15033 |  
 15034 |          inline bool operator <(const generic_function_node<T,GenericFunction>& fn) const 
 15035 |          { 
 15036 |             return this < (&fn); 
 15037 |          } 
 15038 |  
 15039 |          inline T value() const exprtk_override 
 15040 |          { 
 15041 |             if (populate_value_list()) 
 15042 |             { 
 15043 |                typedef typename GenericFunction::parameter_list_t parameter_list_t; 
 15044 |  
 15045 |                return (*function_)(parameter_list_t(typestore_list_)); 
 15046 |             } 
 15047 |  
 15048 |             return std::numeric_limits<T>::quiet_NaN(); 
 15049 |          } 
 15050 |  
 15051 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15052 |          { 
 15053 |             return expression_node<T>::e_genfunction; 
 15054 |          } 
 15055 |  
 15056 |          inline bool valid() const exprtk_override 
 15057 |          { 
 15058 |             return function_; 
 15059 |          } 
 15060 |  
 15061 |       protected: 
 15062 |  
 15063 |          inline virtual bool populate_value_list() const 
 15064 |          { 
 15065 |             for (std::size_t i = 0; i < branch_.size(); ++i) 
 15066 |             { 
 15067 |                expr_as_vec1_store_[i] = branch_[i].first->value(); 
 15068 |             } 
 15069 |  
 15070 |             if (!range_param_list_.empty()) 
 15071 |             { 
 15072 |                assert(range_param_list_.size() <= branch_.size()); 
 15073 |  
 15074 |                for (std::size_t i = 0; i < range_param_list_.size(); ++i) 
 15075 |                { 
 15076 |                   const std::size_t  index = range_param_list_[i]; 
 15077 |                   range_data_type_t& rdt   = range_list_[index]; 
 15078 |  
 15079 |                   const range_t& rp = (*rdt.range); 
 15080 |                   std::size_t r0    = 0; 
 15081 |                   std::size_t r1    = 0; 
 15082 |  
 15083 |                   const std::size_t data_size = 
 15084 |                   #ifndef exprtk_disable_string_capabilities 
 15085 |                      rdt.str_node ? rdt.str_node->size() : rdt.size; 
 15086 |                   #else 
 15087 |                      rdt.size; 
 15088 |                   #endif 
 15089 |  
 15090 |                   if (!rp(r0, r1, data_size)) 
 15091 |                   { 
 15092 |                      return false; 
 15093 |                   } 
 15094 |  
 15095 |                   type_store_t& ts = typestore_list_[index]; 
 15096 |  
 15097 |                   ts.size = rp.cache_size(); 
 15098 |                   #ifndef exprtk_disable_string_capabilities 
 15099 |                   if (ts.type == type_store_t::e_string) 
 15100 |                      ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first; 
 15101 |                   else 
 15102 |                   #endif 
 15103 |                      ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size); 
 15104 |                } 
 15105 |             } 
 15106 |  
 15107 |             return true; 
 15108 |          } 
 15109 |  
 15110 |          GenericFunction* function_; 
 15111 |          mutable typestore_list_t typestore_list_; 
 15112 |  
 15113 |       private: 
 15114 |  
 15115 |          std::vector<expression_ptr> arg_list_; 
 15116 |          std::vector<branch_t>       branch_; 
 15117 |          std::vector<vecview_t>      vv_list_; 
 15118 |          mutable tmp_vs_t            expr_as_vec1_store_; 
 15119 |          mutable range_list_t        range_list_; 
 15120 |          std::vector<std::size_t>    range_param_list_; 
 15121 |       }; 
 15122 |  
 15123 |       #ifndef exprtk_disable_string_capabilities 
 15124 |       template <typename T, typename StringFunction> 
 15125 |       class string_function_node : public generic_function_node<T,StringFunction> 
 15126 |                                  , public string_base_node<T> 
 15127 |                                  , public range_interface <T> 
 15128 |       { 
 15129 |       public: 
 15130 |  
 15131 |          typedef generic_function_node<T,StringFunction> gen_function_t; 
 15132 |          typedef typename range_interface<T>::range_t range_t; 
 15133 |  
 15134 |          string_function_node(StringFunction* func, 
 15135 |                               const std::vector<typename gen_function_t::expression_ptr>& arg_list) 
 15136 |          : gen_function_t(arg_list,func) 
 15137 |          { 
 15138 |             range_.n0_c = std::make_pair<bool,std::size_t>(true,0); 
 15139 |             range_.n1_c = std::make_pair<bool,std::size_t>(true,0); 
 15140 |             range_.cache.first  = range_.n0_c.second; 
 15141 |             range_.cache.second = range_.n1_c.second; 
 15142 |             assert(valid()); 
 15143 |          } 
 15144 |  
 15145 |          inline bool operator <(const string_function_node<T,StringFunction>& fn) const 
 15146 |          { 
 15147 |             return this < (&fn); 
 15148 |          } 
 15149 |  
 15150 |          inline T value() const exprtk_override 
 15151 |          { 
 15152 |             if (gen_function_t::populate_value_list()) 
 15153 |             { 
 15154 |                typedef typename StringFunction::parameter_list_t parameter_list_t; 
 15155 |  
 15156 |                const T result = 
 15157 |                   (*gen_function_t::function_) 
 15158 |                   ( 
 15159 |                      ret_string_, 
 15160 |                      parameter_list_t(gen_function_t::typestore_list_) 
 15161 |                   ); 
 15162 |  
 15163 |                range_.n1_c.second  = ret_string_.size(); 
 15164 |                range_.cache.second = range_.n1_c.second; 
 15165 |  
 15166 |                return result; 
 15167 |             } 
 15168 |  
 15169 |             return std::numeric_limits<T>::quiet_NaN(); 
 15170 |          } 
 15171 |  
 15172 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15173 |          { 
 15174 |             return expression_node<T>::e_strfunction; 
 15175 |          } 
 15176 |  
 15177 |          inline bool valid() const exprtk_override 
 15178 |          { 
 15179 |             return gen_function_t::function_; 
 15180 |          } 
 15181 |  
 15182 |          std::string str() const exprtk_override 
 15183 |          { 
 15184 |             return ret_string_; 
 15185 |          } 
 15186 |  
 15187 |          char_cptr base() const exprtk_override 
 15188 |          { 
 15189 |            return &ret_string_[0]; 
 15190 |          } 
 15191 |  
 15192 |          std::size_t size() const exprtk_override 
 15193 |          { 
 15194 |             return ret_string_.size(); 
 15195 |          } 
 15196 |  
 15197 |          range_t& range_ref() exprtk_override 
 15198 |          { 
 15199 |             return range_; 
 15200 |          } 
 15201 |  
 15202 |          const range_t& range_ref() const exprtk_override 
 15203 |          { 
 15204 |             return range_; 
 15205 |          } 
 15206 |  
 15207 |       protected: 
 15208 |  
 15209 |          mutable range_t     range_; 
 15210 |          mutable std::string ret_string_; 
 15211 |       }; 
 15212 |       #endif 
 15213 |  
 15214 |       template <typename T, typename GenericFunction> 
 15215 |       class multimode_genfunction_node : public generic_function_node<T,GenericFunction> 
 15216 |       { 
 15217 |       public: 
 15218 |  
 15219 |          typedef generic_function_node<T,GenericFunction> gen_function_t; 
 15220 |          typedef typename gen_function_t::range_t         range_t; 
 15221 |  
 15222 |          multimode_genfunction_node(GenericFunction* func, 
 15223 |                                     const std::size_t& param_seq_index, 
 15224 |                                     const std::vector<typename gen_function_t::expression_ptr>& arg_list) 
 15225 |          : gen_function_t(arg_list,func) 
 15226 |          , param_seq_index_(param_seq_index) 
 15227 |          {} 
 15228 |  
 15229 |          inline T value() const exprtk_override 
 15230 |          { 
 15231 |             assert(gen_function_t::valid()); 
 15232 |  
 15233 |             if (gen_function_t::populate_value_list()) 
 15234 |             { 
 15235 |                typedef typename GenericFunction::parameter_list_t parameter_list_t; 
 15236 |  
 15237 |                return 
 15238 |                   (*gen_function_t::function_) 
 15239 |                   ( 
 15240 |                      param_seq_index_, 
 15241 |                      parameter_list_t(gen_function_t::typestore_list_) 
 15242 |                   ); 
 15243 |             } 
 15244 |  
 15245 |             return std::numeric_limits<T>::quiet_NaN(); 
 15246 |          } 
 15247 |  
 15248 |          inline typename expression_node<T>::node_type type() const exprtk_override exprtk_final 
 15249 |          { 
 15250 |             return expression_node<T>::e_genfunction; 
 15251 |          } 
 15252 |  
 15253 |       private: 
 15254 |  
 15255 |          std::size_t param_seq_index_; 
 15256 |       }; 
 15257 |  
 15258 |       #ifndef exprtk_disable_string_capabilities 
 15259 |       template <typename T, typename StringFunction> 
 15260 |       class multimode_strfunction_node exprtk_final : public string_function_node<T,StringFunction> 
 15261 |       { 
 15262 |       public: 
 15263 |  
 15264 |          typedef string_function_node<T,StringFunction> str_function_t; 
 15265 |          typedef typename str_function_t::range_t range_t; 
 15266 |  
 15267 |          multimode_strfunction_node(StringFunction* func, 
 15268 |                                     const std::size_t& param_seq_index, 
 15269 |                                     const std::vector<typename str_function_t::expression_ptr>& arg_list) 
 15270 |          : str_function_t(func,arg_list) 
 15271 |          , param_seq_index_(param_seq_index) 
 15272 |          {} 
 15273 |  
 15274 |          inline T value() const exprtk_override 
 15275 |          { 
 15276 |             if (str_function_t::populate_value_list()) 
 15277 |             { 
 15278 |                typedef typename StringFunction::parameter_list_t parameter_list_t; 
 15279 |  
 15280 |                const T result = 
 15281 |                   (*str_function_t::function_) 
 15282 |                   ( 
 15283 |                      param_seq_index_, 
 15284 |                      str_function_t::ret_string_, 
 15285 |                      parameter_list_t(str_function_t::typestore_list_) 
 15286 |                   ); 
 15287 |  
 15288 |                str_function_t::range_.n1_c.second  = str_function_t::ret_string_.size(); 
 15289 |                str_function_t::range_.cache.second = str_function_t::range_.n1_c.second; 
 15290 |  
 15291 |                return result; 
 15292 |             } 
 15293 |  
 15294 |             return std::numeric_limits<T>::quiet_NaN(); 
 15295 |          } 
 15296 |  
 15297 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15298 |          { 
 15299 |             return expression_node<T>::e_strfunction; 
 15300 |          } 
 15301 |  
 15302 |       private: 
 15303 |  
 15304 |          const std::size_t param_seq_index_; 
 15305 |       }; 
 15306 |       #endif 
 15307 |  
 15308 |       class return_exception {}; 
 15309 |  
 15310 |       template <typename T> 
 15311 |       class null_igenfunc 
 15312 |       { 
 15313 |       public: 
 15314 |  
 15315 |          virtual ~null_igenfunc() 
 15316 |          {} 
 15317 |  
 15318 |          typedef type_store<T> generic_type; 
 15319 |          typedef typename generic_type::parameter_list parameter_list_t; 
 15320 |  
 15321 |          inline virtual T operator() (parameter_list_t) 
 15322 |          { 
 15323 |             return std::numeric_limits<T>::quiet_NaN(); 
 15324 |          } 
 15325 |       }; 
 15326 |  
 15327 |       #ifndef exprtk_disable_return_statement 
 15328 |       template <typename T> 
 15329 |       class return_node exprtk_final : public generic_function_node<T,null_igenfunc<T> > 
 15330 |       { 
 15331 |       public: 
 15332 |  
 15333 |          typedef results_context<T>   results_context_t; 
 15334 |          typedef null_igenfunc<T>     igeneric_function_t; 
 15335 |          typedef igeneric_function_t* igeneric_function_ptr; 
 15336 |          typedef generic_function_node<T,igeneric_function_t> gen_function_t; 
 15337 |  
 15338 |          return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list, 
 15339 |                      results_context_t& rc) 
 15340 |          : gen_function_t  (arg_list) 
 15341 |          , results_context_(&rc) 
 15342 |          { 
 15343 |             assert(valid()); 
 15344 |          } 
 15345 |  
 15346 |          inline T value() const exprtk_override 
 15347 |          { 
 15348 |             if (gen_function_t::populate_value_list()) 
 15349 |             { 
 15350 |                typedef typename type_store<T>::parameter_list parameter_list_t; 
 15351 |  
 15352 |                results_context_-> 
 15353 |                   assign(parameter_list_t(gen_function_t::typestore_list_)); 
 15354 |  
 15355 |                throw return_exception(); 
 15356 |             } 
 15357 |  
 15358 |             return std::numeric_limits<T>::quiet_NaN(); 
 15359 |          } 
 15360 |  
 15361 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15362 |          { 
 15363 |             return expression_node<T>::e_return; 
 15364 |          } 
 15365 |  
 15366 |          inline bool valid() const exprtk_override 
 15367 |          { 
 15368 |             return results_context_; 
 15369 |          } 
 15370 |  
 15371 |       private: 
 15372 |  
 15373 |          results_context_t* results_context_; 
 15374 |       }; 
 15375 |  
 15376 |       template <typename T> 
 15377 |       class return_envelope_node exprtk_final : public expression_node<T> 
 15378 |       { 
 15379 |       public: 
 15380 |  
 15381 |          typedef expression_node<T>* expression_ptr; 
 15382 |          typedef results_context<T>  results_context_t; 
 15383 |          typedef std::pair<expression_ptr,bool> branch_t; 
 15384 |  
 15385 |          return_envelope_node(expression_ptr body, results_context_t& rc) 
 15386 |          : results_context_(&rc  ) 
 15387 |          , return_invoked_ (false) 
 15388 |          { 
 15389 |             construct_branch_pair(body_, body); 
 15390 |             assert(valid()); 
 15391 |          } 
 15392 |  
 15393 |          inline T value() const exprtk_override 
 15394 |          { 
 15395 |             try 
 15396 |             { 
 15397 |                return_invoked_ = false; 
 15398 |                results_context_->clear(); 
 15399 |  
 15400 |                return body_.first->value(); 
 15401 |             } 
 15402 |             catch(const return_exception&) 
 15403 |             { 
 15404 |                return_invoked_ = true; 
 15405 |  
 15406 |                return std::numeric_limits<T>::quiet_NaN(); 
 15407 |             } 
 15408 |          } 
 15409 |  
 15410 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 15411 |          { 
 15412 |             return expression_node<T>::e_retenv; 
 15413 |          } 
 15414 |  
 15415 |          inline bool valid() const exprtk_override 
 15416 |          { 
 15417 |             return results_context_ && body_.first; 
 15418 |          } 
 15419 |  
 15420 |          inline bool* retinvk_ptr() 
 15421 |          { 
 15422 |             return &return_invoked_; 
 15423 |          } 
 15424 |  
 15425 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 15426 |          { 
 15427 |             expression_node<T>::ndb_t::collect(body_, node_delete_list); 
 15428 |          } 
 15429 |  
 15430 |          std::size_t node_depth() const exprtk_override 
 15431 |          { 
 15432 |             return expression_node<T>::ndb_t::compute_node_depth(body_); 
 15433 |          } 
 15434 |  
 15435 |       private: 
 15436 |  
 15437 |          results_context_t* results_context_; 
 15438 |          mutable bool        return_invoked_; 
 15439 |          branch_t                      body_; 
 15440 |       }; 
 15441 |       #endif 
 15442 |  
 15443 |       #define exprtk_define_unary_op(OpName)                    \ 
 15444 |       template <typename T>                                     \ 
 15445 |       struct OpName##_op                                        \ 
 15446 |       {                                                         \ 
 15447 |          typedef typename functor_t<T>::Type Type;              \ 
 15448 |          typedef typename expression_node<T>::node_type node_t; \ 
 15449 |                                                                 \ 
 15450 |          static inline T process(Type v)                        \ 
 15451 |          {                                                      \ 
 15452 |             return numeric:: OpName (v);                        \ 
 15453 |          }                                                      \ 
 15454 |                                                                 \ 
 15455 |          static inline node_t type()                            \ 
 15456 |          {                                                      \ 
 15457 |             return expression_node<T>::e_##OpName;              \ 
 15458 |          }                                                      \ 
 15459 |                                                                 \ 
 15460 |          static inline details::operator_type operation()       \ 
 15461 |          {                                                      \ 
 15462 |             return details::e_##OpName;                         \ 
 15463 |          }                                                      \ 
 15464 |       };                                                        \ 
 15465 |  
 15466 |       exprtk_define_unary_op(abs  ) 
 15467 |       exprtk_define_unary_op(acos ) 
 15468 |       exprtk_define_unary_op(acosh) 
 15469 |       exprtk_define_unary_op(asin ) 
 15470 |       exprtk_define_unary_op(asinh) 
 15471 |       exprtk_define_unary_op(atan ) 
 15472 |       exprtk_define_unary_op(atanh) 
 15473 |       exprtk_define_unary_op(ceil ) 
 15474 |       exprtk_define_unary_op(cos  ) 
 15475 |       exprtk_define_unary_op(cosh ) 
 15476 |       exprtk_define_unary_op(cot  ) 
 15477 |       exprtk_define_unary_op(csc  ) 
 15478 |       exprtk_define_unary_op(d2g  ) 
 15479 |       exprtk_define_unary_op(d2r  ) 
 15480 |       exprtk_define_unary_op(erf  ) 
 15481 |       exprtk_define_unary_op(erfc ) 
 15482 |       exprtk_define_unary_op(exp  ) 
 15483 |       exprtk_define_unary_op(expm1) 
 15484 |       exprtk_define_unary_op(floor) 
 15485 |       exprtk_define_unary_op(frac ) 
 15486 |       exprtk_define_unary_op(g2d  ) 
 15487 |       exprtk_define_unary_op(log  ) 
 15488 |       exprtk_define_unary_op(log10) 
 15489 |       exprtk_define_unary_op(log2 ) 
 15490 |       exprtk_define_unary_op(log1p) 
 15491 |       exprtk_define_unary_op(ncdf ) 
 15492 |       exprtk_define_unary_op(neg  ) 
 15493 |       exprtk_define_unary_op(notl ) 
 15494 |       exprtk_define_unary_op(pos  ) 
 15495 |       exprtk_define_unary_op(r2d  ) 
 15496 |       exprtk_define_unary_op(round) 
 15497 |       exprtk_define_unary_op(sec  ) 
 15498 |       exprtk_define_unary_op(sgn  ) 
 15499 |       exprtk_define_unary_op(sin  ) 
 15500 |       exprtk_define_unary_op(sinc ) 
 15501 |       exprtk_define_unary_op(sinh ) 
 15502 |       exprtk_define_unary_op(sqrt ) 
 15503 |       exprtk_define_unary_op(tan  ) 
 15504 |       exprtk_define_unary_op(tanh ) 
 15505 |       exprtk_define_unary_op(trunc) 
 15506 |       #undef exprtk_define_unary_op 
 15507 |  
 15508 |       template <typename T> 
 15509 |       struct opr_base 
 15510 |       { 
 15511 |          typedef typename details::functor_t<T>::Type    Type; 
 15512 |          typedef typename details::functor_t<T>::RefType RefType; 
 15513 |          typedef typename details::functor_t<T> functor_t; 
 15514 |          typedef typename functor_t::qfunc_t    quaternary_functor_t; 
 15515 |          typedef typename functor_t::tfunc_t    trinary_functor_t; 
 15516 |          typedef typename functor_t::bfunc_t    binary_functor_t; 
 15517 |          typedef typename functor_t::ufunc_t    unary_functor_t; 
 15518 |       }; 
 15519 |  
 15520 |       template <typename T> 
 15521 |       struct add_op : public opr_base<T> 
 15522 |       { 
 15523 |          typedef typename opr_base<T>::Type    Type; 
 15524 |          typedef typename opr_base<T>::RefType RefType; 
 15525 |  
 15526 |          static inline T process(Type t1, Type t2) { return t1 + t2; } 
 15527 |          static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; } 
 15528 |          static inline void assign(RefType t1, Type t2) { t1 += t2; } 
 15529 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; } 
 15530 |          static inline details::operator_type operation() { return details::e_add; } 
 15531 |       }; 
 15532 |  
 15533 |       template <typename T> 
 15534 |       struct mul_op : public opr_base<T> 
 15535 |       { 
 15536 |          typedef typename opr_base<T>::Type    Type; 
 15537 |          typedef typename opr_base<T>::RefType RefType; 
 15538 |  
 15539 |          static inline T process(Type t1, Type t2) { return t1 * t2; } 
 15540 |          static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; } 
 15541 |          static inline void assign(RefType t1, Type t2) { t1 *= t2; } 
 15542 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; } 
 15543 |          static inline details::operator_type operation() { return details::e_mul; } 
 15544 |       }; 
 15545 |  
 15546 |       template <typename T> 
 15547 |       struct sub_op : public opr_base<T> 
 15548 |       { 
 15549 |          typedef typename opr_base<T>::Type    Type; 
 15550 |          typedef typename opr_base<T>::RefType RefType; 
 15551 |  
 15552 |          static inline T process(Type t1, Type t2) { return t1 - t2; } 
 15553 |          static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; } 
 15554 |          static inline void assign(RefType t1, Type t2) { t1 -= t2; } 
 15555 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; } 
 15556 |          static inline details::operator_type operation() { return details::e_sub; } 
 15557 |       }; 
 15558 |  
 15559 |       template <typename T> 
 15560 |       struct div_op : public opr_base<T> 
 15561 |       { 
 15562 |          typedef typename opr_base<T>::Type    Type; 
 15563 |          typedef typename opr_base<T>::RefType RefType; 
 15564 |  
 15565 |          static inline T process(Type t1, Type t2) { return t1 / t2; } 
 15566 |          static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; } 
 15567 |          static inline void assign(RefType t1, Type t2) { t1 /= t2; } 
 15568 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; } 
 15569 |          static inline details::operator_type operation() { return details::e_div; } 
 15570 |       }; 
 15571 |  
 15572 |       template <typename T> 
 15573 |       struct mod_op : public opr_base<T> 
 15574 |       { 
 15575 |          typedef typename opr_base<T>::Type    Type; 
 15576 |          typedef typename opr_base<T>::RefType RefType; 
 15577 |  
 15578 |          static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); } 
 15579 |          static inline void assign(RefType t1, Type t2) { t1 = numeric::modulus<T>(t1,t2); } 
 15580 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; } 
 15581 |          static inline details::operator_type operation() { return details::e_mod; } 
 15582 |       }; 
 15583 |  
 15584 |       template <typename T> 
 15585 |       struct pow_op : public opr_base<T> 
 15586 |       { 
 15587 |          typedef typename opr_base<T>::Type    Type; 
 15588 |          typedef typename opr_base<T>::RefType RefType; 
 15589 |  
 15590 |          static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); } 
 15591 |          static inline void assign(RefType t1, Type t2) { t1 = numeric::pow<T>(t1,t2); } 
 15592 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; } 
 15593 |          static inline details::operator_type operation() { return details::e_pow; } 
 15594 |       }; 
 15595 |  
 15596 |       template <typename T> 
 15597 |       struct lt_op : public opr_base<T> 
 15598 |       { 
 15599 |          typedef typename opr_base<T>::Type Type; 
 15600 |  
 15601 |          static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); } 
 15602 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); } 
 15603 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; } 
 15604 |          static inline details::operator_type operation() { return details::e_lt; } 
 15605 |       }; 
 15606 |  
 15607 |       template <typename T> 
 15608 |       struct lte_op : public opr_base<T> 
 15609 |       { 
 15610 |          typedef typename opr_base<T>::Type Type; 
 15611 |  
 15612 |          static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); } 
 15613 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); } 
 15614 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; } 
 15615 |          static inline details::operator_type operation() { return details::e_lte; } 
 15616 |       }; 
 15617 |  
 15618 |       template <typename T> 
 15619 |       struct gt_op : public opr_base<T> 
 15620 |       { 
 15621 |          typedef typename opr_base<T>::Type Type; 
 15622 |  
 15623 |          static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); } 
 15624 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); } 
 15625 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; } 
 15626 |          static inline details::operator_type operation() { return details::e_gt; } 
 15627 |       }; 
 15628 |  
 15629 |       template <typename T> 
 15630 |       struct gte_op : public opr_base<T> 
 15631 |       { 
 15632 |          typedef typename opr_base<T>::Type Type; 
 15633 |  
 15634 |          static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); } 
 15635 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); } 
 15636 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; } 
 15637 |          static inline details::operator_type operation() { return details::e_gte; } 
 15638 |       }; 
 15639 |  
 15640 |       template <typename T> 
 15641 |       struct eq_op : public opr_base<T> 
 15642 |       { 
 15643 |          typedef typename opr_base<T>::Type Type; 
 15644 |          static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); } 
 15645 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); } 
 15646 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; } 
 15647 |          static inline details::operator_type operation() { return details::e_eq; } 
 15648 |       }; 
 15649 |  
 15650 |       template <typename T> 
 15651 |       struct equal_op : public opr_base<T> 
 15652 |       { 
 15653 |          typedef typename opr_base<T>::Type Type; 
 15654 |  
 15655 |          static inline T process(Type t1, Type t2) { return numeric::equal(t1,t2); } 
 15656 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); } 
 15657 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; } 
 15658 |          static inline details::operator_type operation() { return details::e_equal; } 
 15659 |       }; 
 15660 |  
 15661 |       template <typename T> 
 15662 |       struct ne_op : public opr_base<T> 
 15663 |       { 
 15664 |          typedef typename opr_base<T>::Type Type; 
 15665 |  
 15666 |          static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); } 
 15667 |          static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); } 
 15668 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; } 
 15669 |          static inline details::operator_type operation() { return details::e_ne; } 
 15670 |       }; 
 15671 |  
 15672 |       template <typename T> 
 15673 |       struct and_op : public opr_base<T> 
 15674 |       { 
 15675 |          typedef typename opr_base<T>::Type Type; 
 15676 |  
 15677 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); } 
 15678 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; } 
 15679 |          static inline details::operator_type operation() { return details::e_and; } 
 15680 |       }; 
 15681 |  
 15682 |       template <typename T> 
 15683 |       struct nand_op : public opr_base<T> 
 15684 |       { 
 15685 |          typedef typename opr_base<T>::Type Type; 
 15686 |  
 15687 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); } 
 15688 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nand; } 
 15689 |          static inline details::operator_type operation() { return details::e_nand; } 
 15690 |       }; 
 15691 |  
 15692 |       template <typename T> 
 15693 |       struct or_op : public opr_base<T> 
 15694 |       { 
 15695 |          typedef typename opr_base<T>::Type Type; 
 15696 |  
 15697 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); } 
 15698 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; } 
 15699 |          static inline details::operator_type operation() { return details::e_or; } 
 15700 |       }; 
 15701 |  
 15702 |       template <typename T> 
 15703 |       struct nor_op : public opr_base<T> 
 15704 |       { 
 15705 |          typedef typename opr_base<T>::Type Type; 
 15706 |  
 15707 |          static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); } 
 15708 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; } 
 15709 |          static inline details::operator_type operation() { return details::e_nor; } 
 15710 |       }; 
 15711 |  
 15712 |       template <typename T> 
 15713 |       struct xor_op : public opr_base<T> 
 15714 |       { 
 15715 |          typedef typename opr_base<T>::Type Type; 
 15716 |  
 15717 |          static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); } 
 15718 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; } 
 15719 |          static inline details::operator_type operation() { return details::e_xor; } 
 15720 |       }; 
 15721 |  
 15722 |       template <typename T> 
 15723 |       struct xnor_op : public opr_base<T> 
 15724 |       { 
 15725 |          typedef typename opr_base<T>::Type Type; 
 15726 |  
 15727 |          static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); } 
 15728 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; } 
 15729 |          static inline details::operator_type operation() { return details::e_xnor; } 
 15730 |       }; 
 15731 |  
 15732 |       template <typename T> 
 15733 |       struct in_op : public opr_base<T> 
 15734 |       { 
 15735 |          typedef typename opr_base<T>::Type Type; 
 15736 |  
 15737 |          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); } 
 15738 |          static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); } 
 15739 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; } 
 15740 |          static inline details::operator_type operation() { return details::e_in; } 
 15741 |       }; 
 15742 |  
 15743 |       template <typename T> 
 15744 |       struct like_op : public opr_base<T> 
 15745 |       { 
 15746 |          typedef typename opr_base<T>::Type Type; 
 15747 |  
 15748 |          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); } 
 15749 |          static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); } 
 15750 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_like; } 
 15751 |          static inline details::operator_type operation() { return details::e_like; } 
 15752 |       }; 
 15753 |  
 15754 |       template <typename T> 
 15755 |       struct ilike_op : public opr_base<T> 
 15756 |       { 
 15757 |          typedef typename opr_base<T>::Type Type; 
 15758 |  
 15759 |          static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); } 
 15760 |          static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); } 
 15761 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ilike; } 
 15762 |          static inline details::operator_type operation() { return details::e_ilike; } 
 15763 |       }; 
 15764 |  
 15765 |       template <typename T> 
 15766 |       struct inrange_op : public opr_base<T> 
 15767 |       { 
 15768 |          typedef typename opr_base<T>::Type Type; 
 15769 |  
 15770 |          static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); } 
 15771 |          static inline T process(const std::string& t0, const std::string& t1, const std::string& t2) 
 15772 |          { 
 15773 |             return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); 
 15774 |          } 
 15775 |          static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_inranges; } 
 15776 |          static inline details::operator_type operation() { return details::e_inrange; } 
 15777 |       }; 
 15778 |  
 15779 |       template <typename T> 
 15780 |       inline T value(details::expression_node<T>* n) 
 15781 |       { 
 15782 |          return n->value(); 
 15783 |       } 
 15784 |  
 15785 |       template <typename T> 
 15786 |       inline T value(std::pair<details::expression_node<T>*,bool> n) 
 15787 |       { 
 15788 |          return n.first->value(); 
 15789 |       } 
 15790 |  
 15791 |       template <typename T> 
 15792 |       inline T value(const T* t) 
 15793 |       { 
 15794 |          return (*t); 
 15795 |       } 
 15796 |  
 15797 |       template <typename T> 
 15798 |       inline T value(const T& t) 
 15799 |       { 
 15800 |          return t; 
 15801 |       } 
 15802 |  
 15803 |       template <typename T> 
 15804 |       struct vararg_add_op exprtk_final : public opr_base<T> 
 15805 |       { 
 15806 |          typedef typename opr_base<T>::Type Type; 
 15807 |  
 15808 |          template <typename Type, 
 15809 |                    typename Allocator, 
 15810 |                    template <typename, typename> class Sequence> 
 15811 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 15812 |          { 
 15813 |             switch (arg_list.size()) 
 15814 |             { 
 15815 |                case 0  : return T(0); 
 15816 |                case 1  : return process_1(arg_list); 
 15817 |                case 2  : return process_2(arg_list); 
 15818 |                case 3  : return process_3(arg_list); 
 15819 |                case 4  : return process_4(arg_list); 
 15820 |                case 5  : return process_5(arg_list); 
 15821 |                default : 
 15822 |                          { 
 15823 |                             T result = T(0); 
 15824 |  
 15825 |                             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 15826 |                             { 
 15827 |                                result += value(arg_list[i]); 
 15828 |                             } 
 15829 |  
 15830 |                             return result; 
 15831 |                          } 
 15832 |             } 
 15833 |          } 
 15834 |  
 15835 |          template <typename Sequence> 
 15836 |          static inline T process_1(const Sequence& arg_list) 
 15837 |          { 
 15838 |             return value(arg_list[0]); 
 15839 |          } 
 15840 |  
 15841 |          template <typename Sequence> 
 15842 |          static inline T process_2(const Sequence& arg_list) 
 15843 |          { 
 15844 |             return value(arg_list[0]) + value(arg_list[1]); 
 15845 |          } 
 15846 |  
 15847 |          template <typename Sequence> 
 15848 |          static inline T process_3(const Sequence& arg_list) 
 15849 |          { 
 15850 |             return value(arg_list[0]) + value(arg_list[1]) + 
 15851 |                    value(arg_list[2]) ; 
 15852 |          } 
 15853 |  
 15854 |          template <typename Sequence> 
 15855 |          static inline T process_4(const Sequence& arg_list) 
 15856 |          { 
 15857 |             return value(arg_list[0]) + value(arg_list[1]) + 
 15858 |                    value(arg_list[2]) + value(arg_list[3]) ; 
 15859 |          } 
 15860 |  
 15861 |          template <typename Sequence> 
 15862 |          static inline T process_5(const Sequence& arg_list) 
 15863 |          { 
 15864 |             return value(arg_list[0]) + value(arg_list[1]) + 
 15865 |                    value(arg_list[2]) + value(arg_list[3]) + 
 15866 |                    value(arg_list[4]) ; 
 15867 |          } 
 15868 |       }; 
 15869 |  
 15870 |       template <typename T> 
 15871 |       struct vararg_mul_op exprtk_final : public opr_base<T> 
 15872 |       { 
 15873 |          typedef typename opr_base<T>::Type Type; 
 15874 |  
 15875 |          template <typename Type, 
 15876 |                    typename Allocator, 
 15877 |                    template <typename, typename> class Sequence> 
 15878 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 15879 |          { 
 15880 |             switch (arg_list.size()) 
 15881 |             { 
 15882 |                case 0  : return T(0); 
 15883 |                case 1  : return process_1(arg_list); 
 15884 |                case 2  : return process_2(arg_list); 
 15885 |                case 3  : return process_3(arg_list); 
 15886 |                case 4  : return process_4(arg_list); 
 15887 |                case 5  : return process_5(arg_list); 
 15888 |                default : 
 15889 |                          { 
 15890 |                             T result = T(value(arg_list[0])); 
 15891 |  
 15892 |                             for (std::size_t i = 1; i < arg_list.size(); ++i) 
 15893 |                             { 
 15894 |                                result *= value(arg_list[i]); 
 15895 |                             } 
 15896 |  
 15897 |                             return result; 
 15898 |                          } 
 15899 |             } 
 15900 |          } 
 15901 |  
 15902 |          template <typename Sequence> 
 15903 |          static inline T process_1(const Sequence& arg_list) 
 15904 |          { 
 15905 |             return value(arg_list[0]); 
 15906 |          } 
 15907 |  
 15908 |          template <typename Sequence> 
 15909 |          static inline T process_2(const Sequence& arg_list) 
 15910 |          { 
 15911 |             return value(arg_list[0]) * value(arg_list[1]); 
 15912 |          } 
 15913 |  
 15914 |          template <typename Sequence> 
 15915 |          static inline T process_3(const Sequence& arg_list) 
 15916 |          { 
 15917 |             return value(arg_list[0]) * value(arg_list[1]) * 
 15918 |                    value(arg_list[2]) ; 
 15919 |          } 
 15920 |  
 15921 |          template <typename Sequence> 
 15922 |          static inline T process_4(const Sequence& arg_list) 
 15923 |          { 
 15924 |             return value(arg_list[0]) * value(arg_list[1]) * 
 15925 |                    value(arg_list[2]) * value(arg_list[3]) ; 
 15926 |          } 
 15927 |  
 15928 |          template <typename Sequence> 
 15929 |          static inline T process_5(const Sequence& arg_list) 
 15930 |          { 
 15931 |             return value(arg_list[0]) * value(arg_list[1]) * 
 15932 |                    value(arg_list[2]) * value(arg_list[3]) * 
 15933 |                    value(arg_list[4]) ; 
 15934 |          } 
 15935 |       }; 
 15936 |  
 15937 |       template <typename T> 
 15938 |       struct vararg_avg_op exprtk_final : public opr_base<T> 
 15939 |       { 
 15940 |          typedef typename opr_base<T>::Type Type; 
 15941 |  
 15942 |          template <typename Type, 
 15943 |                    typename Allocator, 
 15944 |                    template <typename, typename> class Sequence> 
 15945 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 15946 |          { 
 15947 |             switch (arg_list.size()) 
 15948 |             { 
 15949 |                case 0  : return T(0); 
 15950 |                case 1  : return process_1(arg_list); 
 15951 |                case 2  : return process_2(arg_list); 
 15952 |                case 3  : return process_3(arg_list); 
 15953 |                case 4  : return process_4(arg_list); 
 15954 |                case 5  : return process_5(arg_list); 
 15955 |                default : return vararg_add_op<T>::process(arg_list) / T(arg_list.size()); 
 15956 |             } 
 15957 |          } 
 15958 |  
 15959 |          template <typename Sequence> 
 15960 |          static inline T process_1(const Sequence& arg_list) 
 15961 |          { 
 15962 |             return value(arg_list[0]); 
 15963 |          } 
 15964 |  
 15965 |          template <typename Sequence> 
 15966 |          static inline T process_2(const Sequence& arg_list) 
 15967 |          { 
 15968 |             return (value(arg_list[0]) + value(arg_list[1])) / T(2); 
 15969 |          } 
 15970 |  
 15971 |          template <typename Sequence> 
 15972 |          static inline T process_3(const Sequence& arg_list) 
 15973 |          { 
 15974 |             return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3); 
 15975 |          } 
 15976 |  
 15977 |          template <typename Sequence> 
 15978 |          static inline T process_4(const Sequence& arg_list) 
 15979 |          { 
 15980 |             return (value(arg_list[0]) + value(arg_list[1]) + 
 15981 |                     value(arg_list[2]) + value(arg_list[3])) / T(4); 
 15982 |          } 
 15983 |  
 15984 |          template <typename Sequence> 
 15985 |          static inline T process_5(const Sequence& arg_list) 
 15986 |          { 
 15987 |             return (value(arg_list[0]) + value(arg_list[1]) + 
 15988 |                     value(arg_list[2]) + value(arg_list[3]) + 
 15989 |                     value(arg_list[4])) / T(5); 
 15990 |          } 
 15991 |       }; 
 15992 |  
 15993 |       template <typename T> 
 15994 |       struct vararg_min_op exprtk_final : public opr_base<T> 
 15995 |       { 
 15996 |          typedef typename opr_base<T>::Type Type; 
 15997 |  
 15998 |          template <typename Type, 
 15999 |                    typename Allocator, 
 16000 |                    template <typename, typename> class Sequence> 
 16001 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16002 |          { 
 16003 |             switch (arg_list.size()) 
 16004 |             { 
 16005 |                case 0  : return T(0); 
 16006 |                case 1  : return process_1(arg_list); 
 16007 |                case 2  : return process_2(arg_list); 
 16008 |                case 3  : return process_3(arg_list); 
 16009 |                case 4  : return process_4(arg_list); 
 16010 |                case 5  : return process_5(arg_list); 
 16011 |                default : 
 16012 |                          { 
 16013 |                             T result = T(value(arg_list[0])); 
 16014 |  
 16015 |                             for (std::size_t i = 1; i < arg_list.size(); ++i) 
 16016 |                             { 
 16017 |                                const T v = value(arg_list[i]); 
 16018 |  
 16019 |                                if (v < result) 
 16020 |                                   result = v; 
 16021 |                             } 
 16022 |  
 16023 |                             return result; 
 16024 |                          } 
 16025 |             } 
 16026 |          } 
 16027 |  
 16028 |          template <typename Sequence> 
 16029 |          static inline T process_1(const Sequence& arg_list) 
 16030 |          { 
 16031 |             return value(arg_list[0]); 
 16032 |          } 
 16033 |  
 16034 |          template <typename Sequence> 
 16035 |          static inline T process_2(const Sequence& arg_list) 
 16036 |          { 
 16037 |             return std::min<T>(value(arg_list[0]),value(arg_list[1])); 
 16038 |          } 
 16039 |  
 16040 |          template <typename Sequence> 
 16041 |          static inline T process_3(const Sequence& arg_list) 
 16042 |          { 
 16043 |             return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2])); 
 16044 |          } 
 16045 |  
 16046 |          template <typename Sequence> 
 16047 |          static inline T process_4(const Sequence& arg_list) 
 16048 |          { 
 16049 |             return std::min<T>( 
 16050 |                         std::min<T>(value(arg_list[0]), value(arg_list[1])), 
 16051 |                         std::min<T>(value(arg_list[2]), value(arg_list[3]))); 
 16052 |          } 
 16053 |  
 16054 |          template <typename Sequence> 
 16055 |          static inline T process_5(const Sequence& arg_list) 
 16056 |          { 
 16057 |             return std::min<T>( 
 16058 |                    std::min<T>(std::min<T>(value(arg_list[0]), value(arg_list[1])), 
 16059 |                                std::min<T>(value(arg_list[2]), value(arg_list[3]))), 
 16060 |                                value(arg_list[4])); 
 16061 |          } 
 16062 |       }; 
 16063 |  
 16064 |       template <typename T> 
 16065 |       struct vararg_max_op exprtk_final : public opr_base<T> 
 16066 |       { 
 16067 |          typedef typename opr_base<T>::Type Type; 
 16068 |  
 16069 |          template <typename Type, 
 16070 |                    typename Allocator, 
 16071 |                    template <typename, typename> class Sequence> 
 16072 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16073 |          { 
 16074 |             switch (arg_list.size()) 
 16075 |             { 
 16076 |                case 0  : return T(0); 
 16077 |                case 1  : return process_1(arg_list); 
 16078 |                case 2  : return process_2(arg_list); 
 16079 |                case 3  : return process_3(arg_list); 
 16080 |                case 4  : return process_4(arg_list); 
 16081 |                case 5  : return process_5(arg_list); 
 16082 |                default : 
 16083 |                          { 
 16084 |                             T result = T(value(arg_list[0])); 
 16085 |  
 16086 |                             for (std::size_t i = 1; i < arg_list.size(); ++i) 
 16087 |                             { 
 16088 |                                const T v = value(arg_list[i]); 
 16089 |  
 16090 |                                if (v > result) 
 16091 |                                   result = v; 
 16092 |                             } 
 16093 |  
 16094 |                             return result; 
 16095 |                          } 
 16096 |             } 
 16097 |          } 
 16098 |  
 16099 |          template <typename Sequence> 
 16100 |          static inline T process_1(const Sequence& arg_list) 
 16101 |          { 
 16102 |             return value(arg_list[0]); 
 16103 |          } 
 16104 |  
 16105 |          template <typename Sequence> 
 16106 |          static inline T process_2(const Sequence& arg_list) 
 16107 |          { 
 16108 |             return std::max<T>(value(arg_list[0]),value(arg_list[1])); 
 16109 |          } 
 16110 |  
 16111 |          template <typename Sequence> 
 16112 |          static inline T process_3(const Sequence& arg_list) 
 16113 |          { 
 16114 |             return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2])); 
 16115 |          } 
 16116 |  
 16117 |          template <typename Sequence> 
 16118 |          static inline T process_4(const Sequence& arg_list) 
 16119 |          { 
 16120 |             return std::max<T>( 
 16121 |                         std::max<T>(value(arg_list[0]), value(arg_list[1])), 
 16122 |                         std::max<T>(value(arg_list[2]), value(arg_list[3]))); 
 16123 |          } 
 16124 |  
 16125 |          template <typename Sequence> 
 16126 |          static inline T process_5(const Sequence& arg_list) 
 16127 |          { 
 16128 |             return std::max<T>( 
 16129 |                    std::max<T>(std::max<T>(value(arg_list[0]), value(arg_list[1])), 
 16130 |                                std::max<T>(value(arg_list[2]), value(arg_list[3]))), 
 16131 |                                value(arg_list[4])); 
 16132 |          } 
 16133 |       }; 
 16134 |  
 16135 |       template <typename T> 
 16136 |       struct vararg_mand_op exprtk_final : public opr_base<T> 
 16137 |       { 
 16138 |          typedef typename opr_base<T>::Type Type; 
 16139 |  
 16140 |          template <typename Type, 
 16141 |                    typename Allocator, 
 16142 |                    template <typename, typename> class Sequence> 
 16143 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16144 |          { 
 16145 |             switch (arg_list.size()) 
 16146 |             { 
 16147 |                case 1  : return process_1(arg_list); 
 16148 |                case 2  : return process_2(arg_list); 
 16149 |                case 3  : return process_3(arg_list); 
 16150 |                case 4  : return process_4(arg_list); 
 16151 |                case 5  : return process_5(arg_list); 
 16152 |                default : 
 16153 |                          { 
 16154 |                             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 16155 |                             { 
 16156 |                                if (std::equal_to<T>()(T(0), value(arg_list[i]))) 
 16157 |                                   return T(0); 
 16158 |                             } 
 16159 |  
 16160 |                             return T(1); 
 16161 |                          } 
 16162 |             } 
 16163 |          } 
 16164 |  
 16165 |          template <typename Sequence> 
 16166 |          static inline T process_1(const Sequence& arg_list) 
 16167 |          { 
 16168 |             return std::not_equal_to<T>() 
 16169 |                       (T(0), value(arg_list[0])) ? T(1) : T(0); 
 16170 |          } 
 16171 |  
 16172 |          template <typename Sequence> 
 16173 |          static inline T process_2(const Sequence& arg_list) 
 16174 |          { 
 16175 |             return ( 
 16176 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16177 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) 
 16178 |                    ) ? T(1) : T(0); 
 16179 |          } 
 16180 |  
 16181 |          template <typename Sequence> 
 16182 |          static inline T process_3(const Sequence& arg_list) 
 16183 |          { 
 16184 |             return ( 
 16185 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16186 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) && 
 16187 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) 
 16188 |                    ) ? T(1) : T(0); 
 16189 |          } 
 16190 |  
 16191 |          template <typename Sequence> 
 16192 |          static inline T process_4(const Sequence& arg_list) 
 16193 |          { 
 16194 |             return ( 
 16195 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16196 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) && 
 16197 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) && 
 16198 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) 
 16199 |                    ) ? T(1) : T(0); 
 16200 |          } 
 16201 |  
 16202 |          template <typename Sequence> 
 16203 |          static inline T process_5(const Sequence& arg_list) 
 16204 |          { 
 16205 |             return ( 
 16206 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) && 
 16207 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) && 
 16208 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) && 
 16209 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) && 
 16210 |                      std::not_equal_to<T>()(T(0), value(arg_list[4])) 
 16211 |                    ) ? T(1) : T(0); 
 16212 |          } 
 16213 |       }; 
 16214 |  
 16215 |       template <typename T> 
 16216 |       struct vararg_mor_op exprtk_final : public opr_base<T> 
 16217 |       { 
 16218 |          typedef typename opr_base<T>::Type Type; 
 16219 |  
 16220 |          template <typename Type, 
 16221 |                    typename Allocator, 
 16222 |                    template <typename, typename> class Sequence> 
 16223 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16224 |          { 
 16225 |             switch (arg_list.size()) 
 16226 |             { 
 16227 |                case 1  : return process_1(arg_list); 
 16228 |                case 2  : return process_2(arg_list); 
 16229 |                case 3  : return process_3(arg_list); 
 16230 |                case 4  : return process_4(arg_list); 
 16231 |                case 5  : return process_5(arg_list); 
 16232 |                default : 
 16233 |                          { 
 16234 |                             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 16235 |                             { 
 16236 |                                if (std::not_equal_to<T>()(T(0), value(arg_list[i]))) 
 16237 |                                   return T(1); 
 16238 |                             } 
 16239 |  
 16240 |                             return T(0); 
 16241 |                          } 
 16242 |             } 
 16243 |          } 
 16244 |  
 16245 |          template <typename Sequence> 
 16246 |          static inline T process_1(const Sequence& arg_list) 
 16247 |          { 
 16248 |             return std::not_equal_to<T>() 
 16249 |                       (T(0), value(arg_list[0])) ? T(1) : T(0); 
 16250 |          } 
 16251 |  
 16252 |          template <typename Sequence> 
 16253 |          static inline T process_2(const Sequence& arg_list) 
 16254 |          { 
 16255 |             return ( 
 16256 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16257 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) 
 16258 |                    ) ? T(1) : T(0); 
 16259 |          } 
 16260 |  
 16261 |          template <typename Sequence> 
 16262 |          static inline T process_3(const Sequence& arg_list) 
 16263 |          { 
 16264 |             return ( 
 16265 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16266 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) || 
 16267 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) 
 16268 |                    ) ? T(1) : T(0); 
 16269 |          } 
 16270 |  
 16271 |          template <typename Sequence> 
 16272 |          static inline T process_4(const Sequence& arg_list) 
 16273 |          { 
 16274 |             return ( 
 16275 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16276 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) || 
 16277 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) || 
 16278 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) 
 16279 |                    ) ? T(1) : T(0); 
 16280 |          } 
 16281 |  
 16282 |          template <typename Sequence> 
 16283 |          static inline T process_5(const Sequence& arg_list) 
 16284 |          { 
 16285 |             return ( 
 16286 |                      std::not_equal_to<T>()(T(0), value(arg_list[0])) || 
 16287 |                      std::not_equal_to<T>()(T(0), value(arg_list[1])) || 
 16288 |                      std::not_equal_to<T>()(T(0), value(arg_list[2])) || 
 16289 |                      std::not_equal_to<T>()(T(0), value(arg_list[3])) || 
 16290 |                      std::not_equal_to<T>()(T(0), value(arg_list[4])) 
 16291 |                    ) ? T(1) : T(0); 
 16292 |          } 
 16293 |       }; 
 16294 |  
 16295 |       template <typename T> 
 16296 |       struct vararg_multi_op exprtk_final : public opr_base<T> 
 16297 |       { 
 16298 |          typedef typename opr_base<T>::Type Type; 
 16299 |  
 16300 |          template <typename Type, 
 16301 |                    typename Allocator, 
 16302 |                    template <typename, typename> class Sequence> 
 16303 |          static inline T process(const Sequence<Type,Allocator>& arg_list) 
 16304 |          { 
 16305 |             switch (arg_list.size()) 
 16306 |             { 
 16307 |                case 0  : return std::numeric_limits<T>::quiet_NaN(); 
 16308 |                case 1  : return process_1(arg_list); 
 16309 |                case 2  : return process_2(arg_list); 
 16310 |                case 3  : return process_3(arg_list); 
 16311 |                case 4  : return process_4(arg_list); 
 16312 |                case 5  : return process_5(arg_list); 
 16313 |                case 6  : return process_6(arg_list); 
 16314 |                case 7  : return process_7(arg_list); 
 16315 |                case 8  : return process_8(arg_list); 
 16316 |                default : 
 16317 |                         { 
 16318 |                            for (std::size_t i = 0; i < (arg_list.size() - 1); ++i) 
 16319 |                            { 
 16320 |                               value(arg_list[i]); 
 16321 |                            } 
 16322 |                            return value(arg_list.back()); 
 16323 |                         } 
 16324 |             } 
 16325 |          } 
 16326 |  
 16327 |          template <typename Sequence> 
 16328 |          static inline T process_1(const Sequence& arg_list) 
 16329 |          { 
 16330 |             return value(arg_list[0]); 
 16331 |          } 
 16332 |  
 16333 |          template <typename Sequence> 
 16334 |          static inline T process_2(const Sequence& arg_list) 
 16335 |          { 
 16336 |                    value(arg_list[0]); 
 16337 |             return value(arg_list[1]); 
 16338 |          } 
 16339 |  
 16340 |          template <typename Sequence> 
 16341 |          static inline T process_3(const Sequence& arg_list) 
 16342 |          { 
 16343 |                    value(arg_list[0]); 
 16344 |                    value(arg_list[1]); 
 16345 |             return value(arg_list[2]); 
 16346 |          } 
 16347 |  
 16348 |          template <typename Sequence> 
 16349 |          static inline T process_4(const Sequence& arg_list) 
 16350 |          { 
 16351 |                    value(arg_list[0]); 
 16352 |                    value(arg_list[1]); 
 16353 |                    value(arg_list[2]); 
 16354 |             return value(arg_list[3]); 
 16355 |          } 
 16356 |  
 16357 |          template <typename Sequence> 
 16358 |          static inline T process_5(const Sequence& arg_list) 
 16359 |          { 
 16360 |                    value(arg_list[0]); 
 16361 |                    value(arg_list[1]); 
 16362 |                    value(arg_list[2]); 
 16363 |                    value(arg_list[3]); 
 16364 |             return value(arg_list[4]); 
 16365 |          } 
 16366 |  
 16367 |          template <typename Sequence> 
 16368 |          static inline T process_6(const Sequence& arg_list) 
 16369 |          { 
 16370 |                    value(arg_list[0]); 
 16371 |                    value(arg_list[1]); 
 16372 |                    value(arg_list[2]); 
 16373 |                    value(arg_list[3]); 
 16374 |                    value(arg_list[4]); 
 16375 |             return value(arg_list[5]); 
 16376 |          } 
 16377 |  
 16378 |          template <typename Sequence> 
 16379 |          static inline T process_7(const Sequence& arg_list) 
 16380 |          { 
 16381 |                    value(arg_list[0]); 
 16382 |                    value(arg_list[1]); 
 16383 |                    value(arg_list[2]); 
 16384 |                    value(arg_list[3]); 
 16385 |                    value(arg_list[4]); 
 16386 |                    value(arg_list[5]); 
 16387 |             return value(arg_list[6]); 
 16388 |          } 
 16389 |  
 16390 |          template <typename Sequence> 
 16391 |          static inline T process_8(const Sequence& arg_list) 
 16392 |          { 
 16393 |                    value(arg_list[0]); 
 16394 |                    value(arg_list[1]); 
 16395 |                    value(arg_list[2]); 
 16396 |                    value(arg_list[3]); 
 16397 |                    value(arg_list[4]); 
 16398 |                    value(arg_list[5]); 
 16399 |                    value(arg_list[6]); 
 16400 |             return value(arg_list[7]); 
 16401 |          } 
 16402 |       }; 
 16403 |  
 16404 |       template <typename T> 
 16405 |       struct vec_add_op 
 16406 |       { 
 16407 |          typedef vector_interface<T>* ivector_ptr; 
 16408 |  
 16409 |          static inline T process(const ivector_ptr v) 
 16410 |          { 
 16411 |             const T* vec = v->vec()->vds().data(); 
 16412 |             const std::size_t vec_size = v->size(); 
 16413 |  
 16414 |             loop_unroll::details lud(vec_size); 
 16415 |  
 16416 |             if (vec_size <= static_cast<std::size_t>(lud.batch_size)) 
 16417 |             { 
 16418 |                T result = T(0); 
 16419 |                int i    = 0; 
 16420 |  
 16421 |                switch (vec_size) 
 16422 |                { 
 16423 |                   #define case_stmt(N,fall_through) \ 
 16424 |                   case N : result += vec[i++];      \ 
 16425 |                   fall_through                      \ 
 16426 |  
 16427 |                   #ifndef exprtk_disable_superscalar_unroll 
 16428 |                   case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough) 
 16429 |                   case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough) 
 16430 |                   case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough) 
 16431 |                   case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough) 
 16432 |                   case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough) 
 16433 |                   case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough) 
 16434 |  
 16435 |                   #endif 
 16436 |                   case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough) 
 16437 |                   case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;) 
 16438 |                } 
 16439 |  
 16440 |                #undef case_stmt 
 16441 |  
 16442 |                return result; 
 16443 |             } 
 16444 |  
 16445 |             T r[] = { 
 16446 |                       T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0), 
 16447 |                       T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0) 
 16448 |                     }; 
 16449 |  
 16450 |             const T* upper_bound = vec + lud.upper_bound; 
 16451 |  
 16452 |             while (vec < upper_bound) 
 16453 |             { 
 16454 |                #define exprtk_loop(N) \ 
 16455 |                r[N] += vec[N];        \ 
 16456 |  
 16457 |                exprtk_loop( 0) exprtk_loop( 1) 
 16458 |                exprtk_loop( 2) exprtk_loop( 3) 
 16459 |                #ifndef exprtk_disable_superscalar_unroll 
 16460 |                exprtk_loop( 4) exprtk_loop( 5) 
 16461 |                exprtk_loop( 6) exprtk_loop( 7) 
 16462 |                exprtk_loop( 8) exprtk_loop( 9) 
 16463 |                exprtk_loop(10) exprtk_loop(11) 
 16464 |                exprtk_loop(12) exprtk_loop(13) 
 16465 |                exprtk_loop(14) exprtk_loop(15) 
 16466 |                #endif 
 16467 |  
 16468 |                vec += lud.batch_size; 
 16469 |             } 
 16470 |  
 16471 |             int i = 0; 
 16472 |  
 16473 |             switch (lud.remainder) 
 16474 |             { 
 16475 |                #define case_stmt(N,fall_through) \ 
 16476 |                case N : r[0] += vec[i++];        \ 
 16477 |                fall_through                      \ 
 16478 |  
 16479 |                #ifndef exprtk_disable_superscalar_unroll 
 16480 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 16481 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 16482 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 16483 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 16484 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 16485 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 16486 |                #endif 
 16487 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 16488 |                case_stmt( 1, (void)0;) 
 16489 |             } 
 16490 |  
 16491 |             #undef exprtk_loop 
 16492 |             #undef case_stmt 
 16493 |  
 16494 |             return (r[ 0] + r[ 1] + r[ 2] + r[ 3]) 
 16495 |                    #ifndef exprtk_disable_superscalar_unroll 
 16496 |                  + (r[ 4] + r[ 5] + r[ 6] + r[ 7]) 
 16497 |                  + (r[ 8] + r[ 9] + r[10] + r[11]) 
 16498 |                  + (r[12] + r[13] + r[14] + r[15]) 
 16499 |                    #endif 
 16500 |                    ; 
 16501 |          } 
 16502 |       }; 
 16503 |  
 16504 |       template <typename T> 
 16505 |       struct vec_mul_op 
 16506 |       { 
 16507 |          typedef vector_interface<T>* ivector_ptr; 
 16508 |  
 16509 |          static inline T process(const ivector_ptr v) 
 16510 |          { 
 16511 |             const T* vec = v->vec()->vds().data(); 
 16512 |             const std::size_t vec_size = v->vec()->size(); 
 16513 |  
 16514 |             loop_unroll::details lud(vec_size); 
 16515 |  
 16516 |             if (vec_size <= static_cast<std::size_t>(lud.batch_size)) 
 16517 |             { 
 16518 |                T result = T(1); 
 16519 |                int i    = 0; 
 16520 |  
 16521 |                switch (vec_size) 
 16522 |                { 
 16523 |                   #define case_stmt(N,fall_through) \ 
 16524 |                   case N : result *= vec[i++];      \ 
 16525 |                   fall_through                      \ 
 16526 |  
 16527 |                   #ifndef exprtk_disable_superscalar_unroll 
 16528 |                   case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough) 
 16529 |                   case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough) 
 16530 |                   case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough) 
 16531 |                   case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough) 
 16532 |                   case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough) 
 16533 |                   case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough) 
 16534 |                   #endif 
 16535 |                   case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough) 
 16536 |                   case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;) 
 16537 |                } 
 16538 |  
 16539 |                #undef case_stmt 
 16540 |  
 16541 |                return result; 
 16542 |             } 
 16543 |  
 16544 |             T r[] = { 
 16545 |                       T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1), 
 16546 |                       T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1) 
 16547 |                     }; 
 16548 |  
 16549 |             const T* upper_bound = vec + lud.upper_bound; 
 16550 |  
 16551 |             while (vec < upper_bound) 
 16552 |             { 
 16553 |                #define exprtk_loop(N) \ 
 16554 |                r[N] *= vec[N];        \ 
 16555 |  
 16556 |                exprtk_loop( 0) exprtk_loop( 1) 
 16557 |                exprtk_loop( 2) exprtk_loop( 3) 
 16558 |                #ifndef exprtk_disable_superscalar_unroll 
 16559 |                exprtk_loop( 4) exprtk_loop( 5) 
 16560 |                exprtk_loop( 6) exprtk_loop( 7) 
 16561 |                exprtk_loop( 8) exprtk_loop( 9) 
 16562 |                exprtk_loop(10) exprtk_loop(11) 
 16563 |                exprtk_loop(12) exprtk_loop(13) 
 16564 |                exprtk_loop(14) exprtk_loop(15) 
 16565 |                #endif 
 16566 |  
 16567 |                vec += lud.batch_size; 
 16568 |             } 
 16569 |  
 16570 |             int i = 0; 
 16571 |  
 16572 |             switch (lud.remainder) 
 16573 |             { 
 16574 |                #define case_stmt(N,fall_through) \ 
 16575 |                case N : r[0] *= vec[i++];        \ 
 16576 |                fall_through                      \ 
 16577 |  
 16578 |                #ifndef exprtk_disable_superscalar_unroll 
 16579 |                case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) 
 16580 |                case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) 
 16581 |                case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) 
 16582 |                case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) 
 16583 |                case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) 
 16584 |                case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) 
 16585 |                #endif 
 16586 |                case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) 
 16587 |                case_stmt( 1, (void)0;) 
 16588 |             } 
 16589 |  
 16590 |             #undef exprtk_loop 
 16591 |             #undef case_stmt 
 16592 |  
 16593 |             return (r[ 0] * r[ 1] * r[ 2] * r[ 3]) 
 16594 |                    #ifndef exprtk_disable_superscalar_unroll 
 16595 |                  * (r[ 4] * r[ 5] * r[ 6] * r[ 7]) 
 16596 |                  * (r[ 8] * r[ 9] * r[10] * r[11]) 
 16597 |                  * (r[12] * r[13] * r[14] * r[15]) 
 16598 |                    #endif 
 16599 |                    ; 
 16600 |          } 
 16601 |       }; 
 16602 |  
 16603 |       template <typename T> 
 16604 |       struct vec_avg_op 
 16605 |       { 
 16606 |          typedef vector_interface<T>* ivector_ptr; 
 16607 |  
 16608 |          static inline T process(const ivector_ptr v) 
 16609 |          { 
 16610 |             const T vec_size = T(v->vec()->size()); 
 16611 |             return vec_add_op<T>::process(v) / vec_size; 
 16612 |          } 
 16613 |       }; 
 16614 |  
 16615 |       template <typename T> 
 16616 |       struct vec_min_op 
 16617 |       { 
 16618 |          typedef vector_interface<T>* ivector_ptr; 
 16619 |  
 16620 |          static inline T process(const ivector_ptr v) 
 16621 |          { 
 16622 |             const T* vec = v->vec()->vds().data(); 
 16623 |             const std::size_t vec_size = v->vec()->size(); 
 16624 |  
 16625 |             T result = vec[0]; 
 16626 |  
 16627 |             for (std::size_t i = 1; i < vec_size; ++i) 
 16628 |             { 
 16629 |                const T v_i = vec[i]; 
 16630 |  
 16631 |                if (v_i < result) 
 16632 |                   result = v_i; 
 16633 |             } 
 16634 |  
 16635 |             return result; 
 16636 |          } 
 16637 |       }; 
 16638 |  
 16639 |       template <typename T> 
 16640 |       struct vec_max_op 
 16641 |       { 
 16642 |          typedef vector_interface<T>* ivector_ptr; 
 16643 |  
 16644 |          static inline T process(const ivector_ptr v) 
 16645 |          { 
 16646 |             const T* vec = v->vec()->vds().data(); 
 16647 |             const std::size_t vec_size = v->vec()->size(); 
 16648 |  
 16649 |             T result = vec[0]; 
 16650 |  
 16651 |             for (std::size_t i = 1; i < vec_size; ++i) 
 16652 |             { 
 16653 |                const T v_i = vec[i]; 
 16654 |  
 16655 |                if (v_i > result) 
 16656 |                   result = v_i; 
 16657 |             } 
 16658 |  
 16659 |             return result; 
 16660 |          } 
 16661 |       }; 
 16662 |  
 16663 |       template <typename T> 
 16664 |       class vov_base_node : public expression_node<T> 
 16665 |       { 
 16666 |       public: 
 16667 |  
 16668 |          virtual ~vov_base_node() 
 16669 |          {} 
 16670 |  
 16671 |          inline virtual operator_type operation() const 
 16672 |          { 
 16673 |             return details::e_default; 
 16674 |          } 
 16675 |  
 16676 |          virtual const T& v0() const = 0; 
 16677 |  
 16678 |          virtual const T& v1() const = 0; 
 16679 |       }; 
 16680 |  
 16681 |       template <typename T> 
 16682 |       class cov_base_node : public expression_node<T> 
 16683 |       { 
 16684 |       public: 
 16685 |  
 16686 |          virtual ~cov_base_node() 
 16687 |          {} 
 16688 |  
 16689 |          inline virtual operator_type operation() const 
 16690 |          { 
 16691 |             return details::e_default; 
 16692 |          } 
 16693 |  
 16694 |          virtual const T c() const = 0; 
 16695 |  
 16696 |          virtual const T& v() const = 0; 
 16697 |       }; 
 16698 |  
 16699 |       template <typename T> 
 16700 |       class voc_base_node : public expression_node<T> 
 16701 |       { 
 16702 |       public: 
 16703 |  
 16704 |          virtual ~voc_base_node() 
 16705 |          {} 
 16706 |  
 16707 |          inline virtual operator_type operation() const 
 16708 |          { 
 16709 |             return details::e_default; 
 16710 |          } 
 16711 |  
 16712 |          virtual const T c() const = 0; 
 16713 |  
 16714 |          virtual const T& v() const = 0; 
 16715 |       }; 
 16716 |  
 16717 |       template <typename T> 
 16718 |       class vob_base_node : public expression_node<T> 
 16719 |       { 
 16720 |       public: 
 16721 |  
 16722 |          virtual ~vob_base_node() 
 16723 |          {} 
 16724 |  
 16725 |          virtual const T& v() const = 0; 
 16726 |       }; 
 16727 |  
 16728 |       template <typename T> 
 16729 |       class bov_base_node : public expression_node<T> 
 16730 |       { 
 16731 |       public: 
 16732 |  
 16733 |          virtual ~bov_base_node() 
 16734 |          {} 
 16735 |  
 16736 |          virtual const T& v() const = 0; 
 16737 |       }; 
 16738 |  
 16739 |       template <typename T> 
 16740 |       class cob_base_node : public expression_node<T> 
 16741 |       { 
 16742 |       public: 
 16743 |  
 16744 |          virtual ~cob_base_node() 
 16745 |          {} 
 16746 |  
 16747 |          inline virtual operator_type operation() const 
 16748 |          { 
 16749 |             return details::e_default; 
 16750 |          } 
 16751 |  
 16752 |          virtual const T c() const = 0; 
 16753 |  
 16754 |          virtual void set_c(const T) = 0; 
 16755 |  
 16756 |          virtual expression_node<T>* move_branch(const std::size_t& index) = 0; 
 16757 |       }; 
 16758 |  
 16759 |       template <typename T> 
 16760 |       class boc_base_node : public expression_node<T> 
 16761 |       { 
 16762 |       public: 
 16763 |  
 16764 |          virtual ~boc_base_node() 
 16765 |          {} 
 16766 |  
 16767 |          inline virtual operator_type operation() const 
 16768 |          { 
 16769 |             return details::e_default; 
 16770 |          } 
 16771 |  
 16772 |          virtual const T c() const = 0; 
 16773 |  
 16774 |          virtual void set_c(const T) = 0; 
 16775 |  
 16776 |          virtual expression_node<T>* move_branch(const std::size_t& index) = 0; 
 16777 |       }; 
 16778 |  
 16779 |       template <typename T> 
 16780 |       class uv_base_node : public expression_node<T> 
 16781 |       { 
 16782 |       public: 
 16783 |  
 16784 |          virtual ~uv_base_node() 
 16785 |          {} 
 16786 |  
 16787 |          inline virtual operator_type operation() const 
 16788 |          { 
 16789 |             return details::e_default; 
 16790 |          } 
 16791 |  
 16792 |          virtual const T& v() const = 0; 
 16793 |       }; 
 16794 |  
 16795 |       template <typename T> 
 16796 |       class sos_base_node : public expression_node<T> 
 16797 |       { 
 16798 |       public: 
 16799 |  
 16800 |          virtual ~sos_base_node() 
 16801 |          {} 
 16802 |  
 16803 |          inline virtual operator_type operation() const 
 16804 |          { 
 16805 |             return details::e_default; 
 16806 |          } 
 16807 |       }; 
 16808 |  
 16809 |       template <typename T> 
 16810 |       class sosos_base_node : public expression_node<T> 
 16811 |       { 
 16812 |       public: 
 16813 |  
 16814 |          virtual ~sosos_base_node() 
 16815 |          {} 
 16816 |  
 16817 |          inline virtual operator_type operation() const 
 16818 |          { 
 16819 |             return details::e_default; 
 16820 |          } 
 16821 |       }; 
 16822 |  
 16823 |       template <typename T> 
 16824 |       class T0oT1oT2_base_node : public expression_node<T> 
 16825 |       { 
 16826 |       public: 
 16827 |  
 16828 |          virtual ~T0oT1oT2_base_node() 
 16829 |          {} 
 16830 |  
 16831 |          virtual std::string type_id() const = 0; 
 16832 |       }; 
 16833 |  
 16834 |       template <typename T> 
 16835 |       class T0oT1oT2oT3_base_node : public expression_node<T> 
 16836 |       { 
 16837 |       public: 
 16838 |  
 16839 |          virtual ~T0oT1oT2oT3_base_node() 
 16840 |          {} 
 16841 |  
 16842 |          virtual std::string type_id() const = 0; 
 16843 |       }; 
 16844 |  
 16845 |       template <typename T, typename Operation> 
 16846 |       class unary_variable_node exprtk_final : public uv_base_node<T> 
 16847 |       { 
 16848 |       public: 
 16849 |  
 16850 |          typedef expression_node<T>* expression_ptr; 
 16851 |          typedef Operation operation_t; 
 16852 |  
 16853 |          explicit unary_variable_node(const T& var) 
 16854 |          : v_(var) 
 16855 |          {} 
 16856 |  
 16857 |          inline T value() const exprtk_override 
 16858 |          { 
 16859 |             return Operation::process(v_); 
 16860 |          } 
 16861 |  
 16862 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 16863 |          { 
 16864 |             return Operation::type(); 
 16865 |          } 
 16866 |  
 16867 |          inline operator_type operation() const exprtk_override 
 16868 |          { 
 16869 |             return Operation::operation(); 
 16870 |          } 
 16871 |  
 16872 |          inline const T& v() const exprtk_override 
 16873 |          { 
 16874 |             return v_; 
 16875 |          } 
 16876 |  
 16877 |       private: 
 16878 |  
 16879 |          unary_variable_node(const unary_variable_node<T,Operation>&) exprtk_delete; 
 16880 |          unary_variable_node<T,Operation>& operator=(const unary_variable_node<T,Operation>&) exprtk_delete; 
 16881 |  
 16882 |          const T& v_; 
 16883 |       }; 
 16884 |  
 16885 |       template <typename T> 
 16886 |       class uvouv_node exprtk_final : public expression_node<T> 
 16887 |       { 
 16888 |       public: 
 16889 |  
 16890 |          // UOpr1(v0) Op UOpr2(v1) 
 16891 |          typedef typename details::functor_t<T> functor_t; 
 16892 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 16893 |          typedef typename functor_t::ufunc_t    ufunc_t; 
 16894 |          typedef expression_node<T>*            expression_ptr; 
 16895 |  
 16896 |          explicit uvouv_node(const T& var0,const T& var1, 
 16897 |                              ufunc_t uf0, ufunc_t uf1, bfunc_t bf) 
 16898 |          : v0_(var0) 
 16899 |          , v1_(var1) 
 16900 |          , u0_(uf0 ) 
 16901 |          , u1_(uf1 ) 
 16902 |          , f_ (bf  ) 
 16903 |          {} 
 16904 |  
 16905 |          inline T value() const exprtk_override 
 16906 |          { 
 16907 |             return f_(u0_(v0_),u1_(v1_)); 
 16908 |          } 
 16909 |  
 16910 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 16911 |          { 
 16912 |             return expression_node<T>::e_uvouv; 
 16913 |          } 
 16914 |  
 16915 |          inline const T& v0() 
 16916 |          { 
 16917 |             return v0_; 
 16918 |          } 
 16919 |  
 16920 |          inline const T& v1() 
 16921 |          { 
 16922 |             return v1_; 
 16923 |          } 
 16924 |  
 16925 |          inline ufunc_t u0() 
 16926 |          { 
 16927 |             return u0_; 
 16928 |          } 
 16929 |  
 16930 |          inline ufunc_t u1() 
 16931 |          { 
 16932 |             return u1_; 
 16933 |          } 
 16934 |  
 16935 |          inline ufunc_t f() 
 16936 |          { 
 16937 |             return f_; 
 16938 |          } 
 16939 |  
 16940 |       private: 
 16941 |  
 16942 |          uvouv_node(const uvouv_node<T>&) exprtk_delete; 
 16943 |          uvouv_node<T>& operator=(const uvouv_node<T>&) exprtk_delete; 
 16944 |  
 16945 |          const T& v0_; 
 16946 |          const T& v1_; 
 16947 |          const ufunc_t u0_; 
 16948 |          const ufunc_t u1_; 
 16949 |          const bfunc_t f_; 
 16950 |       }; 
 16951 |  
 16952 |       template <typename T, typename Operation> 
 16953 |       class unary_branch_node exprtk_final : public expression_node<T> 
 16954 |       { 
 16955 |       public: 
 16956 |  
 16957 |          typedef Operation                      operation_t; 
 16958 |          typedef expression_node<T>*            expression_ptr; 
 16959 |          typedef std::pair<expression_ptr,bool> branch_t; 
 16960 |  
 16961 |          explicit unary_branch_node(expression_ptr branch) 
 16962 |          { 
 16963 |             construct_branch_pair(branch_, branch); 
 16964 |          } 
 16965 |  
 16966 |          inline T value() const exprtk_override 
 16967 |          { 
 16968 |             return Operation::process(branch_.first->value()); 
 16969 |          } 
 16970 |  
 16971 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 16972 |          { 
 16973 |             return Operation::type(); 
 16974 |          } 
 16975 |  
 16976 |          inline bool valid() const exprtk_override 
 16977 |          { 
 16978 |             return branch_.first && branch_.first->valid(); 
 16979 |          } 
 16980 |  
 16981 |          inline operator_type operation() 
 16982 |          { 
 16983 |             return Operation::operation(); 
 16984 |          } 
 16985 |  
 16986 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 16987 |          { 
 16988 |             return branch_.first; 
 16989 |          } 
 16990 |  
 16991 |          inline void release() 
 16992 |          { 
 16993 |             branch_.second = false; 
 16994 |          } 
 16995 |  
 16996 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 16997 |          { 
 16998 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 16999 |          } 
 17000 |  
 17001 |          std::size_t node_depth() const exprtk_override 
 17002 |          { 
 17003 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 17004 |          } 
 17005 |  
 17006 |       private: 
 17007 |  
 17008 |          unary_branch_node(const unary_branch_node<T,Operation>&) exprtk_delete; 
 17009 |          unary_branch_node<T,Operation>& operator=(const unary_branch_node<T,Operation>&) exprtk_delete; 
 17010 |  
 17011 |          branch_t branch_; 
 17012 |       }; 
 17013 |  
 17014 |       template <typename T> struct is_const                { enum {result = 0}; }; 
 17015 |       template <typename T> struct is_const <const T>      { enum {result = 1}; }; 
 17016 |       template <typename T> struct is_const_ref            { enum {result = 0}; }; 
 17017 |       template <typename T> struct is_const_ref <const T&> { enum {result = 1}; }; 
 17018 |       template <typename T> struct is_ref                  { enum {result = 0}; }; 
 17019 |       template <typename T> struct is_ref<T&>              { enum {result = 1}; }; 
 17020 |       template <typename T> struct is_ref<const T&>        { enum {result = 0}; }; 
 17021 |  
 17022 |       template <std::size_t State> 
 17023 |       struct param_to_str { static std::string result() { static const std::string r("v"); return r; } }; 
 17024 |  
 17025 |       template <> 
 17026 |       struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } }; 
 17027 |  
 17028 |       #define exprtk_crtype(Type)                          \ 
 17029 |       param_to_str<is_const_ref< Type >::result>::result() \ 
 17030 |  
 17031 |       template <typename T> 
 17032 |       struct T0oT1oT2process 
 17033 |       { 
 17034 |          typedef typename details::functor_t<T> functor_t; 
 17035 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17036 |  
 17037 |          struct mode0 
 17038 |          { 
 17039 |             static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1) 
 17040 |             { 
 17041 |                // (T0 o0 T1) o1 T2 
 17042 |                return bf1(bf0(t0,t1),t2); 
 17043 |             } 
 17044 |  
 17045 |             template <typename T0, typename T1, typename T2> 
 17046 |             static inline std::string id() 
 17047 |             { 
 17048 |                static const std::string result = "(" + exprtk_crtype(T0) + "o"   + 
 17049 |                                                        exprtk_crtype(T1) + ")o(" + 
 17050 |                                                        exprtk_crtype(T2) + ")"   ; 
 17051 |                return result; 
 17052 |             } 
 17053 |          }; 
 17054 |  
 17055 |          struct mode1 
 17056 |          { 
 17057 |             static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1) 
 17058 |             { 
 17059 |                // T0 o0 (T1 o1 T2) 
 17060 |                return bf0(t0,bf1(t1,t2)); 
 17061 |             } 
 17062 |  
 17063 |             template <typename T0, typename T1, typename T2> 
 17064 |             static inline std::string id() 
 17065 |             { 
 17066 |                static const std::string result = "(" + exprtk_crtype(T0) + ")o(" + 
 17067 |                                                        exprtk_crtype(T1) + "o"   + 
 17068 |                                                        exprtk_crtype(T2) + ")"   ; 
 17069 |                return result; 
 17070 |             } 
 17071 |          }; 
 17072 |       }; 
 17073 |  
 17074 |       template <typename T> 
 17075 |       struct T0oT1oT20T3process 
 17076 |       { 
 17077 |          typedef typename details::functor_t<T> functor_t; 
 17078 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17079 |  
 17080 |          struct mode0 
 17081 |          { 
 17082 |             static inline T process(const T& t0, const T& t1, 
 17083 |                                     const T& t2, const T& t3, 
 17084 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17085 |             { 
 17086 |                // (T0 o0 T1) o1 (T2 o2 T3) 
 17087 |                return bf1(bf0(t0,t1),bf2(t2,t3)); 
 17088 |             } 
 17089 |  
 17090 |             template <typename T0, typename T1, typename T2, typename T3> 
 17091 |             static inline std::string id() 
 17092 |             { 
 17093 |                static const std::string result = "(" + exprtk_crtype(T0) + "o"  + 
 17094 |                                                        exprtk_crtype(T1) + ")o" + 
 17095 |                                                  "(" + exprtk_crtype(T2) + "o"  + 
 17096 |                                                        exprtk_crtype(T3) + ")"  ; 
 17097 |                return result; 
 17098 |             } 
 17099 |          }; 
 17100 |  
 17101 |          struct mode1 
 17102 |          { 
 17103 |             static inline T process(const T& t0, const T& t1, 
 17104 |                                     const T& t2, const T& t3, 
 17105 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17106 |             { 
 17107 |                // (T0 o0 (T1 o1 (T2 o2 T3)) 
 17108 |                return bf0(t0,bf1(t1,bf2(t2,t3))); 
 17109 |             } 
 17110 |             template <typename T0, typename T1, typename T2, typename T3> 
 17111 |             static inline std::string id() 
 17112 |             { 
 17113 |                static const std::string result = "(" + exprtk_crtype(T0) +  ")o((" + 
 17114 |                                                        exprtk_crtype(T1) +  ")o("  + 
 17115 |                                                        exprtk_crtype(T2) +  "o"    + 
 17116 |                                                        exprtk_crtype(T3) +  "))"   ; 
 17117 |                return result; 
 17118 |             } 
 17119 |          }; 
 17120 |  
 17121 |          struct mode2 
 17122 |          { 
 17123 |             static inline T process(const T& t0, const T& t1, 
 17124 |                                     const T& t2, const T& t3, 
 17125 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17126 |             { 
 17127 |                // (T0 o0 ((T1 o1 T2) o2 T3) 
 17128 |                return bf0(t0,bf2(bf1(t1,t2),t3)); 
 17129 |             } 
 17130 |  
 17131 |             template <typename T0, typename T1, typename T2, typename T3> 
 17132 |             static inline std::string id() 
 17133 |             { 
 17134 |                static const std::string result = "(" + exprtk_crtype(T0) + ")o((" + 
 17135 |                                                        exprtk_crtype(T1) + "o"    + 
 17136 |                                                        exprtk_crtype(T2) + ")o("  + 
 17137 |                                                        exprtk_crtype(T3) + "))"   ; 
 17138 |                return result; 
 17139 |             } 
 17140 |          }; 
 17141 |  
 17142 |          struct mode3 
 17143 |          { 
 17144 |             static inline T process(const T& t0, const T& t1, 
 17145 |                                     const T& t2, const T& t3, 
 17146 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17147 |             { 
 17148 |                // (((T0 o0 T1) o1 T2) o2 T3) 
 17149 |                return bf2(bf1(bf0(t0,t1),t2),t3); 
 17150 |             } 
 17151 |  
 17152 |             template <typename T0, typename T1, typename T2, typename T3> 
 17153 |             static inline std::string id() 
 17154 |             { 
 17155 |                static const std::string result = "((" + exprtk_crtype(T0) + "o"    + 
 17156 |                                                         exprtk_crtype(T1) + ")o("  + 
 17157 |                                                         exprtk_crtype(T2) + "))o(" + 
 17158 |                                                         exprtk_crtype(T3) + ")" 
 17159 |                return result; 
 17160 |             } 
 17161 |          }; 
 17162 |  
 17163 |          struct mode4 
 17164 |          { 
 17165 |             static inline T process(const T& t0, const T& t1, 
 17166 |                                     const T& t2, const T& t3, 
 17167 |                                     const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2) 
 17168 |             { 
 17169 |                // ((T0 o0 (T1 o1 T2)) o2 T3 
 17170 |                return bf2(bf0(t0,bf1(t1,t2)),t3); 
 17171 |             } 
 17172 |  
 17173 |             template <typename T0, typename T1, typename T2, typename T3> 
 17174 |             static inline std::string id() 
 17175 |             { 
 17176 |                static const std::string result = "((" + exprtk_crtype(T0) + ")o("  + 
 17177 |                                                         exprtk_crtype(T1) + "o"    + 
 17178 |                                                         exprtk_crtype(T2) + "))o(" + 
 17179 |                                                         exprtk_crtype(T3) + ")"    ; 
 17180 |                return result; 
 17181 |             } 
 17182 |          }; 
 17183 |       }; 
 17184 |  
 17185 |       #undef exprtk_crtype 
 17186 |  
 17187 |       template <typename T, typename T0, typename T1> 
 17188 |       struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; }; 
 17189 |       template <typename T, typename T0, typename T1> 
 17190 |       const typename expression_node<T>::node_type nodetype_T0oT1<T,T0,T1>::result = expression_node<T>::e_none; 
 17191 |  
 17192 |       #define synthesis_node_type_define(T0_, T1_, v_)                                                          \ 
 17193 |       template <typename T, typename T0, typename T1>                                                           \ 
 17194 |       struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; };         \ 
 17195 |       template <typename T, typename T0, typename T1>                                                           \ 
 17196 |       const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \ 
 17197 |  
 17198 |       synthesis_node_type_define(const T0&, const T1&,  e_vov) 
 17199 |       synthesis_node_type_define(const T0&, const T1 ,  e_voc) 
 17200 |       synthesis_node_type_define(const T0 , const T1&,  e_cov) 
 17201 |       synthesis_node_type_define(      T0&,       T1&, e_none) 
 17202 |       synthesis_node_type_define(const T0 , const T1 , e_none) 
 17203 |       synthesis_node_type_define(      T0&, const T1 , e_none) 
 17204 |       synthesis_node_type_define(const T0 ,       T1&, e_none) 
 17205 |       synthesis_node_type_define(const T0&,       T1&, e_none) 
 17206 |       synthesis_node_type_define(      T0&, const T1&, e_none) 
 17207 |       #undef synthesis_node_type_define 
 17208 |  
 17209 |       template <typename T, typename T0, typename T1, typename T2> 
 17210 |       struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; }; 
 17211 |       template <typename T, typename T0, typename T1, typename T2> 
 17212 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0,T1,T2>::result = expression_node<T>::e_none; 
 17213 |  
 17214 |       #define synthesis_node_type_define(T0_, T1_, T2_, v_)                                                            \ 
 17215 |       template <typename T, typename T0, typename T1, typename T2>                                                     \ 
 17216 |       struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; };         \ 
 17217 |       template <typename T, typename T0, typename T1, typename T2>                                                     \ 
 17218 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \ 
 17219 |  
 17220 |       synthesis_node_type_define(const T0&, const T1&, const T2&, e_vovov) 
 17221 |       synthesis_node_type_define(const T0&, const T1&, const T2 , e_vovoc) 
 17222 |       synthesis_node_type_define(const T0&, const T1 , const T2&, e_vocov) 
 17223 |       synthesis_node_type_define(const T0 , const T1&, const T2&, e_covov) 
 17224 |       synthesis_node_type_define(const T0 , const T1&, const T2 , e_covoc) 
 17225 |       synthesis_node_type_define(const T0 , const T1 , const T2 , e_none ) 
 17226 |       synthesis_node_type_define(const T0 , const T1 , const T2&, e_none ) 
 17227 |       synthesis_node_type_define(const T0&, const T1 , const T2 , e_none ) 
 17228 |       synthesis_node_type_define(      T0&,       T1&,       T2&, e_none ) 
 17229 |       #undef synthesis_node_type_define 
 17230 |  
 17231 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17232 |       struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; }; 
 17233 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17234 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result = expression_node<T>::e_none; 
 17235 |  
 17236 |       #define synthesis_node_type_define(T0_, T1_, T2_, T3_, v_)                                                              \ 
 17237 |       template <typename T, typename T0, typename T1, typename T2, typename T3>                                               \ 
 17238 |       struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; };         \ 
 17239 |       template <typename T, typename T0, typename T1, typename T2, typename T3>                                               \ 
 17240 |       const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \ 
 17241 |  
 17242 |       synthesis_node_type_define(const T0&, const T1&, const T2&, const T3&, e_vovovov) 
 17243 |       synthesis_node_type_define(const T0&, const T1&, const T2&, const T3 , e_vovovoc) 
 17244 |       synthesis_node_type_define(const T0&, const T1&, const T2 , const T3&, e_vovocov) 
 17245 |       synthesis_node_type_define(const T0&, const T1 , const T2&, const T3&, e_vocovov) 
 17246 |       synthesis_node_type_define(const T0 , const T1&, const T2&, const T3&, e_covovov) 
 17247 |       synthesis_node_type_define(const T0 , const T1&, const T2 , const T3&, e_covocov) 
 17248 |       synthesis_node_type_define(const T0&, const T1 , const T2&, const T3 , e_vocovoc) 
 17249 |       synthesis_node_type_define(const T0 , const T1&, const T2&, const T3 , e_covovoc) 
 17250 |       synthesis_node_type_define(const T0&, const T1 , const T2 , const T3&, e_vococov) 
 17251 |       synthesis_node_type_define(const T0 , const T1 , const T2 , const T3 , e_none   ) 
 17252 |       synthesis_node_type_define(const T0 , const T1 , const T2 , const T3&, e_none   ) 
 17253 |       synthesis_node_type_define(const T0 , const T1 , const T2&, const T3 , e_none   ) 
 17254 |       synthesis_node_type_define(const T0 , const T1&, const T2 , const T3 , e_none   ) 
 17255 |       synthesis_node_type_define(const T0&, const T1 , const T2 , const T3 , e_none   ) 
 17256 |       synthesis_node_type_define(const T0 , const T1 , const T2&, const T3&, e_none   ) 
 17257 |       synthesis_node_type_define(const T0&, const T1&, const T2 , const T3 , e_none   ) 
 17258 |       #undef synthesis_node_type_define 
 17259 |  
 17260 |       template <typename T, typename T0, typename T1> 
 17261 |       class T0oT1 exprtk_final : public expression_node<T> 
 17262 |       { 
 17263 |       public: 
 17264 |  
 17265 |          typedef typename details::functor_t<T> functor_t; 
 17266 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17267 |          typedef T value_type; 
 17268 |          typedef T0oT1<T,T0,T1> node_type; 
 17269 |  
 17270 |          T0oT1(T0 p0, T1 p1, const bfunc_t p2) 
 17271 |          : t0_(p0) 
 17272 |          , t1_(p1) 
 17273 |          , f_ (p2) 
 17274 |          {} 
 17275 |  
 17276 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17277 |          { 
 17278 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result; 
 17279 |             return result; 
 17280 |          } 
 17281 |  
 17282 |          inline operator_type operation() const exprtk_override 
 17283 |          { 
 17284 |             return e_default; 
 17285 |          } 
 17286 |  
 17287 |          inline T value() const exprtk_override 
 17288 |          { 
 17289 |             return f_(t0_,t1_); 
 17290 |          } 
 17291 |  
 17292 |          inline T0 t0() const 
 17293 |          { 
 17294 |             return t0_; 
 17295 |          } 
 17296 |  
 17297 |          inline T1 t1() const 
 17298 |          { 
 17299 |             return t1_; 
 17300 |          } 
 17301 |  
 17302 |          inline bfunc_t f() const 
 17303 |          { 
 17304 |             return f_; 
 17305 |          } 
 17306 |  
 17307 |          template <typename Allocator> 
 17308 |          static inline expression_node<T>* allocate(Allocator& allocator, 
 17309 |                                                     T0 p0, T1 p1, 
 17310 |                                                     bfunc_t p2) 
 17311 |          { 
 17312 |             return allocator 
 17313 |                      .template allocate_type<node_type, T0, T1, bfunc_t&> 
 17314 |                         (p0, p1, p2); 
 17315 |          } 
 17316 |  
 17317 |       private: 
 17318 |  
 17319 |          T0oT1(const T0oT1<T,T0,T1>&) exprtk_delete; 
 17320 |          T0oT1<T,T0,T1>& operator=(const T0oT1<T,T0,T1>&) { return (*this); } 
 17321 |  
 17322 |          T0 t0_; 
 17323 |          T1 t1_; 
 17324 |          const bfunc_t f_; 
 17325 |       }; 
 17326 |  
 17327 |       template <typename T, typename T0, typename T1, typename T2, typename ProcessMode> 
 17328 |       class T0oT1oT2 exprtk_final : public T0oT1oT2_base_node<T> 
 17329 |       { 
 17330 |       public: 
 17331 |  
 17332 |          typedef typename details::functor_t<T> functor_t; 
 17333 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17334 |          typedef T value_type; 
 17335 |          typedef T0oT1oT2<T,T0,T1,T2,ProcessMode> node_type; 
 17336 |          typedef ProcessMode process_mode_t; 
 17337 |  
 17338 |          T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4) 
 17339 |          : t0_(p0) 
 17340 |          , t1_(p1) 
 17341 |          , t2_(p2) 
 17342 |          , f0_(p3) 
 17343 |          , f1_(p4) 
 17344 |          {} 
 17345 |  
 17346 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17347 |          { 
 17348 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result; 
 17349 |             return result; 
 17350 |          } 
 17351 |  
 17352 |          inline operator_type operation() 
 17353 |          { 
 17354 |             return e_default; 
 17355 |          } 
 17356 |  
 17357 |          inline T value() const exprtk_override 
 17358 |          { 
 17359 |             return ProcessMode::process(t0_, t1_, t2_, f0_, f1_); 
 17360 |          } 
 17361 |  
 17362 |          inline T0 t0() const 
 17363 |          { 
 17364 |             return t0_; 
 17365 |          } 
 17366 |  
 17367 |          inline T1 t1() const 
 17368 |          { 
 17369 |             return t1_; 
 17370 |          } 
 17371 |  
 17372 |          inline T2 t2() const 
 17373 |          { 
 17374 |             return t2_; 
 17375 |          } 
 17376 |  
 17377 |          bfunc_t f0() const 
 17378 |          { 
 17379 |             return f0_; 
 17380 |          } 
 17381 |  
 17382 |          bfunc_t f1() const 
 17383 |          { 
 17384 |             return f1_; 
 17385 |          } 
 17386 |  
 17387 |          std::string type_id() const exprtk_override 
 17388 |          { 
 17389 |             return id(); 
 17390 |          } 
 17391 |  
 17392 |          static inline std::string id() 
 17393 |          { 
 17394 |             return process_mode_t::template id<T0,T1,T2>(); 
 17395 |          } 
 17396 |  
 17397 |          template <typename Allocator> 
 17398 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4) 
 17399 |          { 
 17400 |             return allocator 
 17401 |                       .template allocate_type<node_type, T0, T1, T2, bfunc_t, bfunc_t> 
 17402 |                          (p0, p1, p2, p3, p4); 
 17403 |          } 
 17404 |  
 17405 |       private: 
 17406 |  
 17407 |          T0oT1oT2(const node_type&) exprtk_delete; 
 17408 |          node_type& operator=(const node_type&) exprtk_delete; 
 17409 |  
 17410 |          T0 t0_; 
 17411 |          T1 t1_; 
 17412 |          T2 t2_; 
 17413 |          const bfunc_t f0_; 
 17414 |          const bfunc_t f1_; 
 17415 |       }; 
 17416 |  
 17417 |       template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode> 
 17418 |       class T0oT1oT2oT3 exprtk_final : public T0oT1oT2oT3_base_node<T> 
 17419 |       { 
 17420 |       public: 
 17421 |  
 17422 |          typedef typename details::functor_t<T> functor_t; 
 17423 |          typedef typename functor_t::bfunc_t    bfunc_t; 
 17424 |          typedef T value_type; 
 17425 |          typedef T0_ T0; 
 17426 |          typedef T1_ T1; 
 17427 |          typedef T2_ T2; 
 17428 |          typedef T3_ T3; 
 17429 |          typedef T0oT1oT2oT3<T,T0,T1,T2,T3,ProcessMode> node_type; 
 17430 |          typedef ProcessMode process_mode_t; 
 17431 |  
 17432 |          T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6) 
 17433 |          : t0_(p0) 
 17434 |          , t1_(p1) 
 17435 |          , t2_(p2) 
 17436 |          , t3_(p3) 
 17437 |          , f0_(p4) 
 17438 |          , f1_(p5) 
 17439 |          , f2_(p6) 
 17440 |          {} 
 17441 |  
 17442 |          inline T value() const exprtk_override 
 17443 |          { 
 17444 |             return ProcessMode::process(t0_, t1_, t2_, t3_, f0_, f1_, f2_); 
 17445 |          } 
 17446 |  
 17447 |          inline T0 t0() const 
 17448 |          { 
 17449 |             return t0_; 
 17450 |          } 
 17451 |  
 17452 |          inline T1 t1() const 
 17453 |          { 
 17454 |             return t1_; 
 17455 |          } 
 17456 |  
 17457 |          inline T2 t2() const 
 17458 |          { 
 17459 |             return t2_; 
 17460 |          } 
 17461 |  
 17462 |          inline T3 t3() const 
 17463 |          { 
 17464 |             return t3_; 
 17465 |          } 
 17466 |  
 17467 |          inline bfunc_t f0() const 
 17468 |          { 
 17469 |             return f0_; 
 17470 |          } 
 17471 |  
 17472 |          inline bfunc_t f1() const 
 17473 |          { 
 17474 |             return f1_; 
 17475 |          } 
 17476 |  
 17477 |          inline bfunc_t f2() const 
 17478 |          { 
 17479 |             return f2_; 
 17480 |          } 
 17481 |  
 17482 |          inline std::string type_id() const exprtk_override 
 17483 |          { 
 17484 |             return id(); 
 17485 |          } 
 17486 |  
 17487 |          static inline std::string id() 
 17488 |          { 
 17489 |             return process_mode_t::template id<T0, T1, T2, T3>(); 
 17490 |          } 
 17491 |  
 17492 |          template <typename Allocator> 
 17493 |          static inline expression_node<T>* allocate(Allocator& allocator, 
 17494 |                                                     T0 p0, T1 p1, T2 p2, T3 p3, 
 17495 |                                                     bfunc_t p4, bfunc_t p5, bfunc_t p6) 
 17496 |          { 
 17497 |             return allocator 
 17498 |                       .template allocate_type<node_type, T0, T1, T2, T3, bfunc_t, bfunc_t> 
 17499 |                          (p0, p1, p2, p3, p4, p5, p6); 
 17500 |          } 
 17501 |  
 17502 |       private: 
 17503 |  
 17504 |          T0oT1oT2oT3(const node_type&) exprtk_delete; 
 17505 |          node_type& operator=(const node_type&) exprtk_delete; 
 17506 |  
 17507 |          T0 t0_; 
 17508 |          T1 t1_; 
 17509 |          T2 t2_; 
 17510 |          T3 t3_; 
 17511 |          const bfunc_t f0_; 
 17512 |          const bfunc_t f1_; 
 17513 |          const bfunc_t f2_; 
 17514 |       }; 
 17515 |  
 17516 |       template <typename T, typename T0, typename T1, typename T2> 
 17517 |       class T0oT1oT2_sf3 exprtk_final : public T0oT1oT2_base_node<T> 
 17518 |       { 
 17519 |       public: 
 17520 |  
 17521 |          typedef typename details::functor_t<T> functor_t; 
 17522 |          typedef typename functor_t::tfunc_t    tfunc_t; 
 17523 |          typedef T value_type; 
 17524 |          typedef T0oT1oT2_sf3<T,T0,T1,T2> node_type; 
 17525 |  
 17526 |          T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3) 
 17527 |          : t0_(p0) 
 17528 |          , t1_(p1) 
 17529 |          , t2_(p2) 
 17530 |          , f_ (p3) 
 17531 |          {} 
 17532 |  
 17533 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17534 |          { 
 17535 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result; 
 17536 |             return result; 
 17537 |          } 
 17538 |  
 17539 |          inline operator_type operation() const exprtk_override 
 17540 |          { 
 17541 |             return e_default; 
 17542 |          } 
 17543 |  
 17544 |          inline T value() const exprtk_override 
 17545 |          { 
 17546 |             return f_(t0_, t1_, t2_); 
 17547 |          } 
 17548 |  
 17549 |          inline T0 t0() const 
 17550 |          { 
 17551 |             return t0_; 
 17552 |          } 
 17553 |  
 17554 |          inline T1 t1() const 
 17555 |          { 
 17556 |             return t1_; 
 17557 |          } 
 17558 |  
 17559 |          inline T2 t2() const 
 17560 |          { 
 17561 |             return t2_; 
 17562 |          } 
 17563 |  
 17564 |          tfunc_t f() const 
 17565 |          { 
 17566 |             return f_; 
 17567 |          } 
 17568 |  
 17569 |          std::string type_id() const 
 17570 |          { 
 17571 |             return id(); 
 17572 |          } 
 17573 |  
 17574 |          static inline std::string id() 
 17575 |          { 
 17576 |             return "sf3" 
 17577 |          } 
 17578 |  
 17579 |          template <typename Allocator> 
 17580 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3) 
 17581 |          { 
 17582 |             return allocator 
 17583 |                      .template allocate_type<node_type, T0, T1, T2, tfunc_t> 
 17584 |                         (p0, p1, p2, p3); 
 17585 |          } 
 17586 |  
 17587 |       private: 
 17588 |  
 17589 |          T0oT1oT2_sf3(const node_type&) exprtk_delete; 
 17590 |          node_type& operator=(const node_type&) exprtk_delete; 
 17591 |  
 17592 |          T0 t0_; 
 17593 |          T1 t1_; 
 17594 |          T2 t2_; 
 17595 |          const tfunc_t f_; 
 17596 |       }; 
 17597 |  
 17598 |       template <typename T, typename T0, typename T1, typename T2> 
 17599 |       class sf3ext_type_node : public T0oT1oT2_base_node<T> 
 17600 |       { 
 17601 |       public: 
 17602 |  
 17603 |          virtual ~sf3ext_type_node() 
 17604 |          {} 
 17605 |  
 17606 |          virtual T0 t0() const = 0; 
 17607 |  
 17608 |          virtual T1 t1() const = 0; 
 17609 |  
 17610 |          virtual T2 t2() const = 0; 
 17611 |       }; 
 17612 |  
 17613 |       template <typename T, typename T0, typename T1, typename T2, typename SF3Operation> 
 17614 |       class T0oT1oT2_sf3ext exprtk_final : public sf3ext_type_node<T,T0,T1,T2> 
 17615 |       { 
 17616 |       public: 
 17617 |  
 17618 |          typedef T value_type; 
 17619 |          typedef T0oT1oT2_sf3ext<T, T0, T1, T2, SF3Operation> node_type; 
 17620 |  
 17621 |          T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2) 
 17622 |          : t0_(p0) 
 17623 |          , t1_(p1) 
 17624 |          , t2_(p2) 
 17625 |          {} 
 17626 |  
 17627 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17628 |          { 
 17629 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2<T,T0,T1,T2>::result; 
 17630 |             return result; 
 17631 |          } 
 17632 |  
 17633 |          inline operator_type operation() 
 17634 |          { 
 17635 |             return e_default; 
 17636 |          } 
 17637 |  
 17638 |          inline T value() const exprtk_override 
 17639 |          { 
 17640 |             return SF3Operation::process(t0_, t1_, t2_); 
 17641 |          } 
 17642 |  
 17643 |          T0 t0() const exprtk_override 
 17644 |          { 
 17645 |             return t0_; 
 17646 |          } 
 17647 |  
 17648 |          T1 t1() const exprtk_override 
 17649 |          { 
 17650 |             return t1_; 
 17651 |          } 
 17652 |  
 17653 |          T2 t2() const exprtk_override 
 17654 |          { 
 17655 |             return t2_; 
 17656 |          } 
 17657 |  
 17658 |          std::string type_id() const exprtk_override 
 17659 |          { 
 17660 |             return id(); 
 17661 |          } 
 17662 |  
 17663 |          static inline std::string id() 
 17664 |          { 
 17665 |             return SF3Operation::id(); 
 17666 |          } 
 17667 |  
 17668 |          template <typename Allocator> 
 17669 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2) 
 17670 |          { 
 17671 |             return allocator 
 17672 |                      .template allocate_type<node_type, T0, T1, T2> 
 17673 |                         (p0, p1, p2); 
 17674 |          } 
 17675 |  
 17676 |       private: 
 17677 |  
 17678 |          T0oT1oT2_sf3ext(const node_type&) exprtk_delete; 
 17679 |          node_type& operator=(const node_type&) exprtk_delete; 
 17680 |  
 17681 |          T0 t0_; 
 17682 |          T1 t1_; 
 17683 |          T2 t2_; 
 17684 |       }; 
 17685 |  
 17686 |       template <typename T> 
 17687 |       inline bool is_sf3ext_node(const expression_node<T>* n) 
 17688 |       { 
 17689 |          switch (n->type()) 
 17690 |          { 
 17691 |             case expression_node<T>::e_vovov : return true; 
 17692 |             case expression_node<T>::e_vovoc : return true; 
 17693 |             case expression_node<T>::e_vocov : return true; 
 17694 |             case expression_node<T>::e_covov : return true; 
 17695 |             case expression_node<T>::e_covoc : return true; 
 17696 |             default                          : return false; 
 17697 |          } 
 17698 |       } 
 17699 |  
 17700 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17701 |       class T0oT1oT2oT3_sf4 exprtk_final : public T0oT1oT2_base_node<T> 
 17702 |       { 
 17703 |       public: 
 17704 |  
 17705 |          typedef typename details::functor_t<T> functor_t; 
 17706 |          typedef typename functor_t::qfunc_t    qfunc_t; 
 17707 |          typedef T value_type; 
 17708 |          typedef T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> node_type; 
 17709 |  
 17710 |          T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4) 
 17711 |          : t0_(p0) 
 17712 |          , t1_(p1) 
 17713 |          , t2_(p2) 
 17714 |          , t3_(p3) 
 17715 |          , f_ (p4) 
 17716 |          {} 
 17717 |  
 17718 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17719 |          { 
 17720 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result; 
 17721 |             return result; 
 17722 |          } 
 17723 |  
 17724 |          inline operator_type operation() const exprtk_override 
 17725 |          { 
 17726 |             return e_default; 
 17727 |          } 
 17728 |  
 17729 |          inline T value() const exprtk_override 
 17730 |          { 
 17731 |             return f_(t0_, t1_, t2_, t3_); 
 17732 |          } 
 17733 |  
 17734 |          inline T0 t0() const 
 17735 |          { 
 17736 |             return t0_; 
 17737 |          } 
 17738 |  
 17739 |          inline T1 t1() const 
 17740 |          { 
 17741 |             return t1_; 
 17742 |          } 
 17743 |  
 17744 |          inline T2 t2() const 
 17745 |          { 
 17746 |             return t2_; 
 17747 |          } 
 17748 |  
 17749 |          inline T3 t3() const 
 17750 |          { 
 17751 |             return t3_; 
 17752 |          } 
 17753 |  
 17754 |          qfunc_t f() const 
 17755 |          { 
 17756 |             return f_; 
 17757 |          } 
 17758 |  
 17759 |          std::string type_id() const 
 17760 |          { 
 17761 |             return id(); 
 17762 |          } 
 17763 |  
 17764 |          static inline std::string id() 
 17765 |          { 
 17766 |             return "sf4" 
 17767 |          } 
 17768 |  
 17769 |          template <typename Allocator> 
 17770 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4) 
 17771 |          { 
 17772 |             return allocator 
 17773 |                      .template allocate_type<node_type, T0, T1, T2, T3, qfunc_t> 
 17774 |                         (p0, p1, p2, p3, p4); 
 17775 |          } 
 17776 |  
 17777 |       private: 
 17778 |  
 17779 |          T0oT1oT2oT3_sf4(const node_type&) exprtk_delete; 
 17780 |          node_type& operator=(const node_type&) exprtk_delete; 
 17781 |  
 17782 |          T0 t0_; 
 17783 |          T1 t1_; 
 17784 |          T2 t2_; 
 17785 |          T3 t3_; 
 17786 |          const qfunc_t f_; 
 17787 |       }; 
 17788 |  
 17789 |       template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation> 
 17790 |       class T0oT1oT2oT3_sf4ext exprtk_final : public T0oT1oT2oT3_base_node<T> 
 17791 |       { 
 17792 |       public: 
 17793 |  
 17794 |          typedef T value_type; 
 17795 |          typedef T0oT1oT2oT3_sf4ext<T, T0, T1, T2, T3, SF4Operation> node_type; 
 17796 |  
 17797 |          T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3) 
 17798 |          : t0_(p0) 
 17799 |          , t1_(p1) 
 17800 |          , t2_(p2) 
 17801 |          , t3_(p3) 
 17802 |          {} 
 17803 |  
 17804 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17805 |          { 
 17806 |             static const typename expression_node<T>::node_type result = nodetype_T0oT1oT2oT3<T,T0,T1,T2,T3>::result; 
 17807 |             return result; 
 17808 |          } 
 17809 |  
 17810 |          inline T value() const exprtk_override 
 17811 |          { 
 17812 |             return SF4Operation::process(t0_, t1_, t2_, t3_); 
 17813 |          } 
 17814 |  
 17815 |          inline T0 t0() const 
 17816 |          { 
 17817 |             return t0_; 
 17818 |          } 
 17819 |  
 17820 |          inline T1 t1() const 
 17821 |          { 
 17822 |             return t1_; 
 17823 |          } 
 17824 |  
 17825 |          inline T2 t2() const 
 17826 |          { 
 17827 |             return t2_; 
 17828 |          } 
 17829 |  
 17830 |          inline T3 t3() const 
 17831 |          { 
 17832 |             return t3_; 
 17833 |          } 
 17834 |  
 17835 |          std::string type_id() const exprtk_override 
 17836 |          { 
 17837 |             return id(); 
 17838 |          } 
 17839 |  
 17840 |          static inline std::string id() 
 17841 |          { 
 17842 |             return SF4Operation::id(); 
 17843 |          } 
 17844 |  
 17845 |          template <typename Allocator> 
 17846 |          static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3) 
 17847 |          { 
 17848 |             return allocator 
 17849 |                      .template allocate_type<node_type, T0, T1, T2, T3> 
 17850 |                         (p0, p1, p2, p3); 
 17851 |          } 
 17852 |  
 17853 |       private: 
 17854 |  
 17855 |          T0oT1oT2oT3_sf4ext(const node_type&) exprtk_delete; 
 17856 |          node_type& operator=(const node_type&) exprtk_delete; 
 17857 |  
 17858 |          T0 t0_; 
 17859 |          T1 t1_; 
 17860 |          T2 t2_; 
 17861 |          T3 t3_; 
 17862 |       }; 
 17863 |  
 17864 |       template <typename T> 
 17865 |       inline bool is_sf4ext_node(const expression_node<T>* n) 
 17866 |       { 
 17867 |          switch (n->type()) 
 17868 |          { 
 17869 |             case expression_node<T>::e_vovovov : return true; 
 17870 |             case expression_node<T>::e_vovovoc : return true; 
 17871 |             case expression_node<T>::e_vovocov : return true; 
 17872 |             case expression_node<T>::e_vocovov : return true; 
 17873 |             case expression_node<T>::e_covovov : return true; 
 17874 |             case expression_node<T>::e_covocov : return true; 
 17875 |             case expression_node<T>::e_vocovoc : return true; 
 17876 |             case expression_node<T>::e_covovoc : return true; 
 17877 |             case expression_node<T>::e_vococov : return true; 
 17878 |             default                            : return false; 
 17879 |          } 
 17880 |       } 
 17881 |  
 17882 |       template <typename T, typename T0, typename T1> 
 17883 |       struct T0oT1_define 
 17884 |       { 
 17885 |          typedef details::T0oT1<T, T0, T1> type0; 
 17886 |       }; 
 17887 |  
 17888 |       template <typename T, typename T0, typename T1, typename T2> 
 17889 |       struct T0oT1oT2_define 
 17890 |       { 
 17891 |          typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode0> type0; 
 17892 |          typedef details::T0oT1oT2<T, T0, T1, T2, typename T0oT1oT2process<T>::mode1> type1; 
 17893 |          typedef details::T0oT1oT2_sf3<T, T0, T1, T2> sf3_type; 
 17894 |          typedef details::sf3ext_type_node<T, T0, T1, T2> sf3_type_node; 
 17895 |       }; 
 17896 |  
 17897 |       template <typename T, typename T0, typename T1, typename T2, typename T3> 
 17898 |       struct T0oT1oT2oT3_define 
 17899 |       { 
 17900 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode0> type0; 
 17901 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode1> type1; 
 17902 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode2> type2; 
 17903 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode3> type3; 
 17904 |          typedef details::T0oT1oT2oT3<T, T0, T1, T2, T3, typename T0oT1oT20T3process<T>::mode4> type4; 
 17905 |          typedef details::T0oT1oT2oT3_sf4<T, T0, T1, T2, T3> sf4_type; 
 17906 |       }; 
 17907 |  
 17908 |       template <typename T, typename Operation> 
 17909 |       class vov_node exprtk_final : public vov_base_node<T> 
 17910 |       { 
 17911 |       public: 
 17912 |  
 17913 |          typedef expression_node<T>* expression_ptr; 
 17914 |          typedef Operation operation_t; 
 17915 |  
 17916 |          // variable op variable node 
 17917 |          explicit vov_node(const T& var0, const T& var1) 
 17918 |          : v0_(var0) 
 17919 |          , v1_(var1) 
 17920 |          {} 
 17921 |  
 17922 |          inline T value() const exprtk_override 
 17923 |          { 
 17924 |             return Operation::process(v0_,v1_); 
 17925 |          } 
 17926 |  
 17927 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17928 |          { 
 17929 |             return Operation::type(); 
 17930 |          } 
 17931 |  
 17932 |          inline operator_type operation() const exprtk_override 
 17933 |          { 
 17934 |             return Operation::operation(); 
 17935 |          } 
 17936 |  
 17937 |          inline const T& v0() const exprtk_override 
 17938 |          { 
 17939 |             return v0_; 
 17940 |          } 
 17941 |  
 17942 |          inline const T& v1() const exprtk_override 
 17943 |          { 
 17944 |             return v1_; 
 17945 |          } 
 17946 |  
 17947 |       protected: 
 17948 |  
 17949 |          const T& v0_; 
 17950 |          const T& v1_; 
 17951 |  
 17952 |       private: 
 17953 |  
 17954 |          vov_node(const vov_node<T,Operation>&) exprtk_delete; 
 17955 |          vov_node<T,Operation>& operator=(const vov_node<T,Operation>&) exprtk_delete; 
 17956 |       }; 
 17957 |  
 17958 |       template <typename T, typename Operation> 
 17959 |       class cov_node exprtk_final : public cov_base_node<T> 
 17960 |       { 
 17961 |       public: 
 17962 |  
 17963 |          typedef expression_node<T>* expression_ptr; 
 17964 |          typedef Operation operation_t; 
 17965 |  
 17966 |          // constant op variable node 
 17967 |          explicit cov_node(const T& const_var, const T& var) 
 17968 |          : c_(const_var) 
 17969 |          , v_(var) 
 17970 |          {} 
 17971 |  
 17972 |          inline T value() const exprtk_override 
 17973 |          { 
 17974 |             return Operation::process(c_,v_); 
 17975 |          } 
 17976 |  
 17977 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 17978 |          { 
 17979 |             return Operation::type(); 
 17980 |          } 
 17981 |  
 17982 |          inline operator_type operation() const exprtk_override 
 17983 |          { 
 17984 |             return Operation::operation(); 
 17985 |          } 
 17986 |  
 17987 |          inline const T c() const exprtk_override 
 17988 |          { 
 17989 |             return c_; 
 17990 |          } 
 17991 |  
 17992 |          inline const T& v() const exprtk_override 
 17993 |          { 
 17994 |             return v_; 
 17995 |          } 
 17996 |  
 17997 |       protected: 
 17998 |  
 17999 |          const T  c_; 
 18000 |          const T& v_; 
 18001 |  
 18002 |       private: 
 18003 |  
 18004 |          cov_node(const cov_node<T,Operation>&) exprtk_delete; 
 18005 |          cov_node<T,Operation>& operator=(const cov_node<T,Operation>&) exprtk_delete; 
 18006 |       }; 
 18007 |  
 18008 |       template <typename T, typename Operation> 
 18009 |       class voc_node exprtk_final : public voc_base_node<T> 
 18010 |       { 
 18011 |       public: 
 18012 |  
 18013 |          typedef expression_node<T>* expression_ptr; 
 18014 |          typedef Operation operation_t; 
 18015 |  
 18016 |          // variable op constant node 
 18017 |          explicit voc_node(const T& var, const T& const_var) 
 18018 |          : v_(var) 
 18019 |          , c_(const_var) 
 18020 |          {} 
 18021 |  
 18022 |          inline T value() const exprtk_override 
 18023 |          { 
 18024 |             return Operation::process(v_,c_); 
 18025 |          } 
 18026 |  
 18027 |          inline operator_type operation() const exprtk_override 
 18028 |          { 
 18029 |             return Operation::operation(); 
 18030 |          } 
 18031 |  
 18032 |          inline const T c() const exprtk_override 
 18033 |          { 
 18034 |             return c_; 
 18035 |          } 
 18036 |  
 18037 |          inline const T& v() const exprtk_override 
 18038 |          { 
 18039 |             return v_; 
 18040 |          } 
 18041 |  
 18042 |       protected: 
 18043 |  
 18044 |          const T& v_; 
 18045 |          const T  c_; 
 18046 |  
 18047 |       private: 
 18048 |  
 18049 |          voc_node(const voc_node<T,Operation>&) exprtk_delete; 
 18050 |          voc_node<T,Operation>& operator=(const voc_node<T,Operation>&) exprtk_delete; 
 18051 |       }; 
 18052 |  
 18053 |       template <typename T, typename Operation> 
 18054 |       class vob_node exprtk_final : public vob_base_node<T> 
 18055 |       { 
 18056 |       public: 
 18057 |  
 18058 |          typedef expression_node<T>* expression_ptr; 
 18059 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18060 |          typedef Operation operation_t; 
 18061 |  
 18062 |          // variable op binary node 
 18063 |          explicit vob_node(const T& var, const expression_ptr branch) 
 18064 |          : v_(var) 
 18065 |          { 
 18066 |             construct_branch_pair(branch_, branch); 
 18067 |             assert(valid()); 
 18068 |          } 
 18069 |  
 18070 |          inline T value() const exprtk_override 
 18071 |          { 
 18072 |             return Operation::process(v_,branch_.first->value()); 
 18073 |          } 
 18074 |  
 18075 |          inline const T& v() const exprtk_override 
 18076 |          { 
 18077 |             return v_; 
 18078 |          } 
 18079 |  
 18080 |          inline bool valid() const exprtk_override 
 18081 |          { 
 18082 |             return branch_.first && branch_.first->valid(); 
 18083 |          } 
 18084 |  
 18085 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18086 |          { 
 18087 |             return branch_.first; 
 18088 |          } 
 18089 |  
 18090 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18091 |          { 
 18092 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18093 |          } 
 18094 |  
 18095 |          std::size_t node_depth() const exprtk_override 
 18096 |          { 
 18097 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18098 |          } 
 18099 |  
 18100 |       private: 
 18101 |  
 18102 |          vob_node(const vob_node<T,Operation>&) exprtk_delete; 
 18103 |          vob_node<T,Operation>& operator=(const vob_node<T,Operation>&) exprtk_delete; 
 18104 |  
 18105 |          const T& v_; 
 18106 |          branch_t branch_; 
 18107 |       }; 
 18108 |  
 18109 |       template <typename T, typename Operation> 
 18110 |       class bov_node exprtk_final : public bov_base_node<T> 
 18111 |       { 
 18112 |       public: 
 18113 |  
 18114 |          typedef expression_node<T>* expression_ptr; 
 18115 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18116 |          typedef Operation operation_t; 
 18117 |  
 18118 |          // binary node op variable node 
 18119 |          explicit bov_node(const expression_ptr branch, const T& var) 
 18120 |          : v_(var) 
 18121 |          { 
 18122 |             construct_branch_pair(branch_, branch); 
 18123 |             assert(valid()); 
 18124 |          } 
 18125 |  
 18126 |          inline T value() const exprtk_override 
 18127 |          { 
 18128 |             return Operation::process(branch_.first->value(),v_); 
 18129 |          } 
 18130 |  
 18131 |          inline const T& v() const exprtk_override 
 18132 |          { 
 18133 |             return v_; 
 18134 |          } 
 18135 |  
 18136 |          inline bool valid() const exprtk_override 
 18137 |          { 
 18138 |             return branch_.first && branch_.first->valid(); 
 18139 |          } 
 18140 |  
 18141 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18142 |          { 
 18143 |             return branch_.first; 
 18144 |          } 
 18145 |  
 18146 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18147 |          { 
 18148 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18149 |          } 
 18150 |  
 18151 |          std::size_t node_depth() const exprtk_override 
 18152 |          { 
 18153 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18154 |          } 
 18155 |  
 18156 |       private: 
 18157 |  
 18158 |          bov_node(const bov_node<T,Operation>&) exprtk_delete; 
 18159 |          bov_node<T,Operation>& operator=(const bov_node<T,Operation>&) exprtk_delete; 
 18160 |  
 18161 |          const T& v_; 
 18162 |          branch_t branch_; 
 18163 |       }; 
 18164 |  
 18165 |       template <typename T, typename Operation> 
 18166 |       class cob_node exprtk_final : public cob_base_node<T> 
 18167 |       { 
 18168 |       public: 
 18169 |  
 18170 |          typedef expression_node<T>* expression_ptr; 
 18171 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18172 |          typedef Operation operation_t; 
 18173 |  
 18174 |          // constant op variable node 
 18175 |          explicit cob_node(const T const_var, const expression_ptr branch) 
 18176 |          : c_(const_var) 
 18177 |          { 
 18178 |             construct_branch_pair(branch_, branch); 
 18179 |             assert(valid()); 
 18180 |          } 
 18181 |  
 18182 |          inline T value() const exprtk_override 
 18183 |          { 
 18184 |             return Operation::process(c_,branch_.first->value()); 
 18185 |          } 
 18186 |  
 18187 |          inline operator_type operation() const exprtk_override 
 18188 |          { 
 18189 |             return Operation::operation(); 
 18190 |          } 
 18191 |  
 18192 |          inline const T c() const exprtk_override 
 18193 |          { 
 18194 |             return c_; 
 18195 |          } 
 18196 |  
 18197 |          inline void set_c(const T new_c) exprtk_override 
 18198 |          { 
 18199 |             (*const_cast<T*>(&c_)) = new_c; 
 18200 |          } 
 18201 |  
 18202 |          inline bool valid() const exprtk_override 
 18203 |          { 
 18204 |             return branch_.first && branch_.first->valid(); 
 18205 |          } 
 18206 |  
 18207 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18208 |          { 
 18209 |             return branch_.first; 
 18210 |          } 
 18211 |  
 18212 |          inline expression_node<T>* move_branch(const std::size_t&) exprtk_override 
 18213 |          { 
 18214 |             branch_.second = false; 
 18215 |             return branch_.first; 
 18216 |          } 
 18217 |  
 18218 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18219 |          { 
 18220 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18221 |          } 
 18222 |  
 18223 |          std::size_t node_depth() const exprtk_override 
 18224 |          { 
 18225 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18226 |          } 
 18227 |  
 18228 |       private: 
 18229 |  
 18230 |          cob_node(const cob_node<T,Operation>&) exprtk_delete; 
 18231 |          cob_node<T,Operation>& operator=(const cob_node<T,Operation>&) exprtk_delete; 
 18232 |  
 18233 |          const T  c_; 
 18234 |          branch_t branch_; 
 18235 |       }; 
 18236 |  
 18237 |       template <typename T, typename Operation> 
 18238 |       class boc_node exprtk_final : public boc_base_node<T> 
 18239 |       { 
 18240 |       public: 
 18241 |  
 18242 |          typedef expression_node<T>* expression_ptr; 
 18243 |          typedef std::pair<expression_ptr,bool> branch_t; 
 18244 |          typedef Operation operation_t; 
 18245 |  
 18246 |          // binary node op constant node 
 18247 |          explicit boc_node(const expression_ptr branch, const T const_var) 
 18248 |          : c_(const_var) 
 18249 |          { 
 18250 |             construct_branch_pair(branch_, branch); 
 18251 |             assert(valid()); 
 18252 |          } 
 18253 |  
 18254 |          inline T value() const exprtk_override 
 18255 |          { 
 18256 |             return Operation::process(branch_.first->value(),c_); 
 18257 |          } 
 18258 |  
 18259 |          inline operator_type operation() const exprtk_override 
 18260 |          { 
 18261 |             return Operation::operation(); 
 18262 |          } 
 18263 |  
 18264 |          inline const T c() const exprtk_override 
 18265 |          { 
 18266 |             return c_; 
 18267 |          } 
 18268 |  
 18269 |          inline void set_c(const T new_c) exprtk_override 
 18270 |          { 
 18271 |             (*const_cast<T*>(&c_)) = new_c; 
 18272 |          } 
 18273 |  
 18274 |          inline bool valid() const exprtk_override 
 18275 |          { 
 18276 |             return branch_.first && branch_.first->valid(); 
 18277 |          } 
 18278 |  
 18279 |          inline expression_node<T>* branch(const std::size_t&) const exprtk_override 
 18280 |          { 
 18281 |             return branch_.first; 
 18282 |          } 
 18283 |  
 18284 |          inline expression_node<T>* move_branch(const std::size_t&) exprtk_override 
 18285 |          { 
 18286 |             branch_.second = false; 
 18287 |             return branch_.first; 
 18288 |          } 
 18289 |  
 18290 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18291 |          { 
 18292 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18293 |          } 
 18294 |  
 18295 |          std::size_t node_depth() const exprtk_override 
 18296 |          { 
 18297 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18298 |          } 
 18299 |  
 18300 |       private: 
 18301 |  
 18302 |          boc_node(const boc_node<T,Operation>&) exprtk_delete; 
 18303 |          boc_node<T,Operation>& operator=(const boc_node<T,Operation>&) exprtk_delete; 
 18304 |  
 18305 |          const T  c_; 
 18306 |          branch_t branch_; 
 18307 |       }; 
 18308 |  
 18309 |       #ifndef exprtk_disable_string_capabilities 
 18310 |       template <typename T, typename SType0, typename SType1, typename Operation> 
 18311 |       class sos_node exprtk_final : public sos_base_node<T> 
 18312 |       { 
 18313 |       public: 
 18314 |  
 18315 |          typedef expression_node<T>* expression_ptr; 
 18316 |          typedef Operation operation_t; 
 18317 |  
 18318 |          // string op string node 
 18319 |          explicit sos_node(SType0 p0, SType1 p1) 
 18320 |          : s0_(p0) 
 18321 |          , s1_(p1) 
 18322 |          {} 
 18323 |  
 18324 |          inline T value() const exprtk_override 
 18325 |          { 
 18326 |             return Operation::process(s0_,s1_); 
 18327 |          } 
 18328 |  
 18329 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18330 |          { 
 18331 |             return Operation::type(); 
 18332 |          } 
 18333 |  
 18334 |          inline operator_type operation() const exprtk_override 
 18335 |          { 
 18336 |             return Operation::operation(); 
 18337 |          } 
 18338 |  
 18339 |          inline std::string& s0() 
 18340 |          { 
 18341 |             return s0_; 
 18342 |          } 
 18343 |  
 18344 |          inline std::string& s1() 
 18345 |          { 
 18346 |             return s1_; 
 18347 |          } 
 18348 |  
 18349 |       protected: 
 18350 |  
 18351 |          SType0 s0_; 
 18352 |          SType1 s1_; 
 18353 |  
 18354 |       private: 
 18355 |  
 18356 |          sos_node(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete; 
 18357 |          sos_node<T,SType0,SType1,Operation>& operator=(const sos_node<T,SType0,SType1,Operation>&) exprtk_delete; 
 18358 |       }; 
 18359 |  
 18360 |       template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation> 
 18361 |       class str_xrox_node exprtk_final : public sos_base_node<T> 
 18362 |       { 
 18363 |       public: 
 18364 |  
 18365 |          typedef expression_node<T>* expression_ptr; 
 18366 |          typedef Operation operation_t; 
 18367 |          typedef str_xrox_node<T,SType0,SType1,RangePack,Operation> node_type; 
 18368 |  
 18369 |          // string-range op string node 
 18370 |          explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0) 
 18371 |          : s0_ (p0 ) 
 18372 |          , s1_ (p1 ) 
 18373 |          , rp0_(rp0) 
 18374 |          {} 
 18375 |  
 18376 |         ~str_xrox_node() 
 18377 |          { 
 18378 |             rp0_.free(); 
 18379 |          } 
 18380 |  
 18381 |          inline T value() const exprtk_override 
 18382 |          { 
 18383 |             std::size_t r0 = 0; 
 18384 |             std::size_t r1 = 0; 
 18385 |  
 18386 |             if (rp0_(r0, r1, s0_.size())) 
 18387 |                return Operation::process(s0_.substr(r0, (r1 - r0) + 1), s1_); 
 18388 |             else 
 18389 |                return T(0); 
 18390 |          } 
 18391 |  
 18392 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18393 |          { 
 18394 |             return Operation::type(); 
 18395 |          } 
 18396 |  
 18397 |          inline operator_type operation() const exprtk_override 
 18398 |          { 
 18399 |             return Operation::operation(); 
 18400 |          } 
 18401 |  
 18402 |          inline std::string& s0() 
 18403 |          { 
 18404 |             return s0_; 
 18405 |          } 
 18406 |  
 18407 |          inline std::string& s1() 
 18408 |          { 
 18409 |             return s1_; 
 18410 |          } 
 18411 |  
 18412 |       protected: 
 18413 |  
 18414 |          SType0    s0_; 
 18415 |          SType1    s1_; 
 18416 |          RangePack rp0_; 
 18417 |  
 18418 |       private: 
 18419 |  
 18420 |          str_xrox_node(const node_type&) exprtk_delete; 
 18421 |          node_type& operator=(const node_type&) exprtk_delete; 
 18422 |       }; 
 18423 |  
 18424 |       template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation> 
 18425 |       class str_xoxr_node exprtk_final : public sos_base_node<T> 
 18426 |       { 
 18427 |       public: 
 18428 |  
 18429 |          typedef expression_node<T>* expression_ptr; 
 18430 |          typedef Operation operation_t; 
 18431 |          typedef str_xoxr_node<T,SType0,SType1,RangePack,Operation> node_type; 
 18432 |  
 18433 |          // string op string range node 
 18434 |          explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1) 
 18435 |          : s0_ (p0 ) 
 18436 |          , s1_ (p1 ) 
 18437 |          , rp1_(rp1) 
 18438 |          {} 
 18439 |  
 18440 |         ~str_xoxr_node() 
 18441 |          { 
 18442 |             rp1_.free(); 
 18443 |          } 
 18444 |  
 18445 |          inline T value() const exprtk_override 
 18446 |          { 
 18447 |             std::size_t r0 = 0; 
 18448 |             std::size_t r1 = 0; 
 18449 |  
 18450 |             if (rp1_(r0, r1, s1_.size())) 
 18451 |             { 
 18452 |                return Operation::process 
 18453 |                       ( 
 18454 |                          s0_, 
 18455 |                          s1_.substr(r0, (r1 - r0) + 1) 
 18456 |                       ); 
 18457 |             } 
 18458 |             else 
 18459 |                return T(0); 
 18460 |          } 
 18461 |  
 18462 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18463 |          { 
 18464 |             return Operation::type(); 
 18465 |          } 
 18466 |  
 18467 |          inline operator_type operation() const exprtk_override 
 18468 |          { 
 18469 |             return Operation::operation(); 
 18470 |          } 
 18471 |  
 18472 |          inline std::string& s0() 
 18473 |          { 
 18474 |             return s0_; 
 18475 |          } 
 18476 |  
 18477 |          inline std::string& s1() 
 18478 |          { 
 18479 |             return s1_; 
 18480 |          } 
 18481 |  
 18482 |       protected: 
 18483 |  
 18484 |          SType0    s0_; 
 18485 |          SType1    s1_; 
 18486 |          RangePack rp1_; 
 18487 |  
 18488 |       private: 
 18489 |  
 18490 |          str_xoxr_node(const node_type&) exprtk_delete; 
 18491 |          node_type& operator=(const node_type&) exprtk_delete; 
 18492 |       }; 
 18493 |  
 18494 |       template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation> 
 18495 |       class str_xroxr_node exprtk_final : public sos_base_node<T> 
 18496 |       { 
 18497 |       public: 
 18498 |  
 18499 |          typedef expression_node<T>* expression_ptr; 
 18500 |          typedef Operation operation_t; 
 18501 |          typedef str_xroxr_node<T,SType0,SType1,RangePack,Operation> node_type; 
 18502 |  
 18503 |          // string-range op string-range node 
 18504 |          explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1) 
 18505 |          : s0_ (p0 ) 
 18506 |          , s1_ (p1 ) 
 18507 |          , rp0_(rp0) 
 18508 |          , rp1_(rp1) 
 18509 |          {} 
 18510 |  
 18511 |         ~str_xroxr_node() 
 18512 |          { 
 18513 |             rp0_.free(); 
 18514 |             rp1_.free(); 
 18515 |          } 
 18516 |  
 18517 |          inline T value() const exprtk_override 
 18518 |          { 
 18519 |             std::size_t r0_0 = 0; 
 18520 |             std::size_t r0_1 = 0; 
 18521 |             std::size_t r1_0 = 0; 
 18522 |             std::size_t r1_1 = 0; 
 18523 |  
 18524 |             if ( 
 18525 |                  rp0_(r0_0, r1_0, s0_.size()) && 
 18526 |                  rp1_(r0_1, r1_1, s1_.size()) 
 18527 |                ) 
 18528 |             { 
 18529 |                return Operation::process 
 18530 |                       ( 
 18531 |                          s0_.substr(r0_0, (r1_0 - r0_0) + 1), 
 18532 |                          s1_.substr(r0_1, (r1_1 - r0_1) + 1) 
 18533 |                       ); 
 18534 |             } 
 18535 |             else 
 18536 |                return T(0); 
 18537 |          } 
 18538 |  
 18539 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18540 |          { 
 18541 |             return Operation::type(); 
 18542 |          } 
 18543 |  
 18544 |          inline operator_type operation() const exprtk_override 
 18545 |          { 
 18546 |             return Operation::operation(); 
 18547 |          } 
 18548 |  
 18549 |          inline std::string& s0() 
 18550 |          { 
 18551 |             return s0_; 
 18552 |          } 
 18553 |  
 18554 |          inline std::string& s1() 
 18555 |          { 
 18556 |             return s1_; 
 18557 |          } 
 18558 |  
 18559 |       protected: 
 18560 |  
 18561 |          SType0    s0_; 
 18562 |          SType1    s1_; 
 18563 |          RangePack rp0_; 
 18564 |          RangePack rp1_; 
 18565 |  
 18566 |       private: 
 18567 |  
 18568 |          str_xroxr_node(const node_type&) exprtk_delete; 
 18569 |          node_type& operator=(const node_type&) exprtk_delete; 
 18570 |       }; 
 18571 |  
 18572 |       template <typename T, typename Operation> 
 18573 |       class str_sogens_node exprtk_final : public binary_node<T> 
 18574 |       { 
 18575 |       public: 
 18576 |  
 18577 |          typedef expression_node <T>* expression_ptr; 
 18578 |          typedef string_base_node<T>* str_base_ptr; 
 18579 |          typedef range_pack      <T>  range_t; 
 18580 |          typedef range_t*             range_ptr; 
 18581 |          typedef range_interface <T>  irange_t; 
 18582 |          typedef irange_t*            irange_ptr; 
 18583 |  
 18584 |          using binary_node<T>::branch; 
 18585 |  
 18586 |          str_sogens_node(const operator_type& opr, 
 18587 |                          expression_ptr branch0, 
 18588 |                          expression_ptr branch1) 
 18589 |          : binary_node<T>(opr, branch0, branch1) 
 18590 |          , str0_base_ptr_ (0) 
 18591 |          , str1_base_ptr_ (0) 
 18592 |          , str0_range_ptr_(0) 
 18593 |          , str1_range_ptr_(0) 
 18594 |          , initialised_   (false) 
 18595 |          { 
 18596 |             if (is_generally_string_node(branch(0))) 
 18597 |             { 
 18598 |                str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); 
 18599 |  
 18600 |                if (0 == str0_base_ptr_) 
 18601 |                   return; 
 18602 |  
 18603 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(0)); 
 18604 |  
 18605 |                if (0 == range) 
 18606 |                   return; 
 18607 |  
 18608 |                str0_range_ptr_ = &(range->range_ref()); 
 18609 |             } 
 18610 |  
 18611 |             if (is_generally_string_node(branch(1))) 
 18612 |             { 
 18613 |                str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); 
 18614 |  
 18615 |                if (0 == str1_base_ptr_) 
 18616 |                   return; 
 18617 |  
 18618 |                irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); 
 18619 |  
 18620 |                if (0 == range) 
 18621 |                   return; 
 18622 |  
 18623 |                str1_range_ptr_ = &(range->range_ref()); 
 18624 |             } 
 18625 |  
 18626 |             initialised_ = 
 18627 |                str0_base_ptr_  && 
 18628 |                str1_base_ptr_  && 
 18629 |                str0_range_ptr_ && 
 18630 |                str1_range_ptr_; 
 18631 |  
 18632 |             assert(valid()); 
 18633 |          } 
 18634 |  
 18635 |          inline T value() const exprtk_override 
 18636 |          { 
 18637 |             branch(0)->value(); 
 18638 |             branch(1)->value(); 
 18639 |  
 18640 |             std::size_t str0_r0 = 0; 
 18641 |             std::size_t str0_r1 = 0; 
 18642 |  
 18643 |             std::size_t str1_r0 = 0; 
 18644 |             std::size_t str1_r1 = 0; 
 18645 |  
 18646 |             const range_t& range0 = (*str0_range_ptr_); 
 18647 |             const range_t& range1 = (*str1_range_ptr_); 
 18648 |  
 18649 |             if ( 
 18650 |                  range0(str0_r0, str0_r1, str0_base_ptr_->size()) && 
 18651 |                  range1(str1_r0, str1_r1, str1_base_ptr_->size()) 
 18652 |                ) 
 18653 |             { 
 18654 |                return Operation::process 
 18655 |                       ( 
 18656 |                          str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0)), 
 18657 |                          str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0)) 
 18658 |                       ); 
 18659 |             } 
 18660 |  
 18661 |             return std::numeric_limits<T>::quiet_NaN(); 
 18662 |          } 
 18663 |  
 18664 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18665 |          { 
 18666 |             return Operation::type(); 
 18667 |          } 
 18668 |  
 18669 |          inline bool valid() const exprtk_override 
 18670 |          { 
 18671 |             return initialised_; 
 18672 |          } 
 18673 |  
 18674 |       private: 
 18675 |  
 18676 |          str_sogens_node(const str_sogens_node<T,Operation>&) exprtk_delete; 
 18677 |          str_sogens_node<T,Operation>& operator=(const str_sogens_node<T,Operation>&) exprtk_delete; 
 18678 |  
 18679 |          str_base_ptr str0_base_ptr_; 
 18680 |          str_base_ptr str1_base_ptr_; 
 18681 |          range_ptr    str0_range_ptr_; 
 18682 |          range_ptr    str1_range_ptr_; 
 18683 |          bool         initialised_; 
 18684 |       }; 
 18685 |  
 18686 |       template <typename T, typename SType0, typename SType1, typename SType2, typename Operation> 
 18687 |       class sosos_node exprtk_final : public sosos_base_node<T> 
 18688 |       { 
 18689 |       public: 
 18690 |  
 18691 |          typedef expression_node<T>* expression_ptr; 
 18692 |          typedef Operation operation_t; 
 18693 |          typedef sosos_node<T, SType0, SType1, SType2, Operation> node_type; 
 18694 |  
 18695 |          // string op string op string node 
 18696 |          explicit sosos_node(SType0 p0, SType1 p1, SType2 p2) 
 18697 |          : s0_(p0) 
 18698 |          , s1_(p1) 
 18699 |          , s2_(p2) 
 18700 |          {} 
 18701 |  
 18702 |          inline T value() const exprtk_override 
 18703 |          { 
 18704 |             return Operation::process(s0_, s1_, s2_); 
 18705 |          } 
 18706 |  
 18707 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18708 |          { 
 18709 |             return Operation::type(); 
 18710 |          } 
 18711 |  
 18712 |          inline operator_type operation() const exprtk_override 
 18713 |          { 
 18714 |             return Operation::operation(); 
 18715 |          } 
 18716 |  
 18717 |          inline std::string& s0() 
 18718 |          { 
 18719 |             return s0_; 
 18720 |          } 
 18721 |  
 18722 |          inline std::string& s1() 
 18723 |          { 
 18724 |             return s1_; 
 18725 |          } 
 18726 |  
 18727 |          inline std::string& s2() 
 18728 |          { 
 18729 |             return s2_; 
 18730 |          } 
 18731 |  
 18732 |       protected: 
 18733 |  
 18734 |          SType0 s0_; 
 18735 |          SType1 s1_; 
 18736 |          SType2 s2_; 
 18737 |  
 18738 |       private: 
 18739 |  
 18740 |          sosos_node(const node_type&) exprtk_delete; 
 18741 |          node_type& operator=(const node_type&) exprtk_delete; 
 18742 |       }; 
 18743 |       #endif 
 18744 |  
 18745 |       template <typename T, typename PowOp> 
 18746 |       class ipow_node exprtk_final: public expression_node<T> 
 18747 |       { 
 18748 |       public: 
 18749 |  
 18750 |          typedef expression_node<T>* expression_ptr; 
 18751 |          typedef PowOp operation_t; 
 18752 |  
 18753 |          explicit ipow_node(const T& v) 
 18754 |          : v_(v) 
 18755 |          {} 
 18756 |  
 18757 |          inline T value() const exprtk_override 
 18758 |          { 
 18759 |             return PowOp::result(v_); 
 18760 |          } 
 18761 |  
 18762 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18763 |          { 
 18764 |             return expression_node<T>::e_ipow; 
 18765 |          } 
 18766 |  
 18767 |       private: 
 18768 |  
 18769 |          ipow_node(const ipow_node<T,PowOp>&) exprtk_delete; 
 18770 |          ipow_node<T,PowOp>& operator=(const ipow_node<T,PowOp>&) exprtk_delete; 
 18771 |  
 18772 |          const T& v_; 
 18773 |       }; 
 18774 |  
 18775 |       template <typename T, typename PowOp> 
 18776 |       class bipow_node exprtk_final : public expression_node<T> 
 18777 |       { 
 18778 |       public: 
 18779 |  
 18780 |          typedef expression_node<T>* expression_ptr; 
 18781 |          typedef std::pair<expression_ptr, bool> branch_t; 
 18782 |          typedef PowOp operation_t; 
 18783 |  
 18784 |          explicit bipow_node(expression_ptr branch) 
 18785 |          { 
 18786 |             construct_branch_pair(branch_, branch); 
 18787 |             assert(valid()); 
 18788 |          } 
 18789 |  
 18790 |          inline T value() const exprtk_override 
 18791 |          { 
 18792 |             return PowOp::result(branch_.first->value()); 
 18793 |          } 
 18794 |  
 18795 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18796 |          { 
 18797 |             return expression_node<T>::e_ipow; 
 18798 |          } 
 18799 |  
 18800 |          inline bool valid() const exprtk_override 
 18801 |          { 
 18802 |             return branch_.first && branch_.first->valid(); 
 18803 |          } 
 18804 |  
 18805 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18806 |          { 
 18807 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18808 |          } 
 18809 |  
 18810 |          std::size_t node_depth() const exprtk_override 
 18811 |          { 
 18812 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18813 |          } 
 18814 |  
 18815 |       private: 
 18816 |  
 18817 |          bipow_node(const bipow_node<T,PowOp>&) exprtk_delete; 
 18818 |          bipow_node<T,PowOp>& operator=(const bipow_node<T,PowOp>&) exprtk_delete; 
 18819 |  
 18820 |          branch_t branch_; 
 18821 |       }; 
 18822 |  
 18823 |       template <typename T, typename PowOp> 
 18824 |       class ipowinv_node exprtk_final : public expression_node<T> 
 18825 |       { 
 18826 |       public: 
 18827 |  
 18828 |          typedef expression_node<T>* expression_ptr; 
 18829 |          typedef PowOp operation_t; 
 18830 |  
 18831 |          explicit ipowinv_node(const T& v) 
 18832 |          : v_(v) 
 18833 |          {} 
 18834 |  
 18835 |          inline T value() const exprtk_override 
 18836 |          { 
 18837 |             return (T(1) / PowOp::result(v_)); 
 18838 |          } 
 18839 |  
 18840 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18841 |          { 
 18842 |             return expression_node<T>::e_ipowinv; 
 18843 |          } 
 18844 |  
 18845 |       private: 
 18846 |  
 18847 |          ipowinv_node(const ipowinv_node<T,PowOp>&) exprtk_delete; 
 18848 |          ipowinv_node<T,PowOp>& operator=(const ipowinv_node<T,PowOp>&) exprtk_delete; 
 18849 |  
 18850 |          const T& v_; 
 18851 |       }; 
 18852 |  
 18853 |       template <typename T, typename PowOp> 
 18854 |       class bipowinv_node exprtk_final : public expression_node<T> 
 18855 |       { 
 18856 |       public: 
 18857 |  
 18858 |          typedef expression_node<T>* expression_ptr; 
 18859 |          typedef std::pair<expression_ptr, bool> branch_t; 
 18860 |          typedef PowOp operation_t; 
 18861 |  
 18862 |          explicit bipowinv_node(expression_ptr branch) 
 18863 |          { 
 18864 |             construct_branch_pair(branch_, branch); 
 18865 |             assert(valid()); 
 18866 |          } 
 18867 |  
 18868 |          inline T value() const exprtk_override 
 18869 |          { 
 18870 |             return (T(1) / PowOp::result(branch_.first->value())); 
 18871 |          } 
 18872 |  
 18873 |          inline typename expression_node<T>::node_type type() const exprtk_override 
 18874 |          { 
 18875 |             return expression_node<T>::e_ipowinv; 
 18876 |          } 
 18877 |  
 18878 |          inline bool valid() const exprtk_override 
 18879 |          { 
 18880 |             return branch_.first && branch_.first->valid(); 
 18881 |          } 
 18882 |  
 18883 |          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) exprtk_override 
 18884 |          { 
 18885 |             expression_node<T>::ndb_t::collect(branch_, node_delete_list); 
 18886 |          } 
 18887 |  
 18888 |          std::size_t node_depth() const exprtk_override 
 18889 |          { 
 18890 |             return expression_node<T>::ndb_t::compute_node_depth(branch_); 
 18891 |          } 
 18892 |  
 18893 |       private: 
 18894 |  
 18895 |          bipowinv_node(const bipowinv_node<T,PowOp>&) exprtk_delete; 
 18896 |          bipowinv_node<T,PowOp>& operator=(const bipowinv_node<T,PowOp>&) exprtk_delete; 
 18897 |  
 18898 |          branch_t branch_; 
 18899 |       }; 
 18900 |  
 18901 |       template <typename T> 
 18902 |       inline bool is_vov_node(const expression_node<T>* node) 
 18903 |       { 
 18904 |          return (0 != dynamic_cast<const vov_base_node<T>*>(node)); 
 18905 |       } 
 18906 |  
 18907 |       template <typename T> 
 18908 |       inline bool is_cov_node(const expression_node<T>* node) 
 18909 |       { 
 18910 |          return (0 != dynamic_cast<const cov_base_node<T>*>(node)); 
 18911 |       } 
 18912 |  
 18913 |       template <typename T> 
 18914 |       inline bool is_voc_node(const expression_node<T>* node) 
 18915 |       { 
 18916 |          return (0 != dynamic_cast<const voc_base_node<T>*>(node)); 
 18917 |       } 
 18918 |  
 18919 |       template <typename T> 
 18920 |       inline bool is_cob_node(const expression_node<T>* node) 
 18921 |       { 
 18922 |          return (0 != dynamic_cast<const cob_base_node<T>*>(node)); 
 18923 |       } 
 18924 |  
 18925 |       template <typename T> 
 18926 |       inline bool is_boc_node(const expression_node<T>* node) 
 18927 |       { 
 18928 |          return (0 != dynamic_cast<const boc_base_node<T>*>(node)); 
 18929 |       } 
 18930 |  
 18931 |       template <typename T> 
 18932 |       inline bool is_t0ot1ot2_node(const expression_node<T>* node) 
 18933 |       { 
 18934 |          return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node)); 
 18935 |       } 
 18936 |  
 18937 |       template <typename T> 
 18938 |       inline bool is_t0ot1ot2ot3_node(const expression_node<T>* node) 
 18939 |       { 
 18940 |          return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node)); 
 18941 |       } 
 18942 |  
 18943 |       template <typename T> 
 18944 |       inline bool is_uv_node(const expression_node<T>* node) 
 18945 |       { 
 18946 |          return (0 != dynamic_cast<const uv_base_node<T>*>(node)); 
 18947 |       } 
 18948 |  
 18949 |       template <typename T> 
 18950 |       inline bool is_string_node(const expression_node<T>* node) 
 18951 |       { 
 18952 |          return node && (expression_node<T>::e_stringvar == node->type()); 
 18953 |       } 
 18954 |  
 18955 |       template <typename T> 
 18956 |       inline bool is_string_range_node(const expression_node<T>* node) 
 18957 |       { 
 18958 |          return node && (expression_node<T>::e_stringvarrng == node->type()); 
 18959 |       } 
 18960 |  
 18961 |       template <typename T> 
 18962 |       inline bool is_const_string_node(const expression_node<T>* node) 
 18963 |       { 
 18964 |          return node && (expression_node<T>::e_stringconst == node->type()); 
 18965 |       } 
 18966 |  
 18967 |       template <typename T> 
 18968 |       inline bool is_const_string_range_node(const expression_node<T>* node) 
 18969 |       { 
 18970 |          return node && (expression_node<T>::e_cstringvarrng == node->type()); 
 18971 |       } 
 18972 |  
 18973 |       template <typename T> 
 18974 |       inline bool is_string_assignment_node(const expression_node<T>* node) 
 18975 |       { 
 18976 |          return node && (expression_node<T>::e_strass == node->type()); 
 18977 |       } 
 18978 |  
 18979 |       template <typename T> 
 18980 |       inline bool is_string_concat_node(const expression_node<T>* node) 
 18981 |       { 
 18982 |          return node && (expression_node<T>::e_strconcat == node->type()); 
 18983 |       } 
 18984 |  
 18985 |       template <typename T> 
 18986 |       inline bool is_string_function_node(const expression_node<T>* node) 
 18987 |       { 
 18988 |          return node && (expression_node<T>::e_strfunction == node->type()); 
 18989 |       } 
 18990 |  
 18991 |       template <typename T> 
 18992 |       inline bool is_string_condition_node(const expression_node<T>* node) 
 18993 |       { 
 18994 |          return node && (expression_node<T>::e_strcondition == node->type()); 
 18995 |       } 
 18996 |  
 18997 |       template <typename T> 
 18998 |       inline bool is_string_ccondition_node(const expression_node<T>* node) 
 18999 |       { 
 19000 |          return node && (expression_node<T>::e_strccondition == node->type()); 
 19001 |       } 
 19002 |  
 19003 |       template <typename T> 
 19004 |       inline bool is_string_vararg_node(const expression_node<T>* node) 
 19005 |       { 
 19006 |          return node && (expression_node<T>::e_stringvararg == node->type()); 
 19007 |       } 
 19008 |  
 19009 |       template <typename T> 
 19010 |       inline bool is_genricstring_range_node(const expression_node<T>* node) 
 19011 |       { 
 19012 |          return node && (expression_node<T>::e_strgenrange == node->type()); 
 19013 |       } 
 19014 |  
 19015 |       template <typename T> 
 19016 |       inline bool is_generally_string_node(const expression_node<T>* node) 
 19017 |       { 
 19018 |          if (node) 
 19019 |          { 
 19020 |             switch (node->type()) 
 19021 |             { 
 19022 |                case expression_node<T>::e_stringvar     : 
 19023 |                case expression_node<T>::e_stringconst   : 
 19024 |                case expression_node<T>::e_stringvarrng  : 
 19025 |                case expression_node<T>::e_cstringvarrng : 
 19026 |                case expression_node<T>::e_strgenrange   : 
 19027 |                case expression_node<T>::e_strass        : 
 19028 |                case expression_node<T>::e_strconcat     : 
 19029 |                case expression_node<T>::e_strfunction   : 
 19030 |                case expression_node<T>::e_strcondition  : 
 19031 |                case expression_node<T>::e_strccondition : 
 19032 |                case expression_node<T>::e_stringvararg  : return true; 
 19033 |                default                                  : return false; 
 19034 |             } 
 19035 |          } 
 19036 |  
 19037 |          return false; 
 19038 |       } 
 19039 |  
 19040 |       template <typename T> 
 19041 |       inline bool is_loop_node(const expression_node<T>* node) 
 19042 |       { 
 19043 |          if (node) 
 19044 |          { 
 19045 |             switch (node->type()) 
 19046 |             { 
 19047 |                case expression_node<T>::e_for    : 
 19048 |                case expression_node<T>::e_repeat : 
 19049 |                case expression_node<T>::e_while  : return true; 
 19050 |                default                           : return false; 
 19051 |             } 
 19052 |          } 
 19053 |  
 19054 |          return false; 
 19055 |       } 
 19056 |  
 19057 |       template <typename T> 
 19058 |       inline bool is_block_node(const expression_node<T>* node) 
 19059 |       { 
 19060 |          if (node) 
 19061 |          { 
 19062 |             if (is_loop_node(node)) 
 19063 |             { 
 19064 |                return true; 
 19065 |             } 
 19066 |  
 19067 |             switch (node->type()) 
 19068 |             { 
 19069 |                case expression_node<T>::e_conditional : 
 19070 |                case expression_node<T>::e_mswitch     : 
 19071 |                case expression_node<T>::e_switch      : 
 19072 |                case expression_node<T>::e_vararg      : return true; 
 19073 |                default                                : return false; 
 19074 |             } 
 19075 |          } 
 19076 |  
 19077 |          return false; 
 19078 |       } 
 19079 |  
 19080 |       class node_allocator 
 19081 |       { 
 19082 |       public: 
 19083 |  
 19084 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19085 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1]) 
 19086 |          { 
 19087 |             expression_node<typename ResultNode::value_type>* result = 
 19088 |                allocate<ResultNode>(operation, branch[0]); 
 19089 |             result->node_depth(); 
 19090 |             return result; 
 19091 |          } 
 19092 |  
 19093 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19094 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[2]) 
 19095 |          { 
 19096 |             expression_node<typename ResultNode::value_type>* result = 
 19097 |                allocate<ResultNode>(operation, branch[0], branch[1]); 
 19098 |             result->node_depth(); 
 19099 |             return result; 
 19100 |          } 
 19101 |  
 19102 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19103 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[3]) 
 19104 |          { 
 19105 |             expression_node<typename ResultNode::value_type>* result = 
 19106 |                allocate<ResultNode>(operation, branch[0], branch[1], branch[2]); 
 19107 |             result->node_depth(); 
 19108 |             return result; 
 19109 |          } 
 19110 |  
 19111 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19112 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[4]) 
 19113 |          { 
 19114 |             expression_node<typename ResultNode::value_type>* result = 
 19115 |                allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3]); 
 19116 |             result->node_depth(); 
 19117 |             return result; 
 19118 |          } 
 19119 |  
 19120 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19121 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5]) 
 19122 |          { 
 19123 |             expression_node<typename ResultNode::value_type>* result = 
 19124 |                allocate<ResultNode>(operation, branch[0],branch[1], branch[2], branch[3], branch[4]); 
 19125 |             result->node_depth(); 
 19126 |             return result; 
 19127 |          } 
 19128 |  
 19129 |          template <typename ResultNode, typename OpType, typename ExprNode> 
 19130 |          inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6]) 
 19131 |          { 
 19132 |             expression_node<typename ResultNode::value_type>* result = 
 19133 |                allocate<ResultNode>(operation, branch[0], branch[1], branch[2], branch[3], branch[4], branch[5]); 
 19134 |             result->node_depth(); 
 19135 |             return result; 
 19136 |          } 
 19137 |  
 19138 |          template <typename node_type> 
 19139 |          inline expression_node<typename node_type::value_type>* allocate() const 
 19140 |          { 
 19141 |             return (new node_type()); 
 19142 |          } 
 19143 |  
 19144 |          template <typename node_type, 
 19145 |                    typename Type, 
 19146 |                    typename Allocator, 
 19147 |                    template <typename, typename> class Sequence> 
 19148 |          inline expression_node<typename node_type::value_type>* allocate(const Sequence<Type,Allocator>& seq) const 
 19149 |          { 
 19150 |             expression_node<typename node_type::value_type>* 
 19151 |             result = (new node_type(seq)); 
 19152 |             result->node_depth(); 
 19153 |             return result; 
 19154 |          } 
 19155 |  
 19156 |          template <typename node_type, typename T1> 
 19157 |          inline expression_node<typename node_type::value_type>* allocate(T1& t1) const 
 19158 |          { 
 19159 |             expression_node<typename node_type::value_type>* 
 19160 |             result = (new node_type(t1)); 
 19161 |             result->node_depth(); 
 19162 |             return result; 
 19163 |          } 
 19164 |  
 19165 |          template <typename node_type, typename T1> 
 19166 |          inline expression_node<typename node_type::value_type>* allocate_c(const T1& t1) const 
 19167 |          { 
 19168 |             expression_node<typename node_type::value_type>* 
 19169 |             result = (new node_type(t1)); 
 19170 |             result->node_depth(); 
 19171 |             return result; 
 19172 |          } 
 19173 |  
 19174 |          template <typename node_type, 
 19175 |                    typename T1, typename T2> 
 19176 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const 
 19177 |          { 
 19178 |             expression_node<typename node_type::value_type>* 
 19179 |             result = (new node_type(t1, t2)); 
 19180 |             result->node_depth(); 
 19181 |             return result; 
 19182 |          } 
 19183 |  
 19184 |          template <typename node_type, 
 19185 |                    typename T1, typename T2> 
 19186 |          inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const 
 19187 |          { 
 19188 |             expression_node<typename node_type::value_type>* 
 19189 |             result = (new node_type(t1, t2)); 
 19190 |             result->node_depth(); 
 19191 |             return result; 
 19192 |          } 
 19193 |  
 19194 |          template <typename node_type, 
 19195 |                    typename T1, typename T2> 
 19196 |          inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const 
 19197 |          { 
 19198 |             expression_node<typename node_type::value_type>* 
 19199 |             result = (new node_type(t1, t2)); 
 19200 |             result->node_depth(); 
 19201 |             return result; 
 19202 |          } 
 19203 |  
 19204 |          template <typename node_type, 
 19205 |                    typename T1, typename T2> 
 19206 |          inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const 
 19207 |          { 
 19208 |             expression_node<typename node_type::value_type>* 
 19209 |             result = (new node_type(t1, t2)); 
 19210 |             result->node_depth(); 
 19211 |             return result; 
 19212 |          } 
 19213 |  
 19214 |          template <typename node_type, 
 19215 |                    typename T1, typename T2> 
 19216 |          inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const 
 19217 |          { 
 19218 |             expression_node<typename node_type::value_type>* 
 19219 |             result = (new node_type(t1, t2)); 
 19220 |             result->node_depth(); 
 19221 |             return result; 
 19222 |          } 
 19223 |  
 19224 |          template <typename node_type, 
 19225 |                    typename T1, typename T2, typename T3> 
 19226 |          inline expression_node<typename node_type::value_type>* allocate_ttt(T1 t1, T2 t2, T3 t3) const 
 19227 |          { 
 19228 |             expression_node<typename node_type::value_type>* 
 19229 |             result = (new node_type(t1, t2, t3)); 
 19230 |             result->node_depth(); 
 19231 |             return result; 
 19232 |          } 
 19233 |  
 19234 |          template <typename node_type, 
 19235 |                    typename T1, typename T2, typename T3, typename T4> 
 19236 |          inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const 
 19237 |          { 
 19238 |             expression_node<typename node_type::value_type>* 
 19239 |             result = (new node_type(t1, t2, t3, t4)); 
 19240 |             result->node_depth(); 
 19241 |             return result; 
 19242 |          } 
 19243 |  
 19244 |          template <typename node_type, 
 19245 |                    typename T1, typename T2, typename T3> 
 19246 |          inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const 
 19247 |          { 
 19248 |             expression_node<typename node_type::value_type>* 
 19249 |             result = (new node_type(t1, t2, t3)); 
 19250 |             result->node_depth(); 
 19251 |             return result; 
 19252 |          } 
 19253 |  
 19254 |          template <typename node_type, 
 19255 |                    typename T1, typename T2, typename T3, typename T4> 
 19256 |          inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const 
 19257 |          { 
 19258 |             expression_node<typename node_type::value_type>* 
 19259 |             result = (new node_type(t1, t2, t3, t4)); 
 19260 |             result->node_depth(); 
 19261 |             return result; 
 19262 |          } 
 19263 |  
 19264 |          template <typename node_type, 
 19265 |                    typename T1, typename T2, typename T3, typename T4, typename T5> 
 19266 |          inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const 
 19267 |          { 
 19268 |             expression_node<typename node_type::value_type>* 
 19269 |             result = (new node_type(t1, t2, t3, t4, t5)); 
 19270 |             result->node_depth(); 
 19271 |             return result; 
 19272 |          } 
 19273 |  
 19274 |          template <typename node_type, 
 19275 |                    typename T1, typename T2, typename T3> 
 19276 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19277 |                                                                           const T3& t3) const 
 19278 |          { 
 19279 |             expression_node<typename node_type::value_type>* 
 19280 |             result = (new node_type(t1, t2, t3)); 
 19281 |             result->node_depth(); 
 19282 |             return result; 
 19283 |          } 
 19284 |  
 19285 |          template <typename node_type, 
 19286 |                    typename T1, typename T2, 
 19287 |                    typename T3, typename T4> 
 19288 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19289 |                                                                           const T3& t3, const T4& t4) const 
 19290 |          { 
 19291 |             expression_node<typename node_type::value_type>* 
 19292 |             result = (new node_type(t1, t2, t3, t4)); 
 19293 |             result->node_depth(); 
 19294 |             return result; 
 19295 |          } 
 19296 |  
 19297 |          template <typename node_type, 
 19298 |                    typename T1, typename T2, 
 19299 |                    typename T3, typename T4, typename T5> 
 19300 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19301 |                                                                           const T3& t3, const T4& t4, 
 19302 |                                                                           const T5& t5) const 
 19303 |          { 
 19304 |             expression_node<typename node_type::value_type>* 
 19305 |             result = (new node_type(t1, t2, t3, t4, t5)); 
 19306 |             result->node_depth(); 
 19307 |             return result; 
 19308 |          } 
 19309 |  
 19310 |          template <typename node_type, 
 19311 |                    typename T1, typename T2, 
 19312 |                    typename T3, typename T4, typename T5, typename T6> 
 19313 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19314 |                                                                           const T3& t3, const T4& t4, 
 19315 |                                                                           const T5& t5, const T6& t6) const 
 19316 |          { 
 19317 |             expression_node<typename node_type::value_type>* 
 19318 |             result = (new node_type(t1, t2, t3, t4, t5, t6)); 
 19319 |             result->node_depth(); 
 19320 |             return result; 
 19321 |          } 
 19322 |  
 19323 |          template <typename node_type, 
 19324 |                    typename T1, typename T2, 
 19325 |                    typename T3, typename T4, 
 19326 |                    typename T5, typename T6, typename T7> 
 19327 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19328 |                                                                           const T3& t3, const T4& t4, 
 19329 |                                                                           const T5& t5, const T6& t6, 
 19330 |                                                                           const T7& t7) const 
 19331 |          { 
 19332 |             expression_node<typename node_type::value_type>* 
 19333 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7)); 
 19334 |             result->node_depth(); 
 19335 |             return result; 
 19336 |          } 
 19337 |  
 19338 |          template <typename node_type, 
 19339 |                    typename T1, typename T2, 
 19340 |                    typename T3, typename T4, 
 19341 |                    typename T5, typename T6, 
 19342 |                    typename T7, typename T8> 
 19343 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19344 |                                                                           const T3& t3, const T4& t4, 
 19345 |                                                                           const T5& t5, const T6& t6, 
 19346 |                                                                           const T7& t7, const T8& t8) const 
 19347 |          { 
 19348 |             expression_node<typename node_type::value_type>* 
 19349 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8)); 
 19350 |             result->node_depth(); 
 19351 |             return result; 
 19352 |          } 
 19353 |  
 19354 |          template <typename node_type, 
 19355 |                    typename T1, typename T2, 
 19356 |                    typename T3, typename T4, 
 19357 |                    typename T5, typename T6, 
 19358 |                    typename T7, typename T8, typename T9> 
 19359 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, 
 19360 |                                                                           const T3& t3, const T4& t4, 
 19361 |                                                                           const T5& t5, const T6& t6, 
 19362 |                                                                           const T7& t7, const T8& t8, 
 19363 |                                                                           const T9& t9) const 
 19364 |          { 
 19365 |             expression_node<typename node_type::value_type>* 
 19366 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9)); 
 19367 |             result->node_depth(); 
 19368 |             return result; 
 19369 |          } 
 19370 |  
 19371 |          template <typename node_type, 
 19372 |                    typename T1, typename T2, 
 19373 |                    typename T3, typename T4, 
 19374 |                    typename T5, typename T6, 
 19375 |                    typename T7, typename T8, 
 19376 |                    typename T9, typename T10> 
 19377 |          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const  T2&  t2, 
 19378 |                                                                           const T3& t3, const  T4&  t4, 
 19379 |                                                                           const T5& t5, const  T6&  t6, 
 19380 |                                                                           const T7& t7, const  T8&  t8, 
 19381 |                                                                           const T9& t9, const T10& t10) const 
 19382 |          { 
 19383 |             expression_node<typename node_type::value_type>* 
 19384 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)); 
 19385 |             result->node_depth(); 
 19386 |             return result; 
 19387 |          } 
 19388 |  
 19389 |          template <typename node_type, 
 19390 |                    typename T1, typename T2, typename T3> 
 19391 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const 
 19392 |          { 
 19393 |             expression_node<typename node_type::value_type>* 
 19394 |             result = (new node_type(t1, t2, t3)); 
 19395 |             result->node_depth(); 
 19396 |             return result; 
 19397 |          } 
 19398 |  
 19399 |          template <typename node_type, 
 19400 |                    typename T1, typename T2, 
 19401 |                    typename T3, typename T4> 
 19402 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19403 |                                                                                T3 t3, T4 t4) const 
 19404 |          { 
 19405 |             expression_node<typename node_type::value_type>* 
 19406 |             result = (new node_type(t1, t2, t3, t4)); 
 19407 |             result->node_depth(); 
 19408 |             return result; 
 19409 |          } 
 19410 |  
 19411 |          template <typename node_type, 
 19412 |                    typename T1, typename T2, 
 19413 |                    typename T3, typename T4, 
 19414 |                    typename T5> 
 19415 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19416 |                                                                                T3 t3, T4 t4, 
 19417 |                                                                                T5 t5) const 
 19418 |          { 
 19419 |             expression_node<typename node_type::value_type>* 
 19420 |             result = (new node_type(t1, t2, t3, t4, t5)); 
 19421 |             result->node_depth(); 
 19422 |             return result; 
 19423 |          } 
 19424 |  
 19425 |          template <typename node_type, 
 19426 |                    typename T1, typename T2, 
 19427 |                    typename T3, typename T4, 
 19428 |                    typename T5, typename T6> 
 19429 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19430 |                                                                                T3 t3, T4 t4, 
 19431 |                                                                                T5 t5, T6 t6) const 
 19432 |          { 
 19433 |             expression_node<typename node_type::value_type>* 
 19434 |             result = (new node_type(t1, t2, t3, t4, t5, t6)); 
 19435 |             result->node_depth(); 
 19436 |             return result; 
 19437 |          } 
 19438 |  
 19439 |          template <typename node_type, 
 19440 |                    typename T1, typename T2, 
 19441 |                    typename T3, typename T4, 
 19442 |                    typename T5, typename T6, typename T7> 
 19443 |          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, 
 19444 |                                                                                T3 t3, T4 t4, 
 19445 |                                                                                T5 t5, T6 t6, 
 19446 |                                                                                T7 t7) const 
 19447 |          { 
 19448 |             expression_node<typename node_type::value_type>* 
 19449 |             result = (new node_type(t1, t2, t3, t4, t5, t6, t7)); 
 19450 |             result->node_depth(); 
 19451 |             return result; 
 19452 |          } 
 19453 |  
 19454 |          template <typename T> 
 19455 |          void inline free(expression_node<T>*& e) const 
 19456 |          { 
 19457 |             exprtk_debug(("node_allocator::free() - deleting expression_node " 
 19458 |                           "type: %03d addr: %p\n", 
 19459 |                           static_cast<int>(e->type()), 
 19460 |                           reinterpret_cast<void*>(e))); 
 19461 |             delete e; 
 19462 |             e = 0; 
 19463 |          } 
 19464 |       }; 
 19465 |  
 19466 |       inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m) 
 19467 |       { 
 19468 |          #define register_op(Symbol, Type, Args)                                             \ 
 19469 |          m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \ 
 19470 |  
 19471 |          register_op("abs"       , e_abs     , 1) 
 19472 |          register_op("acos"      , e_acos    , 1) 
 19473 |          register_op("acosh"     , e_acosh   , 1) 
 19474 |          register_op("asin"      , e_asin    , 1) 
 19475 |          register_op("asinh"     , e_asinh   , 1) 
 19476 |          register_op("atan"      , e_atan    , 1) 
 19477 |          register_op("atanh"     , e_atanh   , 1) 
 19478 |          register_op("ceil"      , e_ceil    , 1) 
 19479 |          register_op("cos"       , e_cos     , 1) 
 19480 |          register_op("cosh"      , e_cosh    , 1) 
 19481 |          register_op("exp"       , e_exp     , 1) 
 19482 |          register_op("expm1"     , e_expm1   , 1) 
 19483 |          register_op("floor"     , e_floor   , 1) 
 19484 |          register_op("log"       , e_log     , 1) 
 19485 |          register_op("log10"     , e_log10   , 1) 
 19486 |          register_op("log2"      , e_log2    , 1) 
 19487 |          register_op("log1p"     , e_log1p   , 1) 
 19488 |          register_op("round"     , e_round   , 1) 
 19489 |          register_op("sin"       , e_sin     , 1) 
 19490 |          register_op("sinc"      , e_sinc    , 1) 
 19491 |          register_op("sinh"      , e_sinh    , 1) 
 19492 |          register_op("sec"       , e_sec     , 1) 
 19493 |          register_op("csc"       , e_csc     , 1) 
 19494 |          register_op("sqrt"      , e_sqrt    , 1) 
 19495 |          register_op("tan"       , e_tan     , 1) 
 19496 |          register_op("tanh"      , e_tanh    , 1) 
 19497 |          register_op("cot"       , e_cot     , 1) 
 19498 |          register_op("rad2deg"   , e_r2d     , 1) 
 19499 |          register_op("deg2rad"   , e_d2r     , 1) 
 19500 |          register_op("deg2grad"  , e_d2g     , 1) 
 19501 |          register_op("grad2deg"  , e_g2d     , 1) 
 19502 |          register_op("sgn"       , e_sgn     , 1) 
 19503 |          register_op("not"       , e_notl    , 1) 
 19504 |          register_op("erf"       , e_erf     , 1) 
 19505 |          register_op("erfc"      , e_erfc    , 1) 
 19506 |          register_op("ncdf"      , e_ncdf    , 1) 
 19507 |          register_op("frac"      , e_frac    , 1) 
 19508 |          register_op("trunc"     , e_trunc   , 1) 
 19509 |          register_op("atan2"     , e_atan2   , 2) 
 19510 |          register_op("mod"       , e_mod     , 2) 
 19511 |          register_op("logn"      , e_logn    , 2) 
 19512 |          register_op("pow"       , e_pow     , 2) 
 19513 |          register_op("root"      , e_root    , 2) 
 19514 |          register_op("roundn"    , e_roundn  , 2) 
 19515 |          register_op("equal"     , e_equal   , 2) 
 19516 |          register_op("not_equal" , e_nequal  , 2) 
 19517 |          register_op("hypot"     , e_hypot   , 2) 
 19518 |          register_op("shr"       , e_shr     , 2) 
 19519 |          register_op("shl"       , e_shl     , 2) 
 19520 |          register_op("clamp"     , e_clamp   , 3) 
 19521 |          register_op("iclamp"    , e_iclamp  , 3) 
 19522 |          register_op("inrange"   , e_inrange , 3) 
 19523 |          #undef register_op 
 19524 |       } 
 19525 |  
 19526 |    } // namespace details 
 19527 |  
 19528 |    class function_traits 
 19529 |    { 
 19530 |    public: 
 19531 |  
 19532 |       function_traits() 
 19533 |       : allow_zero_parameters_(false) 
 19534 |       , has_side_effects_(true) 
 19535 |       , min_num_args_(0) 
 19536 |       , max_num_args_(std::numeric_limits<std::size_t>::max()) 
 19537 |       {} 
 19538 |  
 19539 |       inline bool& allow_zero_parameters() 
 19540 |       { 
 19541 |          return allow_zero_parameters_; 
 19542 |       } 
 19543 |  
 19544 |       inline bool& has_side_effects() 
 19545 |       { 
 19546 |          return has_side_effects_; 
 19547 |       } 
 19548 |  
 19549 |       std::size_t& min_num_args() 
 19550 |       { 
 19551 |          return min_num_args_; 
 19552 |       } 
 19553 |  
 19554 |       std::size_t& max_num_args() 
 19555 |       { 
 19556 |          return max_num_args_; 
 19557 |       } 
 19558 |  
 19559 |    private: 
 19560 |  
 19561 |       bool allow_zero_parameters_; 
 19562 |       bool has_side_effects_; 
 19563 |       std::size_t min_num_args_; 
 19564 |       std::size_t max_num_args_; 
 19565 |    }; 
 19566 |  
 19567 |    template <typename FunctionType> 
 19568 |    void enable_zero_parameters(FunctionType& func) 
 19569 |    { 
 19570 |       func.allow_zero_parameters() = true; 
 19571 |  
 19572 |       if (0 != func.min_num_args()) 
 19573 |       { 
 19574 |          func.min_num_args() = 0; 
 19575 |       } 
 19576 |    } 
 19577 |  
 19578 |    template <typename FunctionType> 
 19579 |    void disable_zero_parameters(FunctionType& func) 
 19580 |    { 
 19581 |       func.allow_zero_parameters() = false; 
 19582 |    } 
 19583 |  
 19584 |    template <typename FunctionType> 
 19585 |    void enable_has_side_effects(FunctionType& func) 
 19586 |    { 
 19587 |       func.has_side_effects() = true; 
 19588 |    } 
 19589 |  
 19590 |    template <typename FunctionType> 
 19591 |    void disable_has_side_effects(FunctionType& func) 
 19592 |    { 
 19593 |       func.has_side_effects() = false; 
 19594 |    } 
 19595 |  
 19596 |    template <typename FunctionType> 
 19597 |    void set_min_num_args(FunctionType& func, const std::size_t& num_args) 
 19598 |    { 
 19599 |       func.min_num_args() = num_args; 
 19600 |  
 19601 |       if ((0 != func.min_num_args()) && func.allow_zero_parameters()) 
 19602 |          func.allow_zero_parameters() = false; 
 19603 |    } 
 19604 |  
 19605 |    template <typename FunctionType> 
 19606 |    void set_max_num_args(FunctionType& func, const std::size_t& num_args) 
 19607 |    { 
 19608 |       func.max_num_args() = num_args; 
 19609 |    } 
 19610 |  
 19611 |    template <typename T> 
 19612 |    class ifunction : public function_traits 
 19613 |    { 
 19614 |    public: 
 19615 |  
 19616 |       explicit ifunction(const std::size_t& pc) 
 19617 |       : param_count(pc) 
 19618 |       {} 
 19619 |  
 19620 |       virtual ~ifunction() 
 19621 |       {} 
 19622 |  
 19623 |       #define empty_method_body(N)                   \ 
 19624 |       {                                              \ 
 19625 |          exprtk_debug(("ifunction::operator() - Operator(" #N ") has not been overridden\n")); \ 
 19626 |          return std::numeric_limits<T>::quiet_NaN(); \ 
 19627 |       }                                              \ 
 19628 |  
 19629 |       inline virtual T operator() () 
 19630 |       empty_method_body(0) 
 19631 |  
 19632 |       inline virtual T operator() (const T&) 
 19633 |       empty_method_body(1) 
 19634 |  
 19635 |       inline virtual T operator() (const T&,const T&) 
 19636 |       empty_method_body(2) 
 19637 |  
 19638 |       inline virtual T operator() (const T&, const T&, const T&) 
 19639 |       empty_method_body(3) 
 19640 |  
 19641 |       inline virtual T operator() (const T&, const T&, const T&, const T&) 
 19642 |       empty_method_body(4) 
 19643 |  
 19644 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&) 
 19645 |       empty_method_body(5) 
 19646 |  
 19647 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&) 
 19648 |       empty_method_body(6) 
 19649 |  
 19650 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19651 |       empty_method_body(7) 
 19652 |  
 19653 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19654 |       empty_method_body(8) 
 19655 |  
 19656 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19657 |       empty_method_body(9) 
 19658 |  
 19659 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19660 |       empty_method_body(10) 
 19661 |  
 19662 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19663 |                                    const T&) 
 19664 |       empty_method_body(11) 
 19665 |  
 19666 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19667 |                                    const T&, const T&) 
 19668 |       empty_method_body(12) 
 19669 |  
 19670 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19671 |                                    const T&, const T&, const T&) 
 19672 |       empty_method_body(13) 
 19673 |  
 19674 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19675 |                                    const T&, const T&, const T&, const T&) 
 19676 |       empty_method_body(14) 
 19677 |  
 19678 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19679 |                                    const T&, const T&, const T&, const T&, const T&) 
 19680 |       empty_method_body(15) 
 19681 |  
 19682 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19683 |                                    const T&, const T&, const T&, const T&, const T&, const T&) 
 19684 |       empty_method_body(16) 
 19685 |  
 19686 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19687 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19688 |       empty_method_body(17) 
 19689 |  
 19690 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19691 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19692 |       empty_method_body(18) 
 19693 |  
 19694 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19695 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19696 |       empty_method_body(19) 
 19697 |  
 19698 |       inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, 
 19699 |                                    const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&) 
 19700 |       empty_method_body(20) 
 19701 |  
 19702 |       #undef empty_method_body 
 19703 |  
 19704 |       std::size_t param_count; 
 19705 |    }; 
 19706 |  
 19707 |    template <typename T> 
 19708 |    class ivararg_function : public function_traits 
 19709 |    { 
 19710 |    public: 
 19711 |  
 19712 |       virtual ~ivararg_function() 
 19713 |       {} 
 19714 |  
 19715 |       inline virtual T operator() (const std::vector<T>&) 
 19716 |       { 
 19717 |          exprtk_debug(("ivararg_function::operator() - Operator has not been overridden\n")); 
 19718 |          return std::numeric_limits<T>::quiet_NaN(); 
 19719 |       } 
 19720 |    }; 
 19721 |  
 19722 |    template <typename T> 
 19723 |    class igeneric_function : public function_traits 
 19724 |    { 
 19725 |    public: 
 19726 |  
 19727 |       enum return_type 
 19728 |       { 
 19729 |          e_rtrn_scalar   = 0, 
 19730 |          e_rtrn_string   = 1, 
 19731 |          e_rtrn_overload = 2 
 19732 |       }; 
 19733 |  
 19734 |       typedef T type; 
 19735 |       typedef type_store<T> generic_type; 
 19736 |       typedef typename generic_type::parameter_list parameter_list_t; 
 19737 |  
 19738 |       explicit igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar) 
 19739 |       : parameter_sequence(param_seq) 
 19740 |       , rtrn_type(rtr_type) 
 19741 |       {} 
 19742 |  
 19743 |       virtual ~igeneric_function() 
 19744 |       {} 
 19745 |  
 19746 |       #define igeneric_function_empty_body(N)        \ 
 19747 |       {                                              \ 
 19748 |          exprtk_debug(("igeneric_function::operator() - Operator(" #N ") has not been overridden\n")); \ 
 19749 |          return std::numeric_limits<T>::quiet_NaN(); \ 
 19750 |       }                                              \ 
 19751 |  
 19752 |       // f(i_0,i_1,....,i_N) --> Scalar 
 19753 |       inline virtual T operator() (parameter_list_t) 
 19754 |       igeneric_function_empty_body(1) 
 19755 |  
 19756 |       // f(i_0,i_1,....,i_N) --> String 
 19757 |       inline virtual T operator() (std::string&, parameter_list_t) 
 19758 |       igeneric_function_empty_body(2) 
 19759 |  
 19760 |       // f(psi,i_0,i_1,....,i_N) --> Scalar 
 19761 |       inline virtual T operator() (const std::size_t&, parameter_list_t) 
 19762 |       igeneric_function_empty_body(3) 
 19763 |  
 19764 |       // f(psi,i_0,i_1,....,i_N) --> String 
 19765 |       inline virtual T operator() (const std::size_t&, std::string&, parameter_list_t) 
 19766 |       igeneric_function_empty_body(4) 
 19767 |  
 19768 |       #undef igeneric_function_empty_body 
 19769 |  
 19770 |       std::string parameter_sequence; 
 19771 |       return_type rtrn_type; 
 19772 |    }; 
 19773 |  
 19774 |    #ifndef exprtk_disable_string_capabilities 
 19775 |    template <typename T> 
 19776 |    class stringvar_base 
 19777 |    { 
 19778 |    public: 
 19779 |  
 19780 |       typedef typename details::stringvar_node<T> stringvar_node_t; 
 19781 |  
 19782 |       stringvar_base(const std::string& name, stringvar_node_t* svn) 
 19783 |       : name_(name) 
 19784 |       , string_varnode_(svn) 
 19785 |       {} 
 19786 |  
 19787 |       bool valid() const 
 19788 |       { 
 19789 |          return !name_.empty() && (0 != string_varnode_); 
 19790 |       } 
 19791 |  
 19792 |       std::string name() const 
 19793 |       { 
 19794 |          assert(string_varnode_); 
 19795 |          return name_; 
 19796 |       } 
 19797 |  
 19798 |       void rebase(std::string& s) 
 19799 |       { 
 19800 |          assert(string_varnode_); 
 19801 |          string_varnode_->rebase(s); 
 19802 |       } 
 19803 |  
 19804 |    private: 
 19805 |  
 19806 |       std::string name_; 
 19807 |       stringvar_node_t* string_varnode_; 
 19808 |    }; 
 19809 |    #endif 
 19810 |  
 19811 |    template <typename T> class parser; 
 19812 |    template <typename T> class expression_helper; 
 19813 |  
 19814 |    template <typename T> 
 19815 |    class symbol_table 
 19816 |    { 
 19817 |    public: 
 19818 |  
 19819 |      enum symtab_mutability_type 
 19820 |      { 
 19821 |        e_unknown   = 0, 
 19822 |        e_mutable   = 1, 
 19823 |        e_immutable = 2 
 19824 |      }; 
 19825 |  
 19826 |      typedef T (*ff00_functor)(); 
 19827 |      typedef T (*ff01_functor)(T); 
 19828 |      typedef T (*ff02_functor)(T, T); 
 19829 |      typedef T (*ff03_functor)(T, T, T); 
 19830 |      typedef T (*ff04_functor)(T, T, T, T); 
 19831 |      typedef T (*ff05_functor)(T, T, T, T, T); 
 19832 |      typedef T (*ff06_functor)(T, T, T, T, T, T); 
 19833 |      typedef T (*ff07_functor)(T, T, T, T, T, T, T); 
 19834 |      typedef T (*ff08_functor)(T, T, T, T, T, T, T, T); 
 19835 |      typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T); 
 19836 |      typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T); 
 19837 |      typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T); 
 19838 |      typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T); 
 19839 |      typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T); 
 19840 |      typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T); 
 19841 |      typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T); 
 19842 |  
 19843 |    protected: 
 19844 |  
 19845 |        struct freefunc00 exprtk_final : public exprtk::ifunction<T> 
 19846 |        { 
 19847 |           using exprtk::ifunction<T>::operator(); 
 19848 |  
 19849 |           explicit freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {} 
 19850 |           inline T operator() () exprtk_override 
 19851 |           { return f(); } 
 19852 |           ff00_functor f; 
 19853 |        }; 
 19854 |  
 19855 |       struct freefunc01 exprtk_final : public exprtk::ifunction<T> 
 19856 |       { 
 19857 |          using exprtk::ifunction<T>::operator(); 
 19858 |  
 19859 |          explicit freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {} 
 19860 |          inline T operator() (const T& v0) exprtk_override 
 19861 |          { return f(v0); } 
 19862 |          ff01_functor f; 
 19863 |       }; 
 19864 |  
 19865 |       struct freefunc02 exprtk_final : public exprtk::ifunction<T> 
 19866 |       { 
 19867 |          using exprtk::ifunction<T>::operator(); 
 19868 |  
 19869 |          explicit freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {} 
 19870 |          inline T operator() (const T& v0, const T& v1) exprtk_override 
 19871 |          { return f(v0, v1); } 
 19872 |          ff02_functor f; 
 19873 |       }; 
 19874 |  
 19875 |       struct freefunc03 exprtk_final : public exprtk::ifunction<T> 
 19876 |       { 
 19877 |          using exprtk::ifunction<T>::operator(); 
 19878 |  
 19879 |          explicit freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {} 
 19880 |          inline T operator() (const T& v0, const T& v1, const T& v2) exprtk_override 
 19881 |          { return f(v0, v1, v2); } 
 19882 |          ff03_functor f; 
 19883 |       }; 
 19884 |  
 19885 |       struct freefunc04 exprtk_final : public exprtk::ifunction<T> 
 19886 |       { 
 19887 |          using exprtk::ifunction<T>::operator(); 
 19888 |  
 19889 |          explicit freefunc04(ff04_functor ff) : exprtk::ifunction<T>(4), f(ff) {} 
 19890 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3) exprtk_override 
 19891 |          { return f(v0, v1, v2, v3); } 
 19892 |          ff04_functor f; 
 19893 |       }; 
 19894 |  
 19895 |       struct freefunc05 : public exprtk::ifunction<T> 
 19896 |       { 
 19897 |          using exprtk::ifunction<T>::operator(); 
 19898 |  
 19899 |          explicit freefunc05(ff05_functor ff) : exprtk::ifunction<T>(5), f(ff) {} 
 19900 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) exprtk_override 
 19901 |          { return f(v0, v1, v2, v3, v4); } 
 19902 |          ff05_functor f; 
 19903 |       }; 
 19904 |  
 19905 |       struct freefunc06 exprtk_final : public exprtk::ifunction<T> 
 19906 |       { 
 19907 |          using exprtk::ifunction<T>::operator(); 
 19908 |  
 19909 |          explicit freefunc06(ff06_functor ff) : exprtk::ifunction<T>(6), f(ff) {} 
 19910 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) exprtk_override 
 19911 |          { return f(v0, v1, v2, v3, v4, v5); } 
 19912 |          ff06_functor f; 
 19913 |       }; 
 19914 |  
 19915 |       struct freefunc07 exprtk_final : public exprtk::ifunction<T> 
 19916 |       { 
 19917 |          using exprtk::ifunction<T>::operator(); 
 19918 |  
 19919 |          explicit freefunc07(ff07_functor ff) : exprtk::ifunction<T>(7), f(ff) {} 
 19920 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19921 |                               const T& v5, const T& v6) exprtk_override 
 19922 |          { return f(v0, v1, v2, v3, v4, v5, v6); } 
 19923 |          ff07_functor f; 
 19924 |       }; 
 19925 |  
 19926 |       struct freefunc08 exprtk_final : public exprtk::ifunction<T> 
 19927 |       { 
 19928 |          using exprtk::ifunction<T>::operator(); 
 19929 |  
 19930 |          explicit freefunc08(ff08_functor ff) : exprtk::ifunction<T>(8), f(ff) {} 
 19931 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19932 |                               const T& v5, const T& v6, const T& v7) exprtk_override 
 19933 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7); } 
 19934 |          ff08_functor f; 
 19935 |       }; 
 19936 |  
 19937 |       struct freefunc09 exprtk_final : public exprtk::ifunction<T> 
 19938 |       { 
 19939 |          using exprtk::ifunction<T>::operator(); 
 19940 |  
 19941 |          explicit freefunc09(ff09_functor ff) : exprtk::ifunction<T>(9), f(ff) {} 
 19942 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19943 |                               const T& v5, const T& v6, const T& v7, const T& v8) exprtk_override 
 19944 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); } 
 19945 |          ff09_functor f; 
 19946 |       }; 
 19947 |  
 19948 |       struct freefunc10 exprtk_final : public exprtk::ifunction<T> 
 19949 |       { 
 19950 |          using exprtk::ifunction<T>::operator(); 
 19951 |  
 19952 |          explicit freefunc10(ff10_functor ff) : exprtk::ifunction<T>(10), f(ff) {} 
 19953 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19954 |                               const T& v5, const T& v6, const T& v7, const T& v8, const T& v9) exprtk_override 
 19955 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); } 
 19956 |          ff10_functor f; 
 19957 |       }; 
 19958 |  
 19959 |       struct freefunc11 exprtk_final : public exprtk::ifunction<T> 
 19960 |       { 
 19961 |          using exprtk::ifunction<T>::operator(); 
 19962 |  
 19963 |          explicit freefunc11(ff11_functor ff) : exprtk::ifunction<T>(11), f(ff) {} 
 19964 |          inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, 
 19965 |                               const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10) exprtk_override 
 19966 |          { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); } 
 19967 |          ff11_functor f; 
 19968 |       }; 
 19969 |  
 19970 |       struct freefunc12 exprtk_final : public exprtk::ifunction<T> 
 19971 |       { 
 19972 |          using exprtk::ifunction<T>::operator(); 
 19973 |  
 19974 |          explicit freefunc12(ff12_functor ff) : exprtk::ifunction<T>(12), f(ff) {} 
 19975 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 19976 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 19977 |                               const T& v10, const T& v11) exprtk_override 
 19978 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11); } 
 19979 |          ff12_functor f; 
 19980 |       }; 
 19981 |  
 19982 |       struct freefunc13 exprtk_final : public exprtk::ifunction<T> 
 19983 |       { 
 19984 |          using exprtk::ifunction<T>::operator(); 
 19985 |  
 19986 |          explicit freefunc13(ff13_functor ff) : exprtk::ifunction<T>(13), f(ff) {} 
 19987 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 19988 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 19989 |                               const T& v10, const T& v11, const T& v12) exprtk_override 
 19990 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12); } 
 19991 |          ff13_functor f; 
 19992 |       }; 
 19993 |  
 19994 |       struct freefunc14 exprtk_final : public exprtk::ifunction<T> 
 19995 |       { 
 19996 |          using exprtk::ifunction<T>::operator(); 
 19997 |  
 19998 |          explicit freefunc14(ff14_functor ff) : exprtk::ifunction<T>(14), f(ff) {} 
 19999 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 20000 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 20001 |                               const T& v10, const T& v11, const T& v12, const T& v13) exprtk_override 
 20002 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13); } 
 20003 |          ff14_functor f; 
 20004 |       }; 
 20005 |  
 20006 |       struct freefunc15 exprtk_final : public exprtk::ifunction<T> 
 20007 |       { 
 20008 |          using exprtk::ifunction<T>::operator(); 
 20009 |  
 20010 |          explicit freefunc15(ff15_functor ff) : exprtk::ifunction<T>(15), f(ff) {} 
 20011 |          inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, 
 20012 |                               const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, 
 20013 |                               const T& v10, const T& v11, const T& v12, const T& v13, const T& v14) exprtk_override 
 20014 |          { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14); } 
 20015 |          ff15_functor f; 
 20016 |       }; 
 20017 |  
 20018 |       template <typename Type, typename RawType> 
 20019 |       struct type_store 
 20020 |       { 
 20021 |          typedef details::expression_node<T>*        expression_ptr; 
 20022 |          typedef typename details::variable_node<T>  variable_node_t; 
 20023 |          typedef ifunction<T>                        ifunction_t; 
 20024 |          typedef ivararg_function<T>                 ivararg_function_t; 
 20025 |          typedef igeneric_function<T>                igeneric_function_t; 
 20026 |          typedef details::vector_holder<T>           vector_t; 
 20027 |          #ifndef exprtk_disable_string_capabilities 
 20028 |          typedef typename details::stringvar_node<T> stringvar_node_t; 
 20029 |          #endif 
 20030 |  
 20031 |          typedef Type type_t; 
 20032 |          typedef type_t* type_ptr; 
 20033 |          typedef std::pair<bool,type_ptr> type_pair_t; 
 20034 |          typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t; 
 20035 |          typedef typename type_map_t::iterator tm_itr_t; 
 20036 |          typedef typename type_map_t::const_iterator tm_const_itr_t; 
 20037 |  
 20038 |          enum { lut_size = 256 }; 
 20039 |  
 20040 |          type_map_t  map; 
 20041 |          std::size_t size; 
 20042 |  
 20043 |          type_store() 
 20044 |          : size(0) 
 20045 |          {} 
 20046 |  
 20047 |          struct deleter 
 20048 |          { 
 20049 |             #define exprtk_define_process(Type)                  \ 
 20050 |             static inline void process(std::pair<bool,Type*>& n) \ 
 20051 |             {                                                    \ 
 20052 |                delete n.second;                                  \ 
 20053 |             }                                                    \ 
 20054 |  
 20055 |             exprtk_define_process(variable_node_t ) 
 20056 |             exprtk_define_process(vector_t        ) 
 20057 |             #ifndef exprtk_disable_string_capabilities 
 20058 |             exprtk_define_process(stringvar_node_t) 
 20059 |             #endif 
 20060 |  
 20061 |             #undef exprtk_define_process 
 20062 |  
 20063 |             template <typename DeleteType> 
 20064 |             static inline void process(std::pair<bool,DeleteType*>&) 
 20065 |             {} 
 20066 |          }; 
 20067 |  
 20068 |          inline bool symbol_exists(const std::string& symbol_name) const 
 20069 |          { 
 20070 |             if (symbol_name.empty()) 
 20071 |                return false; 
 20072 |             else if (map.end() != map.find(symbol_name)) 
 20073 |                return true; 
 20074 |             else 
 20075 |                return false; 
 20076 |          } 
 20077 |  
 20078 |          template <typename PtrType> 
 20079 |          inline std::string entity_name(const PtrType& ptr) const 
 20080 |          { 
 20081 |             if (map.empty()) 
 20082 |                return std::string(); 
 20083 |  
 20084 |             tm_const_itr_t itr = map.begin(); 
 20085 |  
 20086 |             while (map.end() != itr) 
 20087 |             { 
 20088 |                if (itr->second.second == ptr) 
 20089 |                { 
 20090 |                   return itr->first; 
 20091 |                } 
 20092 |                else 
 20093 |                   ++itr; 
 20094 |             } 
 20095 |  
 20096 |             return std::string(); 
 20097 |          } 
 20098 |  
 20099 |          inline bool is_constant(const std::string& symbol_name) const 
 20100 |          { 
 20101 |             if (symbol_name.empty()) 
 20102 |                return false; 
 20103 |             else 
 20104 |             { 
 20105 |                const tm_const_itr_t itr = map.find(symbol_name); 
 20106 |  
 20107 |                if (map.end() == itr) 
 20108 |                   return false; 
 20109 |                else 
 20110 |                   return (*itr).second.first; 
 20111 |             } 
 20112 |          } 
 20113 |  
 20114 |          template <typename Tie, typename RType> 
 20115 |          inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const) 
 20116 |          { 
 20117 |             if (symbol_name.size() > 1) 
 20118 |             { 
 20119 |                for (std::size_t i = 0; i < details::reserved_symbols_size; ++i) 
 20120 |                { 
 20121 |                   if (details::imatch(symbol_name, details::reserved_symbols[i])) 
 20122 |                   { 
 20123 |                      return false; 
 20124 |                   } 
 20125 |                } 
 20126 |             } 
 20127 |  
 20128 |             const tm_itr_t itr = map.find(symbol_name); 
 20129 |  
 20130 |             if (map.end() == itr) 
 20131 |             { 
 20132 |                map[symbol_name] = Tie::make(t,is_const); 
 20133 |                ++size; 
 20134 |             } 
 20135 |  
 20136 |             return true; 
 20137 |          } 
 20138 |  
 20139 |          struct tie_array 
 20140 |          { 
 20141 |             static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false) 
 20142 |             { 
 20143 |                return std::make_pair(is_const, new vector_t(v.first, v.second)); 
 20144 |             } 
 20145 |          }; 
 20146 |  
 20147 |          struct tie_stdvec 
 20148 |          { 
 20149 |             template <typename Allocator> 
 20150 |             static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false) 
 20151 |             { 
 20152 |                return std::make_pair(is_const, new vector_t(v)); 
 20153 |             } 
 20154 |          }; 
 20155 |  
 20156 |          struct tie_vecview 
 20157 |          { 
 20158 |             static inline std::pair<bool,vector_t*> make(exprtk::vector_view<T>& v, const bool is_const = false) 
 20159 |             { 
 20160 |                return std::make_pair(is_const, new vector_t(v)); 
 20161 |             } 
 20162 |          }; 
 20163 |  
 20164 |          struct tie_stddeq 
 20165 |          { 
 20166 |             template <typename Allocator> 
 20167 |             static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false) 
 20168 |             { 
 20169 |                return std::make_pair(is_const, new vector_t(v)); 
 20170 |             } 
 20171 |          }; 
 20172 |  
 20173 |          template <std::size_t v_size> 
 20174 |          inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false) 
 20175 |          { 
 20176 |             return add_impl<tie_array,std::pair<T*,std::size_t> > 
 20177 |                       (symbol_name, std::make_pair(v,v_size), is_const); 
 20178 |          } 
 20179 |  
 20180 |          inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false) 
 20181 |          { 
 20182 |             return add_impl<tie_array,std::pair<T*,std::size_t> > 
 20183 |                      (symbol_name, std::make_pair(v,v_size), is_const); 
 20184 |          } 
 20185 |  
 20186 |          template <typename Allocator> 
 20187 |          inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false) 
 20188 |          { 
 20189 |             return add_impl<tie_stdvec,std::vector<T,Allocator>&> 
 20190 |                       (symbol_name, v, is_const); 
 20191 |          } 
 20192 |  
 20193 |          inline bool add(const std::string& symbol_name, exprtk::vector_view<T>& v, const bool is_const = false) 
 20194 |          { 
 20195 |             return add_impl<tie_vecview,exprtk::vector_view<T>&> 
 20196 |                       (symbol_name, v, is_const); 
 20197 |          } 
 20198 |  
 20199 |          template <typename Allocator> 
 20200 |          inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false) 
 20201 |          { 
 20202 |             return add_impl<tie_stddeq,std::deque<T,Allocator>&> 
 20203 |                       (symbol_name, v, is_const); 
 20204 |          } 
 20205 |  
 20206 |          inline bool add(const std::string& symbol_name, RawType& t_, const bool is_const = false) 
 20207 |          { 
 20208 |             struct tie 
 20209 |             { 
 20210 |                static inline std::pair<bool,variable_node_t*> make(T& t, const bool is_constant = false) 
 20211 |                { 
 20212 |                   return std::make_pair(is_constant, new variable_node_t(t)); 
 20213 |                } 
 20214 |  
 20215 |                #ifndef exprtk_disable_string_capabilities 
 20216 |                static inline std::pair<bool,stringvar_node_t*> make(std::string& t, const bool is_constant = false) 
 20217 |                { 
 20218 |                   return std::make_pair(is_constant, new stringvar_node_t(t)); 
 20219 |                } 
 20220 |                #endif 
 20221 |  
 20222 |                static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false) 
 20223 |                { 
 20224 |                   return std::make_pair(is_constant,&t); 
 20225 |                } 
 20226 |  
 20227 |                static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_constant = false) 
 20228 |                { 
 20229 |                   return std::make_pair(is_constant,&t); 
 20230 |                } 
 20231 |  
 20232 |                static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false) 
 20233 |                { 
 20234 |                   return std::make_pair(is_constant,&t); 
 20235 |                } 
 20236 |             }; 
 20237 |  
 20238 |             const tm_itr_t itr = map.find(symbol_name); 
 20239 |  
 20240 |             if (map.end() == itr) 
 20241 |             { 
 20242 |                map[symbol_name] = tie::make(t_,is_const); 
 20243 |                ++size; 
 20244 |             } 
 20245 |  
 20246 |             return true; 
 20247 |          } 
 20248 |  
 20249 |          inline type_ptr get(const std::string& symbol_name) const 
 20250 |          { 
 20251 |             const tm_const_itr_t itr = map.find(symbol_name); 
 20252 |  
 20253 |             if (map.end() == itr) 
 20254 |                return reinterpret_cast<type_ptr>(0); 
 20255 |             else 
 20256 |                return itr->second.second; 
 20257 |          } 
 20258 |  
 20259 |          template <typename TType, typename TRawType, typename PtrType> 
 20260 |          struct ptr_match 
 20261 |          { 
 20262 |             static inline bool test(const PtrType, const void*) 
 20263 |             { 
 20264 |                return false; 
 20265 |             } 
 20266 |          }; 
 20267 |  
 20268 |          template <typename TType, typename TRawType> 
 20269 |          struct ptr_match<TType,TRawType,variable_node_t*> 
 20270 |          { 
 20271 |             static inline bool test(const variable_node_t* p, const void* ptr) 
 20272 |             { 
 20273 |                exprtk_debug(("ptr_match::test() - %p <--> %p\n", reinterpret_cast<const void*>(&(p->ref())), ptr)); 
 20274 |                return (&(p->ref()) == ptr); 
 20275 |             } 
 20276 |          }; 
 20277 |  
 20278 |          inline type_ptr get_from_varptr(const void* ptr) const 
 20279 |          { 
 20280 |             tm_const_itr_t itr = map.begin(); 
 20281 |  
 20282 |             while (map.end() != itr) 
 20283 |             { 
 20284 |                type_ptr ret_ptr = itr->second.second; 
 20285 |  
 20286 |                if (ptr_match<Type,RawType,type_ptr>::test(ret_ptr,ptr)) 
 20287 |                { 
 20288 |                   return ret_ptr; 
 20289 |                } 
 20290 |  
 20291 |                ++itr; 
 20292 |             } 
 20293 |  
 20294 |             return type_ptr(0); 
 20295 |          } 
 20296 |  
 20297 |          inline bool remove(const std::string& symbol_name, const bool delete_node = true) 
 20298 |          { 
 20299 |             const tm_itr_t itr = map.find(symbol_name); 
 20300 |  
 20301 |             if (map.end() != itr) 
 20302 |             { 
 20303 |                if (delete_node) 
 20304 |                { 
 20305 |                   deleter::process((*itr).second); 
 20306 |                } 
 20307 |  
 20308 |                map.erase(itr); 
 20309 |                --size; 
 20310 |  
 20311 |                return true; 
 20312 |             } 
 20313 |             else 
 20314 |                return false; 
 20315 |          } 
 20316 |  
 20317 |          inline RawType& type_ref(const std::string& symbol_name) 
 20318 |          { 
 20319 |             struct init_type 
 20320 |             { 
 20321 |                static inline double set(double)           { return (0.0);           } 
 20322 |                static inline double set(long double)      { return (0.0);           } 
 20323 |                static inline float  set(float)            { return (0.0f);          } 
 20324 |                static inline std::string set(std::string) { return std::string(""); } 
 20325 |             }; 
 20326 |  
 20327 |             static RawType null_type = init_type::set(RawType()); 
 20328 |  
 20329 |             const tm_const_itr_t itr = map.find(symbol_name); 
 20330 |  
 20331 |             if (map.end() == itr) 
 20332 |                return null_type; 
 20333 |             else 
 20334 |                return itr->second.second->ref(); 
 20335 |          } 
 20336 |  
 20337 |          inline void clear(const bool delete_node = true) 
 20338 |          { 
 20339 |             if (!map.empty()) 
 20340 |             { 
 20341 |                if (delete_node) 
 20342 |                { 
 20343 |                   tm_itr_t itr = map.begin(); 
 20344 |                   tm_itr_t end = map.end  (); 
 20345 |  
 20346 |                   while (end != itr) 
 20347 |                   { 
 20348 |                      deleter::process((*itr).second); 
 20349 |                      ++itr; 
 20350 |                   } 
 20351 |                } 
 20352 |  
 20353 |                map.clear(); 
 20354 |             } 
 20355 |  
 20356 |             size = 0; 
 20357 |          } 
 20358 |  
 20359 |          template <typename Allocator, 
 20360 |                    template <typename, typename> class Sequence> 
 20361 |          inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const 
 20362 |          { 
 20363 |             std::size_t count = 0; 
 20364 |  
 20365 |             if (!map.empty()) 
 20366 |             { 
 20367 |                tm_const_itr_t itr = map.begin(); 
 20368 |                tm_const_itr_t end = map.end  (); 
 20369 |  
 20370 |                while (end != itr) 
 20371 |                { 
 20372 |                   list.push_back(std::make_pair((*itr).first,itr->second.second->ref())); 
 20373 |                   ++itr; 
 20374 |                   ++count; 
 20375 |                } 
 20376 |             } 
 20377 |  
 20378 |             return count; 
 20379 |          } 
 20380 |  
 20381 |          template <typename Allocator, 
 20382 |                    template <typename, typename> class Sequence> 
 20383 |          inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const 
 20384 |          { 
 20385 |             std::size_t count = 0; 
 20386 |  
 20387 |             if (!map.empty()) 
 20388 |             { 
 20389 |                tm_const_itr_t itr = map.begin(); 
 20390 |                tm_const_itr_t end = map.end  (); 
 20391 |  
 20392 |                while (end != itr) 
 20393 |                { 
 20394 |                   vlist.push_back((*itr).first); 
 20395 |                   ++itr; 
 20396 |                   ++count; 
 20397 |                } 
 20398 |             } 
 20399 |  
 20400 |             return count; 
 20401 |          } 
 20402 |       }; 
 20403 |  
 20404 |       typedef details::expression_node<T>*        expression_ptr; 
 20405 |       typedef typename details::variable_node<T>  variable_t; 
 20406 |       typedef typename details::vector_holder<T>  vector_holder_t; 
 20407 |       typedef variable_t*                         variable_ptr; 
 20408 |       #ifndef exprtk_disable_string_capabilities 
 20409 |       typedef typename details::stringvar_node<T> stringvar_t; 
 20410 |       typedef stringvar_t*                        stringvar_ptr; 
 20411 |       #endif 
 20412 |       typedef ifunction        <T>                function_t; 
 20413 |       typedef ivararg_function <T>                vararg_function_t; 
 20414 |       typedef igeneric_function<T>                generic_function_t; 
 20415 |       typedef function_t*                         function_ptr; 
 20416 |       typedef vararg_function_t*                  vararg_function_ptr; 
 20417 |       typedef generic_function_t*                 generic_function_ptr; 
 20418 |  
 20419 |       static const std::size_t lut_size = 256; 
 20420 |  
 20421 |       // Symbol Table Holder 
 20422 |       struct control_block 
 20423 |       { 
 20424 |          struct st_data 
 20425 |          { 
 20426 |             type_store<variable_t        , T                 > variable_store; 
 20427 |             type_store<function_t        , function_t        > function_store; 
 20428 |             type_store<vararg_function_t , vararg_function_t > vararg_function_store; 
 20429 |             type_store<generic_function_t, generic_function_t> generic_function_store; 
 20430 |             type_store<generic_function_t, generic_function_t> string_function_store; 
 20431 |             type_store<generic_function_t, generic_function_t> overload_function_store; 
 20432 |             type_store<vector_holder_t   , vector_holder_t   > vector_store; 
 20433 |             #ifndef exprtk_disable_string_capabilities 
 20434 |             type_store<stringvar_t       , std::string       > stringvar_store; 
 20435 |             #endif 
 20436 |  
 20437 |             st_data() 
 20438 |             { 
 20439 |                for (std::size_t i = 0; i < details::reserved_words_size; ++i) 
 20440 |                { 
 20441 |                   reserved_symbol_table_.insert(details::reserved_words[i]); 
 20442 |                } 
 20443 |  
 20444 |                for (std::size_t i = 0; i < details::reserved_symbols_size; ++i) 
 20445 |                { 
 20446 |                   reserved_symbol_table_.insert(details::reserved_symbols[i]); 
 20447 |                } 
 20448 |             } 
 20449 |  
 20450 |            ~st_data() 
 20451 |             { 
 20452 |                for (std::size_t i = 0; i < free_function_list_.size(); ++i) 
 20453 |                { 
 20454 |                   delete free_function_list_[i]; 
 20455 |                } 
 20456 |             } 
 20457 |  
 20458 |             inline bool is_reserved_symbol(const std::string& symbol) const 
 20459 |             { 
 20460 |                return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol)); 
 20461 |             } 
 20462 |  
 20463 |             static inline st_data* create() 
 20464 |             { 
 20465 |                return (new st_data); 
 20466 |             } 
 20467 |  
 20468 |             static inline void destroy(st_data*& sd) 
 20469 |             { 
 20470 |                delete sd; 
 20471 |                sd = reinterpret_cast<st_data*>(0); 
 20472 |             } 
 20473 |  
 20474 |             std::list<T>               local_symbol_list_; 
 20475 |             std::list<std::string>     local_stringvar_list_; 
 20476 |             std::set<std::string>      reserved_symbol_table_; 
 20477 |             std::vector<ifunction<T>*> free_function_list_; 
 20478 |          }; 
 20479 |  
 20480 |          control_block() 
 20481 |          : ref_count(1) 
 20482 |          , data_(st_data::create()) 
 20483 |          , mutability_(e_mutable) 
 20484 |          {} 
 20485 |  
 20486 |          explicit control_block(st_data* data) 
 20487 |          : ref_count(1) 
 20488 |          , data_(data) 
 20489 |          , mutability_(e_mutable) 
 20490 |          {} 
 20491 |  
 20492 |         ~control_block() 
 20493 |          { 
 20494 |             if (data_ && (0 == ref_count)) 
 20495 |             { 
 20496 |                st_data::destroy(data_); 
 20497 |             } 
 20498 |          } 
 20499 |  
 20500 |          static inline control_block* create() 
 20501 |          { 
 20502 |             return (new control_block); 
 20503 |          } 
 20504 |  
 20505 |          template <typename SymTab> 
 20506 |          static inline void destroy(control_block*& cntrl_blck, SymTab* sym_tab) 
 20507 |          { 
 20508 |             if (cntrl_blck) 
 20509 |             { 
 20510 |                if ( 
 20511 |                     (0 !=   cntrl_blck->ref_count) && 
 20512 |                     (0 == --cntrl_blck->ref_count) 
 20513 |                   ) 
 20514 |                { 
 20515 |                   if (sym_tab) 
 20516 |                      sym_tab->clear(); 
 20517 |  
 20518 |                   delete cntrl_blck; 
 20519 |                } 
 20520 |  
 20521 |                cntrl_blck = 0; 
 20522 |             } 
 20523 |          } 
 20524 |  
 20525 |          void set_mutability(const symtab_mutability_type mutability) 
 20526 |          { 
 20527 |             mutability_ = mutability; 
 20528 |          } 
 20529 |  
 20530 |          std::size_t ref_count; 
 20531 |          st_data* data_; 
 20532 |          symtab_mutability_type mutability_; 
 20533 |       }; 
 20534 |  
 20535 |    public: 
 20536 |  
 20537 |       explicit symbol_table(const symtab_mutability_type mutability = e_mutable) 
 20538 |       : control_block_(control_block::create()) 
 20539 |       { 
 20540 |          control_block_->set_mutability(mutability); 
 20541 |          clear(); 
 20542 |       } 
 20543 |  
 20544 |      ~symbol_table() 
 20545 |       { 
 20546 |          exprtk::details::dump_ptr("~symbol_table", this); 
 20547 |          control_block::destroy(control_block_, this); 
 20548 |       } 
 20549 |  
 20550 |       symbol_table(const symbol_table<T>& st) 
 20551 |       { 
 20552 |          control_block_ = st.control_block_; 
 20553 |          control_block_->ref_count++; 
 20554 |       } 
 20555 |  
 20556 |       inline symbol_table<T>& operator=(const symbol_table<T>& st) 
 20557 |       { 
 20558 |          if (this != &st) 
 20559 |          { 
 20560 |             control_block::destroy(control_block_,reinterpret_cast<symbol_table<T>*>(0)); 
 20561 |  
 20562 |             control_block_ = st.control_block_; 
 20563 |             control_block_->ref_count++; 
 20564 |          } 
 20565 |  
 20566 |          return (*this); 
 20567 |       } 
 20568 |  
 20569 |       inline bool operator==(const symbol_table<T>& st) const 
 20570 |       { 
 20571 |          return (this == &st) || (control_block_ == st.control_block_); 
 20572 |       } 
 20573 |  
 20574 |       inline symtab_mutability_type mutability() const 
 20575 |       { 
 20576 |          return valid() ? control_block_->mutability_ : e_unknown; 
 20577 |       } 
 20578 |  
 20579 |       inline void clear_variables(const bool delete_node = true) 
 20580 |       { 
 20581 |          local_data().variable_store.clear(delete_node); 
 20582 |       } 
 20583 |  
 20584 |       inline void clear_functions() 
 20585 |       { 
 20586 |          local_data().function_store.clear(); 
 20587 |       } 
 20588 |  
 20589 |       inline void clear_strings() 
 20590 |       { 
 20591 |          #ifndef exprtk_disable_string_capabilities 
 20592 |          local_data().stringvar_store.clear(); 
 20593 |          #endif 
 20594 |       } 
 20595 |  
 20596 |       inline void clear_vectors() 
 20597 |       { 
 20598 |          local_data().vector_store.clear(); 
 20599 |       } 
 20600 |  
 20601 |       inline void clear_local_constants() 
 20602 |       { 
 20603 |          local_data().local_symbol_list_.clear(); 
 20604 |       } 
 20605 |  
 20606 |       inline void clear() 
 20607 |       { 
 20608 |          if (!valid()) return; 
 20609 |          clear_variables      (); 
 20610 |          clear_functions      (); 
 20611 |          clear_strings        (); 
 20612 |          clear_vectors        (); 
 20613 |          clear_local_constants(); 
 20614 |       } 
 20615 |  
 20616 |       inline std::size_t variable_count() const 
 20617 |       { 
 20618 |          if (valid()) 
 20619 |             return local_data().variable_store.size; 
 20620 |          else 
 20621 |             return 0; 
 20622 |       } 
 20623 |  
 20624 |       #ifndef exprtk_disable_string_capabilities 
 20625 |       inline std::size_t stringvar_count() const 
 20626 |       { 
 20627 |          if (valid()) 
 20628 |             return local_data().stringvar_store.size; 
 20629 |          else 
 20630 |             return 0; 
 20631 |       } 
 20632 |       #endif 
 20633 |  
 20634 |       inline std::size_t function_count() const 
 20635 |       { 
 20636 |          if (valid()) 
 20637 |             return local_data().function_store.size; 
 20638 |          else 
 20639 |             return 0; 
 20640 |       } 
 20641 |  
 20642 |       inline std::size_t vector_count() const 
 20643 |       { 
 20644 |          if (valid()) 
 20645 |             return local_data().vector_store.size; 
 20646 |          else 
 20647 |             return 0; 
 20648 |       } 
 20649 |  
 20650 |       inline variable_ptr get_variable(const std::string& variable_name) const 
 20651 |       { 
 20652 |          if (!valid()) 
 20653 |             return reinterpret_cast<variable_ptr>(0); 
 20654 |          else if (!valid_symbol(variable_name)) 
 20655 |             return reinterpret_cast<variable_ptr>(0); 
 20656 |          else 
 20657 |             return local_data().variable_store.get(variable_name); 
 20658 |       } 
 20659 |  
 20660 |       inline variable_ptr get_variable(const T& var_ref) const 
 20661 |       { 
 20662 |          if (!valid()) 
 20663 |             return reinterpret_cast<variable_ptr>(0); 
 20664 |          else 
 20665 |             return local_data().variable_store.get_from_varptr( 
 20666 |                                                   reinterpret_cast<const void*>(&var_ref)); 
 20667 |       } 
 20668 |  
 20669 |       #ifndef exprtk_disable_string_capabilities 
 20670 |       inline stringvar_ptr get_stringvar(const std::string& string_name) const 
 20671 |       { 
 20672 |          if (!valid()) 
 20673 |             return reinterpret_cast<stringvar_ptr>(0); 
 20674 |          else if (!valid_symbol(string_name)) 
 20675 |             return reinterpret_cast<stringvar_ptr>(0); 
 20676 |          else 
 20677 |             return local_data().stringvar_store.get(string_name); 
 20678 |       } 
 20679 |  
 20680 |       inline stringvar_base<T> get_stringvar_base(const std::string& string_name) const 
 20681 |       { 
 20682 |          static stringvar_base<T> null_stringvar_base("",reinterpret_cast<stringvar_ptr>(0)); 
 20683 |          if (!valid()) 
 20684 |             return null_stringvar_base; 
 20685 |          else if (!valid_symbol(string_name)) 
 20686 |             return null_stringvar_base; 
 20687 |  
 20688 |          stringvar_ptr stringvar = local_data().stringvar_store.get(string_name); 
 20689 |  
 20690 |          if (0 == stringvar) 
 20691 |          { 
 20692 |             return null_stringvar_base; 
 20693 |          } 
 20694 |  
 20695 |          return stringvar_base<T>(string_name,stringvar); 
 20696 |       } 
 20697 |       #endif 
 20698 |  
 20699 |       inline function_ptr get_function(const std::string& function_name) const 
 20700 |       { 
 20701 |          if (!valid()) 
 20702 |             return reinterpret_cast<function_ptr>(0); 
 20703 |          else if (!valid_symbol(function_name)) 
 20704 |             return reinterpret_cast<function_ptr>(0); 
 20705 |          else 
 20706 |             return local_data().function_store.get(function_name); 
 20707 |       } 
 20708 |  
 20709 |       inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const 
 20710 |       { 
 20711 |          if (!valid()) 
 20712 |             return reinterpret_cast<vararg_function_ptr>(0); 
 20713 |          else if (!valid_symbol(vararg_function_name)) 
 20714 |             return reinterpret_cast<vararg_function_ptr>(0); 
 20715 |          else 
 20716 |             return local_data().vararg_function_store.get(vararg_function_name); 
 20717 |       } 
 20718 |  
 20719 |       inline generic_function_ptr get_generic_function(const std::string& function_name) const 
 20720 |       { 
 20721 |          if (!valid()) 
 20722 |             return reinterpret_cast<generic_function_ptr>(0); 
 20723 |          else if (!valid_symbol(function_name)) 
 20724 |             return reinterpret_cast<generic_function_ptr>(0); 
 20725 |          else 
 20726 |             return local_data().generic_function_store.get(function_name); 
 20727 |       } 
 20728 |  
 20729 |       inline generic_function_ptr get_string_function(const std::string& function_name) const 
 20730 |       { 
 20731 |          if (!valid()) 
 20732 |             return reinterpret_cast<generic_function_ptr>(0); 
 20733 |          else if (!valid_symbol(function_name)) 
 20734 |             return reinterpret_cast<generic_function_ptr>(0); 
 20735 |          else 
 20736 |             return local_data().string_function_store.get(function_name); 
 20737 |       } 
 20738 |  
 20739 |       inline generic_function_ptr get_overload_function(const std::string& function_name) const 
 20740 |       { 
 20741 |          if (!valid()) 
 20742 |             return reinterpret_cast<generic_function_ptr>(0); 
 20743 |          else if (!valid_symbol(function_name)) 
 20744 |             return reinterpret_cast<generic_function_ptr>(0); 
 20745 |          else 
 20746 |             return local_data().overload_function_store.get(function_name); 
 20747 |       } 
 20748 |  
 20749 |       typedef vector_holder_t* vector_holder_ptr; 
 20750 |  
 20751 |       inline vector_holder_ptr get_vector(const std::string& vector_name) const 
 20752 |       { 
 20753 |          if (!valid()) 
 20754 |             return reinterpret_cast<vector_holder_ptr>(0); 
 20755 |          else if (!valid_symbol(vector_name)) 
 20756 |             return reinterpret_cast<vector_holder_ptr>(0); 
 20757 |          else 
 20758 |             return local_data().vector_store.get(vector_name); 
 20759 |       } 
 20760 |  
 20761 |       inline T& variable_ref(const std::string& symbol_name) 
 20762 |       { 
 20763 |          static T null_var = T(0); 
 20764 |          if (!valid()) 
 20765 |             return null_var; 
 20766 |          else if (!valid_symbol(symbol_name)) 
 20767 |             return null_var; 
 20768 |          else 
 20769 |             return local_data().variable_store.type_ref(symbol_name); 
 20770 |       } 
 20771 |  
 20772 |       #ifndef exprtk_disable_string_capabilities 
 20773 |       inline std::string& stringvar_ref(const std::string& symbol_name) 
 20774 |       { 
 20775 |          static std::string null_stringvar; 
 20776 |          if (!valid()) 
 20777 |             return null_stringvar; 
 20778 |          else if (!valid_symbol(symbol_name)) 
 20779 |             return null_stringvar; 
 20780 |          else 
 20781 |             return local_data().stringvar_store.type_ref(symbol_name); 
 20782 |       } 
 20783 |       #endif 
 20784 |  
 20785 |       inline bool is_constant_node(const std::string& symbol_name) const 
 20786 |       { 
 20787 |          if (!valid()) 
 20788 |             return false; 
 20789 |          else if (!valid_symbol(symbol_name)) 
 20790 |             return false; 
 20791 |          else 
 20792 |             return local_data().variable_store.is_constant(symbol_name); 
 20793 |       } 
 20794 |  
 20795 |       #ifndef exprtk_disable_string_capabilities 
 20796 |       inline bool is_constant_string(const std::string& symbol_name) const 
 20797 |       { 
 20798 |          if (!valid()) 
 20799 |             return false; 
 20800 |          else if (!valid_symbol(symbol_name)) 
 20801 |             return false; 
 20802 |          else if (!local_data().stringvar_store.symbol_exists(symbol_name)) 
 20803 |             return false; 
 20804 |          else 
 20805 |             return local_data().stringvar_store.is_constant(symbol_name); 
 20806 |       } 
 20807 |       #endif 
 20808 |  
 20809 |       inline bool create_variable(const std::string& variable_name, const T& value = T(0)) 
 20810 |       { 
 20811 |          if (!valid()) 
 20812 |             return false; 
 20813 |          else if (!valid_symbol(variable_name)) 
 20814 |             return false; 
 20815 |          else if (symbol_exists(variable_name)) 
 20816 |             return false; 
 20817 |  
 20818 |          local_data().local_symbol_list_.push_back(value); 
 20819 |          T& t = local_data().local_symbol_list_.back(); 
 20820 |  
 20821 |          return add_variable(variable_name,t); 
 20822 |       } 
 20823 |  
 20824 |       #ifndef exprtk_disable_string_capabilities 
 20825 |       inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string("")) 
 20826 |       { 
 20827 |          if (!valid()) 
 20828 |             return false; 
 20829 |          else if (!valid_symbol(stringvar_name)) 
 20830 |             return false; 
 20831 |          else if (symbol_exists(stringvar_name)) 
 20832 |             return false; 
 20833 |  
 20834 |          local_data().local_stringvar_list_.push_back(value); 
 20835 |          std::string& s = local_data().local_stringvar_list_.back(); 
 20836 |  
 20837 |          return add_stringvar(stringvar_name,s); 
 20838 |       } 
 20839 |       #endif 
 20840 |  
 20841 |       inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false) 
 20842 |       { 
 20843 |          if (!valid()) 
 20844 |             return false; 
 20845 |          else if (!valid_symbol(variable_name)) 
 20846 |             return false; 
 20847 |          else if (symbol_exists(variable_name)) 
 20848 |             return false; 
 20849 |          else 
 20850 |             return local_data().variable_store.add(variable_name, t, is_constant); 
 20851 |       } 
 20852 |  
 20853 |       inline bool add_constant(const std::string& constant_name, const T& value) 
 20854 |       { 
 20855 |          if (!valid()) 
 20856 |             return false; 
 20857 |          else if (!valid_symbol(constant_name)) 
 20858 |             return false; 
 20859 |          else if (symbol_exists(constant_name)) 
 20860 |             return false; 
 20861 |  
 20862 |          local_data().local_symbol_list_.push_back(value); 
 20863 |          T& t = local_data().local_symbol_list_.back(); 
 20864 |  
 20865 |          return add_variable(constant_name, t, true); 
 20866 |       } 
 20867 |  
 20868 |       #ifndef exprtk_disable_string_capabilities 
 20869 |       inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false) 
 20870 |       { 
 20871 |          if (!valid()) 
 20872 |             return false; 
 20873 |          else if (!valid_symbol(stringvar_name)) 
 20874 |             return false; 
 20875 |          else if (symbol_exists(stringvar_name)) 
 20876 |             return false; 
 20877 |          else 
 20878 |             return local_data().stringvar_store.add(stringvar_name, s, is_constant); 
 20879 |       } 
 20880 |       #endif 
 20881 |  
 20882 |       inline bool add_function(const std::string& function_name, function_t& function) 
 20883 |       { 
 20884 |          if (!valid()) 
 20885 |             return false; 
 20886 |          else if (!valid_symbol(function_name)) 
 20887 |             return false; 
 20888 |          else if (symbol_exists(function_name)) 
 20889 |             return false; 
 20890 |          else 
 20891 |             return local_data().function_store.add(function_name,function); 
 20892 |       } 
 20893 |  
 20894 |       inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function) 
 20895 |       { 
 20896 |          if (!valid()) 
 20897 |             return false; 
 20898 |          else if (!valid_symbol(vararg_function_name)) 
 20899 |             return false; 
 20900 |          else if (symbol_exists(vararg_function_name)) 
 20901 |             return false; 
 20902 |          else 
 20903 |             return local_data().vararg_function_store.add(vararg_function_name,vararg_function); 
 20904 |       } 
 20905 |  
 20906 |       inline bool add_function(const std::string& function_name, generic_function_t& function) 
 20907 |       { 
 20908 |          if (!valid()) 
 20909 |             return false; 
 20910 |          else if (!valid_symbol(function_name)) 
 20911 |             return false; 
 20912 |          else if (symbol_exists(function_name)) 
 20913 |             return false; 
 20914 |          else 
 20915 |          { 
 20916 |             switch (function.rtrn_type) 
 20917 |             { 
 20918 |                case generic_function_t::e_rtrn_scalar : 
 20919 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 20920 |                          local_data().generic_function_store.add(function_name,function) : false; 
 20921 |  
 20922 |                case generic_function_t::e_rtrn_string : 
 20923 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 20924 |                          local_data().string_function_store.add(function_name,function)  : false; 
 20925 |  
 20926 |                case generic_function_t::e_rtrn_overload : 
 20927 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ? 
 20928 |                          local_data().overload_function_store.add(function_name,function) : false; 
 20929 |             } 
 20930 |          } 
 20931 |  
 20932 |          return false; 
 20933 |       } 
 20934 |  
 20935 |       #define exprtk_define_freefunction(NN)                                                \ 
 20936 |       inline bool add_function(const std::string& function_name, ff##NN##_functor function) \ 
 20937 |       {                                                                                     \ 
 20938 |          if (!valid())                                                                      \ 
 20939 |          { return false; }                                                                  \ 
 20940 |          if (!valid_symbol(function_name))                                                  \ 
 20941 |          { return false; }                                                                  \ 
 20942 |          if (symbol_exists(function_name))                                                  \ 
 20943 |          { return false; }                                                                  \ 
 20944 |                                                                                             \ 
 20945 |          exprtk::ifunction<T>* ifunc = new freefunc##NN(function);                          \ 
 20946 |                                                                                             \ 
 20947 |          local_data().free_function_list_.push_back(ifunc);                                 \ 
 20948 |                                                                                             \ 
 20949 |          return add_function(function_name,(*local_data().free_function_list_.back()));     \ 
 20950 |       }                                                                                     \ 
 20951 |  
 20952 |       exprtk_define_freefunction(00) exprtk_define_freefunction(01) 
 20953 |       exprtk_define_freefunction(02) exprtk_define_freefunction(03) 
 20954 |       exprtk_define_freefunction(04) exprtk_define_freefunction(05) 
 20955 |       exprtk_define_freefunction(06) exprtk_define_freefunction(07) 
 20956 |       exprtk_define_freefunction(08) exprtk_define_freefunction(09) 
 20957 |       exprtk_define_freefunction(10) exprtk_define_freefunction(11) 
 20958 |       exprtk_define_freefunction(12) exprtk_define_freefunction(13) 
 20959 |       exprtk_define_freefunction(14) exprtk_define_freefunction(15) 
 20960 |  
 20961 |       #undef exprtk_define_freefunction 
 20962 |  
 20963 |       inline bool add_reserved_function(const std::string& function_name, function_t& function) 
 20964 |       { 
 20965 |          if (!valid()) 
 20966 |             return false; 
 20967 |          else if (!valid_symbol(function_name,false)) 
 20968 |             return false; 
 20969 |          else if (symbol_exists(function_name,false)) 
 20970 |             return false; 
 20971 |          else 
 20972 |             return local_data().function_store.add(function_name,function); 
 20973 |       } 
 20974 |  
 20975 |       inline bool add_reserved_function(const std::string& vararg_function_name, vararg_function_t& vararg_function) 
 20976 |       { 
 20977 |          if (!valid()) 
 20978 |             return false; 
 20979 |          else if (!valid_symbol(vararg_function_name,false)) 
 20980 |             return false; 
 20981 |          else if (symbol_exists(vararg_function_name,false)) 
 20982 |             return false; 
 20983 |          else 
 20984 |             return local_data().vararg_function_store.add(vararg_function_name,vararg_function); 
 20985 |       } 
 20986 |  
 20987 |       inline bool add_reserved_function(const std::string& function_name, generic_function_t& function) 
 20988 |       { 
 20989 |          if (!valid()) 
 20990 |             return false; 
 20991 |          else if (!valid_symbol(function_name,false)) 
 20992 |             return false; 
 20993 |          else if (symbol_exists(function_name,false)) 
 20994 |             return false; 
 20995 |          else 
 20996 |          { 
 20997 |             switch (function.rtrn_type) 
 20998 |             { 
 20999 |                case generic_function_t::e_rtrn_scalar : 
 21000 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 21001 |                          local_data().generic_function_store.add(function_name,function) : false; 
 21002 |  
 21003 |                case generic_function_t::e_rtrn_string : 
 21004 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|")) ? 
 21005 |                          local_data().string_function_store.add(function_name,function)  : false; 
 21006 |  
 21007 |                case generic_function_t::e_rtrn_overload : 
 21008 |                   return (std::string::npos == function.parameter_sequence.find_first_not_of("STVZ*?|:")) ? 
 21009 |                          local_data().overload_function_store.add(function_name,function) : false; 
 21010 |             } 
 21011 |          } 
 21012 |  
 21013 |          return false; 
 21014 |       } 
 21015 |  
 21016 |       #define exprtk_define_reserved_function(NN)                                                    \ 
 21017 |       inline bool add_reserved_function(const std::string& function_name, ff##NN##_functor function) \ 
 21018 |       {                                                                                              \ 
 21019 |          if (!valid())                                                                               \ 
 21020 |          { return false; }                                                                           \ 
 21021 |          if (!valid_symbol(function_name,false))                                                     \ 
 21022 |          { return false; }                                                                           \ 
 21023 |          if (symbol_exists(function_name,false))                                                     \ 
 21024 |          { return false; }                                                                           \ 
 21025 |                                                                                                      \ 
 21026 |          exprtk::ifunction<T>* ifunc = new freefunc##NN(function);                                   \ 
 21027 |                                                                                                      \ 
 21028 |          local_data().free_function_list_.push_back(ifunc);                                          \ 
 21029 |                                                                                                      \ 
 21030 |          return add_reserved_function(function_name,(*local_data().free_function_list_.back()));     \ 
 21031 |       }                                                                                              \ 
 21032 |  
 21033 |       exprtk_define_reserved_function(00) exprtk_define_reserved_function(01) 
 21034 |       exprtk_define_reserved_function(02) exprtk_define_reserved_function(03) 
 21035 |       exprtk_define_reserved_function(04) exprtk_define_reserved_function(05) 
 21036 |       exprtk_define_reserved_function(06) exprtk_define_reserved_function(07) 
 21037 |       exprtk_define_reserved_function(08) exprtk_define_reserved_function(09) 
 21038 |       exprtk_define_reserved_function(10) exprtk_define_reserved_function(11) 
 21039 |       exprtk_define_reserved_function(12) exprtk_define_reserved_function(13) 
 21040 |       exprtk_define_reserved_function(14) exprtk_define_reserved_function(15) 
 21041 |  
 21042 |       #undef exprtk_define_reserved_function 
 21043 |  
 21044 |       template <std::size_t N> 
 21045 |       inline bool add_vector(const std::string& vector_name, T (&v)[N]) 
 21046 |       { 
 21047 |          if (!valid()) 
 21048 |             return false; 
 21049 |          else if (!valid_symbol(vector_name)) 
 21050 |             return false; 
 21051 |          else if (symbol_exists(vector_name)) 
 21052 |             return false; 
 21053 |          else 
 21054 |             return local_data().vector_store.add(vector_name,v); 
 21055 |       } 
 21056 |  
 21057 |       inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size) 
 21058 |       { 
 21059 |          if (!valid()) 
 21060 |             return false; 
 21061 |          else if (!valid_symbol(vector_name)) 
 21062 |             return false; 
 21063 |          else if (symbol_exists(vector_name)) 
 21064 |             return false; 
 21065 |          else if (0 == v_size) 
 21066 |             return false; 
 21067 |          else 
 21068 |             return local_data().vector_store.add(vector_name, v, v_size); 
 21069 |       } 
 21070 |  
 21071 |       template <typename Allocator> 
 21072 |       inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v) 
 21073 |       { 
 21074 |          if (!valid()) 
 21075 |             return false; 
 21076 |          else if (!valid_symbol(vector_name)) 
 21077 |             return false; 
 21078 |          else if (symbol_exists(vector_name)) 
 21079 |             return false; 
 21080 |          else if (0 == v.size()) 
 21081 |             return false; 
 21082 |          else 
 21083 |             return local_data().vector_store.add(vector_name,v); 
 21084 |       } 
 21085 |  
 21086 |       inline bool add_vector(const std::string& vector_name, exprtk::vector_view<T>& v) 
 21087 |       { 
 21088 |          if (!valid()) 
 21089 |             return false; 
 21090 |          else if (!valid_symbol(vector_name)) 
 21091 |             return false; 
 21092 |          else if (symbol_exists(vector_name)) 
 21093 |             return false; 
 21094 |          else if (0 == v.size()) 
 21095 |             return false; 
 21096 |          else 
 21097 |             return local_data().vector_store.add(vector_name,v); 
 21098 |       } 
 21099 |  
 21100 |       inline bool remove_variable(const std::string& variable_name, const bool delete_node = true) 
 21101 |       { 
 21102 |          if (!valid()) 
 21103 |             return false; 
 21104 |          else 
 21105 |             return local_data().variable_store.remove(variable_name, delete_node); 
 21106 |       } 
 21107 |  
 21108 |       #ifndef exprtk_disable_string_capabilities 
 21109 |       inline bool remove_stringvar(const std::string& string_name) 
 21110 |       { 
 21111 |          if (!valid()) 
 21112 |             return false; 
 21113 |          else 
 21114 |             return local_data().stringvar_store.remove(string_name); 
 21115 |       } 
 21116 |       #endif 
 21117 |  
 21118 |       inline bool remove_function(const std::string& function_name) 
 21119 |       { 
 21120 |          if (!valid()) 
 21121 |             return false; 
 21122 |          else 
 21123 |             return local_data().function_store.remove(function_name); 
 21124 |       } 
 21125 |  
 21126 |       inline bool remove_vararg_function(const std::string& vararg_function_name) 
 21127 |       { 
 21128 |          if (!valid()) 
 21129 |             return false; 
 21130 |          else 
 21131 |             return local_data().vararg_function_store.remove(vararg_function_name); 
 21132 |       } 
 21133 |  
 21134 |       inline bool remove_vector(const std::string& vector_name) 
 21135 |       { 
 21136 |          if (!valid()) 
 21137 |             return false; 
 21138 |          else 
 21139 |             return local_data().vector_store.remove(vector_name); 
 21140 |       } 
 21141 |  
 21142 |       inline bool add_constants() 
 21143 |       { 
 21144 |          return add_pi      () && 
 21145 |                 add_epsilon () && 
 21146 |                 add_infinity() ; 
 21147 |       } 
 21148 |  
 21149 |       inline bool add_pi() 
 21150 |       { 
 21151 |          const typename details::numeric::details::number_type<T>::type num_type; 
 21152 |          static const T local_pi = details::numeric::details::const_pi_impl<T>(num_type); 
 21153 |          return add_constant("pi",local_pi); 
 21154 |       } 
 21155 |  
 21156 |       inline bool add_epsilon() 
 21157 |       { 
 21158 |          static const T local_epsilon = details::numeric::details::epsilon_type<T>::value(); 
 21159 |          return add_constant("epsilon",local_epsilon); 
 21160 |       } 
 21161 |  
 21162 |       inline bool add_infinity() 
 21163 |       { 
 21164 |          static const T local_infinity = std::numeric_limits<T>::infinity(); 
 21165 |          return add_constant("inf",local_infinity); 
 21166 |       } 
 21167 |  
 21168 |       template <typename Package> 
 21169 |       inline bool add_package(Package& package) 
 21170 |       { 
 21171 |          return package.register_package(*this); 
 21172 |       } 
 21173 |  
 21174 |       template <typename Allocator, 
 21175 |                 template <typename, typename> class Sequence> 
 21176 |       inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const 
 21177 |       { 
 21178 |          if (!valid()) 
 21179 |             return 0; 
 21180 |          else 
 21181 |             return local_data().variable_store.get_list(vlist); 
 21182 |       } 
 21183 |  
 21184 |       template <typename Allocator, 
 21185 |                 template <typename, typename> class Sequence> 
 21186 |       inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const 
 21187 |       { 
 21188 |          if (!valid()) 
 21189 |             return 0; 
 21190 |          else 
 21191 |             return local_data().variable_store.get_list(vlist); 
 21192 |       } 
 21193 |  
 21194 |       #ifndef exprtk_disable_string_capabilities 
 21195 |       template <typename Allocator, 
 21196 |                 template <typename, typename> class Sequence> 
 21197 |       inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const 
 21198 |       { 
 21199 |          if (!valid()) 
 21200 |             return 0; 
 21201 |          else 
 21202 |             return local_data().stringvar_store.get_list(svlist); 
 21203 |       } 
 21204 |  
 21205 |       template <typename Allocator, 
 21206 |                 template <typename, typename> class Sequence> 
 21207 |       inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const 
 21208 |       { 
 21209 |          if (!valid()) 
 21210 |             return 0; 
 21211 |          else 
 21212 |             return local_data().stringvar_store.get_list(svlist); 
 21213 |       } 
 21214 |       #endif 
 21215 |  
 21216 |       template <typename Allocator, 
 21217 |                 template <typename, typename> class Sequence> 
 21218 |       inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vec_list) const 
 21219 |       { 
 21220 |          if (!valid()) 
 21221 |             return 0; 
 21222 |          else 
 21223 |             return local_data().vector_store.get_list(vec_list); 
 21224 |       } 
 21225 |  
 21226 |       template <typename Allocator, 
 21227 |                 template <typename, typename> class Sequence> 
 21228 |       inline std::size_t get_function_list(Sequence<std::string,Allocator>& function_list) const 
 21229 |       { 
 21230 |          if (!valid()) 
 21231 |             return 0; 
 21232 |  
 21233 |          std::vector<std::string> function_names; 
 21234 |          std::size_t count = 0; 
 21235 |  
 21236 |          count += local_data().function_store         .get_list(function_names); 
 21237 |          count += local_data().vararg_function_store  .get_list(function_names); 
 21238 |          count += local_data().generic_function_store .get_list(function_names); 
 21239 |          count += local_data().string_function_store  .get_list(function_names); 
 21240 |          count += local_data().overload_function_store.get_list(function_names); 
 21241 |  
 21242 |          std::set<std::string> function_set; 
 21243 |  
 21244 |          for (std::size_t i = 0; i < function_names.size(); ++i) 
 21245 |          { 
 21246 |             function_set.insert(function_names[i]); 
 21247 |          } 
 21248 |  
 21249 |          std::copy(function_set.begin(), function_set.end(), 
 21250 |                    std::back_inserter(function_list)); 
 21251 |  
 21252 |          return count; 
 21253 |       } 
 21254 |  
 21255 |       inline std::vector<std::string> get_function_list() const 
 21256 |       { 
 21257 |          std::vector<std::string> result; 
 21258 |          get_function_list(result); 
 21259 |          return result; 
 21260 |       } 
 21261 |  
 21262 |       inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const 
 21263 |       { 
 21264 |          /* 
 21265 |             Function will return true if symbol_name exists as either a 
 21266 |             reserved symbol, variable, stringvar, vector or function name 
 21267 |             in any of the type stores. 
 21268 |          */ 
 21269 |          if (!valid()) 
 21270 |             return false; 
 21271 |          else if (local_data().variable_store.symbol_exists(symbol_name)) 
 21272 |             return true; 
 21273 |          #ifndef exprtk_disable_string_capabilities 
 21274 |          else if (local_data().stringvar_store.symbol_exists(symbol_name)) 
 21275 |             return true; 
 21276 |          #endif 
 21277 |          else if (local_data().vector_store.symbol_exists(symbol_name)) 
 21278 |             return true; 
 21279 |          else if (local_data().function_store.symbol_exists(symbol_name)) 
 21280 |             return true; 
 21281 |          else if (check_reserved_symb && local_data().is_reserved_symbol(symbol_name)) 
 21282 |             return true; 
 21283 |          else 
 21284 |             return false; 
 21285 |       } 
 21286 |  
 21287 |       inline bool is_variable(const std::string& variable_name) const 
 21288 |       { 
 21289 |          if (!valid()) 
 21290 |             return false; 
 21291 |          else 
 21292 |             return local_data().variable_store.symbol_exists(variable_name); 
 21293 |       } 
 21294 |  
 21295 |       #ifndef exprtk_disable_string_capabilities 
 21296 |       inline bool is_stringvar(const std::string& stringvar_name) const 
 21297 |       { 
 21298 |          if (!valid()) 
 21299 |             return false; 
 21300 |          else 
 21301 |             return local_data().stringvar_store.symbol_exists(stringvar_name); 
 21302 |       } 
 21303 |  
 21304 |       inline bool is_conststr_stringvar(const std::string& symbol_name) const 
 21305 |       { 
 21306 |          if (!valid()) 
 21307 |             return false; 
 21308 |          else if (!valid_symbol(symbol_name)) 
 21309 |             return false; 
 21310 |          else if (!local_data().stringvar_store.symbol_exists(symbol_name)) 
 21311 |             return false; 
 21312 |  
 21313 |          return ( 
 21314 |                   local_data().stringvar_store.symbol_exists(symbol_name) || 
 21315 |                   local_data().stringvar_store.is_constant  (symbol_name) 
 21316 |                 ); 
 21317 |       } 
 21318 |       #endif 
 21319 |  
 21320 |       inline bool is_function(const std::string& function_name) const 
 21321 |       { 
 21322 |          if (!valid()) 
 21323 |             return false; 
 21324 |          else 
 21325 |             return local_data().function_store.symbol_exists(function_name); 
 21326 |       } 
 21327 |  
 21328 |       inline bool is_vararg_function(const std::string& vararg_function_name) const 
 21329 |       { 
 21330 |          if (!valid()) 
 21331 |             return false; 
 21332 |          else 
 21333 |             return local_data().vararg_function_store.symbol_exists(vararg_function_name); 
 21334 |       } 
 21335 |  
 21336 |       inline bool is_vector(const std::string& vector_name) const 
 21337 |       { 
 21338 |          if (!valid()) 
 21339 |             return false; 
 21340 |          else 
 21341 |             return local_data().vector_store.symbol_exists(vector_name); 
 21342 |       } 
 21343 |  
 21344 |       inline std::string get_variable_name(const expression_ptr& ptr) const 
 21345 |       { 
 21346 |          return local_data().variable_store.entity_name(ptr); 
 21347 |       } 
 21348 |  
 21349 |       inline std::string get_vector_name(const vector_holder_ptr& ptr) const 
 21350 |       { 
 21351 |          return local_data().vector_store.entity_name(ptr); 
 21352 |       } 
 21353 |  
 21354 |       #ifndef exprtk_disable_string_capabilities 
 21355 |       inline std::string get_stringvar_name(const expression_ptr& ptr) const 
 21356 |       { 
 21357 |          return local_data().stringvar_store.entity_name(ptr); 
 21358 |       } 
 21359 |  
 21360 |       inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const 
 21361 |       { 
 21362 |          return local_data().stringvar_store.entity_name(ptr); 
 21363 |       } 
 21364 |       #endif 
 21365 |  
 21366 |       inline bool valid() const 
 21367 |       { 
 21368 |          // Symbol table sanity check. 
 21369 |          return control_block_ && control_block_->data_; 
 21370 |       } 
 21371 |  
 21372 |       inline void load_from(const symbol_table<T>& st) 
 21373 |       { 
 21374 |          { 
 21375 |             std::vector<std::string> name_list; 
 21376 |  
 21377 |             st.local_data().function_store.get_list(name_list); 
 21378 |  
 21379 |             if (!name_list.empty()) 
 21380 |             { 
 21381 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21382 |                { 
 21383 |                   exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]); 
 21384 |                   add_function(name_list[i],ifunc); 
 21385 |                } 
 21386 |             } 
 21387 |          } 
 21388 |  
 21389 |          { 
 21390 |             std::vector<std::string> name_list; 
 21391 |  
 21392 |             st.local_data().vararg_function_store.get_list(name_list); 
 21393 |  
 21394 |             if (!name_list.empty()) 
 21395 |             { 
 21396 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21397 |                { 
 21398 |                   exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]); 
 21399 |                   add_function(name_list[i],ivafunc); 
 21400 |                } 
 21401 |             } 
 21402 |          } 
 21403 |  
 21404 |          { 
 21405 |             std::vector<std::string> name_list; 
 21406 |  
 21407 |             st.local_data().generic_function_store.get_list(name_list); 
 21408 |  
 21409 |             if (!name_list.empty()) 
 21410 |             { 
 21411 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21412 |                { 
 21413 |                   exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]); 
 21414 |                   add_function(name_list[i],ifunc); 
 21415 |                } 
 21416 |             } 
 21417 |          } 
 21418 |  
 21419 |          { 
 21420 |             std::vector<std::string> name_list; 
 21421 |  
 21422 |             st.local_data().string_function_store.get_list(name_list); 
 21423 |  
 21424 |             if (!name_list.empty()) 
 21425 |             { 
 21426 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21427 |                { 
 21428 |                   exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]); 
 21429 |                   add_function(name_list[i],ifunc); 
 21430 |                } 
 21431 |             } 
 21432 |          } 
 21433 |  
 21434 |          { 
 21435 |             std::vector<std::string> name_list; 
 21436 |  
 21437 |             st.local_data().overload_function_store.get_list(name_list); 
 21438 |  
 21439 |             if (!name_list.empty()) 
 21440 |             { 
 21441 |                for (std::size_t i = 0; i < name_list.size(); ++i) 
 21442 |                { 
 21443 |                   exprtk::igeneric_function<T>& ifunc = *st.get_overload_function(name_list[i]); 
 21444 |                   add_function(name_list[i],ifunc); 
 21445 |                } 
 21446 |             } 
 21447 |          } 
 21448 |       } 
 21449 |  
 21450 |       inline void load_variables_from(const symbol_table<T>& st) 
 21451 |       { 
 21452 |          std::vector<std::string> name_list; 
 21453 |  
 21454 |          st.local_data().variable_store.get_list(name_list); 
 21455 |  
 21456 |          if (!name_list.empty()) 
 21457 |          { 
 21458 |             for (std::size_t i = 0; i < name_list.size(); ++i) 
 21459 |             { 
 21460 |                T& variable = st.get_variable(name_list[i])->ref(); 
 21461 |                add_variable(name_list[i], variable); 
 21462 |             } 
 21463 |          } 
 21464 |       } 
 21465 |  
 21466 |       inline void load_vectors_from(const symbol_table<T>& st) 
 21467 |       { 
 21468 |          std::vector<std::string> name_list; 
 21469 |  
 21470 |          st.local_data().vector_store.get_list(name_list); 
 21471 |  
 21472 |          if (!name_list.empty()) 
 21473 |          { 
 21474 |             for (std::size_t i = 0; i < name_list.size(); ++i) 
 21475 |             { 
 21476 |                vector_holder_t& vecholder = *st.get_vector(name_list[i]); 
 21477 |                add_vector(name_list[i], vecholder.data(), vecholder.size()); 
 21478 |             } 
 21479 |          } 
 21480 |       } 
 21481 |  
 21482 |    private: 
 21483 |  
 21484 |       inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const 
 21485 |       { 
 21486 |          if (symbol.empty()) 
 21487 |             return false; 
 21488 |          else if (!details::is_letter(symbol[0])) 
 21489 |             return false; 
 21490 |          else if (symbol.size() > 1) 
 21491 |          { 
 21492 |             for (std::size_t i = 1; i < symbol.size(); ++i) 
 21493 |             { 
 21494 |                if ( 
 21495 |                     !details::is_letter_or_digit(symbol[i]) && 
 21496 |                     ('_' != symbol[i]) 
 21497 |                   ) 
 21498 |                { 
 21499 |                   if ((i < (symbol.size() - 1)) && ('.' == symbol[i])) 
 21500 |                      continue; 
 21501 |                   else 
 21502 |                      return false; 
 21503 |                } 
 21504 |             } 
 21505 |          } 
 21506 |  
 21507 |          return (check_reserved_symb) ? (!local_data().is_reserved_symbol(symbol)) : true; 
 21508 |       } 
 21509 |  
 21510 |       inline bool valid_function(const std::string& symbol) const 
 21511 |       { 
 21512 |          if (symbol.empty()) 
 21513 |             return false; 
 21514 |          else if (!details::is_letter(symbol[0])) 
 21515 |             return false; 
 21516 |          else if (symbol.size() > 1) 
 21517 |          { 
 21518 |             for (std::size_t i = 1; i < symbol.size(); ++i) 
 21519 |             { 
 21520 |                if ( 
 21521 |                     !details::is_letter_or_digit(symbol[i]) && 
 21522 |                     ('_' != symbol[i]) 
 21523 |                   ) 
 21524 |                { 
 21525 |                   if ((i < (symbol.size() - 1)) && ('.' == symbol[i])) 
 21526 |                      continue; 
 21527 |                   else 
 21528 |                      return false; 
 21529 |                } 
 21530 |             } 
 21531 |          } 
 21532 |  
 21533 |          return true; 
 21534 |       } 
 21535 |  
 21536 |       typedef typename control_block::st_data local_data_t; 
 21537 |  
 21538 |       inline local_data_t& local_data() 
 21539 |       { 
 21540 |          return *(control_block_->data_); 
 21541 |       } 
 21542 |  
 21543 |       inline const local_data_t& local_data() const 
 21544 |       { 
 21545 |          return *(control_block_->data_); 
 21546 |       } 
 21547 |  
 21548 |       control_block* control_block_; 
 21549 |  
 21550 |       friend class parser<T>; 
 21551 |    }; // class symbol_table 
 21552 |  
 21553 |    template <typename T> 
 21554 |    class function_compositor; 
 21555 |  
 21556 |    template <typename T> 
 21557 |    class expression 
 21558 |    { 
 21559 |    private: 
 21560 |  
 21561 |       typedef details::expression_node<T>*  expression_ptr; 
 21562 |       typedef details::vector_holder<T>*    vector_holder_ptr; 
 21563 |       typedef std::vector<symbol_table<T> > symtab_list_t; 
 21564 |  
 21565 |       struct control_block 
 21566 |       { 
 21567 |          enum data_type 
 21568 |          { 
 21569 |             e_unknown  , 
 21570 |             e_expr     , 
 21571 |             e_vecholder, 
 21572 |             e_data     , 
 21573 |             e_vecdata  , 
 21574 |             e_string 
 21575 |          }; 
 21576 |  
 21577 |          static std::string to_str(data_type dt) 
 21578 |          { 
 21579 |             switch(dt) 
 21580 |             { 
 21581 |                case e_unknown   : return "e_unknown  " 
 21582 |                case e_expr      : return "e_expr"     ; 
 21583 |                case e_vecholder : return "e_vecholder" 
 21584 |                case e_data      : return "e_data"     ; 
 21585 |                case e_vecdata   : return "e_vecdata"  ; 
 21586 |                case e_string    : return "e_string"   ; 
 21587 |             } 
 21588 |  
 21589 |             return "" 
 21590 |          } 
 21591 |  
 21592 |          struct data_pack 
 21593 |          { 
 21594 |             data_pack() 
 21595 |             : pointer(0) 
 21596 |             , type(e_unknown) 
 21597 |             , size(0) 
 21598 |             {} 
 21599 |  
 21600 |             data_pack(void* ptr, const data_type dt, const std::size_t sz = 0) 
 21601 |             : pointer(ptr) 
 21602 |             , type(dt) 
 21603 |             , size(sz) 
 21604 |             {} 
 21605 |  
 21606 |             void*       pointer; 
 21607 |             data_type   type; 
 21608 |             std::size_t size; 
 21609 |          }; 
 21610 |  
 21611 |          typedef std::vector<data_pack> local_data_list_t; 
 21612 |          typedef results_context<T>     results_context_t; 
 21613 |          typedef control_block*         cntrl_blck_ptr_t; 
 21614 |  
 21615 |          control_block() 
 21616 |          : ref_count(0) 
 21617 |          , expr     (0) 
 21618 |          , results  (0) 
 21619 |          , retinv_null(false) 
 21620 |          , return_invoked(&retinv_null) 
 21621 |          {} 
 21622 |  
 21623 |          explicit control_block(expression_ptr e) 
 21624 |          : ref_count(1) 
 21625 |          , expr     (e) 
 21626 |          , results  (0) 
 21627 |          , retinv_null(false) 
 21628 |          , return_invoked(&retinv_null) 
 21629 |          {} 
 21630 |  
 21631 |         ~control_block() 
 21632 |          { 
 21633 |             if (expr && details::branch_deletable(expr)) 
 21634 |             { 
 21635 |                destroy_node(expr); 
 21636 |             } 
 21637 |  
 21638 |             if (!local_data_list.empty()) 
 21639 |             { 
 21640 |                for (std::size_t i = 0; i < local_data_list.size(); ++i) 
 21641 |                { 
 21642 |                   switch (local_data_list[i].type) 
 21643 |                   { 
 21644 |                      case e_expr      : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer); 
 21645 |                                         break; 
 21646 |  
 21647 |                      case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer); 
 21648 |                                         break; 
 21649 |  
 21650 |                      case e_data      : delete reinterpret_cast<T*>(local_data_list[i].pointer); 
 21651 |                                         break; 
 21652 |  
 21653 |                      case e_vecdata   : delete [] reinterpret_cast<T*>(local_data_list[i].pointer); 
 21654 |                                         break; 
 21655 |  
 21656 |                      case e_string    : delete reinterpret_cast<std::string*>(local_data_list[i].pointer); 
 21657 |                                         break; 
 21658 |  
 21659 |                      default          : break; 
 21660 |                   } 
 21661 |                } 
 21662 |             } 
 21663 |  
 21664 |             if (results) 
 21665 |             { 
 21666 |                delete results; 
 21667 |             } 
 21668 |          } 
 21669 |  
 21670 |          static inline cntrl_blck_ptr_t create(expression_ptr e) 
 21671 |          { 
 21672 |             return new control_block(e); 
 21673 |          } 
 21674 |  
 21675 |          static inline void destroy(cntrl_blck_ptr_t& cntrl_blck) 
 21676 |          { 
 21677 |             if (cntrl_blck) 
 21678 |             { 
 21679 |                if ( 
 21680 |                     (0 !=   cntrl_blck->ref_count) && 
 21681 |                     (0 == --cntrl_blck->ref_count) 
 21682 |                   ) 
 21683 |                { 
 21684 |                   delete cntrl_blck; 
 21685 |                } 
 21686 |  
 21687 |                cntrl_blck = 0; 
 21688 |             } 
 21689 |          } 
 21690 |  
 21691 |          std::size_t ref_count; 
 21692 |          expression_ptr expr; 
 21693 |          local_data_list_t local_data_list; 
 21694 |          results_context_t* results; 
 21695 |          bool  retinv_null; 
 21696 |          bool* return_invoked; 
 21697 |  
 21698 |          friend class function_compositor<T>; 
 21699 |       }; 
 21700 |  
 21701 |    public: 
 21702 |  
 21703 |       expression() 
 21704 |       : control_block_(0) 
 21705 |       { 
 21706 |          set_expression(new details::null_node<T>()); 
 21707 |       } 
 21708 |  
 21709 |       expression(const expression<T>& e) 
 21710 |       : control_block_    (e.control_block_    ) 
 21711 |       , symbol_table_list_(e.symbol_table_list_) 
 21712 |       { 
 21713 |          control_block_->ref_count++; 
 21714 |       } 
 21715 |  
 21716 |       explicit expression(const symbol_table<T>& symbol_table) 
 21717 |       : control_block_(0) 
 21718 |       { 
 21719 |          set_expression(new details::null_node<T>()); 
 21720 |          symbol_table_list_.push_back(symbol_table); 
 21721 |       } 
 21722 |  
 21723 |       inline expression<T>& operator=(const expression<T>& e) 
 21724 |       { 
 21725 |          if (this != &e) 
 21726 |          { 
 21727 |             if (control_block_) 
 21728 |             { 
 21729 |                if ( 
 21730 |                     (0 !=   control_block_->ref_count) && 
 21731 |                     (0 == --control_block_->ref_count) 
 21732 |                   ) 
 21733 |                { 
 21734 |                   delete control_block_; 
 21735 |                } 
 21736 |  
 21737 |                control_block_ = 0; 
 21738 |             } 
 21739 |  
 21740 |             control_block_ = e.control_block_; 
 21741 |             control_block_->ref_count++; 
 21742 |             symbol_table_list_ = e.symbol_table_list_; 
 21743 |          } 
 21744 |  
 21745 |          return *this; 
 21746 |       } 
 21747 |  
 21748 |       inline bool operator==(const expression<T>& e) const 
 21749 |       { 
 21750 |          return (this == &e); 
 21751 |       } 
 21752 |  
 21753 |       inline bool operator!() const 
 21754 |       { 
 21755 |          return ( 
 21756 |                   (0 == control_block_      ) || 
 21757 |                   (0 == control_block_->expr) 
 21758 |                 ); 
 21759 |       } 
 21760 |  
 21761 |       inline expression<T>& release() 
 21762 |       { 
 21763 |          exprtk::details::dump_ptr("expression::release", this); 
 21764 |          control_block::destroy(control_block_); 
 21765 |  
 21766 |          return (*this); 
 21767 |       } 
 21768 |  
 21769 |      ~expression() 
 21770 |       { 
 21771 |          control_block::destroy(control_block_); 
 21772 |       } 
 21773 |  
 21774 |       inline T value() const 
 21775 |       { 
 21776 |          assert(control_block_      ); 
 21777 |          assert(control_block_->expr); 
 21778 |  
 21779 |          return control_block_->expr->value(); 
 21780 |       } 
 21781 |  
 21782 |       inline T operator() () const 
 21783 |       { 
 21784 |          return value(); 
 21785 |       } 
 21786 |  
 21787 |       inline operator T() const 
 21788 |       { 
 21789 |          return value(); 
 21790 |       } 
 21791 |  
 21792 |       inline operator bool() const 
 21793 |       { 
 21794 |          return details::is_true(value()); 
 21795 |       } 
 21796 |  
 21797 |       inline bool register_symbol_table(symbol_table<T>& st) 
 21798 |       { 
 21799 |          for (std::size_t i = 0; i < symbol_table_list_.size(); ++i) 
 21800 |          { 
 21801 |             if (st == symbol_table_list_[i]) 
 21802 |             { 
 21803 |                return false; 
 21804 |             } 
 21805 |          } 
 21806 |  
 21807 |          symbol_table_list_.push_back(st); 
 21808 |          return true; 
 21809 |       } 
 21810 |  
 21811 |       inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const 
 21812 |       { 
 21813 |          return symbol_table_list_[index]; 
 21814 |       } 
 21815 |  
 21816 |       inline symbol_table<T>& get_symbol_table(const std::size_t& index = 0) 
 21817 |       { 
 21818 |          return symbol_table_list_[index]; 
 21819 |       } 
 21820 |  
 21821 |       std::size_t num_symbol_tables() const 
 21822 |       { 
 21823 |          return symbol_table_list_.size(); 
 21824 |       } 
 21825 |  
 21826 |       typedef results_context<T> results_context_t; 
 21827 |  
 21828 |       inline const results_context_t& results() const 
 21829 |       { 
 21830 |          if (control_block_->results) 
 21831 |             return (*control_block_->results); 
 21832 |          else 
 21833 |          { 
 21834 |             static const results_context_t null_results; 
 21835 |             return null_results; 
 21836 |          } 
 21837 |       } 
 21838 |  
 21839 |       inline bool return_invoked() const 
 21840 |       { 
 21841 |          return (*control_block_->return_invoked); 
 21842 |       } 
 21843 |  
 21844 |    private: 
 21845 |  
 21846 |       inline symtab_list_t get_symbol_table_list() const 
 21847 |       { 
 21848 |          return symbol_table_list_; 
 21849 |       } 
 21850 |  
 21851 |       inline void set_expression(const expression_ptr expr) 
 21852 |       { 
 21853 |          if (expr) 
 21854 |          { 
 21855 |             if (control_block_) 
 21856 |             { 
 21857 |                if (0 == --control_block_->ref_count) 
 21858 |                { 
 21859 |                   delete control_block_; 
 21860 |                } 
 21861 |             } 
 21862 |  
 21863 |             control_block_ = control_block::create(expr); 
 21864 |          } 
 21865 |       } 
 21866 |  
 21867 |       inline void register_local_var(expression_ptr expr) 
 21868 |       { 
 21869 |          if (expr) 
 21870 |          { 
 21871 |             if (control_block_) 
 21872 |             { 
 21873 |                control_block_-> 
 21874 |                   local_data_list.push_back( 
 21875 |                      typename expression<T>::control_block:: 
 21876 |                         data_pack(reinterpret_cast<void*>(expr), 
 21877 |                                   control_block::e_expr)); 
 21878 |             } 
 21879 |          } 
 21880 |       } 
 21881 |  
 21882 |       inline void register_local_var(vector_holder_ptr vec_holder) 
 21883 |       { 
 21884 |          if (vec_holder) 
 21885 |          { 
 21886 |             if (control_block_) 
 21887 |             { 
 21888 |                control_block_-> 
 21889 |                   local_data_list.push_back( 
 21890 |                      typename expression<T>::control_block:: 
 21891 |                         data_pack(reinterpret_cast<void*>(vec_holder), 
 21892 |                                   control_block::e_vecholder)); 
 21893 |             } 
 21894 |          } 
 21895 |       } 
 21896 |  
 21897 |       inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0) 
 21898 |       { 
 21899 |          if (data) 
 21900 |          { 
 21901 |             if (control_block_) 
 21902 |             { 
 21903 |                typename control_block::data_type dt = control_block::e_data; 
 21904 |  
 21905 |                switch (data_mode) 
 21906 |                { 
 21907 |                   case 0 : dt = control_block::e_data;    break; 
 21908 |                   case 1 : dt = control_block::e_vecdata; break; 
 21909 |                   case 2 : dt = control_block::e_string;  break; 
 21910 |                } 
 21911 |  
 21912 |                control_block_-> 
 21913 |                   local_data_list.push_back( 
 21914 |                      typename expression<T>::control_block:: 
 21915 |                         data_pack(reinterpret_cast<void*>(data), dt, size)); 
 21916 |             } 
 21917 |          } 
 21918 |       } 
 21919 |  
 21920 |       inline const typename control_block::local_data_list_t& local_data_list() 
 21921 |       { 
 21922 |          if (control_block_) 
 21923 |          { 
 21924 |             return control_block_->local_data_list; 
 21925 |          } 
 21926 |          else 
 21927 |          { 
 21928 |             static typename control_block::local_data_list_t null_local_data_list; 
 21929 |             return null_local_data_list; 
 21930 |          } 
 21931 |       } 
 21932 |  
 21933 |       inline void register_return_results(results_context_t* rc) 
 21934 |       { 
 21935 |          if (control_block_ && rc) 
 21936 |          { 
 21937 |             control_block_->results = rc; 
 21938 |          } 
 21939 |       } 
 21940 |  
 21941 |       inline void set_retinvk(bool* retinvk_ptr) 
 21942 |       { 
 21943 |          if (control_block_) 
 21944 |          { 
 21945 |             control_block_->return_invoked = retinvk_ptr; 
 21946 |          } 
 21947 |       } 
 21948 |  
 21949 |       control_block* control_block_; 
 21950 |       symtab_list_t  symbol_table_list_; 
 21951 |  
 21952 |       friend class parser<T>; 
 21953 |       friend class expression_helper<T>; 
 21954 |       friend class function_compositor<T>; 
 21955 |       template <typename TT> 
 21956 |       friend bool is_valid(const expression<TT>& expr); 
 21957 |    }; // class expression 
 21958 |  
 21959 |    template <typename T> 
 21960 |    class expression_helper 
 21961 |    { 
 21962 |    public: 
 21963 |  
 21964 |       enum node_types 
 21965 |       { 
 21966 |          e_literal, 
 21967 |          e_variable, 
 21968 |          e_string, 
 21969 |          e_unary, 
 21970 |          e_binary, 
 21971 |          e_function, 
 21972 |          e_vararg, 
 21973 |          e_null, 
 21974 |          e_assert, 
 21975 |          e_sf3ext, 
 21976 |          e_sf4ext 
 21977 |       }; 
 21978 |  
 21979 |       static inline bool is_literal(const expression<T>& expr) 
 21980 |       { 
 21981 |          return expr.control_block_ && details::is_literal_node(expr.control_block_->expr); 
 21982 |       } 
 21983 |  
 21984 |       static inline bool is_variable(const expression<T>& expr) 
 21985 |       { 
 21986 |          return expr.control_block_ && details::is_variable_node(expr.control_block_->expr); 
 21987 |       } 
 21988 |  
 21989 |       static inline bool is_string(const expression<T>& expr) 
 21990 |       { 
 21991 |          return expr.control_block_ && details::is_generally_string_node(expr.control_block_->expr); 
 21992 |       } 
 21993 |  
 21994 |       static inline bool is_unary(const expression<T>& expr) 
 21995 |       { 
 21996 |          return expr.control_block_ && details::is_unary_node(expr.control_block_->expr); 
 21997 |       } 
 21998 |  
 21999 |       static inline bool is_binary(const expression<T>& expr) 
 22000 |       { 
 22001 |          return expr.control_block_ && details::is_binary_node(expr.control_block_->expr); 
 22002 |       } 
 22003 |  
 22004 |       static inline bool is_function(const expression<T>& expr) 
 22005 |       { 
 22006 |          return expr.control_block_ && details::is_function(expr.control_block_->expr); 
 22007 |       } 
 22008 |  
 22009 |       static inline bool is_vararg(const expression<T>& expr) 
 22010 |       { 
 22011 |          return expr.control_block_ && details::is_vararg_node(expr.control_block_->expr); 
 22012 |       } 
 22013 |  
 22014 |       static inline bool is_null(const expression<T>& expr) 
 22015 |       { 
 22016 |          return expr.control_block_ && details::is_null_node(expr.control_block_->expr); 
 22017 |       } 
 22018 |  
 22019 |       static inline bool is_assert(const expression<T>& expr) 
 22020 |       { 
 22021 |          return expr.control_block_ && details::is_assert_node(expr.control_block_->expr); 
 22022 |       } 
 22023 |  
 22024 |       static inline bool is_sf3ext(const expression<T>& expr) 
 22025 |       { 
 22026 |          return expr.control_block_ && details::is_sf3ext_node(expr.control_block_->expr); 
 22027 |       } 
 22028 |  
 22029 |       static inline bool is_sf4ext(const expression<T>& expr) 
 22030 |       { 
 22031 |          return expr.control_block_ && details::is_sf4ext_node(expr.control_block_->expr); 
 22032 |       } 
 22033 |  
 22034 |       static inline bool is_type(const expression<T>& expr, const node_types node_type) 
 22035 |       { 
 22036 |          if (0 == expr.control_block_) 
 22037 |          { 
 22038 |             return false; 
 22039 |          } 
 22040 |  
 22041 |          switch (node_type) 
 22042 |          { 
 22043 |             case e_literal  : return is_literal_node(expr); 
 22044 |             case e_variable : return is_variable    (expr); 
 22045 |             case e_string   : return is_string      (expr); 
 22046 |             case e_unary    : return is_unary       (expr); 
 22047 |             case e_binary   : return is_binary      (expr); 
 22048 |             case e_function : return is_function    (expr); 
 22049 |             case e_null     : return is_null        (expr); 
 22050 |             case e_assert   : return is_assert      (expr); 
 22051 |             case e_sf3ext   : return is_sf3ext      (expr); 
 22052 |             case e_sf4ext   : return is_sf4ext      (expr); 
 22053 |          }; 
 22054 |  
 22055 |          return false; 
 22056 |       } 
 22057 |  
 22058 |       static inline bool match_type_sequence(const expression<T>& expr, const std::vector<node_types>& type_seq) 
 22059 |       { 
 22060 |          if ((0 == expr.control_block_) || !is_vararg(expr)) 
 22061 |          { 
 22062 |             return false; 
 22063 |          } 
 22064 |  
 22065 |          typedef details::vararg_node<T, exprtk::details::vararg_multi_op<T> > mo_vararg_t; 
 22066 |  
 22067 |          mo_vararg_t* vnode = dynamic_cast<mo_vararg_t*>(expr.control_block_->expr); 
 22068 |  
 22069 |          if ( 
 22070 |               (0 == vnode) || 
 22071 |               type_seq.empty() || 
 22072 |               (vnode->size() < type_seq.size()) 
 22073 |             ) 
 22074 |          { 
 22075 |             return false; 
 22076 |          } 
 22077 |  
 22078 |          for (std::size_t i = 0; i < type_seq.size(); ++i) 
 22079 |          { 
 22080 |             assert((*vnode)[i]); 
 22081 |  
 22082 |             switch(type_seq[i]) 
 22083 |             { 
 22084 |                case e_literal  : { if (details::is_literal_node         ((*vnode)[i])) continue; } break; 
 22085 |                case e_variable : { if (details::is_variable_node        ((*vnode)[i])) continue; } break; 
 22086 |                case e_string   : { if (details::is_generally_string_node((*vnode)[i])) continue; } break; 
 22087 |                case e_unary    : { if (details::is_unary_node           ((*vnode)[i])) continue; } break; 
 22088 |                case e_binary   : { if (details::is_binary_node          ((*vnode)[i])) continue; } break; 
 22089 |                case e_function : { if (details::is_function             ((*vnode)[i])) continue; } break; 
 22090 |                case e_null     : { if (details::is_null_node            ((*vnode)[i])) continue; } break; 
 22091 |                case e_assert   : { if (details::is_assert_node          ((*vnode)[i])) continue; } break; 
 22092 |                case e_sf3ext   : { if (details::is_sf3ext_node          ((*vnode)[i])) continue; } break; 
 22093 |                case e_sf4ext   : { if (details::is_sf4ext_node          ((*vnode)[i])) continue; } break; 
 22094 |                case e_vararg   : break; 
 22095 |             } 
 22096 |  
 22097 |             return false; 
 22098 |          } 
 22099 |  
 22100 |          return true; 
 22101 |       } 
 22102 |    }; 
 22103 |  
 22104 |    template <typename T> 
 22105 |    inline bool is_valid(const expression<T>& expr) 
 22106 |    { 
 22107 |       return expr.control_block_ && !expression_helper<T>::is_null(expr); 
 22108 |    } 
 22109 |  
 22110 |    namespace parser_error 
 22111 |    { 
 22112 |       enum error_mode 
 22113 |       { 
 22114 |          e_unknown   = 0, 
 22115 |          e_syntax    = 1, 
 22116 |          e_token     = 2, 
 22117 |          e_numeric   = 4, 
 22118 |          e_symtab    = 5, 
 22119 |          e_lexer     = 6, 
 22120 |          e_synthesis = 7, 
 22121 |          e_helper    = 8, 
 22122 |          e_parser    = 9 
 22123 |       }; 
 22124 |  
 22125 |       struct type 
 22126 |       { 
 22127 |          type() 
 22128 |          : mode(parser_error::e_unknown) 
 22129 |          , line_no  (0) 
 22130 |          , column_no(0) 
 22131 |          {} 
 22132 |  
 22133 |          lexer::token token; 
 22134 |          error_mode mode; 
 22135 |          std::string diagnostic; 
 22136 |          std::string src_location; 
 22137 |          std::string error_line; 
 22138 |          std::size_t line_no; 
 22139 |          std::size_t column_no; 
 22140 |       }; 
 22141 |  
 22142 |       inline type make_error(const error_mode mode, 
 22143 |                              const std::string& diagnostic   = "", 
 22144 |                              const std::string& src_location = "") 
 22145 |       { 
 22146 |          type t; 
 22147 |          t.mode         = mode; 
 22148 |          t.token.type   = lexer::token::e_error; 
 22149 |          t.diagnostic   = diagnostic; 
 22150 |          t.src_location = src_location; 
 22151 |          exprtk_debug(("%s\n", diagnostic .c_str())); 
 22152 |          return t; 
 22153 |       } 
 22154 |  
 22155 |       inline type make_error(const error_mode mode, 
 22156 |                              const lexer::token& tk, 
 22157 |                              const std::string& diagnostic   = "", 
 22158 |                              const std::string& src_location = "") 
 22159 |       { 
 22160 |          type t; 
 22161 |          t.mode         = mode; 
 22162 |          t.token        = tk; 
 22163 |          t.diagnostic   = diagnostic; 
 22164 |          t.src_location = src_location; 
 22165 |          exprtk_debug(("%s\n", diagnostic .c_str())); 
 22166 |          return t; 
 22167 |       } 
 22168 |  
 22169 |       inline std::string to_str(error_mode mode) 
 22170 |       { 
 22171 |          switch (mode) 
 22172 |          { 
 22173 |             case e_unknown : return std::string("Unknown Error"); 
 22174 |             case e_syntax  : return std::string("Syntax Error" ); 
 22175 |             case e_token   : return std::string("Token Error"  ); 
 22176 |             case e_numeric : return std::string("Numeric Error"); 
 22177 |             case e_symtab  : return std::string("Symbol Error" ); 
 22178 |             case e_lexer   : return std::string("Lexer Error"  ); 
 22179 |             case e_helper  : return std::string("Helper Error" ); 
 22180 |             case e_parser  : return std::string("Parser Error" ); 
 22181 |             default        : return std::string("Unknown Error"); 
 22182 |          } 
 22183 |       } 
 22184 |  
 22185 |       inline bool update_error(type& error, const std::string& expression) 
 22186 |       { 
 22187 |          if ( 
 22188 |               expression.empty()                         || 
 22189 |               (error.token.position > expression.size()) || 
 22190 |               (std::numeric_limits<std::size_t>::max() == error.token.position) 
 22191 |             ) 
 22192 |          { 
 22193 |             return false; 
 22194 |          } 
 22195 |  
 22196 |          std::size_t error_line_start = 0; 
 22197 |  
 22198 |          for (std::size_t i = error.token.position; i > 0; --i) 
 22199 |          { 
 22200 |             const details::char_t c = expression[i]; 
 22201 |  
 22202 |             if (('\n' == c) || ('\r' == c)) 
 22203 |             { 
 22204 |                error_line_start = i + 1; 
 22205 |                break; 
 22206 |             } 
 22207 |          } 
 22208 |  
 22209 |          std::size_t next_nl_position = std::min(expression.size(), 
 22210 |                                                  expression.find_first_of('\n',error.token.position + 1)); 
 22211 |  
 22212 |          error.column_no  = error.token.position - error_line_start; 
 22213 |          error.error_line = expression.substr(error_line_start, 
 22214 |                                               next_nl_position - error_line_start); 
 22215 |  
 22216 |          error.line_no = 0; 
 22217 |  
 22218 |          for (std::size_t i = 0; i < next_nl_position; ++i) 
 22219 |          { 
 22220 |             if ('\n' == expression[i]) 
 22221 |                ++error.line_no; 
 22222 |          } 
 22223 |  
 22224 |          return true; 
 22225 |       } 
 22226 |  
 22227 |       inline void dump_error(const type& error) 
 22228 |       { 
 22229 |          printf("Position: %02d   Type: [%s]   Msg: %s\n", 
 22230 |                 static_cast<int>(error.token.position), 
 22231 |                 exprtk::parser_error::to_str(error.mode).c_str(), 
 22232 |                 error.diagnostic.c_str()); 
 22233 |       } 
 22234 |    } 
 22235 |  
 22236 |    namespace details 
 22237 |    { 
 22238 |       template <typename Parser> 
 22239 |       inline void disable_type_checking(Parser& p) 
 22240 |       { 
 22241 |          p.state_.type_check_enabled = false; 
 22242 |       } 
 22243 |    } 
 22244 |  
 22245 |    template <typename T> 
 22246 |    class parser : public lexer::parser_helper 
 22247 |    { 
 22248 |    private: 
 22249 |  
 22250 |       enum precedence_level 
 22251 |       { 
 22252 |          e_level00, e_level01, e_level02, e_level03, e_level04, 
 22253 |          e_level05, e_level06, e_level07, e_level08, e_level09, 
 22254 |          e_level10, e_level11, e_level12, e_level13, e_level14 
 22255 |       }; 
 22256 |  
 22257 |       typedef const T&                                       cref_t; 
 22258 |       typedef const T                                        const_t; 
 22259 |       typedef ifunction<T>                                   F; 
 22260 |       typedef ivararg_function<T>                            VAF; 
 22261 |       typedef igeneric_function<T>                           GF; 
 22262 |       typedef ifunction<T>                                   ifunction_t; 
 22263 |       typedef ivararg_function<T>                            ivararg_function_t; 
 22264 |       typedef igeneric_function<T>                           igeneric_function_t; 
 22265 |       typedef details::expression_node<T>                    expression_node_t; 
 22266 |       typedef details::literal_node<T>                       literal_node_t; 
 22267 |       typedef details::unary_node<T>                         unary_node_t; 
 22268 |       typedef details::binary_node<T>                        binary_node_t; 
 22269 |       typedef details::trinary_node<T>                       trinary_node_t; 
 22270 |       typedef details::quaternary_node<T>                    quaternary_node_t; 
 22271 |       typedef details::conditional_node<T>                   conditional_node_t; 
 22272 |       typedef details::cons_conditional_node<T>              cons_conditional_node_t; 
 22273 |       typedef details::while_loop_node<T>                    while_loop_node_t; 
 22274 |       typedef details::repeat_until_loop_node<T>             repeat_until_loop_node_t; 
 22275 |       typedef details::for_loop_node<T>                      for_loop_node_t; 
 22276 |       typedef details::while_loop_rtc_node<T>                while_loop_rtc_node_t; 
 22277 |       typedef details::repeat_until_loop_rtc_node<T>         repeat_until_loop_rtc_node_t; 
 22278 |       typedef details::for_loop_rtc_node<T>                  for_loop_rtc_node_t; 
 22279 |       #ifndef exprtk_disable_break_continue 
 22280 |       typedef details::while_loop_bc_node<T>                 while_loop_bc_node_t; 
 22281 |       typedef details::repeat_until_loop_bc_node<T>          repeat_until_loop_bc_node_t; 
 22282 |       typedef details::for_loop_bc_node<T>                   for_loop_bc_node_t; 
 22283 |       typedef details::while_loop_bc_rtc_node<T>             while_loop_bc_rtc_node_t; 
 22284 |       typedef details::repeat_until_loop_bc_rtc_node<T>      repeat_until_loop_bc_rtc_node_t; 
 22285 |       typedef details::for_loop_bc_rtc_node<T>               for_loop_bc_rtc_node_t; 
 22286 |       #endif 
 22287 |       typedef details::switch_node<T>                        switch_node_t; 
 22288 |       typedef details::variable_node<T>                      variable_node_t; 
 22289 |       typedef details::vector_elem_node<T>                   vector_elem_node_t; 
 22290 |       typedef details::vector_celem_node<T>                  vector_celem_node_t; 
 22291 |       typedef details::vector_elem_rtc_node<T>               vector_elem_rtc_node_t; 
 22292 |       typedef details::vector_celem_rtc_node<T>              vector_celem_rtc_node_t; 
 22293 |       typedef details::rebasevector_elem_node<T>             rebasevector_elem_node_t; 
 22294 |       typedef details::rebasevector_celem_node<T>            rebasevector_celem_node_t; 
 22295 |       typedef details::rebasevector_elem_rtc_node<T>         rebasevector_elem_rtc_node_t; 
 22296 |       typedef details::rebasevector_celem_rtc_node<T>        rebasevector_celem_rtc_node_t; 
 22297 |       typedef details::vector_node<T>                        vector_node_t; 
 22298 |       typedef details::vector_size_node<T>                   vector_size_node_t; 
 22299 |       typedef details::range_pack<T>                         range_t; 
 22300 |       #ifndef exprtk_disable_string_capabilities 
 22301 |       typedef details::stringvar_node<T>                     stringvar_node_t; 
 22302 |       typedef details::string_literal_node<T>                string_literal_node_t; 
 22303 |       typedef details::string_range_node<T>                  string_range_node_t; 
 22304 |       typedef details::const_string_range_node<T>            const_string_range_node_t; 
 22305 |       typedef details::generic_string_range_node<T>          generic_string_range_node_t; 
 22306 |       typedef details::string_concat_node<T>                 string_concat_node_t; 
 22307 |       typedef details::assignment_string_node<T>             assignment_string_node_t; 
 22308 |       typedef details::assignment_string_range_node<T>       assignment_string_range_node_t; 
 22309 |       typedef details::conditional_string_node<T>            conditional_string_node_t; 
 22310 |       typedef details::cons_conditional_str_node<T>          cons_conditional_str_node_t; 
 22311 |       #endif 
 22312 |       typedef details::assignment_node<T>                    assignment_node_t; 
 22313 |       typedef details::assignment_vec_elem_node<T>           assignment_vec_elem_node_t; 
 22314 |       typedef details::assignment_vec_elem_rtc_node<T>       assignment_vec_elem_rtc_node_t; 
 22315 |       typedef details::assignment_rebasevec_elem_node<T>     assignment_rebasevec_elem_node_t; 
 22316 |       typedef details::assignment_rebasevec_elem_rtc_node<T> assignment_rebasevec_elem_rtc_node_t; 
 22317 |       typedef details::assignment_rebasevec_celem_node<T>    assignment_rebasevec_celem_node_t; 
 22318 |       typedef details::assignment_vec_node<T>                assignment_vec_node_t; 
 22319 |       typedef details::assignment_vecvec_node<T>             assignment_vecvec_node_t; 
 22320 |       typedef details::conditional_vector_node<T>            conditional_vector_node_t; 
 22321 |       typedef details::scand_node<T>                         scand_node_t; 
 22322 |       typedef details::scor_node<T>                          scor_node_t; 
 22323 |       typedef lexer::token                                   token_t; 
 22324 |       typedef expression_node_t*                             expression_node_ptr; 
 22325 |       typedef expression<T>                                  expression_t; 
 22326 |       typedef symbol_table<T>                                symbol_table_t; 
 22327 |       typedef typename expression<T>::symtab_list_t          symbol_table_list_t; 
 22328 |       typedef details::vector_holder<T>                      vector_holder_t; 
 22329 |       typedef vector_holder_t*                               vector_holder_ptr; 
 22330 |  
 22331 |       typedef typename details::functor_t<T> functor_t; 
 22332 |       typedef typename functor_t::qfunc_t    quaternary_functor_t; 
 22333 |       typedef typename functor_t::tfunc_t    trinary_functor_t; 
 22334 |       typedef typename functor_t::bfunc_t    binary_functor_t; 
 22335 |       typedef typename functor_t::ufunc_t    unary_functor_t; 
 22336 |  
 22337 |       typedef details::operator_type operator_t; 
 22338 |  
 22339 |       typedef std::map<operator_t, unary_functor_t  > unary_op_map_t; 
 22340 |       typedef std::map<operator_t, binary_functor_t > binary_op_map_t; 
 22341 |       typedef std::map<operator_t, trinary_functor_t> trinary_op_map_t; 
 22342 |  
 22343 |       typedef std::map<std::string,std::pair<trinary_functor_t   ,operator_t> > sf3_map_t; 
 22344 |       typedef std::map<std::string,std::pair<quaternary_functor_t,operator_t> > sf4_map_t; 
 22345 |  
 22346 |       typedef std::map<binary_functor_t,operator_t> inv_binary_op_map_t; 
 22347 |       typedef std::multimap<std::string,details::base_operation_t,details::ilesscompare> base_ops_map_t; 
 22348 |       typedef std::set<std::string,details::ilesscompare> disabled_func_set_t; 
 22349 |  
 22350 |       typedef details::T0oT1_define<T, cref_t , cref_t > vov_t; 
 22351 |       typedef details::T0oT1_define<T, const_t, cref_t > cov_t; 
 22352 |       typedef details::T0oT1_define<T, cref_t , const_t> voc_t; 
 22353 |  
 22354 |       typedef details::T0oT1oT2_define<T, cref_t , cref_t , cref_t > vovov_t; 
 22355 |       typedef details::T0oT1oT2_define<T, cref_t , cref_t , const_t> vovoc_t; 
 22356 |       typedef details::T0oT1oT2_define<T, cref_t , const_t, cref_t > vocov_t; 
 22357 |       typedef details::T0oT1oT2_define<T, const_t, cref_t , cref_t > covov_t; 
 22358 |       typedef details::T0oT1oT2_define<T, const_t, cref_t , const_t> covoc_t; 
 22359 |       typedef details::T0oT1oT2_define<T, const_t, const_t, cref_t > cocov_t; 
 22360 |       typedef details::T0oT1oT2_define<T, cref_t , const_t, const_t> vococ_t; 
 22361 |  
 22362 |       typedef details::T0oT1oT2oT3_define<T, cref_t , cref_t , cref_t , cref_t > vovovov_t; 
 22363 |       typedef details::T0oT1oT2oT3_define<T, cref_t , cref_t , cref_t , const_t> vovovoc_t; 
 22364 |       typedef details::T0oT1oT2oT3_define<T, cref_t , cref_t , const_t, cref_t > vovocov_t; 
 22365 |       typedef details::T0oT1oT2oT3_define<T, cref_t , const_t, cref_t , cref_t > vocovov_t; 
 22366 |       typedef details::T0oT1oT2oT3_define<T, const_t, cref_t , cref_t , cref_t > covovov_t; 
 22367 |  
 22368 |       typedef details::T0oT1oT2oT3_define<T, const_t, cref_t , const_t, cref_t > covocov_t; 
 22369 |       typedef details::T0oT1oT2oT3_define<T, cref_t , const_t, cref_t , const_t> vocovoc_t; 
 22370 |       typedef details::T0oT1oT2oT3_define<T, const_t, cref_t , cref_t , const_t> covovoc_t; 
 22371 |       typedef details::T0oT1oT2oT3_define<T, cref_t , const_t, const_t, cref_t > vococov_t; 
 22372 |  
 22373 |       typedef results_context<T> results_context_t; 
 22374 |  
 22375 |       typedef parser_helper prsrhlpr_t; 
 22376 |  
 22377 |       struct scope_element 
 22378 |       { 
 22379 |          enum element_type 
 22380 |          { 
 22381 |             e_none    , 
 22382 |             e_literal , 
 22383 |             e_variable, 
 22384 |             e_vector  , 
 22385 |             e_vecelem , 
 22386 |             e_string 
 22387 |          }; 
 22388 |  
 22389 |          typedef details::vector_holder<T> vector_holder_t; 
 22390 |          typedef literal_node_t*           literal_node_ptr; 
 22391 |          typedef variable_node_t*          variable_node_ptr; 
 22392 |          typedef vector_holder_t*          vector_holder_ptr; 
 22393 |          typedef expression_node_t*        expression_node_ptr; 
 22394 |          #ifndef exprtk_disable_string_capabilities 
 22395 |          typedef stringvar_node_t*         stringvar_node_ptr; 
 22396 |          #endif 
 22397 |  
 22398 |          scope_element() 
 22399 |          : name("???") 
 22400 |          , size (std::numeric_limits<std::size_t>::max()) 
 22401 |          , index(std::numeric_limits<std::size_t>::max()) 
 22402 |          , depth(std::numeric_limits<std::size_t>::max()) 
 22403 |          , ref_count(0) 
 22404 |          , ip_index (0) 
 22405 |          , type     (e_none) 
 22406 |          , active   (false) 
 22407 |          , data     (0) 
 22408 |          , var_node (0) 
 22409 |          , vec_node (0) 
 22410 |          #ifndef exprtk_disable_string_capabilities 
 22411 |          , str_node(0) 
 22412 |          #endif 
 22413 |          {} 
 22414 |  
 22415 |          bool operator < (const scope_element& se) const 
 22416 |          { 
 22417 |             if (ip_index < se.ip_index) 
 22418 |                return true; 
 22419 |             else if (ip_index > se.ip_index) 
 22420 |                return false; 
 22421 |             else if (depth < se.depth) 
 22422 |                return true; 
 22423 |             else if (depth > se.depth) 
 22424 |                return false; 
 22425 |             else if (index < se.index) 
 22426 |                return true; 
 22427 |             else if (index > se.index) 
 22428 |                return false; 
 22429 |             else 
 22430 |                return (name < se.name); 
 22431 |          } 
 22432 |  
 22433 |          void clear() 
 22434 |          { 
 22435 |             name   = "???" 
 22436 |             size   = std::numeric_limits<std::size_t>::max(); 
 22437 |             index  = std::numeric_limits<std::size_t>::max(); 
 22438 |             depth  = std::numeric_limits<std::size_t>::max(); 
 22439 |             type   = e_none; 
 22440 |             active = false; 
 22441 |             ref_count = 0; 
 22442 |             ip_index  = 0; 
 22443 |             data      = 0; 
 22444 |             var_node  = 0; 
 22445 |             vec_node  = 0; 
 22446 |             #ifndef exprtk_disable_string_capabilities 
 22447 |             str_node  = 0; 
 22448 |             #endif 
 22449 |          } 
 22450 |  
 22451 |          std::string  name; 
 22452 |          std::size_t  size; 
 22453 |          std::size_t  index; 
 22454 |          std::size_t  depth; 
 22455 |          std::size_t  ref_count; 
 22456 |          std::size_t  ip_index; 
 22457 |          element_type type; 
 22458 |          bool         active; 
 22459 |          void*        data; 
 22460 |          expression_node_ptr var_node; 
 22461 |          vector_holder_ptr   vec_node; 
 22462 |          #ifndef exprtk_disable_string_capabilities 
 22463 |          stringvar_node_ptr str_node; 
 22464 |          #endif 
 22465 |       }; 
 22466 |  
 22467 |       class scope_element_manager 
 22468 |       { 
 22469 |       public: 
 22470 |  
 22471 |          typedef expression_node_t* expression_node_ptr; 
 22472 |          typedef variable_node_t*   variable_node_ptr; 
 22473 |          typedef parser<T>          parser_t; 
 22474 |  
 22475 |          explicit scope_element_manager(parser<T>& p) 
 22476 |          : parser_(p) 
 22477 |          , input_param_cnt_(0) 
 22478 |          {} 
 22479 |  
 22480 |          inline std::size_t size() const 
 22481 |          { 
 22482 |             return element_.size(); 
 22483 |          } 
 22484 |  
 22485 |          inline bool empty() const 
 22486 |          { 
 22487 |             return element_.empty(); 
 22488 |          } 
 22489 |  
 22490 |          inline scope_element& get_element(const std::size_t& index) 
 22491 |          { 
 22492 |             if (index < element_.size()) 
 22493 |                return element_[index]; 
 22494 |             else 
 22495 |                return null_element_; 
 22496 |          } 
 22497 |  
 22498 |          inline scope_element& get_element(const std::string& var_name, 
 22499 |                                            const std::size_t index = std::numeric_limits<std::size_t>::max()) 
 22500 |          { 
 22501 |             const std::size_t current_depth = parser_.state_.scope_depth; 
 22502 |  
 22503 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22504 |             { 
 22505 |                scope_element& se = element_[i]; 
 22506 |  
 22507 |                if (se.depth > current_depth) 
 22508 |                   continue; 
 22509 |                else if ( 
 22510 |                          details::imatch(se.name, var_name) && 
 22511 |                          (se.index == index) 
 22512 |                        ) 
 22513 |                   return se; 
 22514 |             } 
 22515 |  
 22516 |             return null_element_; 
 22517 |          } 
 22518 |  
 22519 |          inline scope_element& get_active_element(const std::string& var_name, 
 22520 |                                                   const std::size_t index = std::numeric_limits<std::size_t>::max()) 
 22521 |          { 
 22522 |             const std::size_t current_depth = parser_.state_.scope_depth; 
 22523 |  
 22524 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22525 |             { 
 22526 |                scope_element& se = element_[i]; 
 22527 |  
 22528 |                if (se.depth > current_depth) 
 22529 |                   continue; 
 22530 |                else if ( 
 22531 |                          details::imatch(se.name, var_name) && 
 22532 |                          (se.index == index)                && 
 22533 |                          (se.active) 
 22534 |                        ) 
 22535 |                   return se; 
 22536 |             } 
 22537 |  
 22538 |             return null_element_; 
 22539 |          } 
 22540 |  
 22541 |          inline bool add_element(const scope_element& se) 
 22542 |          { 
 22543 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22544 |             { 
 22545 |                scope_element& cse = element_[i]; 
 22546 |  
 22547 |                if ( 
 22548 |                     details::imatch(cse.name, se.name) && 
 22549 |                     (cse.depth <= se.depth)            && 
 22550 |                     (cse.index == se.index)            && 
 22551 |                     (cse.size  == se.size )            && 
 22552 |                     (cse.type  == se.type )            && 
 22553 |                     (cse.active) 
 22554 |                   ) 
 22555 |                   return false; 
 22556 |             } 
 22557 |  
 22558 |             element_.push_back(se); 
 22559 |             std::sort(element_.begin(),element_.end()); 
 22560 |  
 22561 |             return true; 
 22562 |          } 
 22563 |  
 22564 |          inline void deactivate(const std::size_t& scope_depth) 
 22565 |          { 
 22566 |             exprtk_debug(("deactivate() - Scope depth: %d\n", 
 22567 |                           static_cast<int>(parser_.state_.scope_depth))); 
 22568 |  
 22569 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22570 |             { 
 22571 |                scope_element& se = element_[i]; 
 22572 |  
 22573 |                if (se.active && (se.depth >= scope_depth)) 
 22574 |                { 
 22575 |                   exprtk_debug(("deactivate() - element[%02d] '%s'\n", 
 22576 |                                 static_cast<int>(i), 
 22577 |                                 se.name.c_str())); 
 22578 |  
 22579 |                   se.active = false; 
 22580 |                } 
 22581 |             } 
 22582 |          } 
 22583 |  
 22584 |          inline void free_element(scope_element& se) 
 22585 |          { 
 22586 |             exprtk_debug(("free_element() - se[%s]\n", se.name.c_str())); 
 22587 |  
 22588 |             switch (se.type) 
 22589 |             { 
 22590 |                case scope_element::e_literal    : delete reinterpret_cast<T*>(se.data); 
 22591 |                                                   delete se.var_node; 
 22592 |                                                   break; 
 22593 |  
 22594 |                case scope_element::e_variable   : delete reinterpret_cast<T*>(se.data); 
 22595 |                                                   delete se.var_node; 
 22596 |                                                   break; 
 22597 |  
 22598 |                case scope_element::e_vector     : delete[] reinterpret_cast<T*>(se.data); 
 22599 |                                                   delete se.vec_node; 
 22600 |                                                   break; 
 22601 |  
 22602 |                case scope_element::e_vecelem    : delete se.var_node; 
 22603 |                                                   break; 
 22604 |  
 22605 |                #ifndef exprtk_disable_string_capabilities 
 22606 |                case scope_element::e_string     : delete reinterpret_cast<std::string*>(se.data); 
 22607 |                                                   delete se.str_node; 
 22608 |                                                   break; 
 22609 |                #endif 
 22610 |  
 22611 |                default                          : return; 
 22612 |             } 
 22613 |  
 22614 |             se.clear(); 
 22615 |          } 
 22616 |  
 22617 |          inline void cleanup() 
 22618 |          { 
 22619 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22620 |             { 
 22621 |                free_element(element_[i]); 
 22622 |             } 
 22623 |  
 22624 |             element_.clear(); 
 22625 |  
 22626 |             input_param_cnt_ = 0; 
 22627 |          } 
 22628 |  
 22629 |          inline std::size_t next_ip_index() 
 22630 |          { 
 22631 |             return ++input_param_cnt_; 
 22632 |          } 
 22633 |  
 22634 |          inline expression_node_ptr get_variable(const T& v) 
 22635 |          { 
 22636 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22637 |             { 
 22638 |                scope_element& se = element_[i]; 
 22639 |  
 22640 |                if ( 
 22641 |                     se.active   && 
 22642 |                     se.var_node && 
 22643 |                     details::is_variable_node(se.var_node) 
 22644 |                   ) 
 22645 |                { 
 22646 |                   variable_node_ptr vn = reinterpret_cast<variable_node_ptr>(se.var_node); 
 22647 |  
 22648 |                   if (&(vn->ref()) == (&v)) 
 22649 |                   { 
 22650 |                      return se.var_node; 
 22651 |                   } 
 22652 |                } 
 22653 |             } 
 22654 |  
 22655 |             return expression_node_ptr(0); 
 22656 |          } 
 22657 |  
 22658 |          inline std::string get_vector_name(const T* data) 
 22659 |          { 
 22660 |             for (std::size_t i = 0; i < element_.size(); ++i) 
 22661 |             { 
 22662 |                scope_element& se = element_[i]; 
 22663 |  
 22664 |                if ( 
 22665 |                     se.active   && 
 22666 |                     se.vec_node && 
 22667 |                     (se.vec_node->data() == data) 
 22668 |                   ) 
 22669 |                { 
 22670 |                   return se.name; 
 22671 |                } 
 22672 |             } 
 22673 |  
 22674 |             return "neo-vector" 
 22675 |          } 
 22676 |  
 22677 |       private: 
 22678 |  
 22679 |          scope_element_manager(const scope_element_manager&) exprtk_delete; 
 22680 |          scope_element_manager& operator=(const scope_element_manager&) exprtk_delete; 
 22681 |  
 22682 |          parser_t& parser_; 
 22683 |          std::vector<scope_element> element_; 
 22684 |          scope_element null_element_; 
 22685 |          std::size_t input_param_cnt_; 
 22686 |       }; 
 22687 |  
 22688 |       class scope_handler 
 22689 |       { 
 22690 |       public: 
 22691 |  
 22692 |          typedef parser<T> parser_t; 
 22693 |  
 22694 |          explicit scope_handler(parser<T>& p) 
 22695 |          : parser_(p) 
 22696 |          { 
 22697 |             parser_.state_.scope_depth++; 
 22698 |             #ifdef exprtk_enable_debugging 
 22699 |             const std::string depth(2 * parser_.state_.scope_depth,'-'); 
 22700 |             exprtk_debug(("%s> Scope Depth: %02d\n", 
 22701 |                           depth.c_str(), 
 22702 |                           static_cast<int>(parser_.state_.scope_depth))); 
 22703 |             #endif 
 22704 |          } 
 22705 |  
 22706 |         ~scope_handler() 
 22707 |          { 
 22708 |             parser_.sem_.deactivate(parser_.state_.scope_depth); 
 22709 |             parser_.state_.scope_depth--; 
 22710 |             #ifdef exprtk_enable_debugging 
 22711 |             const std::string depth(2 * parser_.state_.scope_depth,'-'); 
 22712 |             exprtk_debug(("<%s Scope Depth: %02d\n", 
 22713 |                           depth.c_str(), 
 22714 |                           static_cast<int>(parser_.state_.scope_depth))); 
 22715 |             #endif 
 22716 |          } 
 22717 |  
 22718 |       private: 
 22719 |  
 22720 |          scope_handler(const scope_handler&) exprtk_delete; 
 22721 |          scope_handler& operator=(const scope_handler&) exprtk_delete; 
 22722 |  
 22723 |          parser_t& parser_; 
 22724 |       }; 
 22725 |  
 22726 |       template <typename T_> 
 22727 |       struct halfopen_range_policy 
 22728 |       { 
 22729 |          static inline bool is_within(const T_& v, const T_& begin, const T_& end) 
 22730 |          { 
 22731 |             assert(begin <= end); 
 22732 |             return (begin <= v) && (v < end); 
 22733 |          } 
 22734 |  
 22735 |          static inline bool is_less(const T_& v, const T_& begin) 
 22736 |          { 
 22737 |             return (v < begin); 
 22738 |          } 
 22739 |  
 22740 |          static inline bool is_greater(const T_& v, const T_& end) 
 22741 |          { 
 22742 |             return (end <= v); 
 22743 |          } 
 22744 |  
 22745 |          static inline bool end_inclusive() 
 22746 |          { 
 22747 |             return false; 
 22748 |          } 
 22749 |       }; 
 22750 |  
 22751 |       template <typename T_> 
 22752 |       struct closed_range_policy 
 22753 |       { 
 22754 |          static inline bool is_within(const T_& v, const T_& begin, const T_& end) 
 22755 |          { 
 22756 |             assert(begin <= end); 
 22757 |             return (begin <= v) && (v <= end); 
 22758 |          } 
 22759 |  
 22760 |          static inline bool is_less(const T_& v, const T_& begin) 
 22761 |          { 
 22762 |             return (v < begin); 
 22763 |          } 
 22764 |  
 22765 |          static inline bool is_greater(const T_& v, const T_& end) 
 22766 |          { 
 22767 |             return (end < v); 
 22768 |          } 
 22769 |  
 22770 |          static inline bool end_inclusive() 
 22771 |          { 
 22772 |             return true; 
 22773 |          } 
 22774 |       }; 
 22775 |  
 22776 |       template <typename IntervalPointType, 
 22777 |                 typename RangePolicy = halfopen_range_policy<IntervalPointType> > 
 22778 |       class interval_container_t 
 22779 |       { 
 22780 |       public: 
 22781 |  
 22782 |          typedef IntervalPointType interval_point_t; 
 22783 |          typedef std::pair<interval_point_t, interval_point_t> interval_t; 
 22784 |          typedef std::map<interval_point_t, interval_t> interval_map_t; 
 22785 |          typedef typename interval_map_t::const_iterator interval_map_citr_t; 
 22786 |  
 22787 |          std::size_t size() const 
 22788 |          { 
 22789 |             return interval_map_.size(); 
 22790 |          } 
 22791 |  
 22792 |          void reset() 
 22793 |          { 
 22794 |             interval_map_.clear(); 
 22795 |          } 
 22796 |  
 22797 |          bool in_interval(const interval_point_t point, interval_t& interval) const 
 22798 |          { 
 22799 |             interval_map_citr_t itr = RangePolicy::end_inclusive() ? 
 22800 |                                       interval_map_.lower_bound(point): 
 22801 |                                       interval_map_.upper_bound(point); 
 22802 |  
 22803 |             for (; itr != interval_map_.end(); ++itr) 
 22804 |             { 
 22805 |                const interval_point_t& begin = itr->second.first; 
 22806 |                const interval_point_t& end   = itr->second.second; 
 22807 |  
 22808 |                if (RangePolicy::is_within(point, begin, end)) 
 22809 |                { 
 22810 |                   interval = interval_t(begin,end); 
 22811 |                   return true; 
 22812 |                } 
 22813 |                else if (RangePolicy::is_greater(point, end)) 
 22814 |                { 
 22815 |                   break; 
 22816 |                } 
 22817 |             } 
 22818 |  
 22819 |             return false; 
 22820 |          } 
 22821 |  
 22822 |          bool in_interval(const interval_point_t point) const 
 22823 |          { 
 22824 |             interval_t interval; 
 22825 |             return in_interval(point,interval); 
 22826 |          } 
 22827 |  
 22828 |          bool add_interval(const interval_point_t begin, const interval_point_t end) 
 22829 |          { 
 22830 |             if ((end <= begin) || in_interval(begin) || in_interval(end)) 
 22831 |             { 
 22832 |                return false; 
 22833 |             } 
 22834 |  
 22835 |             interval_map_[end] = std::make_pair(begin, end); 
 22836 |  
 22837 |             return true; 
 22838 |          } 
 22839 |  
 22840 |          bool add_interval(const interval_t interval) 
 22841 |          { 
 22842 |             return add_interval(interval.first, interval.second); 
 22843 |          } 
 22844 |  
 22845 |       private: 
 22846 |  
 22847 |          interval_map_t interval_map_; 
 22848 |       }; 
 22849 |  
 22850 |       class stack_limit_handler 
 22851 |       { 
 22852 |       public: 
 22853 |  
 22854 |          typedef parser<T> parser_t; 
 22855 |  
 22856 |          explicit stack_limit_handler(parser<T>& p) 
 22857 |          : parser_(p) 
 22858 |          , limit_exceeded_(false) 
 22859 |          { 
 22860 |             if (++parser_.state_.stack_depth > parser_.settings_.max_stack_depth_) 
 22861 |             { 
 22862 |                limit_exceeded_ = true; 
 22863 |                parser_.set_error(make_error( 
 22864 |                   parser_error::e_parser, 
 22865 |                   "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) + 
 22866 |                   " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_), 
 22867 |                   exprtk_error_location)); 
 22868 |             } 
 22869 |          } 
 22870 |  
 22871 |         ~stack_limit_handler() 
 22872 |          { 
 22873 |             assert(parser_.state_.stack_depth > 0); 
 22874 |             parser_.state_.stack_depth--; 
 22875 |          } 
 22876 |  
 22877 |          bool operator!() 
 22878 |          { 
 22879 |             return limit_exceeded_; 
 22880 |          } 
 22881 |  
 22882 |       private: 
 22883 |  
 22884 |          stack_limit_handler(const stack_limit_handler&) exprtk_delete; 
 22885 |          stack_limit_handler& operator=(const stack_limit_handler&) exprtk_delete; 
 22886 |  
 22887 |          parser_t& parser_; 
 22888 |          bool limit_exceeded_; 
 22889 |       }; 
 22890 |  
 22891 |       struct symtab_store 
 22892 |       { 
 22893 |          symbol_table_list_t symtab_list_; 
 22894 |  
 22895 |          typedef typename symbol_table_t::local_data_t local_data_t; 
 22896 |          typedef typename symbol_table_t::variable_ptr variable_ptr; 
 22897 |          typedef typename symbol_table_t::function_ptr function_ptr; 
 22898 |          #ifndef exprtk_disable_string_capabilities 
 22899 |          typedef typename symbol_table_t::stringvar_ptr stringvar_ptr; 
 22900 |          #endif 
 22901 |          typedef typename symbol_table_t::vector_holder_ptr    vector_holder_ptr; 
 22902 |          typedef typename symbol_table_t::vararg_function_ptr  vararg_function_ptr; 
 22903 |          typedef typename symbol_table_t::generic_function_ptr generic_function_ptr; 
 22904 |  
 22905 |          struct variable_context 
 22906 |          { 
 22907 |             variable_context() 
 22908 |             : symbol_table(0) 
 22909 |             , variable(0) 
 22910 |             {} 
 22911 |  
 22912 |             const symbol_table_t* symbol_table; 
 22913 |             variable_ptr variable; 
 22914 |          }; 
 22915 |  
 22916 |          struct vector_context 
 22917 |          { 
 22918 |             vector_context() 
 22919 |             : symbol_table(0) 
 22920 |             , vector_holder(0) 
 22921 |             {} 
 22922 |  
 22923 |             const symbol_table_t* symbol_table; 
 22924 |             vector_holder_ptr vector_holder; 
 22925 |          }; 
 22926 |  
 22927 |          #ifndef exprtk_disable_string_capabilities 
 22928 |          struct string_context 
 22929 |          { 
 22930 |             string_context() 
 22931 |             : symbol_table(0) 
 22932 |             , str_var(0) 
 22933 |             {} 
 22934 |  
 22935 |             const symbol_table_t* symbol_table; 
 22936 |             stringvar_ptr str_var; 
 22937 |          }; 
 22938 |          #endif 
 22939 |  
 22940 |          inline bool empty() const 
 22941 |          { 
 22942 |             return symtab_list_.empty(); 
 22943 |          } 
 22944 |  
 22945 |          inline void clear() 
 22946 |          { 
 22947 |             symtab_list_.clear(); 
 22948 |          } 
 22949 |  
 22950 |          inline bool valid() const 
 22951 |          { 
 22952 |             if (!empty()) 
 22953 |             { 
 22954 |                for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 22955 |                { 
 22956 |                   if (symtab_list_[i].valid()) 
 22957 |                      return true; 
 22958 |                } 
 22959 |             } 
 22960 |  
 22961 |             return false; 
 22962 |          } 
 22963 |  
 22964 |          inline bool valid_symbol(const std::string& symbol) const 
 22965 |          { 
 22966 |             if (!symtab_list_.empty()) 
 22967 |                return symtab_list_[0].valid_symbol(symbol); 
 22968 |             else 
 22969 |                return false; 
 22970 |          } 
 22971 |  
 22972 |          inline bool valid_function_name(const std::string& symbol) const 
 22973 |          { 
 22974 |             if (!symtab_list_.empty()) 
 22975 |                return symtab_list_[0].valid_function(symbol); 
 22976 |             else 
 22977 |                return false; 
 22978 |          } 
 22979 |  
 22980 |          inline variable_context get_variable_context(const std::string& variable_name) const 
 22981 |          { 
 22982 |             variable_context result; 
 22983 |  
 22984 |             if (valid_symbol(variable_name)) 
 22985 |             { 
 22986 |                for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 22987 |                { 
 22988 |                   if (!symtab_list_[i].valid()) 
 22989 |                   { 
 22990 |                      continue; 
 22991 |                   } 
 22992 |  
 22993 |                   result.variable = local_data(i) 
 22994 |                                        .variable_store.get(variable_name); 
 22995 |                   if (result.variable) 
 22996 |                   { 
 22997 |                      result.symbol_table = &symtab_list_[i]; 
 22998 |                      break; 
 22999 |                   } 
 23000 |                } 
 23001 |             } 
 23002 |  
 23003 |             return result; 
 23004 |          } 
 23005 |  
 23006 |          inline variable_ptr get_variable(const std::string& variable_name) const 
 23007 |          { 
 23008 |             if (!valid_symbol(variable_name)) 
 23009 |                return reinterpret_cast<variable_ptr>(0); 
 23010 |  
 23011 |             variable_ptr result = reinterpret_cast<variable_ptr>(0); 
 23012 |  
 23013 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23014 |             { 
 23015 |                if (!symtab_list_[i].valid()) 
 23016 |                   continue; 
 23017 |                else 
 23018 |                   result = local_data(i) 
 23019 |                               .variable_store.get(variable_name); 
 23020 |  
 23021 |                if (result) break; 
 23022 |             } 
 23023 |  
 23024 |             return result; 
 23025 |          } 
 23026 |  
 23027 |          inline variable_ptr get_variable(const T& var_ref) const 
 23028 |          { 
 23029 |             variable_ptr result = reinterpret_cast<variable_ptr>(0); 
 23030 |  
 23031 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23032 |             { 
 23033 |                if (!symtab_list_[i].valid()) 
 23034 |                   continue; 
 23035 |                else 
 23036 |                   result = local_data(i).variable_store 
 23037 |                               .get_from_varptr(reinterpret_cast<const void*>(&var_ref)); 
 23038 |  
 23039 |                if (result) break; 
 23040 |             } 
 23041 |  
 23042 |             return result; 
 23043 |          } 
 23044 |  
 23045 |          #ifndef exprtk_disable_string_capabilities 
 23046 |          inline string_context get_string_context(const std::string& string_name) const 
 23047 |          { 
 23048 |             string_context result; 
 23049 |  
 23050 |             if (!valid_symbol(string_name)) 
 23051 |                return result; 
 23052 |  
 23053 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23054 |             { 
 23055 |                if (!symtab_list_[i].valid()) 
 23056 |                { 
 23057 |                   continue; 
 23058 |                } 
 23059 |  
 23060 |                result.str_var = local_data(i).stringvar_store.get(string_name); 
 23061 |  
 23062 |                if (result.str_var) 
 23063 |                { 
 23064 |                   result.symbol_table = &symtab_list_[i]; 
 23065 |                   break; 
 23066 |                } 
 23067 |             } 
 23068 |  
 23069 |             return result; 
 23070 |          } 
 23071 |  
 23072 |          inline stringvar_ptr get_stringvar(const std::string& string_name) const 
 23073 |          { 
 23074 |             if (!valid_symbol(string_name)) 
 23075 |                return reinterpret_cast<stringvar_ptr>(0); 
 23076 |  
 23077 |             stringvar_ptr result = reinterpret_cast<stringvar_ptr>(0); 
 23078 |  
 23079 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23080 |             { 
 23081 |                if (!symtab_list_[i].valid()) 
 23082 |                   continue; 
 23083 |                else 
 23084 |                   result = local_data(i) 
 23085 |                               .stringvar_store.get(string_name); 
 23086 |  
 23087 |                if (result) break; 
 23088 |             } 
 23089 |  
 23090 |             return result; 
 23091 |          } 
 23092 |          #endif 
 23093 |  
 23094 |          inline function_ptr get_function(const std::string& function_name) const 
 23095 |          { 
 23096 |             if (!valid_function_name(function_name)) 
 23097 |                return reinterpret_cast<function_ptr>(0); 
 23098 |  
 23099 |             function_ptr result = reinterpret_cast<function_ptr>(0); 
 23100 |  
 23101 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23102 |             { 
 23103 |                if (!symtab_list_[i].valid()) 
 23104 |                   continue; 
 23105 |                else 
 23106 |                   result = local_data(i) 
 23107 |                               .function_store.get(function_name); 
 23108 |  
 23109 |                if (result) break; 
 23110 |             } 
 23111 |  
 23112 |             return result; 
 23113 |          } 
 23114 |  
 23115 |          inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const 
 23116 |          { 
 23117 |             if (!valid_function_name(vararg_function_name)) 
 23118 |                return reinterpret_cast<vararg_function_ptr>(0); 
 23119 |  
 23120 |             vararg_function_ptr result = reinterpret_cast<vararg_function_ptr>(0); 
 23121 |  
 23122 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23123 |             { 
 23124 |                if (!symtab_list_[i].valid()) 
 23125 |                   continue; 
 23126 |                else 
 23127 |                   result = local_data(i) 
 23128 |                               .vararg_function_store.get(vararg_function_name); 
 23129 |  
 23130 |                if (result) break; 
 23131 |             } 
 23132 |  
 23133 |             return result; 
 23134 |          } 
 23135 |  
 23136 |          inline generic_function_ptr get_generic_function(const std::string& function_name) const 
 23137 |          { 
 23138 |             if (!valid_function_name(function_name)) 
 23139 |                return reinterpret_cast<generic_function_ptr>(0); 
 23140 |  
 23141 |             generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0); 
 23142 |  
 23143 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23144 |             { 
 23145 |                if (!symtab_list_[i].valid()) 
 23146 |                   continue; 
 23147 |                else 
 23148 |                   result = local_data(i) 
 23149 |                               .generic_function_store.get(function_name); 
 23150 |  
 23151 |                if (result) break; 
 23152 |             } 
 23153 |  
 23154 |             return result; 
 23155 |          } 
 23156 |  
 23157 |          inline generic_function_ptr get_string_function(const std::string& function_name) const 
 23158 |          { 
 23159 |             if (!valid_function_name(function_name)) 
 23160 |                return reinterpret_cast<generic_function_ptr>(0); 
 23161 |  
 23162 |             generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0); 
 23163 |  
 23164 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23165 |             { 
 23166 |                if (!symtab_list_[i].valid()) 
 23167 |                   continue; 
 23168 |                else 
 23169 |                   result = 
 23170 |                      local_data(i).string_function_store.get(function_name); 
 23171 |  
 23172 |                if (result) break; 
 23173 |             } 
 23174 |  
 23175 |             return result; 
 23176 |          } 
 23177 |  
 23178 |          inline generic_function_ptr get_overload_function(const std::string& function_name) const 
 23179 |          { 
 23180 |             if (!valid_function_name(function_name)) 
 23181 |                return reinterpret_cast<generic_function_ptr>(0); 
 23182 |  
 23183 |             generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0); 
 23184 |  
 23185 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23186 |             { 
 23187 |                if (!symtab_list_[i].valid()) 
 23188 |                   continue; 
 23189 |                else 
 23190 |                   result = 
 23191 |                      local_data(i).overload_function_store.get(function_name); 
 23192 |  
 23193 |                if (result) break; 
 23194 |             } 
 23195 |  
 23196 |             return result; 
 23197 |          } 
 23198 |  
 23199 |          inline vector_context get_vector_context(const std::string& vector_name) const 
 23200 |          { 
 23201 |             vector_context result; 
 23202 |             if (!valid_symbol(vector_name)) 
 23203 |                return result; 
 23204 |  
 23205 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23206 |             { 
 23207 |                if (!symtab_list_[i].valid()) 
 23208 |                { 
 23209 |                   continue; 
 23210 |                } 
 23211 |  
 23212 |                result.vector_holder = local_data(i).vector_store.get(vector_name); 
 23213 |  
 23214 |                if (result.vector_holder) 
 23215 |                { 
 23216 |                   result.symbol_table = &symtab_list_[i]; 
 23217 |                   break; 
 23218 |                } 
 23219 |             } 
 23220 |  
 23221 |             return result; 
 23222 |          } 
 23223 |  
 23224 |          inline vector_holder_ptr get_vector(const std::string& vector_name) const 
 23225 |          { 
 23226 |             if (!valid_symbol(vector_name)) 
 23227 |                return reinterpret_cast<vector_holder_ptr>(0); 
 23228 |  
 23229 |             vector_holder_ptr result = reinterpret_cast<vector_holder_ptr>(0); 
 23230 |  
 23231 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23232 |             { 
 23233 |                if (!symtab_list_[i].valid()) 
 23234 |                { 
 23235 |                   continue; 
 23236 |                } 
 23237 |  
 23238 |                result = local_data(i).vector_store.get(vector_name); 
 23239 |  
 23240 |                if (result) 
 23241 |                { 
 23242 |                   break; 
 23243 |                } 
 23244 |             } 
 23245 |  
 23246 |             return result; 
 23247 |          } 
 23248 |  
 23249 |          inline bool is_constant_node(const std::string& symbol_name) const 
 23250 |          { 
 23251 |             if (!valid_symbol(symbol_name)) 
 23252 |                return false; 
 23253 |  
 23254 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23255 |             { 
 23256 |                if (!symtab_list_[i].valid()) 
 23257 |                { 
 23258 |                   continue; 
 23259 |                } 
 23260 |  
 23261 |                if (local_data(i).variable_store.is_constant(symbol_name)) 
 23262 |                { 
 23263 |                   return true; 
 23264 |                } 
 23265 |             } 
 23266 |  
 23267 |             return false; 
 23268 |          } 
 23269 |  
 23270 |          #ifndef exprtk_disable_string_capabilities 
 23271 |          inline bool is_constant_string(const std::string& symbol_name) const 
 23272 |          { 
 23273 |             if (!valid_symbol(symbol_name)) 
 23274 |                return false; 
 23275 |  
 23276 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23277 |             { 
 23278 |                if (!symtab_list_[i].valid()) 
 23279 |                   continue; 
 23280 |                else if (!local_data(i).stringvar_store.symbol_exists(symbol_name)) 
 23281 |                   continue; 
 23282 |                else if (local_data(i).stringvar_store.is_constant(symbol_name)) 
 23283 |                   return true; 
 23284 |             } 
 23285 |  
 23286 |             return false; 
 23287 |          } 
 23288 |          #endif 
 23289 |  
 23290 |          inline bool symbol_exists(const std::string& symbol) const 
 23291 |          { 
 23292 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23293 |             { 
 23294 |                if (!symtab_list_[i].valid()) 
 23295 |                { 
 23296 |                   continue; 
 23297 |                } 
 23298 |  
 23299 |                if (symtab_list_[i].symbol_exists(symbol)) 
 23300 |                { 
 23301 |                   return true; 
 23302 |                } 
 23303 |             } 
 23304 |  
 23305 |             return false; 
 23306 |          } 
 23307 |  
 23308 |          inline bool is_variable(const std::string& variable_name) const 
 23309 |          { 
 23310 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23311 |             { 
 23312 |                if (!symtab_list_[i].valid()) 
 23313 |                   continue; 
 23314 |                else if ( 
 23315 |                          symtab_list_[i].local_data().variable_store 
 23316 |                            .symbol_exists(variable_name) 
 23317 |                        ) 
 23318 |                   return true; 
 23319 |             } 
 23320 |  
 23321 |             return false; 
 23322 |          } 
 23323 |  
 23324 |          #ifndef exprtk_disable_string_capabilities 
 23325 |          inline bool is_stringvar(const std::string& stringvar_name) const 
 23326 |          { 
 23327 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23328 |             { 
 23329 |                if (!symtab_list_[i].valid()) 
 23330 |                   continue; 
 23331 |                else if ( 
 23332 |                          symtab_list_[i].local_data().stringvar_store 
 23333 |                            .symbol_exists(stringvar_name) 
 23334 |                        ) 
 23335 |                   return true; 
 23336 |             } 
 23337 |  
 23338 |             return false; 
 23339 |          } 
 23340 |  
 23341 |          inline bool is_conststr_stringvar(const std::string& symbol_name) const 
 23342 |          { 
 23343 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23344 |             { 
 23345 |                if (!symtab_list_[i].valid()) 
 23346 |                   continue; 
 23347 |                else if ( 
 23348 |                          symtab_list_[i].local_data().stringvar_store 
 23349 |                            .symbol_exists(symbol_name) 
 23350 |                        ) 
 23351 |                { 
 23352 |                   return ( 
 23353 |                            local_data(i).stringvar_store.symbol_exists(symbol_name) || 
 23354 |                            local_data(i).stringvar_store.is_constant  (symbol_name) 
 23355 |                          ); 
 23356 |  
 23357 |                } 
 23358 |             } 
 23359 |  
 23360 |             return false; 
 23361 |          } 
 23362 |          #endif 
 23363 |  
 23364 |          inline bool is_function(const std::string& function_name) const 
 23365 |          { 
 23366 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23367 |             { 
 23368 |                if (!symtab_list_[i].valid()) 
 23369 |                   continue; 
 23370 |                else if ( 
 23371 |                          local_data(i).vararg_function_store 
 23372 |                            .symbol_exists(function_name) 
 23373 |                        ) 
 23374 |                   return true; 
 23375 |             } 
 23376 |  
 23377 |             return false; 
 23378 |          } 
 23379 |  
 23380 |          inline bool is_vararg_function(const std::string& vararg_function_name) const 
 23381 |          { 
 23382 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23383 |             { 
 23384 |                if (!symtab_list_[i].valid()) 
 23385 |                   continue; 
 23386 |                else if ( 
 23387 |                          local_data(i).vararg_function_store 
 23388 |                            .symbol_exists(vararg_function_name) 
 23389 |                        ) 
 23390 |                   return true; 
 23391 |             } 
 23392 |  
 23393 |             return false; 
 23394 |          } 
 23395 |  
 23396 |          inline bool is_vector(const std::string& vector_name) const 
 23397 |          { 
 23398 |             for (std::size_t i = 0; i < symtab_list_.size(); ++i) 
 23399 |             { 
 23400 |                if (!symtab_list_[i].valid()) 
 23401 |                   continue; 
 23402 |                else if ( 
 23403 |                          local_data(i).vector_store 
 23404 |                            .symbol_exists(vector_name) 
 23405 |                        ) 
 23406 |                   return true; 
 23407 |             } 
 23408 |  
 23409 |             return false; 
 23410 |          } 
 23411 |  
 23412 |          inline std::string get_variable_name(const expression_node_ptr& ptr) const 
 23413 |          { 
 23414 |             return local_data().variable_store.entity_name(ptr); 
 23415 |          } 
 23416 |  
 23417 |          inline std::string get_vector_name(const vector_holder_ptr& ptr) const 
 23418 |          { 
 23419 |             return local_data().vector_store.entity_name(ptr); 
 23420 |          } 
 23421 |  
 23422 |          #ifndef exprtk_disable_string_capabilities 
 23423 |          inline std::string get_stringvar_name(const expression_node_ptr& ptr) const 
 23424 |          { 
 23425 |             return local_data().stringvar_store.entity_name(ptr); 
 23426 |          } 
 23427 |  
 23428 |          inline std::string get_conststr_stringvar_name(const expression_node_ptr& ptr) const 
 23429 |          { 
 23430 |             return local_data().stringvar_store.entity_name(ptr); 
 23431 |          } 
 23432 |          #endif 
 23433 |  
 23434 |          inline local_data_t& local_data(const std::size_t& index = 0) 
 23435 |          { 
 23436 |             return symtab_list_[index].local_data(); 
 23437 |          } 
 23438 |  
 23439 |          inline const local_data_t& local_data(const std::size_t& index = 0) const 
 23440 |          { 
 23441 |             return symtab_list_[index].local_data(); 
 23442 |          } 
 23443 |  
 23444 |          inline symbol_table_t& get_symbol_table(const std::size_t& index = 0) 
 23445 |          { 
 23446 |             return symtab_list_[index]; 
 23447 |          } 
 23448 |       }; 
 23449 |  
 23450 |       struct parser_state 
 23451 |       { 
 23452 |          parser_state() 
 23453 |          : type_check_enabled(true) 
 23454 |          { 
 23455 |             reset(); 
 23456 |          } 
 23457 |  
 23458 |          void reset() 
 23459 |          { 
 23460 |             parsing_return_stmt     = false; 
 23461 |             parsing_break_stmt      = false; 
 23462 |             parsing_assert_stmt     = false; 
 23463 |             return_stmt_present     = false; 
 23464 |             side_effect_present     = false; 
 23465 |             scope_depth             = 0; 
 23466 |             stack_depth             = 0; 
 23467 |             parsing_loop_stmt_count = 0; 
 23468 |          } 
 23469 |  
 23470 |          #ifndef exprtk_enable_debugging 
 23471 |          void activate_side_effect(const std::string&) 
 23472 |          #else 
 23473 |          void activate_side_effect(const std::string& source) 
 23474 |          #endif 
 23475 |          { 
 23476 |             if (!side_effect_present) 
 23477 |             { 
 23478 |                side_effect_present = true; 
 23479 |  
 23480 |                exprtk_debug(("activate_side_effect() - caller: %s\n", source.c_str())); 
 23481 |             } 
 23482 |          } 
 23483 |  
 23484 |          bool parsing_return_stmt; 
 23485 |          bool parsing_break_stmt; 
 23486 |          bool parsing_assert_stmt; 
 23487 |          bool return_stmt_present; 
 23488 |          bool side_effect_present; 
 23489 |          bool type_check_enabled; 
 23490 |          std::size_t scope_depth; 
 23491 |          std::size_t stack_depth; 
 23492 |          std::size_t parsing_loop_stmt_count; 
 23493 |       }; 
 23494 |  
 23495 |    public: 
 23496 |  
 23497 |       struct unknown_symbol_resolver 
 23498 |       { 
 23499 |  
 23500 |          enum usr_symbol_type 
 23501 |          { 
 23502 |             e_usr_unknown_type  = 0, 
 23503 |             e_usr_variable_type = 1, 
 23504 |             e_usr_constant_type = 2 
 23505 |          }; 
 23506 |  
 23507 |          enum usr_mode 
 23508 |          { 
 23509 |             e_usrmode_default  = 0, 
 23510 |             e_usrmode_extended = 1 
 23511 |          }; 
 23512 |  
 23513 |          usr_mode mode; 
 23514 |  
 23515 |          unknown_symbol_resolver(const usr_mode m = e_usrmode_default) 
 23516 |          : mode(m) 
 23517 |          {} 
 23518 |  
 23519 |          virtual ~unknown_symbol_resolver() 
 23520 |          {} 
 23521 |  
 23522 |          virtual bool process(const std::string& /*unknown_symbol*/, 
 23523 |                               usr_symbol_type&   st, 
 23524 |                               T&                 default_value, 
 23525 |                               std::string&       error_message) 
 23526 |          { 
 23527 |             if (e_usrmode_default != mode) 
 23528 |                return false; 
 23529 |  
 23530 |             st = e_usr_variable_type; 
 23531 |             default_value = T(0); 
 23532 |             error_message.clear(); 
 23533 |  
 23534 |             return true; 
 23535 |          } 
 23536 |  
 23537 |          virtual bool process(const std::string& /* unknown_symbol */, 
 23538 |                               symbol_table_t&    /* symbol_table   */, 
 23539 |                               std::string&       /* error_message  */) 
 23540 |          { 
 23541 |             return false; 
 23542 |          } 
 23543 |       }; 
 23544 |  
 23545 |       enum collect_type 
 23546 |       { 
 23547 |          e_ct_none        = 0, 
 23548 |          e_ct_variables   = 1, 
 23549 |          e_ct_functions   = 2, 
 23550 |          e_ct_assignments = 4 
 23551 |       }; 
 23552 |  
 23553 |       enum symbol_type 
 23554 |       { 
 23555 |          e_st_unknown        = 0, 
 23556 |          e_st_variable       = 1, 
 23557 |          e_st_vector         = 2, 
 23558 |          e_st_vecelem        = 3, 
 23559 |          e_st_string         = 4, 
 23560 |          e_st_function       = 5, 
 23561 |          e_st_local_variable = 6, 
 23562 |          e_st_local_vector   = 7, 
 23563 |          e_st_local_string   = 8 
 23564 |       }; 
 23565 |  
 23566 |       class dependent_entity_collector 
 23567 |       { 
 23568 |       public: 
 23569 |  
 23570 |          typedef std::pair<std::string,symbol_type> symbol_t; 
 23571 |          typedef std::vector<symbol_t> symbol_list_t; 
 23572 |  
 23573 |          dependent_entity_collector(const std::size_t options = e_ct_none) 
 23574 |          : options_(options) 
 23575 |          , collect_variables_  ((options_ & e_ct_variables  ) == e_ct_variables  ) 
 23576 |          , collect_functions_  ((options_ & e_ct_functions  ) == e_ct_functions  ) 
 23577 |          , collect_assignments_((options_ & e_ct_assignments) == e_ct_assignments) 
 23578 |          , return_present_   (false) 
 23579 |          , final_stmt_return_(false) 
 23580 |          {} 
 23581 |  
 23582 |          template <typename Allocator, 
 23583 |                    template <typename, typename> class Sequence> 
 23584 |          inline std::size_t symbols(Sequence<symbol_t,Allocator>& symbols_list) 
 23585 |          { 
 23586 |             if (!collect_variables_ && !collect_functions_) 
 23587 |                return 0; 
 23588 |             else if (symbol_name_list_.empty()) 
 23589 |                return 0; 
 23590 |  
 23591 |             for (std::size_t i = 0; i < symbol_name_list_.size(); ++i) 
 23592 |             { 
 23593 |                details::case_normalise(symbol_name_list_[i].first); 
 23594 |             } 
 23595 |  
 23596 |             std::sort(symbol_name_list_.begin(), symbol_name_list_.end()); 
 23597 |  
 23598 |             std::unique_copy 
 23599 |             ( 
 23600 |                symbol_name_list_.begin(), 
 23601 |                symbol_name_list_.end  (), 
 23602 |                std::back_inserter(symbols_list) 
 23603 |             ); 
 23604 |  
 23605 |             return symbols_list.size(); 
 23606 |          } 
 23607 |  
 23608 |          template <typename Allocator, 
 23609 |                    template <typename, typename> class Sequence> 
 23610 |          inline std::size_t assignment_symbols(Sequence<symbol_t,Allocator>& assignment_list) 
 23611 |          { 
 23612 |             if (!collect_assignments_) 
 23613 |                return 0; 
 23614 |             else if (assignment_name_list_.empty()) 
 23615 |                return 0; 
 23616 |  
 23617 |             for (std::size_t i = 0; i < assignment_name_list_.size(); ++i) 
 23618 |             { 
 23619 |                details::case_normalise(assignment_name_list_[i].first); 
 23620 |             } 
 23621 |  
 23622 |             std::sort(assignment_name_list_.begin(),assignment_name_list_.end()); 
 23623 |  
 23624 |             std::unique_copy 
 23625 |             ( 
 23626 |                assignment_name_list_.begin(), 
 23627 |                assignment_name_list_.end  (), 
 23628 |                std::back_inserter(assignment_list) 
 23629 |             ); 
 23630 |  
 23631 |             return assignment_list.size(); 
 23632 |          } 
 23633 |  
 23634 |          void clear() 
 23635 |          { 
 23636 |             symbol_name_list_    .clear(); 
 23637 |             assignment_name_list_.clear(); 
 23638 |             retparam_list_       .clear(); 
 23639 |             return_present_    = false; 
 23640 |             final_stmt_return_ = false; 
 23641 |          } 
 23642 |  
 23643 |          bool& collect_variables() 
 23644 |          { 
 23645 |             return collect_variables_; 
 23646 |          } 
 23647 |  
 23648 |          bool& collect_functions() 
 23649 |          { 
 23650 |             return collect_functions_; 
 23651 |          } 
 23652 |  
 23653 |          bool& collect_assignments() 
 23654 |          { 
 23655 |             return collect_assignments_; 
 23656 |          } 
 23657 |  
 23658 |          bool return_present() const 
 23659 |          { 
 23660 |             return return_present_; 
 23661 |          } 
 23662 |  
 23663 |          bool final_stmt_return() const 
 23664 |          { 
 23665 |             return final_stmt_return_; 
 23666 |          } 
 23667 |  
 23668 |          typedef std::vector<std::string> retparam_list_t; 
 23669 |  
 23670 |          retparam_list_t return_param_type_list() const 
 23671 |          { 
 23672 |             return retparam_list_; 
 23673 |          } 
 23674 |  
 23675 |       private: 
 23676 |  
 23677 |          inline void add_symbol(const std::string& symbol, const symbol_type st) 
 23678 |          { 
 23679 |             switch (st) 
 23680 |             { 
 23681 |                case e_st_variable       : 
 23682 |                case e_st_vector         : 
 23683 |                case e_st_string         : 
 23684 |                case e_st_local_variable : 
 23685 |                case e_st_local_vector   : 
 23686 |                case e_st_local_string   : if (collect_variables_) 
 23687 |                                              symbol_name_list_ 
 23688 |                                                 .push_back(std::make_pair(symbol, st)); 
 23689 |                                           break; 
 23690 |  
 23691 |                case e_st_function       : if (collect_functions_) 
 23692 |                                              symbol_name_list_ 
 23693 |                                                 .push_back(std::make_pair(symbol, st)); 
 23694 |                                           break; 
 23695 |  
 23696 |                default                  : return; 
 23697 |             } 
 23698 |          } 
 23699 |  
 23700 |          inline void add_assignment(const std::string& symbol, const symbol_type st) 
 23701 |          { 
 23702 |             switch (st) 
 23703 |             { 
 23704 |                case e_st_variable       : 
 23705 |                case e_st_vector         : 
 23706 |                case e_st_string         : if (collect_assignments_) 
 23707 |                                              assignment_name_list_ 
 23708 |                                                 .push_back(std::make_pair(symbol, st)); 
 23709 |                                           break; 
 23710 |  
 23711 |                default                  : return; 
 23712 |             } 
 23713 |          } 
 23714 |  
 23715 |          std::size_t options_; 
 23716 |          bool collect_variables_; 
 23717 |          bool collect_functions_; 
 23718 |          bool collect_assignments_; 
 23719 |          bool return_present_; 
 23720 |          bool final_stmt_return_; 
 23721 |          symbol_list_t symbol_name_list_; 
 23722 |          symbol_list_t assignment_name_list_; 
 23723 |          retparam_list_t retparam_list_; 
 23724 |  
 23725 |          friend class parser<T>; 
 23726 |       }; 
 23727 |  
 23728 |       class settings_store 
 23729 |       { 
 23730 |       private: 
 23731 |  
 23732 |          typedef std::set<std::string,details::ilesscompare> disabled_entity_set_t; 
 23733 |          typedef disabled_entity_set_t::iterator des_itr_t; 
 23734 |  
 23735 |       public: 
 23736 |  
 23737 |          enum settings_compilation_options 
 23738 |          { 
 23739 |             e_unknown              =    0, 
 23740 |             e_replacer             =    1, 
 23741 |             e_joiner               =    2, 
 23742 |             e_numeric_check        =    4, 
 23743 |             e_bracket_check        =    8, 
 23744 |             e_sequence_check       =   16, 
 23745 |             e_commutative_check    =   32, 
 23746 |             e_strength_reduction   =   64, 
 23747 |             e_disable_vardef       =  128, 
 23748 |             e_collect_vars         =  256, 
 23749 |             e_collect_funcs        =  512, 
 23750 |             e_collect_assings      = 1024, 
 23751 |             e_disable_usr_on_rsrvd = 2048, 
 23752 |             e_disable_zero_return  = 4096 
 23753 |          }; 
 23754 |  
 23755 |          enum settings_base_funcs 
 23756 |          { 
 23757 |             e_bf_unknown = 0, 
 23758 |             e_bf_abs       , e_bf_acos     , e_bf_acosh    , e_bf_asin    , 
 23759 |             e_bf_asinh     , e_bf_atan     , e_bf_atan2    , e_bf_atanh   , 
 23760 |             e_bf_avg       , e_bf_ceil     , e_bf_clamp    , e_bf_cos     , 
 23761 |             e_bf_cosh      , e_bf_cot      , e_bf_csc      , e_bf_equal   , 
 23762 |             e_bf_erf       , e_bf_erfc     , e_bf_exp      , e_bf_expm1   , 
 23763 |             e_bf_floor     , e_bf_frac     , e_bf_hypot    , e_bf_iclamp  , 
 23764 |             e_bf_like      , e_bf_log      , e_bf_log10    , e_bf_log1p   , 
 23765 |             e_bf_log2      , e_bf_logn     , e_bf_mand     , e_bf_max     , 
 23766 |             e_bf_min       , e_bf_mod      , e_bf_mor      , e_bf_mul     , 
 23767 |             e_bf_ncdf      , e_bf_pow      , e_bf_root     , e_bf_round   , 
 23768 |             e_bf_roundn    , e_bf_sec      , e_bf_sgn      , e_bf_sin     , 
 23769 |             e_bf_sinc      , e_bf_sinh     , e_bf_sqrt     , e_bf_sum     , 
 23770 |             e_bf_swap      , e_bf_tan      , e_bf_tanh     , e_bf_trunc   , 
 23771 |             e_bf_not_equal , e_bf_inrange  , e_bf_deg2grad , e_bf_deg2rad , 
 23772 |             e_bf_rad2deg   , e_bf_grad2deg 
 23773 |          }; 
 23774 |  
 23775 |          enum settings_control_structs 
 23776 |          { 
 23777 |             e_ctrl_unknown = 0, 
 23778 |             e_ctrl_ifelse, 
 23779 |             e_ctrl_switch, 
 23780 |             e_ctrl_for_loop, 
 23781 |             e_ctrl_while_loop, 
 23782 |             e_ctrl_repeat_loop, 
 23783 |             e_ctrl_return 
 23784 |          }; 
 23785 |  
 23786 |          enum settings_logic_opr 
 23787 |          { 
 23788 |             e_logic_unknown = 0, 
 23789 |             e_logic_and, e_logic_nand , e_logic_nor , 
 23790 |             e_logic_not, e_logic_or   , e_logic_xnor, 
 23791 |             e_logic_xor, e_logic_scand, e_logic_scor 
 23792 |          }; 
 23793 |  
 23794 |          enum settings_arithmetic_opr 
 23795 |          { 
 23796 |             e_arith_unknown = 0, 
 23797 |             e_arith_add, e_arith_sub, e_arith_mul, 
 23798 |             e_arith_div, e_arith_mod, e_arith_pow 
 23799 |          }; 
 23800 |  
 23801 |          enum settings_assignment_opr 
 23802 |          { 
 23803 |             e_assign_unknown = 0, 
 23804 |             e_assign_assign, e_assign_addass, e_assign_subass, 
 23805 |             e_assign_mulass, e_assign_divass, e_assign_modass 
 23806 |          }; 
 23807 |  
 23808 |          enum settings_inequality_opr 
 23809 |          { 
 23810 |             e_ineq_unknown = 0, 
 23811 |             e_ineq_lt   , e_ineq_lte, e_ineq_eq    , 
 23812 |             e_ineq_equal, e_ineq_ne , e_ineq_nequal, 
 23813 |             e_ineq_gte  , e_ineq_gt 
 23814 |          }; 
 23815 |  
 23816 |          static const std::size_t default_compile_all_opts = 
 23817 |                                      e_replacer          + 
 23818 |                                      e_joiner            + 
 23819 |                                      e_numeric_check     + 
 23820 |                                      e_bracket_check     + 
 23821 |                                      e_sequence_check    + 
 23822 |                                      e_commutative_check + 
 23823 |                                      e_strength_reduction; 
 23824 |  
 23825 |          settings_store(const std::size_t compile_options = default_compile_all_opts) 
 23826 |          : max_stack_depth_(400) 
 23827 |          , max_node_depth_(10000) 
 23828 |          , max_local_vector_size_(2000000000) 
 23829 |          { 
 23830 |            load_compile_options(compile_options); 
 23831 |          } 
 23832 |  
 23833 |          settings_store& enable_all_base_functions() 
 23834 |          { 
 23835 |             disabled_func_set_.clear(); 
 23836 |             return (*this); 
 23837 |          } 
 23838 |  
 23839 |          settings_store& enable_all_control_structures() 
 23840 |          { 
 23841 |             disabled_ctrl_set_.clear(); 
 23842 |             return (*this); 
 23843 |          } 
 23844 |  
 23845 |          settings_store& enable_all_logic_ops() 
 23846 |          { 
 23847 |             disabled_logic_set_.clear(); 
 23848 |             return (*this); 
 23849 |          } 
 23850 |  
 23851 |          settings_store& enable_all_arithmetic_ops() 
 23852 |          { 
 23853 |             disabled_arithmetic_set_.clear(); 
 23854 |             return (*this); 
 23855 |          } 
 23856 |  
 23857 |          settings_store& enable_all_assignment_ops() 
 23858 |          { 
 23859 |             disabled_assignment_set_.clear(); 
 23860 |             return (*this); 
 23861 |          } 
 23862 |  
 23863 |          settings_store& enable_all_inequality_ops() 
 23864 |          { 
 23865 |             disabled_inequality_set_.clear(); 
 23866 |             return (*this); 
 23867 |          } 
 23868 |  
 23869 |          settings_store& enable_local_vardef() 
 23870 |          { 
 23871 |             disable_vardef_ = false; 
 23872 |             return (*this); 
 23873 |          } 
 23874 |  
 23875 |          settings_store& enable_commutative_check() 
 23876 |          { 
 23877 |             enable_commutative_check_ = true; 
 23878 |             return (*this); 
 23879 |          } 
 23880 |  
 23881 |          settings_store& enable_strength_reduction() 
 23882 |          { 
 23883 |             enable_strength_reduction_ = true; 
 23884 |             return (*this); 
 23885 |          } 
 23886 |  
 23887 |          settings_store& disable_all_base_functions() 
 23888 |          { 
 23889 |             std::copy(details::base_function_list, 
 23890 |                       details::base_function_list + details::base_function_list_size, 
 23891 |                       std::insert_iterator<disabled_entity_set_t> 
 23892 |                          (disabled_func_set_, disabled_func_set_.begin())); 
 23893 |             return (*this); 
 23894 |          } 
 23895 |  
 23896 |          settings_store& disable_all_control_structures() 
 23897 |          { 
 23898 |             std::copy(details::cntrl_struct_list, 
 23899 |                       details::cntrl_struct_list + details::cntrl_struct_list_size, 
 23900 |                       std::insert_iterator<disabled_entity_set_t> 
 23901 |                          (disabled_ctrl_set_, disabled_ctrl_set_.begin())); 
 23902 |             return (*this); 
 23903 |          } 
 23904 |  
 23905 |          settings_store& disable_all_logic_ops() 
 23906 |          { 
 23907 |             std::copy(details::logic_ops_list, 
 23908 |                       details::logic_ops_list + details::logic_ops_list_size, 
 23909 |                       std::insert_iterator<disabled_entity_set_t> 
 23910 |                         (disabled_logic_set_, disabled_logic_set_.begin())); 
 23911 |             return (*this); 
 23912 |          } 
 23913 |  
 23914 |          settings_store& disable_all_arithmetic_ops() 
 23915 |          { 
 23916 |             std::copy(details::arithmetic_ops_list, 
 23917 |                       details::arithmetic_ops_list + details::arithmetic_ops_list_size, 
 23918 |                       std::insert_iterator<disabled_entity_set_t> 
 23919 |                          (disabled_arithmetic_set_, disabled_arithmetic_set_.begin())); 
 23920 |             return (*this); 
 23921 |          } 
 23922 |  
 23923 |          settings_store& disable_all_assignment_ops() 
 23924 |          { 
 23925 |             std::copy(details::assignment_ops_list, 
 23926 |                       details::assignment_ops_list + details::assignment_ops_list_size, 
 23927 |                       std::insert_iterator<disabled_entity_set_t> 
 23928 |                          (disabled_assignment_set_, disabled_assignment_set_.begin())); 
 23929 |             return (*this); 
 23930 |          } 
 23931 |  
 23932 |          settings_store& disable_all_inequality_ops() 
 23933 |          { 
 23934 |             std::copy(details::inequality_ops_list, 
 23935 |                       details::inequality_ops_list + details::inequality_ops_list_size, 
 23936 |                       std::insert_iterator<disabled_entity_set_t> 
 23937 |                          (disabled_inequality_set_, disabled_inequality_set_.begin())); 
 23938 |             return (*this); 
 23939 |          } 
 23940 |  
 23941 |          settings_store& disable_local_vardef() 
 23942 |          { 
 23943 |             disable_vardef_ = true; 
 23944 |             return (*this); 
 23945 |          } 
 23946 |  
 23947 |          settings_store& disable_commutative_check() 
 23948 |          { 
 23949 |             enable_commutative_check_ = false; 
 23950 |             return (*this); 
 23951 |          } 
 23952 |  
 23953 |          settings_store& disable_strength_reduction() 
 23954 |          { 
 23955 |             enable_strength_reduction_ = false; 
 23956 |             return (*this); 
 23957 |          } 
 23958 |  
 23959 |          bool replacer_enabled           () const { return enable_replacer_;           } 
 23960 |          bool commutative_check_enabled  () const { return enable_commutative_check_;  } 
 23961 |          bool joiner_enabled             () const { return enable_joiner_;             } 
 23962 |          bool numeric_check_enabled      () const { return enable_numeric_check_;      } 
 23963 |          bool bracket_check_enabled      () const { return enable_bracket_check_;      } 
 23964 |          bool sequence_check_enabled     () const { return enable_sequence_check_;     } 
 23965 |          bool strength_reduction_enabled () const { return enable_strength_reduction_; } 
 23966 |          bool collect_variables_enabled  () const { return enable_collect_vars_;       } 
 23967 |          bool collect_functions_enabled  () const { return enable_collect_funcs_;      } 
 23968 |          bool collect_assignments_enabled() const { return enable_collect_assings_;    } 
 23969 |          bool vardef_disabled            () const { return disable_vardef_;            } 
 23970 |          bool rsrvd_sym_usr_disabled     () const { return disable_rsrvd_sym_usr_;     } 
 23971 |          bool zero_return_disabled       () const { return disable_zero_return_;       } 
 23972 |  
 23973 |          bool function_enabled(const std::string& function_name) const 
 23974 |          { 
 23975 |             if (disabled_func_set_.empty()) 
 23976 |                return true; 
 23977 |             else 
 23978 |                return (disabled_func_set_.end() == disabled_func_set_.find(function_name)); 
 23979 |          } 
 23980 |  
 23981 |          bool control_struct_enabled(const std::string& control_struct) const 
 23982 |          { 
 23983 |             if (disabled_ctrl_set_.empty()) 
 23984 |                return true; 
 23985 |             else 
 23986 |                return (disabled_ctrl_set_.end() == disabled_ctrl_set_.find(control_struct)); 
 23987 |          } 
 23988 |  
 23989 |          bool logic_enabled(const std::string& logic_operation) const 
 23990 |          { 
 23991 |             if (disabled_logic_set_.empty()) 
 23992 |                return true; 
 23993 |             else 
 23994 |                return (disabled_logic_set_.end() == disabled_logic_set_.find(logic_operation)); 
 23995 |          } 
 23996 |  
 23997 |          bool arithmetic_enabled(const details::operator_type& arithmetic_operation) const 
 23998 |          { 
 23999 |             if (disabled_logic_set_.empty()) 
 24000 |                return true; 
 24001 |             else 
 24002 |                return disabled_arithmetic_set_.end() == disabled_arithmetic_set_ 
 24003 |                                                             .find(arith_opr_to_string(arithmetic_operation)); 
 24004 |          } 
 24005 |  
 24006 |          bool assignment_enabled(const details::operator_type& assignment) const 
 24007 |          { 
 24008 |             if (disabled_assignment_set_.empty()) 
 24009 |                return true; 
 24010 |             else 
 24011 |                return disabled_assignment_set_.end() == disabled_assignment_set_ 
 24012 |                                                            .find(assign_opr_to_string(assignment)); 
 24013 |          } 
 24014 |  
 24015 |          bool inequality_enabled(const details::operator_type& inequality) const 
 24016 |          { 
 24017 |             if (disabled_inequality_set_.empty()) 
 24018 |                return true; 
 24019 |             else 
 24020 |                return disabled_inequality_set_.end() == disabled_inequality_set_ 
 24021 |                                                            .find(inequality_opr_to_string(inequality)); 
 24022 |          } 
 24023 |  
 24024 |          bool function_disabled(const std::string& function_name) const 
 24025 |          { 
 24026 |             if (disabled_func_set_.empty()) 
 24027 |                return false; 
 24028 |             else 
 24029 |                return (disabled_func_set_.end() != disabled_func_set_.find(function_name)); 
 24030 |          } 
 24031 |  
 24032 |          bool control_struct_disabled(const std::string& control_struct) const 
 24033 |          { 
 24034 |             if (disabled_ctrl_set_.empty()) 
 24035 |                return false; 
 24036 |             else 
 24037 |                return (disabled_ctrl_set_.end() != disabled_ctrl_set_.find(control_struct)); 
 24038 |          } 
 24039 |  
 24040 |          bool logic_disabled(const std::string& logic_operation) const 
 24041 |          { 
 24042 |             if (disabled_logic_set_.empty()) 
 24043 |                return false; 
 24044 |             else 
 24045 |                return (disabled_logic_set_.end() != disabled_logic_set_.find(logic_operation)); 
 24046 |          } 
 24047 |  
 24048 |          bool assignment_disabled(const details::operator_type assignment_operation) const 
 24049 |          { 
 24050 |             if (disabled_assignment_set_.empty()) 
 24051 |                return false; 
 24052 |             else 
 24053 |                return disabled_assignment_set_.end() != disabled_assignment_set_ 
 24054 |                                                            .find(assign_opr_to_string(assignment_operation)); 
 24055 |          } 
 24056 |  
 24057 |          bool logic_disabled(const details::operator_type logic_operation) const 
 24058 |          { 
 24059 |             if (disabled_logic_set_.empty()) 
 24060 |                return false; 
 24061 |             else 
 24062 |                return disabled_logic_set_.end() != disabled_logic_set_ 
 24063 |                                                            .find(logic_opr_to_string(logic_operation)); 
 24064 |          } 
 24065 |  
 24066 |          bool arithmetic_disabled(const details::operator_type arithmetic_operation) const 
 24067 |          { 
 24068 |             if (disabled_arithmetic_set_.empty()) 
 24069 |                return false; 
 24070 |             else 
 24071 |                return disabled_arithmetic_set_.end() != disabled_arithmetic_set_ 
 24072 |                                                            .find(arith_opr_to_string(arithmetic_operation)); 
 24073 |          } 
 24074 |  
 24075 |          bool inequality_disabled(const details::operator_type& inequality) const 
 24076 |          { 
 24077 |             if (disabled_inequality_set_.empty()) 
 24078 |                return false; 
 24079 |             else 
 24080 |                return disabled_inequality_set_.end() != disabled_inequality_set_ 
 24081 |                                                            .find(inequality_opr_to_string(inequality)); 
 24082 |          } 
 24083 |  
 24084 |          settings_store& disable_base_function(const settings_base_funcs bf) 
 24085 |          { 
 24086 |             if ( 
 24087 |                  (e_bf_unknown != bf) && 
 24088 |                  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1)) 
 24089 |                ) 
 24090 |             { 
 24091 |                disabled_func_set_.insert(details::base_function_list[bf - 1]); 
 24092 |             } 
 24093 |  
 24094 |             return (*this); 
 24095 |          } 
 24096 |  
 24097 |          settings_store& disable_control_structure(const settings_control_structs ctrl_struct) 
 24098 |          { 
 24099 |             if ( 
 24100 |                  (e_ctrl_unknown != ctrl_struct) && 
 24101 |                  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1)) 
 24102 |                ) 
 24103 |             { 
 24104 |                disabled_ctrl_set_.insert(details::cntrl_struct_list[ctrl_struct - 1]); 
 24105 |             } 
 24106 |  
 24107 |             return (*this); 
 24108 |          } 
 24109 |  
 24110 |          settings_store& disable_logic_operation(const settings_logic_opr logic) 
 24111 |          { 
 24112 |             if ( 
 24113 |                  (e_logic_unknown != logic) && 
 24114 |                  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1)) 
 24115 |                ) 
 24116 |             { 
 24117 |                disabled_logic_set_.insert(details::logic_ops_list[logic - 1]); 
 24118 |             } 
 24119 |  
 24120 |             return (*this); 
 24121 |          } 
 24122 |  
 24123 |          settings_store& disable_arithmetic_operation(const settings_arithmetic_opr arithmetic) 
 24124 |          { 
 24125 |             if ( 
 24126 |                  (e_arith_unknown != arithmetic) && 
 24127 |                  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1)) 
 24128 |                ) 
 24129 |             { 
 24130 |                disabled_arithmetic_set_.insert(details::arithmetic_ops_list[arithmetic - 1]); 
 24131 |             } 
 24132 |  
 24133 |             return (*this); 
 24134 |          } 
 24135 |  
 24136 |          settings_store& disable_assignment_operation(const settings_assignment_opr assignment) 
 24137 |          { 
 24138 |             if ( 
 24139 |                  (e_assign_unknown != assignment) && 
 24140 |                  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1)) 
 24141 |                ) 
 24142 |             { 
 24143 |                disabled_assignment_set_.insert(details::assignment_ops_list[assignment - 1]); 
 24144 |             } 
 24145 |  
 24146 |             return (*this); 
 24147 |          } 
 24148 |  
 24149 |          settings_store& disable_inequality_operation(const settings_inequality_opr inequality) 
 24150 |          { 
 24151 |             if ( 
 24152 |                  (e_ineq_unknown != inequality) && 
 24153 |                  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1)) 
 24154 |                ) 
 24155 |             { 
 24156 |                disabled_inequality_set_.insert(details::inequality_ops_list[inequality - 1]); 
 24157 |             } 
 24158 |  
 24159 |             return (*this); 
 24160 |          } 
 24161 |  
 24162 |          settings_store& enable_base_function(const settings_base_funcs bf) 
 24163 |          { 
 24164 |             if ( 
 24165 |                  (e_bf_unknown != bf) && 
 24166 |                  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1)) 
 24167 |                ) 
 24168 |             { 
 24169 |                const des_itr_t itr = disabled_func_set_.find(details::base_function_list[bf - 1]); 
 24170 |  
 24171 |                if (disabled_func_set_.end() != itr) 
 24172 |                { 
 24173 |                   disabled_func_set_.erase(itr); 
 24174 |                } 
 24175 |             } 
 24176 |  
 24177 |             return (*this); 
 24178 |          } 
 24179 |  
 24180 |          settings_store& enable_control_structure(const settings_control_structs ctrl_struct) 
 24181 |          { 
 24182 |             if ( 
 24183 |                  (e_ctrl_unknown != ctrl_struct) && 
 24184 |                  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1)) 
 24185 |                ) 
 24186 |             { 
 24187 |                const des_itr_t itr = disabled_ctrl_set_.find(details::cntrl_struct_list[ctrl_struct - 1]); 
 24188 |  
 24189 |                if (disabled_ctrl_set_.end() != itr) 
 24190 |                { 
 24191 |                   disabled_ctrl_set_.erase(itr); 
 24192 |                } 
 24193 |             } 
 24194 |  
 24195 |             return (*this); 
 24196 |          } 
 24197 |  
 24198 |          settings_store& enable_logic_operation(const settings_logic_opr logic) 
 24199 |          { 
 24200 |             if ( 
 24201 |                  (e_logic_unknown != logic) && 
 24202 |                  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1)) 
 24203 |                ) 
 24204 |             { 
 24205 |                const des_itr_t itr = disabled_logic_set_.find(details::logic_ops_list[logic - 1]); 
 24206 |  
 24207 |                if (disabled_logic_set_.end() != itr) 
 24208 |                { 
 24209 |                   disabled_logic_set_.erase(itr); 
 24210 |                } 
 24211 |             } 
 24212 |  
 24213 |             return (*this); 
 24214 |          } 
 24215 |  
 24216 |          settings_store& enable_arithmetic_operation(const settings_arithmetic_opr arithmetic) 
 24217 |          { 
 24218 |             if ( 
 24219 |                  (e_arith_unknown != arithmetic) && 
 24220 |                  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1)) 
 24221 |                ) 
 24222 |             { 
 24223 |                const des_itr_t itr = disabled_arithmetic_set_.find(details::arithmetic_ops_list[arithmetic - 1]); 
 24224 |  
 24225 |                if (disabled_arithmetic_set_.end() != itr) 
 24226 |                { 
 24227 |                   disabled_arithmetic_set_.erase(itr); 
 24228 |                } 
 24229 |             } 
 24230 |  
 24231 |             return (*this); 
 24232 |          } 
 24233 |  
 24234 |          settings_store& enable_assignment_operation(const settings_assignment_opr assignment) 
 24235 |          { 
 24236 |             if ( 
 24237 |                  (e_assign_unknown != assignment) && 
 24238 |                  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1)) 
 24239 |                ) 
 24240 |             { 
 24241 |                const des_itr_t itr = disabled_assignment_set_.find(details::assignment_ops_list[assignment - 1]); 
 24242 |  
 24243 |                if (disabled_assignment_set_.end() != itr) 
 24244 |                { 
 24245 |                   disabled_assignment_set_.erase(itr); 
 24246 |                } 
 24247 |             } 
 24248 |  
 24249 |             return (*this); 
 24250 |          } 
 24251 |  
 24252 |          settings_store& enable_inequality_operation(const settings_inequality_opr inequality) 
 24253 |          { 
 24254 |             if ( 
 24255 |                  (e_ineq_unknown != inequality) && 
 24256 |                  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1)) 
 24257 |                ) 
 24258 |             { 
 24259 |                const des_itr_t itr = disabled_inequality_set_.find(details::inequality_ops_list[inequality - 1]); 
 24260 |  
 24261 |                if (disabled_inequality_set_.end() != itr) 
 24262 |                { 
 24263 |                   disabled_inequality_set_.erase(itr); 
 24264 |                } 
 24265 |             } 
 24266 |  
 24267 |             return (*this); 
 24268 |          } 
 24269 |  
 24270 |          void set_max_stack_depth(const std::size_t max_stack_depth) 
 24271 |          { 
 24272 |             max_stack_depth_ = max_stack_depth; 
 24273 |          } 
 24274 |  
 24275 |          void set_max_node_depth(const std::size_t max_node_depth) 
 24276 |          { 
 24277 |             max_node_depth_ = max_node_depth; 
 24278 |          } 
 24279 |  
 24280 |          void set_max_local_vector_size(const std::size_t max_local_vector_size) 
 24281 |          { 
 24282 |             max_local_vector_size_ = max_local_vector_size; 
 24283 |          } 
 24284 |  
 24285 |          std::size_t max_stack_depth() const 
 24286 |          { 
 24287 |             return max_stack_depth_; 
 24288 |          } 
 24289 |  
 24290 |          std::size_t max_node_depth() const 
 24291 |          { 
 24292 |             return max_node_depth_; 
 24293 |          } 
 24294 |  
 24295 |          std::size_t max_local_vector_size() const 
 24296 |          { 
 24297 |             return max_local_vector_size_; 
 24298 |          } 
 24299 |  
 24300 |       private: 
 24301 |  
 24302 |          void load_compile_options(const std::size_t compile_options) 
 24303 |          { 
 24304 |             enable_replacer_           = (compile_options & e_replacer            ) == e_replacer; 
 24305 |             enable_joiner_             = (compile_options & e_joiner              ) == e_joiner; 
 24306 |             enable_numeric_check_      = (compile_options & e_numeric_check       ) == e_numeric_check; 
 24307 |             enable_bracket_check_      = (compile_options & e_bracket_check       ) == e_bracket_check; 
 24308 |             enable_sequence_check_     = (compile_options & e_sequence_check      ) == e_sequence_check; 
 24309 |             enable_commutative_check_  = (compile_options & e_commutative_check   ) == e_commutative_check; 
 24310 |             enable_strength_reduction_ = (compile_options & e_strength_reduction  ) == e_strength_reduction; 
 24311 |             enable_collect_vars_       = (compile_options & e_collect_vars        ) == e_collect_vars; 
 24312 |             enable_collect_funcs_      = (compile_options & e_collect_funcs       ) == e_collect_funcs; 
 24313 |             enable_collect_assings_    = (compile_options & e_collect_assings     ) == e_collect_assings; 
 24314 |             disable_vardef_            = (compile_options & e_disable_vardef      ) == e_disable_vardef; 
 24315 |             disable_rsrvd_sym_usr_     = (compile_options & e_disable_usr_on_rsrvd) == e_disable_usr_on_rsrvd; 
 24316 |             disable_zero_return_       = (compile_options & e_disable_zero_return ) == e_disable_zero_return; 
 24317 |          } 
 24318 |  
 24319 |          std::string assign_opr_to_string(details::operator_type opr) const 
 24320 |          { 
 24321 |             switch (opr) 
 24322 |             { 
 24323 |                case details::e_assign : return ":=" 
 24324 |                case details::e_addass : return "+=" 
 24325 |                case details::e_subass : return "-=" 
 24326 |                case details::e_mulass : return "*=" 
 24327 |                case details::e_divass : return "/=" 
 24328 |                case details::e_modass : return "%=" 
 24329 |                default                : return ""  ; 
 24330 |             } 
 24331 |          } 
 24332 |  
 24333 |          std::string arith_opr_to_string(details::operator_type opr) const 
 24334 |          { 
 24335 |             switch (opr) 
 24336 |             { 
 24337 |                case details::e_add : return "+" 
 24338 |                case details::e_sub : return "-" 
 24339 |                case details::e_mul : return "*" 
 24340 |                case details::e_div : return "/" 
 24341 |                case details::e_mod : return "%" 
 24342 |                case details::e_pow : return "^" 
 24343 |                default             : return "" ; 
 24344 |             } 
 24345 |          } 
 24346 |  
 24347 |          std::string inequality_opr_to_string(details::operator_type opr) const 
 24348 |          { 
 24349 |             switch (opr) 
 24350 |             { 
 24351 |                case details::e_lt    : return "<" ; 
 24352 |                case details::e_lte   : return "<=" 
 24353 |                case details::e_eq    : return "==" 
 24354 |                case details::e_equal : return "=" ; 
 24355 |                case details::e_ne    : return "!=" 
 24356 |                case details::e_nequal: return "<>" 
 24357 |                case details::e_gte   : return ">=" 
 24358 |                case details::e_gt    : return ">" ; 
 24359 |                default               : return ""  ; 
 24360 |             } 
 24361 |          } 
 24362 |  
 24363 |          std::string logic_opr_to_string(details::operator_type opr) const 
 24364 |          { 
 24365 |             switch (opr) 
 24366 |             { 
 24367 |                case details::e_and  : return "and" ; 
 24368 |                case details::e_or   : return "or"  ; 
 24369 |                case details::e_xor  : return "xor" ; 
 24370 |                case details::e_nand : return "nand" 
 24371 |                case details::e_nor  : return "nor" ; 
 24372 |                case details::e_xnor : return "xnor" 
 24373 |                case details::e_notl : return "not" ; 
 24374 |                default              : return ""    ; 
 24375 |             } 
 24376 |          } 
 24377 |  
 24378 |          bool enable_replacer_; 
 24379 |          bool enable_joiner_; 
 24380 |          bool enable_numeric_check_; 
 24381 |          bool enable_bracket_check_; 
 24382 |          bool enable_sequence_check_; 
 24383 |          bool enable_commutative_check_; 
 24384 |          bool enable_strength_reduction_; 
 24385 |          bool enable_collect_vars_; 
 24386 |          bool enable_collect_funcs_; 
 24387 |          bool enable_collect_assings_; 
 24388 |          bool disable_vardef_; 
 24389 |          bool disable_rsrvd_sym_usr_; 
 24390 |          bool disable_zero_return_; 
 24391 |  
 24392 |          disabled_entity_set_t disabled_func_set_ ; 
 24393 |          disabled_entity_set_t disabled_ctrl_set_ ; 
 24394 |          disabled_entity_set_t disabled_logic_set_; 
 24395 |          disabled_entity_set_t disabled_arithmetic_set_; 
 24396 |          disabled_entity_set_t disabled_assignment_set_; 
 24397 |          disabled_entity_set_t disabled_inequality_set_; 
 24398 |  
 24399 |          std::size_t max_stack_depth_; 
 24400 |          std::size_t max_node_depth_; 
 24401 |          std::size_t max_local_vector_size_; 
 24402 |  
 24403 |          friend class parser<T>; 
 24404 |       }; 
 24405 |  
 24406 |       typedef settings_store settings_t; 
 24407 |  
 24408 |       explicit parser(const settings_t& settings = settings_t()) 
 24409 |       : settings_(settings) 
 24410 |       , resolve_unknown_symbol_(false) 
 24411 |       , results_context_(0) 
 24412 |       , unknown_symbol_resolver_(reinterpret_cast<unknown_symbol_resolver*>(0)) 
 24413 |         #ifdef _MSC_VER 
 24414 |         #pragma warning(push) 
 24415 |         #pragma warning (disable:4355) 
 24416 |         #endif 
 24417 |       , sem_(*this) 
 24418 |         #ifdef _MSC_VER 
 24419 |         #pragma warning(pop) 
 24420 |         #endif 
 24421 |       , operator_joiner_2_(2) 
 24422 |       , operator_joiner_3_(3) 
 24423 |       , loop_runtime_check_(0) 
 24424 |       , vector_access_runtime_check_(0) 
 24425 |       , compilation_check_ptr_(0) 
 24426 |       , assert_check_(0) 
 24427 |       { 
 24428 |          init_precompilation(); 
 24429 |  
 24430 |          load_operations_map           (base_ops_map_     ); 
 24431 |          load_unary_operations_map     (unary_op_map_     ); 
 24432 |          load_binary_operations_map    (binary_op_map_    ); 
 24433 |          load_inv_binary_operations_map(inv_binary_op_map_); 
 24434 |          load_sf3_map                  (sf3_map_          ); 
 24435 |          load_sf4_map                  (sf4_map_          ); 
 24436 |  
 24437 |          expression_generator_.init_synthesize_map(); 
 24438 |          expression_generator_.set_parser(*this); 
 24439 |          expression_generator_.set_uom (unary_op_map_     ); 
 24440 |          expression_generator_.set_bom (binary_op_map_    ); 
 24441 |          expression_generator_.set_ibom(inv_binary_op_map_); 
 24442 |          expression_generator_.set_sf3m(sf3_map_          ); 
 24443 |          expression_generator_.set_sf4m(sf4_map_          ); 
 24444 |          expression_generator_.set_strength_reduction_state(settings_.strength_reduction_enabled()); 
 24445 |       } 
 24446 |  
 24447 |      ~parser() 
 24448 |       {} 
 24449 |  
 24450 |       inline void init_precompilation() 
 24451 |       { 
 24452 |          dec_.collect_variables() = 
 24453 |             settings_.collect_variables_enabled(); 
 24454 |  
 24455 |          dec_.collect_functions() = 
 24456 |             settings_.collect_functions_enabled(); 
 24457 |  
 24458 |          dec_.collect_assignments() = 
 24459 |             settings_.collect_assignments_enabled(); 
 24460 |  
 24461 |          if (settings_.replacer_enabled()) 
 24462 |          { 
 24463 |             symbol_replacer_.clear(); 
 24464 |             symbol_replacer_.add_replace("true" , "1", lexer::token::e_number); 
 24465 |             symbol_replacer_.add_replace("false", "0", lexer::token::e_number); 
 24466 |             helper_assembly_.token_modifier_list.clear(); 
 24467 |             helper_assembly_.register_modifier(&symbol_replacer_); 
 24468 |          } 
 24469 |  
 24470 |          if (settings_.commutative_check_enabled()) 
 24471 |          { 
 24472 |             for (std::size_t i = 0; i < details::reserved_words_size; ++i) 
 24473 |             { 
 24474 |                commutative_inserter_.ignore_symbol(details::reserved_words[i]); 
 24475 |             } 
 24476 |  
 24477 |             helper_assembly_.token_inserter_list.clear(); 
 24478 |             helper_assembly_.register_inserter(&commutative_inserter_); 
 24479 |          } 
 24480 |  
 24481 |          if (settings_.joiner_enabled()) 
 24482 |          { 
 24483 |             helper_assembly_.token_joiner_list.clear(); 
 24484 |             helper_assembly_.register_joiner(&operator_joiner_2_); 
 24485 |             helper_assembly_.register_joiner(&operator_joiner_3_); 
 24486 |          } 
 24487 |  
 24488 |          if ( 
 24489 |               settings_.numeric_check_enabled () || 
 24490 |               settings_.bracket_check_enabled () || 
 24491 |               settings_.sequence_check_enabled() 
 24492 |             ) 
 24493 |          { 
 24494 |             helper_assembly_.token_scanner_list.clear(); 
 24495 |  
 24496 |             if (settings_.numeric_check_enabled()) 
 24497 |             { 
 24498 |                helper_assembly_.register_scanner(&numeric_checker_); 
 24499 |             } 
 24500 |  
 24501 |             if (settings_.bracket_check_enabled()) 
 24502 |             { 
 24503 |                helper_assembly_.register_scanner(&bracket_checker_); 
 24504 |             } 
 24505 |  
 24506 |             if (settings_.sequence_check_enabled()) 
 24507 |             { 
 24508 |                helper_assembly_.register_scanner(&sequence_validator_      ); 
 24509 |                helper_assembly_.register_scanner(&sequence_validator_3tkns_); 
 24510 |             } 
 24511 |          } 
 24512 |       } 
 24513 |  
 24514 |       inline bool compile(const std::string& expression_string, expression<T>& expr) 
 24515 |       { 
 24516 |          state_               .reset(); 
 24517 |          error_list_          .clear(); 
 24518 |          brkcnt_list_         .clear(); 
 24519 |          synthesis_error_     .clear(); 
 24520 |          immutable_memory_map_.reset(); 
 24521 |          immutable_symtok_map_.clear(); 
 24522 |          current_state_stack_ .clear(); 
 24523 |          assert_ids_          .clear(); 
 24524 |          sem_                 .cleanup(); 
 24525 |  
 24526 |          return_cleanup(); 
 24527 |  
 24528 |          expression_generator_.set_allocator(node_allocator_); 
 24529 |  
 24530 |          if (expression_string.empty()) 
 24531 |          { 
 24532 |             set_error(make_error( 
 24533 |                parser_error::e_syntax, 
 24534 |                "ERR001 - Empty expression!", 
 24535 |                exprtk_error_location)); 
 24536 |  
 24537 |             return false; 
 24538 |          } 
 24539 |  
 24540 |          if (!init(expression_string)) 
 24541 |          { 
 24542 |             process_lexer_errors(); 
 24543 |             return false; 
 24544 |          } 
 24545 |  
 24546 |          if (lexer().empty()) 
 24547 |          { 
 24548 |             set_error(make_error( 
 24549 |                parser_error::e_syntax, 
 24550 |                "ERR002 - Empty expression!", 
 24551 |                exprtk_error_location)); 
 24552 |  
 24553 |             return false; 
 24554 |          } 
 24555 |  
 24556 |          if (halt_compilation_check()) 
 24557 |          { 
 24558 |             exprtk_debug(("halt_compilation_check() - compile checkpoint 0\n")); 
 24559 |             return false; 
 24560 |          } 
 24561 |  
 24562 |          if (!run_assemblies()) 
 24563 |          { 
 24564 |             return false; 
 24565 |          } 
 24566 |  
 24567 |          if (halt_compilation_check()) 
 24568 |          { 
 24569 |             exprtk_debug(("halt_compilation_check() - compile checkpoint 1\n")); 
 24570 |             return false; 
 24571 |          } 
 24572 |  
 24573 |          symtab_store_.symtab_list_ = expr.get_symbol_table_list(); 
 24574 |          dec_.clear(); 
 24575 |  
 24576 |          lexer().begin(); 
 24577 |  
 24578 |          next_token(); 
 24579 |  
 24580 |          expression_node_ptr e = parse_corpus(); 
 24581 |  
 24582 |          if ((0 != e) && (token_t::e_eof == current_token().type)) 
 24583 |          { 
 24584 |             bool* retinvk_ptr = 0; 
 24585 |  
 24586 |             if (state_.return_stmt_present) 
 24587 |             { 
 24588 |                dec_.return_present_ = true; 
 24589 |  
 24590 |                e = expression_generator_ 
 24591 |                      .return_envelope(e, results_context_, retinvk_ptr); 
 24592 |             } 
 24593 |  
 24594 |             expr.set_expression(e); 
 24595 |             expr.set_retinvk(retinvk_ptr); 
 24596 |  
 24597 |             register_local_vars(expr); 
 24598 |             register_return_results(expr); 
 24599 |  
 24600 |             return !(!expr); 
 24601 |          } 
 24602 |          else 
 24603 |          { 
 24604 |             if (error_list_.empty()) 
 24605 |             { 
 24606 |                set_error(make_error( 
 24607 |                   parser_error::e_syntax, 
 24608 |                   current_token(), 
 24609 |                   "ERR003 - Invalid expression encountered", 
 24610 |                   exprtk_error_location)); 
 24611 |             } 
 24612 |  
 24613 |             if ((0 != e) && branch_deletable(e)) 
 24614 |             { 
 24615 |                destroy_node(e); 
 24616 |             } 
 24617 |  
 24618 |             dec_.clear    (); 
 24619 |             sem_.cleanup  (); 
 24620 |             return_cleanup(); 
 24621 |  
 24622 |             return false; 
 24623 |          } 
 24624 |       } 
 24625 |  
 24626 |       inline expression_t compile(const std::string& expression_string, symbol_table_t& symtab) 
 24627 |       { 
 24628 |          expression_t expression; 
 24629 |          expression.register_symbol_table(symtab); 
 24630 |          compile(expression_string,expression); 
 24631 |          return expression; 
 24632 |       } 
 24633 |  
 24634 |       void process_lexer_errors() 
 24635 |       { 
 24636 |          for (std::size_t i = 0; i < lexer().size(); ++i) 
 24637 |          { 
 24638 |             if (lexer()[i].is_error()) 
 24639 |             { 
 24640 |                std::string diagnostic = "ERR004 - " 
 24641 |  
 24642 |                switch (lexer()[i].type) 
 24643 |                { 
 24644 |                   case lexer::token::e_error      : diagnostic += "General token error" 
 24645 |                                                     break; 
 24646 |  
 24647 |                   case lexer::token::e_err_symbol : diagnostic += "Symbol error" 
 24648 |                                                     break; 
 24649 |  
 24650 |                   case lexer::token::e_err_number : diagnostic += "Invalid numeric token" 
 24651 |                                                     break; 
 24652 |  
 24653 |                   case lexer::token::e_err_string : diagnostic += "Invalid string token" 
 24654 |                                                     break; 
 24655 |  
 24656 |                   case lexer::token::e_err_sfunc  : diagnostic += "Invalid special function token" 
 24657 |                                                     break; 
 24658 |  
 24659 |                   default                         : diagnostic += "Unknown compiler error" 
 24660 |                } 
 24661 |  
 24662 |                set_error(make_error( 
 24663 |                   parser_error::e_lexer, 
 24664 |                   lexer()[i], 
 24665 |                   diagnostic + ": " + lexer()[i].value, 
 24666 |                   exprtk_error_location)); 
 24667 |             } 
 24668 |          } 
 24669 |       } 
 24670 |  
 24671 |       inline bool run_assemblies() 
 24672 |       { 
 24673 |          if (settings_.commutative_check_enabled()) 
 24674 |          { 
 24675 |             helper_assembly_.run_inserters(lexer()); 
 24676 |          } 
 24677 |  
 24678 |          if (settings_.joiner_enabled()) 
 24679 |          { 
 24680 |             helper_assembly_.run_joiners(lexer()); 
 24681 |          } 
 24682 |  
 24683 |          if (settings_.replacer_enabled()) 
 24684 |          { 
 24685 |             helper_assembly_.run_modifiers(lexer()); 
 24686 |          } 
 24687 |  
 24688 |          if ( 
 24689 |               settings_.numeric_check_enabled () || 
 24690 |               settings_.bracket_check_enabled () || 
 24691 |               settings_.sequence_check_enabled() 
 24692 |             ) 
 24693 |          { 
 24694 |             if (!helper_assembly_.run_scanners(lexer())) 
 24695 |             { 
 24696 |                if (helper_assembly_.error_token_scanner) 
 24697 |                { 
 24698 |                   lexer::helper::bracket_checker*            bracket_checker_ptr     = 0; 
 24699 |                   lexer::helper::numeric_checker<T>*         numeric_checker_ptr     = 0; 
 24700 |                   lexer::helper::sequence_validator*         sequence_validator_ptr  = 0; 
 24701 |                   lexer::helper::sequence_validator_3tokens* sequence_validator3_ptr = 0; 
 24702 |  
 24703 |                   if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner))) 
 24704 |                   { 
 24705 |                      set_error(make_error( 
 24706 |                         parser_error::e_token, 
 24707 |                         bracket_checker_ptr->error_token(), 
 24708 |                         "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'", 
 24709 |                         exprtk_error_location)); 
 24710 |                   } 
 24711 |                   else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker<T>*>(helper_assembly_.error_token_scanner))) 
 24712 |                   { 
 24713 |                      for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i) 
 24714 |                      { 
 24715 |                         lexer::token error_token = lexer()[numeric_checker_ptr->error_index(i)]; 
 24716 |  
 24717 |                         set_error(make_error( 
 24718 |                            parser_error::e_token, 
 24719 |                            error_token, 
 24720 |                            "ERR006 - Invalid numeric token: '" + error_token.value + "'", 
 24721 |                            exprtk_error_location)); 
 24722 |                      } 
 24723 |  
 24724 |                      if (numeric_checker_ptr->error_count()) 
 24725 |                      { 
 24726 |                         numeric_checker_ptr->clear_errors(); 
 24727 |                      } 
 24728 |                   } 
 24729 |                   else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner))) 
 24730 |                   { 
 24731 |                      for (std::size_t i = 0; i < sequence_validator_ptr->error_count(); ++i) 
 24732 |                      { 
 24733 |                         std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i); 
 24734 |  
 24735 |                         set_error(make_error( 
 24736 |                            parser_error::e_token, 
 24737 |                            error_token.first, 
 24738 |                            "ERR007 - Invalid token sequence: '" + 
 24739 |                            error_token.first.value  + "' and '" + 
 24740 |                            error_token.second.value + "'", 
 24741 |                            exprtk_error_location)); 
 24742 |                      } 
 24743 |  
 24744 |                      if (sequence_validator_ptr->error_count()) 
 24745 |                      { 
 24746 |                         sequence_validator_ptr->clear_errors(); 
 24747 |                      } 
 24748 |                   } 
 24749 |                   else if (0 != (sequence_validator3_ptr = dynamic_cast<lexer::helper::sequence_validator_3tokens*>(helper_assembly_.error_token_scanner))) 
 24750 |                   { 
 24751 |                      for (std::size_t i = 0; i < sequence_validator3_ptr->error_count(); ++i) 
 24752 |                      { 
 24753 |                         std::pair<lexer::token,lexer::token> error_token = sequence_validator3_ptr->error(i); 
 24754 |  
 24755 |                         set_error(make_error( 
 24756 |                            parser_error::e_token, 
 24757 |                            error_token.first, 
 24758 |                            "ERR008 - Invalid token sequence: '" + 
 24759 |                            error_token.first.value  + "' and '" + 
 24760 |                            error_token.second.value + "'", 
 24761 |                            exprtk_error_location)); 
 24762 |                      } 
 24763 |  
 24764 |                      if (sequence_validator3_ptr->error_count()) 
 24765 |                      { 
 24766 |                         sequence_validator3_ptr->clear_errors(); 
 24767 |                      } 
 24768 |                   } 
 24769 |                } 
 24770 |  
 24771 |                return false; 
 24772 |             } 
 24773 |          } 
 24774 |  
 24775 |          return true; 
 24776 |       } 
 24777 |  
 24778 |       inline settings_store& settings() 
 24779 |       { 
 24780 |          return settings_; 
 24781 |       } 
 24782 |  
 24783 |       inline parser_error::type get_error(const std::size_t& index) const 
 24784 |       { 
 24785 |          if (index < error_list_.size()) 
 24786 |          { 
 24787 |             return error_list_[index]; 
 24788 |          } 
 24789 |  
 24790 |          throw std::invalid_argument("parser::get_error() - Invalid error index specified"); 
 24791 |       } 
 24792 |  
 24793 |       inline std::string error() const 
 24794 |       { 
 24795 |          if (!error_list_.empty()) 
 24796 |          { 
 24797 |             return error_list_[0].diagnostic; 
 24798 |          } 
 24799 |          else 
 24800 |             return std::string("No Error"); 
 24801 |       } 
 24802 |  
 24803 |       inline std::size_t error_count() const 
 24804 |       { 
 24805 |          return error_list_.size(); 
 24806 |       } 
 24807 |  
 24808 |       inline dependent_entity_collector& dec() 
 24809 |       { 
 24810 |          return dec_; 
 24811 |       } 
 24812 |  
 24813 |       inline bool replace_symbol(const std::string& old_symbol, const std::string& new_symbol) 
 24814 |       { 
 24815 |          if (!settings_.replacer_enabled()) 
 24816 |             return false; 
 24817 |          else if (details::is_reserved_word(old_symbol)) 
 24818 |             return false; 
 24819 |          else 
 24820 |             return symbol_replacer_.add_replace(old_symbol,new_symbol,lexer::token::e_symbol); 
 24821 |       } 
 24822 |  
 24823 |       inline bool remove_replace_symbol(const std::string& symbol) 
 24824 |       { 
 24825 |          if (!settings_.replacer_enabled()) 
 24826 |             return false; 
 24827 |          else if (details::is_reserved_word(symbol)) 
 24828 |             return false; 
 24829 |          else 
 24830 |             return symbol_replacer_.remove(symbol); 
 24831 |       } 
 24832 |  
 24833 |       inline void enable_unknown_symbol_resolver(unknown_symbol_resolver* usr = reinterpret_cast<unknown_symbol_resolver*>(0)) 
 24834 |       { 
 24835 |          resolve_unknown_symbol_ = true; 
 24836 |  
 24837 |          if (usr) 
 24838 |             unknown_symbol_resolver_ = usr; 
 24839 |          else 
 24840 |             unknown_symbol_resolver_ = &default_usr_; 
 24841 |       } 
 24842 |  
 24843 |       inline void enable_unknown_symbol_resolver(unknown_symbol_resolver& usr) 
 24844 |       { 
 24845 |          enable_unknown_symbol_resolver(&usr); 
 24846 |       } 
 24847 |  
 24848 |       inline void disable_unknown_symbol_resolver() 
 24849 |       { 
 24850 |          resolve_unknown_symbol_  = false; 
 24851 |          unknown_symbol_resolver_ = &default_usr_; 
 24852 |       } 
 24853 |  
 24854 |       inline void register_loop_runtime_check(loop_runtime_check& lrtchk) 
 24855 |       { 
 24856 |          loop_runtime_check_ = &lrtchk; 
 24857 |       } 
 24858 |  
 24859 |       inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk) 
 24860 |       { 
 24861 |          vector_access_runtime_check_ = &vartchk; 
 24862 |       } 
 24863 |  
 24864 |       inline void register_compilation_timeout_check(compilation_check& compchk) 
 24865 |       { 
 24866 |          compilation_check_ptr_ = &compchk; 
 24867 |       } 
 24868 |  
 24869 |       inline void register_assert_check(assert_check& assrt_chck) 
 24870 |       { 
 24871 |          assert_check_ = &assrt_chck; 
 24872 |       } 
 24873 |  
 24874 |       inline void clear_loop_runtime_check() 
 24875 |       { 
 24876 |          loop_runtime_check_ = loop_runtime_check_ptr(0); 
 24877 |       } 
 24878 |  
 24879 |       inline void clear_vector_access_runtime_check() 
 24880 |       { 
 24881 |          vector_access_runtime_check_ = vector_access_runtime_check_ptr(0); 
 24882 |       } 
 24883 |  
 24884 |       inline void clear_compilation_timeout_check() 
 24885 |       { 
 24886 |          compilation_check_ptr_ = compilation_check_ptr(0); 
 24887 |       } 
 24888 |  
 24889 |       inline void clear_assert_check() 
 24890 |       { 
 24891 |          assert_check_ = assert_check_ptr(0); 
 24892 |       } 
 24893 |  
 24894 |    private: 
 24895 |  
 24896 |       inline bool valid_base_operation(const std::string& symbol) const 
 24897 |       { 
 24898 |          const std::size_t length = symbol.size(); 
 24899 |  
 24900 |          if ( 
 24901 |               (length < 3) || // Shortest base op symbol length 
 24902 |               (length > 9)    // Longest base op symbol length 
 24903 |             ) 
 24904 |             return false; 
 24905 |          else 
 24906 |             return settings_.function_enabled(symbol) && 
 24907 |                    (base_ops_map_.end() != base_ops_map_.find(symbol)); 
 24908 |       } 
 24909 |  
 24910 |       inline bool valid_vararg_operation(const std::string& symbol) const 
 24911 |       { 
 24912 |          static const std::string s_sum     = "sum" ; 
 24913 |          static const std::string s_mul     = "mul" ; 
 24914 |          static const std::string s_avg     = "avg" ; 
 24915 |          static const std::string s_min     = "min" ; 
 24916 |          static const std::string s_max     = "max" ; 
 24917 |          static const std::string s_mand    = "mand" 
 24918 |          static const std::string s_mor     = "mor" ; 
 24919 |          static const std::string s_multi   = "~"   ; 
 24920 |          static const std::string s_mswitch = "[*]" ; 
 24921 |  
 24922 |          return 
 24923 |                ( 
 24924 |                   details::imatch(symbol,s_sum    ) || 
 24925 |                   details::imatch(symbol,s_mul    ) || 
 24926 |                   details::imatch(symbol,s_avg    ) || 
 24927 |                   details::imatch(symbol,s_min    ) || 
 24928 |                   details::imatch(symbol,s_max    ) || 
 24929 |                   details::imatch(symbol,s_mand   ) || 
 24930 |                   details::imatch(symbol,s_mor    ) || 
 24931 |                   details::imatch(symbol,s_multi  ) || 
 24932 |                   details::imatch(symbol,s_mswitch) 
 24933 |                ) && 
 24934 |                settings_.function_enabled(symbol); 
 24935 |       } 
 24936 |  
 24937 |       bool is_invalid_logic_operation(const details::operator_type operation) const 
 24938 |       { 
 24939 |          return settings_.logic_disabled(operation); 
 24940 |       } 
 24941 |  
 24942 |       bool is_invalid_arithmetic_operation(const details::operator_type operation) const 
 24943 |       { 
 24944 |          return settings_.arithmetic_disabled(operation); 
 24945 |       } 
 24946 |  
 24947 |       bool is_invalid_assignment_operation(const details::operator_type operation) const 
 24948 |       { 
 24949 |          return settings_.assignment_disabled(operation); 
 24950 |       } 
 24951 |  
 24952 |       bool is_invalid_inequality_operation(const details::operator_type operation) const 
 24953 |       { 
 24954 |          return settings_.inequality_disabled(operation); 
 24955 |       } 
 24956 |  
 24957 |       #ifdef exprtk_enable_debugging 
 24958 |       inline void next_token() 
 24959 |       { 
 24960 |          const std::string ct_str = current_token().value; 
 24961 |          const std::size_t ct_pos = current_token().position; 
 24962 |          parser_helper::next_token(); 
 24963 |          const std::string depth(2 * state_.scope_depth,' '); 
 24964 |          exprtk_debug(("%s" 
 24965 |                        "prev[%s | %04d] --> curr[%s | %04d]  stack_level: %3d\n", 
 24966 |                        depth.c_str(), 
 24967 |                        ct_str.c_str(), 
 24968 |                        static_cast<unsigned int>(ct_pos), 
 24969 |                        current_token().value.c_str(), 
 24970 |                        static_cast<unsigned int>(current_token().position), 
 24971 |                        static_cast<unsigned int>(state_.stack_depth))); 
 24972 |       } 
 24973 |       #endif 
 24974 |  
 24975 |       inline expression_node_ptr parse_corpus() 
 24976 |       { 
 24977 |          std::vector<expression_node_ptr> arg_list; 
 24978 |          std::vector<bool> side_effect_list; 
 24979 |  
 24980 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 24981 |  
 24982 |          lexer::token begin_token; 
 24983 |          lexer::token end_token; 
 24984 |  
 24985 |          for ( ; ; ) 
 24986 |          { 
 24987 |             state_.side_effect_present = false; 
 24988 |  
 24989 |             begin_token = current_token(); 
 24990 |  
 24991 |             expression_node_ptr arg = parse_expression(); 
 24992 |  
 24993 |             if (0 == arg) 
 24994 |             { 
 24995 |                if (error_list_.empty()) 
 24996 |                { 
 24997 |                   set_error(make_error( 
 24998 |                      parser_error::e_syntax, 
 24999 |                      current_token(), 
 25000 |                      "ERR009 - Invalid expression encountered", 
 25001 |                      exprtk_error_location)); 
 25002 |                } 
 25003 |  
 25004 |                return error_node(); 
 25005 |             } 
 25006 |             else 
 25007 |             { 
 25008 |                arg_list.push_back(arg); 
 25009 |  
 25010 |                side_effect_list.push_back(state_.side_effect_present); 
 25011 |  
 25012 |                end_token = current_token(); 
 25013 |  
 25014 |                const std::string sub_expr = construct_subexpr(begin_token, end_token); 
 25015 |  
 25016 |                exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n", 
 25017 |                              static_cast<int>(arg_list.size() - 1), 
 25018 |                              sub_expr.c_str())); 
 25019 |  
 25020 |                exprtk_debug(("parse_corpus(%02d) - Side effect present: %s\n", 
 25021 |                              static_cast<int>(arg_list.size() - 1), 
 25022 |                              state_.side_effect_present ? "true" : "false")); 
 25023 |  
 25024 |                exprtk_debug(("-------------------------------------------------\n")); 
 25025 |             } 
 25026 |  
 25027 |             if (token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 25028 |             { 
 25029 |                if (lexer().finished()) 
 25030 |                   break; 
 25031 |                else 
 25032 |                   next_token(); 
 25033 |             } 
 25034 |             else if ( 
 25035 |                       !settings_.commutative_check_enabled() && 
 25036 |                       ( 
 25037 |                         current_token().type == token_t::e_symbol || 
 25038 |                         current_token().type == token_t::e_number || 
 25039 |                         current_token().type == token_t::e_string || 
 25040 |                         token_is_bracket(prsrhlpr_t::e_hold) 
 25041 |                       ) 
 25042 |                     ) 
 25043 |             { 
 25044 |                set_error(make_error( 
 25045 |                   parser_error::e_syntax, 
 25046 |                   current_token(), 
 25047 |                   "ERR010 - Invalid syntax '" + current_token().value  + "' possible missing operator or context", 
 25048 |                   exprtk_error_location)); 
 25049 |  
 25050 |                return error_node(); 
 25051 |             } 
 25052 |          } 
 25053 |  
 25054 |          if ( 
 25055 |               !arg_list.empty() && 
 25056 |               is_return_node(arg_list.back()) 
 25057 |             ) 
 25058 |          { 
 25059 |             dec_.final_stmt_return_ = true; 
 25060 |          } 
 25061 |  
 25062 |          const expression_node_ptr result = simplify(arg_list,side_effect_list); 
 25063 |  
 25064 |          sdd.delete_ptr = (0 == result); 
 25065 |  
 25066 |          return result; 
 25067 |       } 
 25068 |  
 25069 |       std::string construct_subexpr(lexer::token& begin_token, 
 25070 |                                     lexer::token& end_token, 
 25071 |                                     const bool cleanup_whitespace = true) 
 25072 |       { 
 25073 |          std::string result = lexer().substr(begin_token.position,end_token.position); 
 25074 |          if (cleanup_whitespace) 
 25075 |          { 
 25076 |             for (std::size_t i = 0; i < result.size(); ++i) 
 25077 |             { 
 25078 |                if (details::is_whitespace(result[i])) result[i] = ' '; 
 25079 |             } 
 25080 |          } 
 25081 |  
 25082 |          return result; 
 25083 |       } 
 25084 |  
 25085 |       static const precedence_level default_precedence = e_level00; 
 25086 |  
 25087 |       struct state_t 
 25088 |       { 
 25089 |          inline void set(const precedence_level& l, 
 25090 |                          const precedence_level& r, 
 25091 |                          const details::operator_type& o, 
 25092 |                          const token_t tkn = token_t()) 
 25093 |          { 
 25094 |             left      = l; 
 25095 |             right     = r; 
 25096 |             operation = o; 
 25097 |             token     = tkn; 
 25098 |          } 
 25099 |  
 25100 |          inline void reset() 
 25101 |          { 
 25102 |             left      = e_level00; 
 25103 |             right     = e_level00; 
 25104 |             operation = details::e_default; 
 25105 |          } 
 25106 |  
 25107 |          precedence_level left; 
 25108 |          precedence_level right; 
 25109 |          details::operator_type operation; 
 25110 |          token_t token; 
 25111 |       }; 
 25112 |  
 25113 |       inline void push_current_state(const state_t current_state) 
 25114 |       { 
 25115 |          current_state_stack_.push_back(current_state); 
 25116 |       } 
 25117 |  
 25118 |       inline void pop_current_state() 
 25119 |       { 
 25120 |          if (!current_state_stack_.empty()) 
 25121 |          { 
 25122 |             current_state_stack_.pop_back(); 
 25123 |          } 
 25124 |       } 
 25125 |  
 25126 |       inline state_t current_state() const 
 25127 |       { 
 25128 |          return (!current_state_stack_.empty()) ? 
 25129 |                 current_state_stack_.back()     : 
 25130 |                 state_t(); 
 25131 |       } 
 25132 |  
 25133 |       inline bool halt_compilation_check() 
 25134 |       { 
 25135 |          compilation_check::compilation_context context; 
 25136 |  
 25137 |          if (compilation_check_ptr_ && !compilation_check_ptr_->continue_compilation(context)) 
 25138 |          { 
 25139 |             const std::string error_message = 
 25140 |                !context.error_message.empty() ? " Details: " + context.error_message : "" 
 25141 |  
 25142 |             set_error(make_error( 
 25143 |                parser_error::e_parser, 
 25144 |                token_t(), 
 25145 |                "ERR011 - Internal compilation check failed." + error_message, 
 25146 |                exprtk_error_location)); 
 25147 |  
 25148 |             return true; 
 25149 |          } 
 25150 |  
 25151 |          return false; 
 25152 |       } 
 25153 |  
 25154 |       inline expression_node_ptr parse_expression(precedence_level precedence = e_level00) 
 25155 |       { 
 25156 |          if (halt_compilation_check()) 
 25157 |          { 
 25158 |             exprtk_debug(("halt_compilation_check() - parse_expression checkpoint 2\n")); 
 25159 |             return error_node(); 
 25160 |          } 
 25161 |  
 25162 |          stack_limit_handler slh(*this); 
 25163 |  
 25164 |          if (!slh) 
 25165 |          { 
 25166 |             return error_node(); 
 25167 |          } 
 25168 |  
 25169 |          expression_node_ptr expression = parse_branch(precedence); 
 25170 |  
 25171 |          if (0 == expression) 
 25172 |          { 
 25173 |             return error_node(); 
 25174 |          } 
 25175 |  
 25176 |          if (token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 25177 |          { 
 25178 |             return expression; 
 25179 |          } 
 25180 |  
 25181 |          bool break_loop = false; 
 25182 |  
 25183 |          state_t current_state; 
 25184 |  
 25185 |          for ( ; ; ) 
 25186 |          { 
 25187 |             current_state.reset(); 
 25188 |  
 25189 |             switch (current_token().type) 
 25190 |             { 
 25191 |                case token_t::e_assign : current_state.set(e_level00, e_level00, details::e_assign, current_token()); break; 
 25192 |                case token_t::e_addass : current_state.set(e_level00, e_level00, details::e_addass, current_token()); break; 
 25193 |                case token_t::e_subass : current_state.set(e_level00, e_level00, details::e_subass, current_token()); break; 
 25194 |                case token_t::e_mulass : current_state.set(e_level00, e_level00, details::e_mulass, current_token()); break; 
 25195 |                case token_t::e_divass : current_state.set(e_level00, e_level00, details::e_divass, current_token()); break; 
 25196 |                case token_t::e_modass : current_state.set(e_level00, e_level00, details::e_modass, current_token()); break; 
 25197 |                case token_t::e_swap   : current_state.set(e_level00, e_level00, details::e_swap  , current_token()); break; 
 25198 |                case token_t::e_lt     : current_state.set(e_level05, e_level06, details::e_lt    , current_token()); break; 
 25199 |                case token_t::e_lte    : current_state.set(e_level05, e_level06, details::e_lte   , current_token()); break; 
 25200 |                case token_t::e_eq     : current_state.set(e_level05, e_level06, details::e_eq    , current_token()); break; 
 25201 |                case token_t::e_ne     : current_state.set(e_level05, e_level06, details::e_ne    , current_token()); break; 
 25202 |                case token_t::e_gte    : current_state.set(e_level05, e_level06, details::e_gte   , current_token()); break; 
 25203 |                case token_t::e_gt     : current_state.set(e_level05, e_level06, details::e_gt    , current_token()); break; 
 25204 |                case token_t::e_add    : current_state.set(e_level07, e_level08, details::e_add   , current_token()); break; 
 25205 |                case token_t::e_sub    : current_state.set(e_level07, e_level08, details::e_sub   , current_token()); break; 
 25206 |                case token_t::e_div    : current_state.set(e_level10, e_level11, details::e_div   , current_token()); break; 
 25207 |                case token_t::e_mul    : current_state.set(e_level10, e_level11, details::e_mul   , current_token()); break; 
 25208 |                case token_t::e_mod    : current_state.set(e_level10, e_level11, details::e_mod   , current_token()); break; 
 25209 |                case token_t::e_pow    : current_state.set(e_level12, e_level12, details::e_pow   , current_token()); break; 
 25210 |                default                : 
 25211 |                   if (token_t::e_symbol == current_token().type) 
 25212 |                   { 
 25213 |                      static const std::string s_and   = "and"  ; 
 25214 |                      static const std::string s_nand  = "nand" ; 
 25215 |                      static const std::string s_or    = "or"   ; 
 25216 |                      static const std::string s_nor   = "nor"  ; 
 25217 |                      static const std::string s_xor   = "xor"  ; 
 25218 |                      static const std::string s_xnor  = "xnor" ; 
 25219 |                      static const std::string s_in    = "in"   ; 
 25220 |                      static const std::string s_like  = "like" ; 
 25221 |                      static const std::string s_ilike = "ilike" 
 25222 |                      static const std::string s_and1  = "&"    ; 
 25223 |                      static const std::string s_or1   = "|"    ; 
 25224 |                      static const std::string s_not   = "not"  ; 
 25225 |  
 25226 |                      if (details::imatch(current_token().value,s_and)) 
 25227 |                      { 
 25228 |                         current_state.set(e_level03, e_level04, details::e_and, current_token()); 
 25229 |                         break; 
 25230 |                      } 
 25231 |                      else if (details::imatch(current_token().value,s_and1)) 
 25232 |                      { 
 25233 |                         #ifndef exprtk_disable_sc_andor 
 25234 |                         current_state.set(e_level03, e_level04, details::e_scand, current_token()); 
 25235 |                         #else 
 25236 |                         current_state.set(e_level03, e_level04, details::e_and, current_token()); 
 25237 |                         #endif 
 25238 |                         break; 
 25239 |                      } 
 25240 |                      else if (details::imatch(current_token().value,s_nand)) 
 25241 |                      { 
 25242 |                         current_state.set(e_level03, e_level04, details::e_nand, current_token()); 
 25243 |                         break; 
 25244 |                      } 
 25245 |                      else if (details::imatch(current_token().value,s_or)) 
 25246 |                      { 
 25247 |                         current_state.set(e_level01, e_level02, details::e_or, current_token()); 
 25248 |                         break; 
 25249 |                      } 
 25250 |                      else if (details::imatch(current_token().value,s_or1)) 
 25251 |                      { 
 25252 |                         #ifndef exprtk_disable_sc_andor 
 25253 |                         current_state.set(e_level01, e_level02, details::e_scor, current_token()); 
 25254 |                         #else 
 25255 |                         current_state.set(e_level01, e_level02, details::e_or, current_token()); 
 25256 |                         #endif 
 25257 |                         break; 
 25258 |                      } 
 25259 |                      else if (details::imatch(current_token().value,s_nor)) 
 25260 |                      { 
 25261 |                         current_state.set(e_level01, e_level02, details::e_nor, current_token()); 
 25262 |                         break; 
 25263 |                      } 
 25264 |                      else if (details::imatch(current_token().value,s_xor)) 
 25265 |                      { 
 25266 |                         current_state.set(e_level01, e_level02, details::e_xor, current_token()); 
 25267 |                         break; 
 25268 |                      } 
 25269 |                      else if (details::imatch(current_token().value,s_xnor)) 
 25270 |                      { 
 25271 |                         current_state.set(e_level01, e_level02, details::e_xnor, current_token()); 
 25272 |                         break; 
 25273 |                      } 
 25274 |                      else if (details::imatch(current_token().value,s_in)) 
 25275 |                      { 
 25276 |                         current_state.set(e_level04, e_level04, details::e_in, current_token()); 
 25277 |                         break; 
 25278 |                      } 
 25279 |                      else if (details::imatch(current_token().value,s_like)) 
 25280 |                      { 
 25281 |                         current_state.set(e_level04, e_level04, details::e_like, current_token()); 
 25282 |                         break; 
 25283 |                      } 
 25284 |                      else if (details::imatch(current_token().value,s_ilike)) 
 25285 |                      { 
 25286 |                         current_state.set(e_level04, e_level04, details::e_ilike, current_token()); 
 25287 |                         break; 
 25288 |                      } 
 25289 |                      else if (details::imatch(current_token().value,s_not)) 
 25290 |                      { 
 25291 |                         break; 
 25292 |                      } 
 25293 |                   } 
 25294 |  
 25295 |                   break_loop = true; 
 25296 |             } 
 25297 |  
 25298 |             if (break_loop) 
 25299 |             { 
 25300 |                parse_pending_string_rangesize(expression); 
 25301 |                break; 
 25302 |             } 
 25303 |             else if (current_state.left < precedence) 
 25304 |                break; 
 25305 |  
 25306 |             const lexer::token prev_token = current_token(); 
 25307 |  
 25308 |             next_token(); 
 25309 |  
 25310 |             expression_node_ptr right_branch   = error_node(); 
 25311 |             expression_node_ptr new_expression = error_node(); 
 25312 |  
 25313 |             if (is_invalid_logic_operation(current_state.operation)) 
 25314 |             { 
 25315 |                free_node(node_allocator_, expression); 
 25316 |  
 25317 |                set_error(make_error( 
 25318 |                   parser_error::e_syntax, 
 25319 |                   prev_token, 
 25320 |                   "ERR012 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'", 
 25321 |                   exprtk_error_location)); 
 25322 |  
 25323 |                return error_node(); 
 25324 |             } 
 25325 |             else if (is_invalid_arithmetic_operation(current_state.operation)) 
 25326 |             { 
 25327 |                free_node(node_allocator_, expression); 
 25328 |  
 25329 |                set_error(make_error( 
 25330 |                   parser_error::e_syntax, 
 25331 |                   prev_token, 
 25332 |                   "ERR013 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'", 
 25333 |                   exprtk_error_location)); 
 25334 |  
 25335 |                return error_node(); 
 25336 |             } 
 25337 |             else if (is_invalid_inequality_operation(current_state.operation)) 
 25338 |             { 
 25339 |                free_node(node_allocator_, expression); 
 25340 |  
 25341 |                set_error(make_error( 
 25342 |                   parser_error::e_syntax, 
 25343 |                   prev_token, 
 25344 |                   "ERR014 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'", 
 25345 |                   exprtk_error_location)); 
 25346 |  
 25347 |                return error_node(); 
 25348 |             } 
 25349 |             else if (is_invalid_assignment_operation(current_state.operation)) 
 25350 |             { 
 25351 |                free_node(node_allocator_, expression); 
 25352 |  
 25353 |                set_error(make_error( 
 25354 |                   parser_error::e_syntax, 
 25355 |                   prev_token, 
 25356 |                   "ERR015 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'", 
 25357 |                   exprtk_error_location)); 
 25358 |  
 25359 |                return error_node(); 
 25360 |             } 
 25361 |  
 25362 |             if (0 != (right_branch = parse_expression(current_state.right))) 
 25363 |             { 
 25364 |                if ( 
 25365 |                     details::is_return_node(expression  ) || 
 25366 |                     details::is_return_node(right_branch) 
 25367 |                   ) 
 25368 |                { 
 25369 |                   free_node(node_allocator_, expression  ); 
 25370 |                   free_node(node_allocator_, right_branch); 
 25371 |  
 25372 |                   set_error(make_error( 
 25373 |                      parser_error::e_syntax, 
 25374 |                      prev_token, 
 25375 |                      "ERR016 - Return statements cannot be part of sub-expressions", 
 25376 |                      exprtk_error_location)); 
 25377 |  
 25378 |                   return error_node(); 
 25379 |                } 
 25380 |  
 25381 |                push_current_state(current_state); 
 25382 |  
 25383 |                new_expression = expression_generator_ 
 25384 |                                   ( 
 25385 |                                     current_state.operation, 
 25386 |                                     expression, 
 25387 |                                     right_branch 
 25388 |                                   ); 
 25389 |  
 25390 |                pop_current_state(); 
 25391 |             } 
 25392 |  
 25393 |             if (0 == new_expression) 
 25394 |             { 
 25395 |                if (error_list_.empty()) 
 25396 |                { 
 25397 |                   set_error(make_error( 
 25398 |                      parser_error::e_syntax, 
 25399 |                      prev_token, 
 25400 |                      !synthesis_error_.empty() ? 
 25401 |                      synthesis_error_ : 
 25402 |                      "ERR017 - General parsing error at token: '" + prev_token.value + "'", 
 25403 |                      exprtk_error_location)); 
 25404 |                } 
 25405 |  
 25406 |                free_node(node_allocator_, expression  ); 
 25407 |                free_node(node_allocator_, right_branch); 
 25408 |  
 25409 |                return error_node(); 
 25410 |             } 
 25411 |             else 
 25412 |             { 
 25413 |                if ( 
 25414 |                     token_is(token_t::e_ternary,prsrhlpr_t::e_hold) && 
 25415 |                     (e_level00 == precedence) 
 25416 |                   ) 
 25417 |                { 
 25418 |                   expression = parse_ternary_conditional_statement(new_expression); 
 25419 |                } 
 25420 |                else 
 25421 |                   expression = new_expression; 
 25422 |  
 25423 |                parse_pending_string_rangesize(expression); 
 25424 |             } 
 25425 |          } 
 25426 |  
 25427 |          if ((0 != expression) && (expression->node_depth() > settings_.max_node_depth_)) 
 25428 |          { 
 25429 |             set_error(make_error( 
 25430 |                parser_error::e_syntax, 
 25431 |                current_token(), 
 25432 |                "ERR018 - Expression depth of " + details::to_str(static_cast<int>(expression->node_depth())) + 
 25433 |                " exceeds maximum allowed expression depth of " + details::to_str(static_cast<int>(settings_.max_node_depth_)), 
 25434 |                exprtk_error_location)); 
 25435 |  
 25436 |             free_node(node_allocator_, expression); 
 25437 |  
 25438 |             return error_node(); 
 25439 |          } 
 25440 |          else if ( 
 25441 |                    !settings_.commutative_check_enabled()          && 
 25442 |                    !details::is_logic_opr(current_token().value)   && 
 25443 |                    (current_state.operation == details::e_default) && 
 25444 |                    ( 
 25445 |                      current_token().type == token_t::e_symbol || 
 25446 |                      current_token().type == token_t::e_number || 
 25447 |                      current_token().type == token_t::e_string 
 25448 |                    ) 
 25449 |                  ) 
 25450 |          { 
 25451 |             set_error(make_error( 
 25452 |                parser_error::e_syntax, 
 25453 |                current_token(), 
 25454 |                "ERR019 - Invalid syntax '" + current_token().value  + "' possible missing operator or context", 
 25455 |                exprtk_error_location)); 
 25456 |  
 25457 |             free_node(node_allocator_, expression); 
 25458 |  
 25459 |             return error_node(); 
 25460 |          } 
 25461 |  
 25462 |          return expression; 
 25463 |       } 
 25464 |  
 25465 |       bool simplify_unary_negation_branch(expression_node_ptr& node) 
 25466 |       { 
 25467 |          { 
 25468 |             typedef details::unary_branch_node<T,details::neg_op<T> > ubn_t; 
 25469 |             ubn_t* n = dynamic_cast<ubn_t*>(node); 
 25470 |  
 25471 |             if (n) 
 25472 |             { 
 25473 |                expression_node_ptr un_r = n->branch(0); 
 25474 |                n->release(); 
 25475 |                free_node(node_allocator_, node); 
 25476 |                node = un_r; 
 25477 |  
 25478 |                return true; 
 25479 |             } 
 25480 |          } 
 25481 |  
 25482 |          { 
 25483 |             typedef details::unary_variable_node<T,details::neg_op<T> > uvn_t; 
 25484 |  
 25485 |             uvn_t* n = dynamic_cast<uvn_t*>(node); 
 25486 |  
 25487 |             if (n) 
 25488 |             { 
 25489 |                const T& v = n->v(); 
 25490 |                expression_node_ptr return_node = error_node(); 
 25491 |  
 25492 |                if ( 
 25493 |                     (0 != (return_node = symtab_store_.get_variable(v))) || 
 25494 |                     (0 != (return_node = sem_         .get_variable(v))) 
 25495 |                   ) 
 25496 |                { 
 25497 |                   free_node(node_allocator_, node); 
 25498 |                   node = return_node; 
 25499 |  
 25500 |                   return true; 
 25501 |                } 
 25502 |                else 
 25503 |                { 
 25504 |                   set_error(make_error( 
 25505 |                      parser_error::e_syntax, 
 25506 |                      current_token(), 
 25507 |                      "ERR020 - Failed to find variable node in symbol table", 
 25508 |                      exprtk_error_location)); 
 25509 |  
 25510 |                   free_node(node_allocator_, node); 
 25511 |  
 25512 |                   return false; 
 25513 |                } 
 25514 |             } 
 25515 |          } 
 25516 |  
 25517 |          return false; 
 25518 |       } 
 25519 |  
 25520 |       static inline expression_node_ptr error_node() 
 25521 |       { 
 25522 |          return reinterpret_cast<expression_node_ptr>(0); 
 25523 |       } 
 25524 |  
 25525 |       struct scoped_expression_delete 
 25526 |       { 
 25527 |          scoped_expression_delete(parser<T>& pr, expression_node_ptr& expression) 
 25528 |          : delete_ptr(true) 
 25529 |          , parser_(pr) 
 25530 |          , expression_(expression) 
 25531 |          {} 
 25532 |  
 25533 |         ~scoped_expression_delete() 
 25534 |          { 
 25535 |             if (delete_ptr) 
 25536 |             { 
 25537 |                free_node(parser_.node_allocator_, expression_); 
 25538 |             } 
 25539 |          } 
 25540 |  
 25541 |          bool delete_ptr; 
 25542 |          parser<T>& parser_; 
 25543 |          expression_node_ptr& expression_; 
 25544 |  
 25545 |       private: 
 25546 |  
 25547 |          scoped_expression_delete(const scoped_expression_delete&) exprtk_delete; 
 25548 |          scoped_expression_delete& operator=(const scoped_expression_delete&) exprtk_delete; 
 25549 |       }; 
 25550 |  
 25551 |       template <typename Type, std::size_t N> 
 25552 |       struct scoped_delete 
 25553 |       { 
 25554 |          typedef Type* ptr_t; 
 25555 |  
 25556 |          scoped_delete(parser<T>& pr, ptr_t& p) 
 25557 |          : delete_ptr(true) 
 25558 |          , parser_(pr) 
 25559 |          , p_(&p) 
 25560 |          {} 
 25561 |  
 25562 |          scoped_delete(parser<T>& pr, ptr_t (&p)[N]) 
 25563 |          : delete_ptr(true) 
 25564 |          , parser_(pr) 
 25565 |          , p_(&p[0]) 
 25566 |          {} 
 25567 |  
 25568 |         ~scoped_delete() 
 25569 |          { 
 25570 |             if (delete_ptr) 
 25571 |             { 
 25572 |                for (std::size_t i = 0; i < N; ++i) 
 25573 |                { 
 25574 |                   free_node(parser_.node_allocator_, p_[i]); 
 25575 |                } 
 25576 |             } 
 25577 |          } 
 25578 |  
 25579 |          bool delete_ptr; 
 25580 |          parser<T>& parser_; 
 25581 |          ptr_t* p_; 
 25582 |  
 25583 |       private: 
 25584 |  
 25585 |          scoped_delete(const scoped_delete<Type,N>&) exprtk_delete; 
 25586 |          scoped_delete<Type,N>& operator=(const scoped_delete<Type,N>&) exprtk_delete; 
 25587 |       }; 
 25588 |  
 25589 |       template <typename Type> 
 25590 |       struct scoped_deq_delete 
 25591 |       { 
 25592 |          typedef Type* ptr_t; 
 25593 |  
 25594 |          scoped_deq_delete(parser<T>& pr, std::deque<ptr_t>& deq) 
 25595 |          : delete_ptr(true) 
 25596 |          , parser_(pr) 
 25597 |          , deq_(deq) 
 25598 |          {} 
 25599 |  
 25600 |         ~scoped_deq_delete() 
 25601 |          { 
 25602 |             if (delete_ptr && !deq_.empty()) 
 25603 |             { 
 25604 |                for (std::size_t i = 0; i < deq_.size(); ++i) 
 25605 |                { 
 25606 |                   exprtk_debug(("~scoped_deq_delete() - deleting node: %p\n", reinterpret_cast<void*>(deq_[i]))); 
 25607 |                   free_node(parser_.node_allocator_,deq_[i]); 
 25608 |                } 
 25609 |  
 25610 |                deq_.clear(); 
 25611 |             } 
 25612 |          } 
 25613 |  
 25614 |          bool delete_ptr; 
 25615 |          parser<T>& parser_; 
 25616 |          std::deque<ptr_t>& deq_; 
 25617 |  
 25618 |       private: 
 25619 |  
 25620 |          scoped_deq_delete(const scoped_deq_delete<Type>&) exprtk_delete; 
 25621 |          scoped_deq_delete<Type>& operator=(const scoped_deq_delete<Type>&) exprtk_delete; 
 25622 |       }; 
 25623 |  
 25624 |       template <typename Type> 
 25625 |       struct scoped_vec_delete 
 25626 |       { 
 25627 |          typedef Type* ptr_t; 
 25628 |  
 25629 |          scoped_vec_delete(parser<T>& pr, std::vector<ptr_t>& vec) 
 25630 |          : delete_ptr(true) 
 25631 |          , parser_(pr) 
 25632 |          , vec_(vec) 
 25633 |          {} 
 25634 |  
 25635 |         ~scoped_vec_delete() 
 25636 |          { 
 25637 |             if (delete_ptr && !vec_.empty()) 
 25638 |             { 
 25639 |                for (std::size_t i = 0; i < vec_.size(); ++i) 
 25640 |                { 
 25641 |                   exprtk_debug(("~scoped_vec_delete() - deleting node: %p\n", reinterpret_cast<void*>(vec_[i]))); 
 25642 |                   free_node(parser_.node_allocator_,vec_[i]); 
 25643 |                } 
 25644 |  
 25645 |                vec_.clear(); 
 25646 |             } 
 25647 |          } 
 25648 |  
 25649 |          ptr_t operator[](const std::size_t index) 
 25650 |          { 
 25651 |             return vec_[index]; 
 25652 |          } 
 25653 |  
 25654 |          bool delete_ptr; 
 25655 |          parser<T>& parser_; 
 25656 |          std::vector<ptr_t>& vec_; 
 25657 |  
 25658 |       private: 
 25659 |  
 25660 |          scoped_vec_delete(const scoped_vec_delete<Type>&) exprtk_delete; 
 25661 |          scoped_vec_delete<Type>& operator=(const scoped_vec_delete<Type>&) exprtk_delete; 
 25662 |       }; 
 25663 |  
 25664 |       struct scoped_bool_negator 
 25665 |       { 
 25666 |          explicit scoped_bool_negator(bool& bb) 
 25667 |          : b(bb) 
 25668 |          { b = !b; } 
 25669 |  
 25670 |         ~scoped_bool_negator() 
 25671 |          { b = !b; } 
 25672 |  
 25673 |          bool& b; 
 25674 |       }; 
 25675 |  
 25676 |       struct scoped_bool_or_restorer 
 25677 |       { 
 25678 |          explicit scoped_bool_or_restorer(bool& bb) 
 25679 |          : b(bb) 
 25680 |          , original_value_(bb) 
 25681 |          {} 
 25682 |  
 25683 |         ~scoped_bool_or_restorer() 
 25684 |          { 
 25685 |             b = b || original_value_; 
 25686 |          } 
 25687 |  
 25688 |          bool& b; 
 25689 |          bool original_value_; 
 25690 |       }; 
 25691 |  
 25692 |       struct scoped_inc_dec 
 25693 |       { 
 25694 |          explicit scoped_inc_dec(std::size_t& v) 
 25695 |          : v_(v) 
 25696 |          { ++v_; } 
 25697 |  
 25698 |         ~scoped_inc_dec() 
 25699 |          { 
 25700 |            assert(v_ > 0); 
 25701 |            --v_; 
 25702 |          } 
 25703 |  
 25704 |          std::size_t& v_; 
 25705 |       }; 
 25706 |  
 25707 |       inline expression_node_ptr parse_function_invocation(ifunction<T>* function, const std::string& function_name) 
 25708 |       { 
 25709 |          expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0); 
 25710 |  
 25711 |          switch (function->param_count) 
 25712 |          { 
 25713 |             case  0 : func_node = parse_function_call_0  (function,function_name); break; 
 25714 |             case  1 : func_node = parse_function_call< 1>(function,function_name); break; 
 25715 |             case  2 : func_node = parse_function_call< 2>(function,function_name); break; 
 25716 |             case  3 : func_node = parse_function_call< 3>(function,function_name); break; 
 25717 |             case  4 : func_node = parse_function_call< 4>(function,function_name); break; 
 25718 |             case  5 : func_node = parse_function_call< 5>(function,function_name); break; 
 25719 |             case  6 : func_node = parse_function_call< 6>(function,function_name); break; 
 25720 |             case  7 : func_node = parse_function_call< 7>(function,function_name); break; 
 25721 |             case  8 : func_node = parse_function_call< 8>(function,function_name); break; 
 25722 |             case  9 : func_node = parse_function_call< 9>(function,function_name); break; 
 25723 |             case 10 : func_node = parse_function_call<10>(function,function_name); break; 
 25724 |             case 11 : func_node = parse_function_call<11>(function,function_name); break; 
 25725 |             case 12 : func_node = parse_function_call<12>(function,function_name); break; 
 25726 |             case 13 : func_node = parse_function_call<13>(function,function_name); break; 
 25727 |             case 14 : func_node = parse_function_call<14>(function,function_name); break; 
 25728 |             case 15 : func_node = parse_function_call<15>(function,function_name); break; 
 25729 |             case 16 : func_node = parse_function_call<16>(function,function_name); break; 
 25730 |             case 17 : func_node = parse_function_call<17>(function,function_name); break; 
 25731 |             case 18 : func_node = parse_function_call<18>(function,function_name); break; 
 25732 |             case 19 : func_node = parse_function_call<19>(function,function_name); break; 
 25733 |             case 20 : func_node = parse_function_call<20>(function,function_name); break; 
 25734 |             default : { 
 25735 |                          set_error(make_error( 
 25736 |                            parser_error::e_syntax, 
 25737 |                            current_token(), 
 25738 |                            "ERR021 - Invalid number of parameters for function: '" + function_name + "'", 
 25739 |                            exprtk_error_location)); 
 25740 |  
 25741 |                          return error_node(); 
 25742 |                       } 
 25743 |          } 
 25744 |  
 25745 |          if (func_node) 
 25746 |             return func_node; 
 25747 |          else 
 25748 |          { 
 25749 |             set_error(make_error( 
 25750 |                parser_error::e_syntax, 
 25751 |                current_token(), 
 25752 |                "ERR022 - Failed to generate call to function: '" + function_name + "'", 
 25753 |                exprtk_error_location)); 
 25754 |  
 25755 |             return error_node(); 
 25756 |          } 
 25757 |       } 
 25758 |  
 25759 |       template <std::size_t NumberofParameters> 
 25760 |       inline expression_node_ptr parse_function_call(ifunction<T>* function, const std::string& function_name) 
 25761 |       { 
 25762 |          #ifdef _MSC_VER 
 25763 |             #pragma warning(push) 
 25764 |             #pragma warning(disable: 4127) 
 25765 |          #endif 
 25766 |          if (0 == NumberofParameters) 
 25767 |          { 
 25768 |             set_error(make_error( 
 25769 |                parser_error::e_syntax, 
 25770 |                current_token(), 
 25771 |                "ERR023 - Expecting ifunction '" + function_name + "' to have non-zero parameter count", 
 25772 |                exprtk_error_location)); 
 25773 |  
 25774 |             return error_node(); 
 25775 |          } 
 25776 |          #ifdef _MSC_VER 
 25777 |             #pragma warning(pop) 
 25778 |          #endif 
 25779 |  
 25780 |          expression_node_ptr branch[NumberofParameters]; 
 25781 |          expression_node_ptr result  = error_node(); 
 25782 |  
 25783 |          std::fill_n(branch, NumberofParameters, reinterpret_cast<expression_node_ptr>(0)); 
 25784 |  
 25785 |          scoped_delete<expression_node_t,NumberofParameters> sd((*this),branch); 
 25786 |  
 25787 |          next_token(); 
 25788 |  
 25789 |          if (!token_is(token_t::e_lbracket)) 
 25790 |          { 
 25791 |             set_error(make_error( 
 25792 |                parser_error::e_syntax, 
 25793 |                current_token(), 
 25794 |                "ERR024 - Expecting argument list for function: '" + function_name + "'", 
 25795 |                exprtk_error_location)); 
 25796 |  
 25797 |             return error_node(); 
 25798 |          } 
 25799 |  
 25800 |          for (int i = 0; i < static_cast<int>(NumberofParameters); ++i) 
 25801 |          { 
 25802 |             branch[i] = parse_expression(); 
 25803 |  
 25804 |             if (0 == branch[i]) 
 25805 |             { 
 25806 |                set_error(make_error( 
 25807 |                   parser_error::e_syntax, 
 25808 |                   current_token(), 
 25809 |                   "ERR025 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'", 
 25810 |                   exprtk_error_location)); 
 25811 |  
 25812 |                return error_node(); 
 25813 |             } 
 25814 |             else if (i < static_cast<int>(NumberofParameters - 1)) 
 25815 |             { 
 25816 |                if (!token_is(token_t::e_comma)) 
 25817 |                { 
 25818 |                   set_error(make_error( 
 25819 |                      parser_error::e_syntax, 
 25820 |                      current_token(), 
 25821 |                      "ERR026 - Invalid number of arguments for function: '" + function_name + "'", 
 25822 |                      exprtk_error_location)); 
 25823 |  
 25824 |                   return error_node(); 
 25825 |                } 
 25826 |             } 
 25827 |          } 
 25828 |  
 25829 |          if (!token_is(token_t::e_rbracket)) 
 25830 |          { 
 25831 |             set_error(make_error( 
 25832 |                parser_error::e_syntax, 
 25833 |                current_token(), 
 25834 |                "ERR027 - Invalid number of arguments for function: '" + function_name + "'", 
 25835 |                exprtk_error_location)); 
 25836 |  
 25837 |             return error_node(); 
 25838 |          } 
 25839 |          else 
 25840 |             result = expression_generator_.function(function,branch); 
 25841 |  
 25842 |          sd.delete_ptr = (0 == result); 
 25843 |  
 25844 |          return result; 
 25845 |       } 
 25846 |  
 25847 |       inline expression_node_ptr parse_function_call_0(ifunction<T>* function, const std::string& function_name) 
 25848 |       { 
 25849 |          expression_node_ptr result = expression_generator_.function(function); 
 25850 |  
 25851 |          state_.side_effect_present = function->has_side_effects(); 
 25852 |  
 25853 |          next_token(); 
 25854 |  
 25855 |          if ( 
 25856 |                token_is(token_t::e_lbracket) && 
 25857 |               !token_is(token_t::e_rbracket) 
 25858 |             ) 
 25859 |          { 
 25860 |             set_error(make_error( 
 25861 |                parser_error::e_syntax, 
 25862 |                current_token(), 
 25863 |                "ERR028 - Expecting '()' to proceed call to function: '" + function_name + "'", 
 25864 |                exprtk_error_location)); 
 25865 |  
 25866 |             free_node(node_allocator_, result); 
 25867 |  
 25868 |             return error_node(); 
 25869 |          } 
 25870 |          else 
 25871 |             return result; 
 25872 |       } 
 25873 |  
 25874 |       template <std::size_t MaxNumberofParameters> 
 25875 |       inline std::size_t parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters], const std::string& function_name = "") 
 25876 |       { 
 25877 |          std::fill_n(param_list, MaxNumberofParameters, reinterpret_cast<expression_node_ptr>(0)); 
 25878 |  
 25879 |          scoped_delete<expression_node_t,MaxNumberofParameters> sd((*this),param_list); 
 25880 |  
 25881 |          next_token(); 
 25882 |  
 25883 |          if (!token_is(token_t::e_lbracket)) 
 25884 |          { 
 25885 |             set_error(make_error( 
 25886 |                parser_error::e_syntax, 
 25887 |                current_token(), 
 25888 |                "ERR029 - Expected a '(' at start of function call to '" + function_name  + 
 25889 |                "', instead got: '" + current_token().value + "'", 
 25890 |                exprtk_error_location)); 
 25891 |  
 25892 |             return 0; 
 25893 |          } 
 25894 |  
 25895 |          if (token_is(token_t::e_rbracket, e_hold)) 
 25896 |          { 
 25897 |             set_error(make_error( 
 25898 |                parser_error::e_syntax, 
 25899 |                current_token(), 
 25900 |                "ERR030 - Expected at least one input parameter for function call '" + function_name + "'", 
 25901 |                exprtk_error_location)); 
 25902 |  
 25903 |             return 0; 
 25904 |          } 
 25905 |  
 25906 |          std::size_t param_index = 0; 
 25907 |  
 25908 |          for (; param_index < MaxNumberofParameters; ++param_index) 
 25909 |          { 
 25910 |             param_list[param_index] = parse_expression(); 
 25911 |  
 25912 |             if (0 == param_list[param_index]) 
 25913 |                return 0; 
 25914 |             else if (token_is(token_t::e_rbracket)) 
 25915 |             { 
 25916 |                sd.delete_ptr = false; 
 25917 |                break; 
 25918 |             } 
 25919 |             else if (token_is(token_t::e_comma)) 
 25920 |                continue; 
 25921 |             else 
 25922 |             { 
 25923 |                set_error(make_error( 
 25924 |                   parser_error::e_syntax, 
 25925 |                   current_token(), 
 25926 |                   "ERR031 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'", 
 25927 |                   exprtk_error_location)); 
 25928 |  
 25929 |                return 0; 
 25930 |             } 
 25931 |          } 
 25932 |  
 25933 |          if (sd.delete_ptr) 
 25934 |          { 
 25935 |             set_error(make_error( 
 25936 |                parser_error::e_syntax, 
 25937 |                current_token(), 
 25938 |                "ERR032 - Invalid number of input parameters passed to function '" + function_name  + "'", 
 25939 |                exprtk_error_location)); 
 25940 |  
 25941 |             return 0; 
 25942 |          } 
 25943 |  
 25944 |          return (param_index + 1); 
 25945 |       } 
 25946 |  
 25947 |       inline expression_node_ptr parse_base_operation() 
 25948 |       { 
 25949 |          typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t; 
 25950 |  
 25951 |          const std::string operation_name   = current_token().value; 
 25952 |          const token_t     diagnostic_token = current_token(); 
 25953 |  
 25954 |          map_range_t itr_range = base_ops_map_.equal_range(operation_name); 
 25955 |  
 25956 |          if (0 == std::distance(itr_range.first,itr_range.second)) 
 25957 |          { 
 25958 |             set_error(make_error( 
 25959 |                parser_error::e_syntax, 
 25960 |                diagnostic_token, 
 25961 |                "ERR033 - No entry found for base operation: " + operation_name, 
 25962 |                exprtk_error_location)); 
 25963 |  
 25964 |             return error_node(); 
 25965 |          } 
 25966 |  
 25967 |          static const std::size_t MaxNumberofParameters = 4; 
 25968 |          expression_node_ptr param_list[MaxNumberofParameters] = {0}; 
 25969 |  
 25970 |          const std::size_t parameter_count = parse_base_function_call(param_list, operation_name); 
 25971 |  
 25972 |          if ((parameter_count > 0) && (parameter_count <= MaxNumberofParameters)) 
 25973 |          { 
 25974 |             for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr) 
 25975 |             { 
 25976 |                const details::base_operation_t& operation = itr->second; 
 25977 |  
 25978 |                if (operation.num_params == parameter_count) 
 25979 |                { 
 25980 |                   switch (parameter_count) 
 25981 |                   { 
 25982 |                      #define base_opr_case(N)                                         \ 
 25983 |                      case N : {                                                       \ 
 25984 |                                  expression_node_ptr pl##N[N] = {0};                  \ 
 25985 |                                  std::copy(param_list, param_list + N, pl##N);        \ 
 25986 |                                  lodge_symbol(operation_name, e_st_function);         \ 
 25987 |                                  return expression_generator_(operation.type, pl##N); \ 
 25988 |                               }                                                       \ 
 25989 |  
 25990 |                      base_opr_case(1) 
 25991 |                      base_opr_case(2) 
 25992 |                      base_opr_case(3) 
 25993 |                      base_opr_case(4) 
 25994 |                      #undef base_opr_case 
 25995 |                   } 
 25996 |                } 
 25997 |             } 
 25998 |          } 
 25999 |  
 26000 |          for (std::size_t i = 0; i < MaxNumberofParameters; ++i) 
 26001 |          { 
 26002 |             free_node(node_allocator_, param_list[i]); 
 26003 |          } 
 26004 |  
 26005 |          set_error(make_error( 
 26006 |             parser_error::e_syntax, 
 26007 |             diagnostic_token, 
 26008 |             "ERR034 - Invalid number of input parameters for call to function: '" + operation_name + "'", 
 26009 |             exprtk_error_location)); 
 26010 |  
 26011 |          return error_node(); 
 26012 |       } 
 26013 |  
 26014 |       inline expression_node_ptr parse_conditional_statement_01(expression_node_ptr condition) 
 26015 |       { 
 26016 |          // Parse: [if][(][condition][,][consequent][,][alternative][)] 
 26017 |  
 26018 |          expression_node_ptr consequent  = error_node(); 
 26019 |          expression_node_ptr alternative = error_node(); 
 26020 |  
 26021 |          bool result = true; 
 26022 |  
 26023 |          if (!token_is(token_t::e_comma)) 
 26024 |          { 
 26025 |             set_error(make_error( 
 26026 |                parser_error::e_syntax, 
 26027 |                current_token(), 
 26028 |                "ERR035 - Expected ',' between if-statement condition and consequent", 
 26029 |                exprtk_error_location)); 
 26030 |  
 26031 |             result = false; 
 26032 |          } 
 26033 |          else if (0 == (consequent = parse_expression())) 
 26034 |          { 
 26035 |             set_error(make_error( 
 26036 |                parser_error::e_syntax, 
 26037 |                current_token(), 
 26038 |                "ERR036 - Failed to parse consequent for if-statement", 
 26039 |                exprtk_error_location)); 
 26040 |  
 26041 |             result = false; 
 26042 |          } 
 26043 |          else if (!token_is(token_t::e_comma)) 
 26044 |          { 
 26045 |             set_error(make_error( 
 26046 |                parser_error::e_syntax, 
 26047 |                current_token(), 
 26048 |                "ERR037 - Expected ',' between if-statement consequent and alternative", 
 26049 |                exprtk_error_location)); 
 26050 |  
 26051 |             result = false; 
 26052 |          } 
 26053 |          else if (0 == (alternative = parse_expression())) 
 26054 |          { 
 26055 |             set_error(make_error( 
 26056 |                parser_error::e_syntax, 
 26057 |                current_token(), 
 26058 |                "ERR038 - Failed to parse alternative for if-statement", 
 26059 |                exprtk_error_location)); 
 26060 |  
 26061 |             result = false; 
 26062 |          } 
 26063 |          else if (!token_is(token_t::e_rbracket)) 
 26064 |          { 
 26065 |             set_error(make_error( 
 26066 |                parser_error::e_syntax, 
 26067 |                current_token(), 
 26068 |                "ERR039 - Expected ')' at the end of if-statement", 
 26069 |                exprtk_error_location)); 
 26070 |  
 26071 |             result = false; 
 26072 |          } 
 26073 |  
 26074 |          #ifndef exprtk_disable_string_capabilities 
 26075 |          if (result) 
 26076 |          { 
 26077 |             const bool consq_is_str = is_generally_string_node(consequent ); 
 26078 |             const bool alter_is_str = is_generally_string_node(alternative); 
 26079 |  
 26080 |             if (consq_is_str || alter_is_str) 
 26081 |             { 
 26082 |                if (consq_is_str && alter_is_str) 
 26083 |                { 
 26084 |                   expression_node_ptr result_node = 
 26085 |                      expression_generator_ 
 26086 |                         .conditional_string(condition, consequent, alternative); 
 26087 |  
 26088 |                   if (result_node && result_node->valid()) 
 26089 |                   { 
 26090 |                      return result_node; 
 26091 |                   } 
 26092 |  
 26093 |                   set_error(make_error( 
 26094 |                      parser_error::e_synthesis, 
 26095 |                      current_token(), 
 26096 |                      "ERR040 - Failed to synthesize node: conditional_string", 
 26097 |                      exprtk_error_location)); 
 26098 |  
 26099 |                   free_node(node_allocator_, result_node); 
 26100 |                   return error_node(); 
 26101 |                } 
 26102 |  
 26103 |                set_error(make_error( 
 26104 |                   parser_error::e_syntax, 
 26105 |                   current_token(), 
 26106 |                   "ERR041 - Return types of if-statement differ: string/non-string", 
 26107 |                   exprtk_error_location)); 
 26108 |  
 26109 |                result = false; 
 26110 |             } 
 26111 |          } 
 26112 |          #endif 
 26113 |  
 26114 |          if (result) 
 26115 |          { 
 26116 |             const bool consq_is_vec = is_ivector_node(consequent ); 
 26117 |             const bool alter_is_vec = is_ivector_node(alternative); 
 26118 |  
 26119 |             if (consq_is_vec || alter_is_vec) 
 26120 |             { 
 26121 |                if (consq_is_vec && alter_is_vec) 
 26122 |                { 
 26123 |                   return expression_generator_ 
 26124 |                            .conditional_vector(condition, consequent, alternative); 
 26125 |                } 
 26126 |  
 26127 |                set_error(make_error( 
 26128 |                   parser_error::e_syntax, 
 26129 |                   current_token(), 
 26130 |                   "ERR042 - Return types of if-statement differ: vector/non-vector", 
 26131 |                   exprtk_error_location)); 
 26132 |  
 26133 |                result = false; 
 26134 |             } 
 26135 |          } 
 26136 |  
 26137 |          if (!result) 
 26138 |          { 
 26139 |             free_node(node_allocator_, condition  ); 
 26140 |             free_node(node_allocator_, consequent ); 
 26141 |             free_node(node_allocator_, alternative); 
 26142 |  
 26143 |             return error_node(); 
 26144 |          } 
 26145 |          else 
 26146 |             return expression_generator_ 
 26147 |                       .conditional(condition, consequent, alternative); 
 26148 |       } 
 26149 |  
 26150 |       inline expression_node_ptr parse_conditional_statement_02(expression_node_ptr condition) 
 26151 |       { 
 26152 |          expression_node_ptr consequent  = error_node(); 
 26153 |          expression_node_ptr alternative = error_node(); 
 26154 |  
 26155 |          bool result = true; 
 26156 |  
 26157 |          if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) 
 26158 |          { 
 26159 |             if (0 == (consequent = parse_multi_sequence("if-statement-01"))) 
 26160 |             { 
 26161 |                set_error(make_error( 
 26162 |                   parser_error::e_syntax, 
 26163 |                   current_token(), 
 26164 |                   "ERR043 - Failed to parse body of consequent for if-statement", 
 26165 |                   exprtk_error_location)); 
 26166 |  
 26167 |                result = false; 
 26168 |             } 
 26169 |             else if 
 26170 |             ( 
 26171 |               !settings_.commutative_check_enabled()           && 
 26172 |               !token_is("else",prsrhlpr_t::e_hold)             && 
 26173 |               !token_is_loop(prsrhlpr_t::e_hold)               && 
 26174 |               !token_is_arithmetic_opr(prsrhlpr_t::e_hold)     && 
 26175 |               !token_is_right_bracket (prsrhlpr_t::e_hold)     && 
 26176 |               !token_is_ineq_opr      (prsrhlpr_t::e_hold)     && 
 26177 |               !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) && 
 26178 |               !token_is(token_t::e_eof    ,prsrhlpr_t::e_hold) 
 26179 |             ) 
 26180 |             { 
 26181 |                set_error(make_error( 
 26182 |                   parser_error::e_syntax, 
 26183 |                   current_token(), 
 26184 |                   "ERR044 - Expected ';' at the end of the consequent for if-statement (1)", 
 26185 |                   exprtk_error_location)); 
 26186 |  
 26187 |                result = false; 
 26188 |             } 
 26189 |          } 
 26190 |          else 
 26191 |          { 
 26192 |             if ( 
 26193 |                  settings_.commutative_check_enabled() && 
 26194 |                  token_is(token_t::e_mul,prsrhlpr_t::e_hold) 
 26195 |                ) 
 26196 |             { 
 26197 |                next_token(); 
 26198 |             } 
 26199 |  
 26200 |             if (0 != (consequent = parse_expression())) 
 26201 |             { 
 26202 |                if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold)) 
 26203 |                { 
 26204 |                   set_error(make_error( 
 26205 |                      parser_error::e_syntax, 
 26206 |                      current_token(), 
 26207 |                      "ERR045 - Expected ';' at the end of the consequent for if-statement (2)", 
 26208 |                      exprtk_error_location)); 
 26209 |  
 26210 |                   result = false; 
 26211 |                } 
 26212 |             } 
 26213 |             else 
 26214 |             { 
 26215 |                set_error(make_error( 
 26216 |                   parser_error::e_syntax, 
 26217 |                   current_token(), 
 26218 |                   "ERR046 - Failed to parse body of consequent for if-statement", 
 26219 |                   exprtk_error_location)); 
 26220 |  
 26221 |                result = false; 
 26222 |             } 
 26223 |          } 
 26224 |  
 26225 |          if (result) 
 26226 |          { 
 26227 |             if ( 
 26228 |                  details::imatch(current_token().value,"else") || 
 26229 |                  (token_is(token_t::e_eof, prsrhlpr_t::e_hold) && peek_token_is("else")) 
 26230 |                ) 
 26231 |             { 
 26232 |                next_token(); 
 26233 |  
 26234 |                if (details::imatch(current_token().value,"else")) 
 26235 |                { 
 26236 |                   next_token(); 
 26237 |                } 
 26238 |  
 26239 |                if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) 
 26240 |                { 
 26241 |                   if (0 == (alternative = parse_multi_sequence("else-statement-01"))) 
 26242 |                   { 
 26243 |                      set_error(make_error( 
 26244 |                         parser_error::e_syntax, 
 26245 |                         current_token(), 
 26246 |                         "ERR047 - Failed to parse body of the 'else' for if-statement", 
 26247 |                         exprtk_error_location)); 
 26248 |  
 26249 |                      result = false; 
 26250 |                   } 
 26251 |                } 
 26252 |                else if (details::imatch(current_token().value,"if")) 
 26253 |                { 
 26254 |                   if (0 == (alternative = parse_conditional_statement())) 
 26255 |                   { 
 26256 |                      set_error(make_error( 
 26257 |                         parser_error::e_syntax, 
 26258 |                         current_token(), 
 26259 |                         "ERR048 - Failed to parse body of if-else statement", 
 26260 |                         exprtk_error_location)); 
 26261 |  
 26262 |                      result = false; 
 26263 |                   } 
 26264 |                } 
 26265 |                else if (0 != (alternative = parse_expression())) 
 26266 |                { 
 26267 |                   if ( 
 26268 |                        !token_is(token_t::e_ternary    , prsrhlpr_t::e_hold) && 
 26269 |                        !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) && 
 26270 |                        !token_is(token_t::e_eof) 
 26271 |                      ) 
 26272 |                   { 
 26273 |                      set_error(make_error( 
 26274 |                         parser_error::e_syntax, 
 26275 |                         current_token(), 
 26276 |                         "ERR049 - Expected ';' at the end of the 'else-if' for the if-statement", 
 26277 |                         exprtk_error_location)); 
 26278 |  
 26279 |                      result = false; 
 26280 |                   } 
 26281 |                } 
 26282 |                else 
 26283 |                { 
 26284 |                   set_error(make_error( 
 26285 |                      parser_error::e_syntax, 
 26286 |                      current_token(), 
 26287 |                      "ERR050 - Failed to parse body of the 'else' for if-statement", 
 26288 |                      exprtk_error_location)); 
 26289 |  
 26290 |                   result = false; 
 26291 |                } 
 26292 |             } 
 26293 |          } 
 26294 |  
 26295 |          #ifndef exprtk_disable_string_capabilities 
 26296 |          if (result) 
 26297 |          { 
 26298 |             const bool consq_is_str = is_generally_string_node(consequent ); 
 26299 |             const bool alter_is_str = is_generally_string_node(alternative); 
 26300 |  
 26301 |             if (consq_is_str || alter_is_str) 
 26302 |             { 
 26303 |                if (consq_is_str && alter_is_str) 
 26304 |                { 
 26305 |                   return expression_generator_ 
 26306 |                            .conditional_string(condition, consequent, alternative); 
 26307 |                } 
 26308 |  
 26309 |                set_error(make_error( 
 26310 |                   parser_error::e_syntax, 
 26311 |                   current_token(), 
 26312 |                   "ERR051 - Return types of if-statement differ: string/non-string", 
 26313 |                   exprtk_error_location)); 
 26314 |  
 26315 |                result = false; 
 26316 |             } 
 26317 |          } 
 26318 |          #endif 
 26319 |  
 26320 |          if (result) 
 26321 |          { 
 26322 |             const bool consq_is_vec = is_ivector_node(consequent ); 
 26323 |             const bool alter_is_vec = is_ivector_node(alternative); 
 26324 |  
 26325 |             if (consq_is_vec || alter_is_vec) 
 26326 |             { 
 26327 |                if (consq_is_vec && alter_is_vec) 
 26328 |                { 
 26329 |                   return expression_generator_ 
 26330 |                            .conditional_vector(condition, consequent, alternative); 
 26331 |                } 
 26332 |  
 26333 |                set_error(make_error( 
 26334 |                   parser_error::e_syntax, 
 26335 |                   current_token(), 
 26336 |                   "ERR052 - Return types of if-statement differ: vector/non-vector", 
 26337 |                   exprtk_error_location)); 
 26338 |  
 26339 |                result = false; 
 26340 |             } 
 26341 |          } 
 26342 |  
 26343 |          if (!result) 
 26344 |          { 
 26345 |             free_node(node_allocator_, condition  ); 
 26346 |             free_node(node_allocator_, consequent ); 
 26347 |             free_node(node_allocator_, alternative); 
 26348 |  
 26349 |             return error_node(); 
 26350 |          } 
 26351 |          else 
 26352 |             return expression_generator_ 
 26353 |                       .conditional(condition, consequent, alternative); 
 26354 |       } 
 26355 |  
 26356 |       inline expression_node_ptr parse_conditional_statement() 
 26357 |       { 
 26358 |          expression_node_ptr condition = error_node(); 
 26359 |  
 26360 |          next_token(); 
 26361 |  
 26362 |          if (!token_is(token_t::e_lbracket)) 
 26363 |          { 
 26364 |             set_error(make_error( 
 26365 |                parser_error::e_syntax, 
 26366 |                current_token(), 
 26367 |                "ERR053 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'", 
 26368 |                exprtk_error_location)); 
 26369 |  
 26370 |             return error_node(); 
 26371 |          } 
 26372 |          else if (0 == (condition = parse_expression())) 
 26373 |          { 
 26374 |             set_error(make_error( 
 26375 |                parser_error::e_syntax, 
 26376 |                current_token(), 
 26377 |                "ERR054 - Failed to parse condition for if-statement", 
 26378 |                exprtk_error_location)); 
 26379 |  
 26380 |             return error_node(); 
 26381 |          } 
 26382 |          else if (token_is(token_t::e_comma,prsrhlpr_t::e_hold)) 
 26383 |          { 
 26384 |             // if (x,y,z) 
 26385 |             return parse_conditional_statement_01(condition); 
 26386 |          } 
 26387 |          else if (token_is(token_t::e_rbracket)) 
 26388 |          { 
 26389 |             /* 
 26390 |                00. if (x) y; 
 26391 |                01. if (x) y; else z; 
 26392 |                02. if (x) y; else {z0; ... zn;} 
 26393 |                03. if (x) y; else if (z) w; 
 26394 |                04. if (x) y; else if (z) w; else u; 
 26395 |                05. if (x) y; else if (z) w; else {u0; ... un;} 
 26396 |                06. if (x) y; else if (z) {w0; ... wn;} 
 26397 |                07. if (x) {y0; ... yn;} 
 26398 |                08. if (x) {y0; ... yn;} else z; 
 26399 |                09. if (x) {y0; ... yn;} else {z0; ... zn;}; 
 26400 |                10. if (x) {y0; ... yn;} else if (z) w; 
 26401 |                11. if (x) {y0; ... yn;} else if (z) w; else u; 
 26402 |                12. if (x) {y0; ... nex;} else if (z) w; else {u0 ... un;} 
 26403 |                13. if (x) {y0; ... yn;} else if (z) {w0; ... wn;} 
 26404 |             */ 
 26405 |             return parse_conditional_statement_02(condition); 
 26406 |          } 
 26407 |  
 26408 |          set_error(make_error( 
 26409 |             parser_error::e_syntax, 
 26410 |             current_token(), 
 26411 |             "ERR055 - Invalid if-statement", 
 26412 |             exprtk_error_location)); 
 26413 |  
 26414 |          free_node(node_allocator_, condition); 
 26415 |  
 26416 |          return error_node(); 
 26417 |       } 
 26418 |  
 26419 |       inline expression_node_ptr parse_ternary_conditional_statement(expression_node_ptr condition) 
 26420 |       { 
 26421 |          // Parse: [condition][?][consequent][:][alternative] 
 26422 |          expression_node_ptr consequent  = error_node(); 
 26423 |          expression_node_ptr alternative = error_node(); 
 26424 |  
 26425 |          bool result = true; 
 26426 |  
 26427 |          if (0 == condition) 
 26428 |          { 
 26429 |             set_error(make_error( 
 26430 |                parser_error::e_syntax, 
 26431 |                current_token(), 
 26432 |                "ERR056 - Encountered invalid condition branch for ternary if-statement", 
 26433 |                exprtk_error_location)); 
 26434 |  
 26435 |             return error_node(); 
 26436 |          } 
 26437 |          else if (!token_is(token_t::e_ternary)) 
 26438 |          { 
 26439 |             set_error(make_error( 
 26440 |                parser_error::e_syntax, 
 26441 |                current_token(), 
 26442 |                "ERR057 - Expected '?' after condition of ternary if-statement", 
 26443 |                exprtk_error_location)); 
 26444 |  
 26445 |             result = false; 
 26446 |          } 
 26447 |          else if (0 == (consequent = parse_expression())) 
 26448 |          { 
 26449 |             set_error(make_error( 
 26450 |                parser_error::e_syntax, 
 26451 |                current_token(), 
 26452 |                "ERR058 - Failed to parse consequent for ternary if-statement", 
 26453 |                exprtk_error_location)); 
 26454 |  
 26455 |             result = false; 
 26456 |          } 
 26457 |          else if (!token_is(token_t::e_colon)) 
 26458 |          { 
 26459 |             set_error(make_error( 
 26460 |                parser_error::e_syntax, 
 26461 |                current_token(), 
 26462 |                "ERR059 - Expected ':' between ternary if-statement consequent and alternative", 
 26463 |                exprtk_error_location)); 
 26464 |  
 26465 |             result = false; 
 26466 |          } 
 26467 |          else if (0 == (alternative = parse_expression())) 
 26468 |          { 
 26469 |             set_error(make_error( 
 26470 |                parser_error::e_syntax, 
 26471 |                current_token(), 
 26472 |                "ERR060 - Failed to parse alternative for ternary if-statement", 
 26473 |                exprtk_error_location)); 
 26474 |  
 26475 |             result = false; 
 26476 |          } 
 26477 |  
 26478 |          #ifndef exprtk_disable_string_capabilities 
 26479 |          if (result) 
 26480 |          { 
 26481 |             const bool consq_is_str = is_generally_string_node(consequent ); 
 26482 |             const bool alter_is_str = is_generally_string_node(alternative); 
 26483 |  
 26484 |             if (consq_is_str || alter_is_str) 
 26485 |             { 
 26486 |                if (consq_is_str && alter_is_str) 
 26487 |                { 
 26488 |                   return expression_generator_ 
 26489 |                            .conditional_string(condition, consequent, alternative); 
 26490 |                } 
 26491 |  
 26492 |                set_error(make_error( 
 26493 |                   parser_error::e_syntax, 
 26494 |                   current_token(), 
 26495 |                   "ERR061 - Return types of ternary differ: string/non-string", 
 26496 |                   exprtk_error_location)); 
 26497 |  
 26498 |                result = false; 
 26499 |             } 
 26500 |          } 
 26501 |          #endif 
 26502 |  
 26503 |          if (result) 
 26504 |          { 
 26505 |             const bool consq_is_vec = is_ivector_node(consequent ); 
 26506 |             const bool alter_is_vec = is_ivector_node(alternative); 
 26507 |  
 26508 |             if (consq_is_vec || alter_is_vec) 
 26509 |             { 
 26510 |                if (consq_is_vec && alter_is_vec) 
 26511 |                { 
 26512 |                   return expression_generator_ 
 26513 |                            .conditional_vector(condition, consequent, alternative); 
 26514 |                } 
 26515 |  
 26516 |                set_error(make_error( 
 26517 |                   parser_error::e_syntax, 
 26518 |                   current_token(), 
 26519 |                   "ERR062 - Return types of ternary differ: vector/non-vector", 
 26520 |                   exprtk_error_location)); 
 26521 |  
 26522 |                result = false; 
 26523 |             } 
 26524 |          } 
 26525 |  
 26526 |          if (!result) 
 26527 |          { 
 26528 |             free_node(node_allocator_, condition  ); 
 26529 |             free_node(node_allocator_, consequent ); 
 26530 |             free_node(node_allocator_, alternative); 
 26531 |  
 26532 |             return error_node(); 
 26533 |          } 
 26534 |          else 
 26535 |             return expression_generator_ 
 26536 |                       .conditional(condition, consequent, alternative); 
 26537 |       } 
 26538 |  
 26539 |       inline expression_node_ptr parse_not_statement() 
 26540 |       { 
 26541 |          if (settings_.logic_disabled("not")) 
 26542 |          { 
 26543 |             set_error(make_error( 
 26544 |                parser_error::e_syntax, 
 26545 |                current_token(), 
 26546 |                "ERR063 - Invalid or disabled logic operation 'not'", 
 26547 |                exprtk_error_location)); 
 26548 |  
 26549 |             return error_node(); 
 26550 |          } 
 26551 |  
 26552 |          return parse_base_operation(); 
 26553 |       } 
 26554 |  
 26555 |       void handle_brkcnt_scope_exit() 
 26556 |       { 
 26557 |          assert(!brkcnt_list_.empty()); 
 26558 |          brkcnt_list_.pop_front(); 
 26559 |       } 
 26560 |  
 26561 |       inline expression_node_ptr parse_while_loop() 
 26562 |       { 
 26563 |          // Parse: [while][(][test expr][)][{][expression][}] 
 26564 |          expression_node_ptr condition   = error_node(); 
 26565 |          expression_node_ptr branch      = error_node(); 
 26566 |          expression_node_ptr result_node = error_node(); 
 26567 |  
 26568 |          bool result = true; 
 26569 |  
 26570 |          next_token(); 
 26571 |  
 26572 |          if (!token_is(token_t::e_lbracket)) 
 26573 |          { 
 26574 |             set_error(make_error( 
 26575 |                parser_error::e_syntax, 
 26576 |                current_token(), 
 26577 |                "ERR064 - Expected '(' at start of while-loop condition statement", 
 26578 |                exprtk_error_location)); 
 26579 |  
 26580 |             return error_node(); 
 26581 |          } 
 26582 |          else if (0 == (condition = parse_expression())) 
 26583 |          { 
 26584 |             set_error(make_error( 
 26585 |                parser_error::e_syntax, 
 26586 |                current_token(), 
 26587 |                "ERR065 - Failed to parse condition for while-loop", 
 26588 |                exprtk_error_location)); 
 26589 |  
 26590 |             return error_node(); 
 26591 |          } 
 26592 |          else if (!token_is(token_t::e_rbracket)) 
 26593 |          { 
 26594 |             set_error(make_error( 
 26595 |                parser_error::e_syntax, 
 26596 |                current_token(), 
 26597 |                "ERR066 - Expected ')' at end of while-loop condition statement", 
 26598 |                exprtk_error_location)); 
 26599 |  
 26600 |             result = false; 
 26601 |          } 
 26602 |  
 26603 |          brkcnt_list_.push_front(false); 
 26604 |  
 26605 |          if (result) 
 26606 |          { 
 26607 |             scoped_inc_dec sid(state_.parsing_loop_stmt_count); 
 26608 |  
 26609 |             if (0 == (branch = parse_multi_sequence("while-loop", true))) 
 26610 |             { 
 26611 |                set_error(make_error( 
 26612 |                   parser_error::e_syntax, 
 26613 |                   current_token(), 
 26614 |                   "ERR067 - Failed to parse body of while-loop")); 
 26615 |                result = false; 
 26616 |             } 
 26617 |             else if (0 == (result_node = expression_generator_.while_loop(condition, 
 26618 |                                                                           branch, 
 26619 |                                                                           brkcnt_list_.front()))) 
 26620 |             { 
 26621 |                set_error(make_error( 
 26622 |                   parser_error::e_syntax, 
 26623 |                   current_token(), 
 26624 |                   "ERR068 - Failed to synthesize while-loop", 
 26625 |                   exprtk_error_location)); 
 26626 |  
 26627 |                result = false; 
 26628 |             } 
 26629 |          } 
 26630 |  
 26631 |          handle_brkcnt_scope_exit(); 
 26632 |  
 26633 |          if (!result) 
 26634 |          { 
 26635 |             free_node(node_allocator_, branch     ); 
 26636 |             free_node(node_allocator_, condition  ); 
 26637 |             free_node(node_allocator_, result_node); 
 26638 |  
 26639 |             return error_node(); 
 26640 |          } 
 26641 |  
 26642 |          if (result_node && result_node->valid()) 
 26643 |          { 
 26644 |             return result_node; 
 26645 |          } 
 26646 |  
 26647 |          set_error(make_error( 
 26648 |             parser_error::e_synthesis, 
 26649 |             current_token(), 
 26650 |             "ERR069 - Failed to synthesize 'valid' while-loop", 
 26651 |             exprtk_error_location)); 
 26652 |  
 26653 |          free_node(node_allocator_, result_node); 
 26654 |  
 26655 |          return error_node(); 
 26656 |       } 
 26657 |  
 26658 |       inline expression_node_ptr parse_repeat_until_loop() 
 26659 |       { 
 26660 |          // Parse: [repeat][{][expression][}][until][(][test expr][)] 
 26661 |          expression_node_ptr condition = error_node(); 
 26662 |          expression_node_ptr branch    = error_node(); 
 26663 |          next_token(); 
 26664 |  
 26665 |          std::vector<expression_node_ptr> arg_list; 
 26666 |          std::vector<bool> side_effect_list; 
 26667 |  
 26668 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 26669 |  
 26670 |          brkcnt_list_.push_front(false); 
 26671 |  
 26672 |          if (details::imatch(current_token().value,"until")) 
 26673 |          { 
 26674 |             next_token(); 
 26675 |             branch = node_allocator_.allocate<details::null_node<T> >(); 
 26676 |          } 
 26677 |          else 
 26678 |          { 
 26679 |             const token_t::token_type separator = token_t::e_eof; 
 26680 |  
 26681 |             scope_handler sh(*this); 
 26682 |  
 26683 |             scoped_bool_or_restorer sbr(state_.side_effect_present); 
 26684 |  
 26685 |             scoped_inc_dec sid(state_.parsing_loop_stmt_count); 
 26686 |  
 26687 |             for ( ; ; ) 
 26688 |             { 
 26689 |                state_.side_effect_present = false; 
 26690 |  
 26691 |                expression_node_ptr arg = parse_expression(); 
 26692 |  
 26693 |                if (0 == arg) 
 26694 |                   return error_node(); 
 26695 |                else 
 26696 |                { 
 26697 |                   arg_list.push_back(arg); 
 26698 |                   side_effect_list.push_back(state_.side_effect_present); 
 26699 |                } 
 26700 |  
 26701 |                if (details::imatch(current_token().value,"until")) 
 26702 |                { 
 26703 |                   next_token(); 
 26704 |                   break; 
 26705 |                } 
 26706 |  
 26707 |                const bool is_next_until = peek_token_is(token_t::e_symbol) && 
 26708 |                                           peek_token_is("until"); 
 26709 |  
 26710 |                if (!token_is(separator) && is_next_until) 
 26711 |                { 
 26712 |                   set_error(make_error( 
 26713 |                      parser_error::e_syntax, 
 26714 |                      current_token(), 
 26715 |                      "ERR070 - Expected '" + token_t::to_str(separator) + "' in body of repeat until loop", 
 26716 |                      exprtk_error_location)); 
 26717 |  
 26718 |                   return error_node(); 
 26719 |                } 
 26720 |  
 26721 |                if (details::imatch(current_token().value,"until")) 
 26722 |                { 
 26723 |                   next_token(); 
 26724 |                   break; 
 26725 |                } 
 26726 |             } 
 26727 |  
 26728 |             branch = simplify(arg_list,side_effect_list); 
 26729 |  
 26730 |             sdd.delete_ptr = (0 == branch); 
 26731 |  
 26732 |             if (sdd.delete_ptr) 
 26733 |             { 
 26734 |                set_error(make_error( 
 26735 |                   parser_error::e_syntax, 
 26736 |                   current_token(), 
 26737 |                   "ERR071 - Failed to parse body of repeat until loop", 
 26738 |                   exprtk_error_location)); 
 26739 |  
 26740 |                return error_node(); 
 26741 |             } 
 26742 |          } 
 26743 |  
 26744 |          if (!token_is(token_t::e_lbracket)) 
 26745 |          { 
 26746 |             set_error(make_error( 
 26747 |                parser_error::e_syntax, 
 26748 |                current_token(), 
 26749 |                "ERR072 - Expected '(' before condition statement of repeat until loop", 
 26750 |                exprtk_error_location)); 
 26751 |  
 26752 |             free_node(node_allocator_, branch); 
 26753 |             return error_node(); 
 26754 |          } 
 26755 |          else if (0 == (condition = parse_expression())) 
 26756 |          { 
 26757 |             set_error(make_error( 
 26758 |                parser_error::e_syntax, 
 26759 |                current_token(), 
 26760 |                "ERR073 - Failed to parse condition for repeat until loop", 
 26761 |                exprtk_error_location)); 
 26762 |  
 26763 |             free_node(node_allocator_, branch); 
 26764 |             return error_node(); 
 26765 |          } 
 26766 |          else if (!token_is(token_t::e_rbracket)) 
 26767 |          { 
 26768 |             set_error(make_error( 
 26769 |                parser_error::e_syntax, 
 26770 |                current_token(), 
 26771 |                "ERR074 - Expected ')' after condition of repeat until loop", 
 26772 |                exprtk_error_location)); 
 26773 |  
 26774 |             free_node(node_allocator_, branch   ); 
 26775 |             free_node(node_allocator_, condition); 
 26776 |  
 26777 |             return error_node(); 
 26778 |          } 
 26779 |  
 26780 |          expression_node_ptr result_node = 
 26781 |             expression_generator_ 
 26782 |                .repeat_until_loop( 
 26783 |                   condition, 
 26784 |                   branch, 
 26785 |                   brkcnt_list_.front()); 
 26786 |  
 26787 |          if (0 == result_node) 
 26788 |          { 
 26789 |             set_error(make_error( 
 26790 |                parser_error::e_syntax, 
 26791 |                current_token(), 
 26792 |                "ERR075 - Failed to synthesize repeat until loop", 
 26793 |                exprtk_error_location)); 
 26794 |  
 26795 |             free_node(node_allocator_, condition); 
 26796 |  
 26797 |             return error_node(); 
 26798 |          } 
 26799 |  
 26800 |          handle_brkcnt_scope_exit(); 
 26801 |  
 26802 |          if (result_node && result_node->valid()) 
 26803 |          { 
 26804 |             return result_node; 
 26805 |          } 
 26806 |  
 26807 |          set_error(make_error( 
 26808 |             parser_error::e_synthesis, 
 26809 |             current_token(), 
 26810 |             "ERR076 - Failed to synthesize 'valid' repeat until loop", 
 26811 |             exprtk_error_location)); 
 26812 |  
 26813 |          free_node(node_allocator_, result_node); 
 26814 |  
 26815 |          return error_node(); 
 26816 |       } 
 26817 |  
 26818 |       inline expression_node_ptr parse_for_loop() 
 26819 |       { 
 26820 |          expression_node_ptr initialiser = error_node(); 
 26821 |          expression_node_ptr condition   = error_node(); 
 26822 |          expression_node_ptr incrementor = error_node(); 
 26823 |          expression_node_ptr loop_body   = error_node(); 
 26824 |  
 26825 |          scope_element* se = 0; 
 26826 |          bool result       = true; 
 26827 |  
 26828 |          next_token(); 
 26829 |  
 26830 |          scope_handler sh(*this); 
 26831 |  
 26832 |          if (!token_is(token_t::e_lbracket)) 
 26833 |          { 
 26834 |             set_error(make_error( 
 26835 |                parser_error::e_syntax, 
 26836 |                current_token(), 
 26837 |                "ERR077 - Expected '(' at start of for-loop", 
 26838 |                exprtk_error_location)); 
 26839 |  
 26840 |             return error_node(); 
 26841 |          } 
 26842 |  
 26843 |          if (!token_is(token_t::e_eof)) 
 26844 |          { 
 26845 |             if ( 
 26846 |                  !token_is(token_t::e_symbol,prsrhlpr_t::e_hold) && 
 26847 |                  details::imatch(current_token().value,"var") 
 26848 |                ) 
 26849 |             { 
 26850 |                next_token(); 
 26851 |  
 26852 |                if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) 
 26853 |                { 
 26854 |                   set_error(make_error( 
 26855 |                      parser_error::e_syntax, 
 26856 |                      current_token(), 
 26857 |                      "ERR078 - Expected a variable at the start of initialiser section of for-loop", 
 26858 |                      exprtk_error_location)); 
 26859 |  
 26860 |                   return error_node(); 
 26861 |                } 
 26862 |                else if (!peek_token_is(token_t::e_assign)) 
 26863 |                { 
 26864 |                   set_error(make_error( 
 26865 |                      parser_error::e_syntax, 
 26866 |                      current_token(), 
 26867 |                      "ERR079 - Expected variable assignment of initialiser section of for-loop", 
 26868 |                      exprtk_error_location)); 
 26869 |  
 26870 |                   return error_node(); 
 26871 |                } 
 26872 |  
 26873 |                const std::string loop_counter_symbol = current_token().value; 
 26874 |  
 26875 |                se = &sem_.get_element(loop_counter_symbol); 
 26876 |  
 26877 |                if ((se->name == loop_counter_symbol) && se->active) 
 26878 |                { 
 26879 |                   set_error(make_error( 
 26880 |                      parser_error::e_syntax, 
 26881 |                      current_token(), 
 26882 |                      "ERR080 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration", 
 26883 |                      exprtk_error_location)); 
 26884 |  
 26885 |                   return error_node(); 
 26886 |                } 
 26887 |                else if (!symtab_store_.is_variable(loop_counter_symbol)) 
 26888 |                { 
 26889 |                   if ( 
 26890 |                        !se->active && 
 26891 |                        (se->name == loop_counter_symbol) && 
 26892 |                        (se->type == scope_element::e_variable) 
 26893 |                      ) 
 26894 |                   { 
 26895 |                      se->active = true; 
 26896 |                      se->ref_count++; 
 26897 |                   } 
 26898 |                   else 
 26899 |                   { 
 26900 |                      scope_element nse; 
 26901 |                      nse.name      = loop_counter_symbol; 
 26902 |                      nse.active    = true; 
 26903 |                      nse.ref_count = 1; 
 26904 |                      nse.type      = scope_element::e_variable; 
 26905 |                      nse.depth     = state_.scope_depth; 
 26906 |                      nse.data      = new T(T(0)); 
 26907 |                      nse.var_node  = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data)); 
 26908 |  
 26909 |                      if (!sem_.add_element(nse)) 
 26910 |                      { 
 26911 |                         set_error(make_error( 
 26912 |                            parser_error::e_syntax, 
 26913 |                            current_token(), 
 26914 |                            "ERR081 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM", 
 26915 |                            exprtk_error_location)); 
 26916 |  
 26917 |                         sem_.free_element(nse); 
 26918 |  
 26919 |                         result = false; 
 26920 |                      } 
 26921 |                      else 
 26922 |                      { 
 26923 |                         exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n", nse.name.c_str())); 
 26924 |  
 26925 |                         state_.activate_side_effect("parse_for_loop()"); 
 26926 |                      } 
 26927 |                   } 
 26928 |                } 
 26929 |             } 
 26930 |  
 26931 |             if (0 == (initialiser = parse_expression())) 
 26932 |             { 
 26933 |                set_error(make_error( 
 26934 |                   parser_error::e_syntax, 
 26935 |                   current_token(), 
 26936 |                   "ERR082 - Failed to parse initialiser of for-loop", 
 26937 |                   exprtk_error_location)); 
 26938 |  
 26939 |                result = false; 
 26940 |             } 
 26941 |             else if (!token_is(token_t::e_eof)) 
 26942 |             { 
 26943 |                set_error(make_error( 
 26944 |                   parser_error::e_syntax, 
 26945 |                   current_token(), 
 26946 |                   "ERR083 - Expected ';' after initialiser of for-loop", 
 26947 |                   exprtk_error_location)); 
 26948 |  
 26949 |                result = false; 
 26950 |             } 
 26951 |          } 
 26952 |  
 26953 |          if (!token_is(token_t::e_eof)) 
 26954 |          { 
 26955 |             if (0 == (condition = parse_expression())) 
 26956 |             { 
 26957 |                set_error(make_error( 
 26958 |                   parser_error::e_syntax, 
 26959 |                   current_token(), 
 26960 |                   "ERR084 - Failed to parse condition of for-loop", 
 26961 |                   exprtk_error_location)); 
 26962 |  
 26963 |                result = false; 
 26964 |             } 
 26965 |             else if (!token_is(token_t::e_eof)) 
 26966 |             { 
 26967 |                set_error(make_error( 
 26968 |                   parser_error::e_syntax, 
 26969 |                   current_token(), 
 26970 |                   "ERR085 - Expected ';' after condition section of for-loop", 
 26971 |                   exprtk_error_location)); 
 26972 |  
 26973 |                result = false; 
 26974 |             } 
 26975 |          } 
 26976 |  
 26977 |          if (!token_is(token_t::e_rbracket)) 
 26978 |          { 
 26979 |             if (0 == (incrementor = parse_expression())) 
 26980 |             { 
 26981 |                set_error(make_error( 
 26982 |                   parser_error::e_syntax, 
 26983 |                   current_token(), 
 26984 |                   "ERR086 - Failed to parse incrementor of for-loop", 
 26985 |                   exprtk_error_location)); 
 26986 |  
 26987 |                result = false; 
 26988 |             } 
 26989 |             else if (!token_is(token_t::e_rbracket)) 
 26990 |             { 
 26991 |                set_error(make_error( 
 26992 |                   parser_error::e_syntax, 
 26993 |                   current_token(), 
 26994 |                   "ERR087 - Expected ')' after incrementor section of for-loop", 
 26995 |                   exprtk_error_location)); 
 26996 |  
 26997 |                result = false; 
 26998 |             } 
 26999 |          } 
 27000 |  
 27001 |          if (result) 
 27002 |          { 
 27003 |             brkcnt_list_.push_front(false); 
 27004 |  
 27005 |             scoped_inc_dec sid(state_.parsing_loop_stmt_count); 
 27006 |  
 27007 |             if (0 == (loop_body = parse_multi_sequence("for-loop", true))) 
 27008 |             { 
 27009 |                set_error(make_error( 
 27010 |                   parser_error::e_syntax, 
 27011 |                   current_token(), 
 27012 |                   "ERR088 - Failed to parse body of for-loop", 
 27013 |                   exprtk_error_location)); 
 27014 |  
 27015 |                result = false; 
 27016 |             } 
 27017 |          } 
 27018 |  
 27019 |          if (!result) 
 27020 |          { 
 27021 |             if (se) 
 27022 |             { 
 27023 |                se->ref_count--; 
 27024 |             } 
 27025 |  
 27026 |             free_node(node_allocator_, initialiser); 
 27027 |             free_node(node_allocator_, condition  ); 
 27028 |             free_node(node_allocator_, incrementor); 
 27029 |             free_node(node_allocator_, loop_body  ); 
 27030 |             return error_node(); 
 27031 |          } 
 27032 |  
 27033 |          expression_node_ptr result_node = 
 27034 |             expression_generator_.for_loop(initialiser, 
 27035 |                                            condition, 
 27036 |                                            incrementor, 
 27037 |                                            loop_body, 
 27038 |                                            brkcnt_list_.front()); 
 27039 |          handle_brkcnt_scope_exit(); 
 27040 |  
 27041 |          if (result_node && result_node->valid()) 
 27042 |          { 
 27043 |             return result_node; 
 27044 |          } 
 27045 |  
 27046 |          set_error(make_error( 
 27047 |             parser_error::e_synthesis, 
 27048 |             current_token(), 
 27049 |             "ERR089 - Failed to synthesize 'valid' for-loop", 
 27050 |             exprtk_error_location)); 
 27051 |  
 27052 |          free_node(node_allocator_, result_node); 
 27053 |  
 27054 |          return error_node(); 
 27055 |       } 
 27056 |  
 27057 |       inline expression_node_ptr parse_switch_statement() 
 27058 |       { 
 27059 |          std::vector<expression_node_ptr> arg_list; 
 27060 |          expression_node_ptr result = error_node(); 
 27061 |  
 27062 |          if (!details::imatch(current_token().value,"switch")) 
 27063 |          { 
 27064 |             set_error(make_error( 
 27065 |                parser_error::e_syntax, 
 27066 |                current_token(), 
 27067 |                "ERR090 - Expected keyword 'switch'", 
 27068 |                exprtk_error_location)); 
 27069 |  
 27070 |             return error_node(); 
 27071 |          } 
 27072 |  
 27073 |          scoped_vec_delete<expression_node_t> svd((*this),arg_list); 
 27074 |  
 27075 |          next_token(); 
 27076 |  
 27077 |          if (!token_is(token_t::e_lcrlbracket)) 
 27078 |          { 
 27079 |             set_error(make_error( 
 27080 |                parser_error::e_syntax, 
 27081 |                current_token(), 
 27082 |                "ERR091 - Expected '{' for call to switch statement", 
 27083 |                exprtk_error_location)); 
 27084 |  
 27085 |             return error_node(); 
 27086 |          } 
 27087 |  
 27088 |          expression_node_ptr default_statement = error_node(); 
 27089 |  
 27090 |          scoped_expression_delete defstmt_delete((*this), default_statement); 
 27091 |  
 27092 |          for ( ; ; ) 
 27093 |          { 
 27094 |             if (details::imatch("case",current_token().value)) 
 27095 |             { 
 27096 |                next_token(); 
 27097 |  
 27098 |                expression_node_ptr condition = parse_expression(); 
 27099 |  
 27100 |                if (0 == condition) 
 27101 |                   return error_node(); 
 27102 |                else if (!token_is(token_t::e_colon)) 
 27103 |                { 
 27104 |                   set_error(make_error( 
 27105 |                      parser_error::e_syntax, 
 27106 |                      current_token(), 
 27107 |                      "ERR092 - Expected ':' for case of switch statement", 
 27108 |                      exprtk_error_location)); 
 27109 |  
 27110 |                   free_node(node_allocator_, condition); 
 27111 |  
 27112 |                   return error_node(); 
 27113 |                } 
 27114 |  
 27115 |                expression_node_ptr consequent = 
 27116 |                   (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? 
 27117 |                   parse_multi_sequence("switch-consequent") : 
 27118 |                   parse_expression(); 
 27119 |  
 27120 |                if (0 == consequent) 
 27121 |                { 
 27122 |                   free_node(node_allocator_, condition); 
 27123 |  
 27124 |                   return error_node(); 
 27125 |                } 
 27126 |                else if (!token_is(token_t::e_eof)) 
 27127 |                { 
 27128 |                   set_error(make_error( 
 27129 |                      parser_error::e_syntax, 
 27130 |                      current_token(), 
 27131 |                      "ERR093 - Expected ';' at end of case for switch statement", 
 27132 |                      exprtk_error_location)); 
 27133 |  
 27134 |                   free_node(node_allocator_, condition ); 
 27135 |                   free_node(node_allocator_, consequent); 
 27136 |  
 27137 |                   return error_node(); 
 27138 |                } 
 27139 |  
 27140 |                // Can we optimise away the case statement? 
 27141 |                if (is_constant_node(condition) && is_false(condition)) 
 27142 |                { 
 27143 |                   free_node(node_allocator_, condition ); 
 27144 |                   free_node(node_allocator_, consequent); 
 27145 |                } 
 27146 |                else 
 27147 |                { 
 27148 |                   arg_list.push_back(condition ); 
 27149 |                   arg_list.push_back(consequent); 
 27150 |                } 
 27151 |  
 27152 |             } 
 27153 |             else if (details::imatch("default",current_token().value)) 
 27154 |             { 
 27155 |                if (0 != default_statement) 
 27156 |                { 
 27157 |                   set_error(make_error( 
 27158 |                      parser_error::e_syntax, 
 27159 |                      current_token(), 
 27160 |                      "ERR094 - Multiple default cases for switch statement", 
 27161 |                      exprtk_error_location)); 
 27162 |  
 27163 |                   return error_node(); 
 27164 |                } 
 27165 |  
 27166 |                next_token(); 
 27167 |  
 27168 |                if (!token_is(token_t::e_colon)) 
 27169 |                { 
 27170 |                   set_error(make_error( 
 27171 |                      parser_error::e_syntax, 
 27172 |                      current_token(), 
 27173 |                      "ERR095 - Expected ':' for default of switch statement", 
 27174 |                      exprtk_error_location)); 
 27175 |  
 27176 |                   return error_node(); 
 27177 |                } 
 27178 |  
 27179 |                default_statement = 
 27180 |                   (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? 
 27181 |                   parse_multi_sequence("switch-default"): 
 27182 |                   parse_expression(); 
 27183 |  
 27184 |                if (0 == default_statement) 
 27185 |                   return error_node(); 
 27186 |                else if (!token_is(token_t::e_eof)) 
 27187 |                { 
 27188 |                   set_error(make_error( 
 27189 |                      parser_error::e_syntax, 
 27190 |                      current_token(), 
 27191 |                      "ERR096 - Expected ';' at end of default for switch statement", 
 27192 |                      exprtk_error_location)); 
 27193 |  
 27194 |                   return error_node(); 
 27195 |                } 
 27196 |             } 
 27197 |             else if (token_is(token_t::e_rcrlbracket)) 
 27198 |                break; 
 27199 |             else 
 27200 |             { 
 27201 |                set_error(make_error( 
 27202 |                   parser_error::e_syntax, 
 27203 |                   current_token(), 
 27204 |                   "ERR097 - Expected '}' at end of switch statement", 
 27205 |                   exprtk_error_location)); 
 27206 |  
 27207 |                return error_node(); 
 27208 |             } 
 27209 |          } 
 27210 |  
 27211 |          const bool default_statement_present = (0 != default_statement); 
 27212 |  
 27213 |          if (default_statement_present) 
 27214 |          { 
 27215 |             arg_list.push_back(default_statement); 
 27216 |          } 
 27217 |          else 
 27218 |          { 
 27219 |             arg_list.push_back(node_allocator_.allocate_c<literal_node_t>(std::numeric_limits<T>::quiet_NaN())); 
 27220 |          } 
 27221 |  
 27222 |          result = expression_generator_.switch_statement(arg_list, (0 != default_statement)); 
 27223 |  
 27224 |          svd.delete_ptr = (0 == result); 
 27225 |          defstmt_delete.delete_ptr = (0 == result); 
 27226 |  
 27227 |          return result; 
 27228 |       } 
 27229 |  
 27230 |       inline expression_node_ptr parse_multi_switch_statement() 
 27231 |       { 
 27232 |          std::vector<expression_node_ptr> arg_list; 
 27233 |  
 27234 |          if (!details::imatch(current_token().value,"[*]")) 
 27235 |          { 
 27236 |             set_error(make_error( 
 27237 |                parser_error::e_syntax, 
 27238 |                current_token(), 
 27239 |                "ERR098 - Expected token '[*]'", 
 27240 |                exprtk_error_location)); 
 27241 |  
 27242 |             return error_node(); 
 27243 |          } 
 27244 |  
 27245 |          scoped_vec_delete<expression_node_t> svd((*this),arg_list); 
 27246 |  
 27247 |          next_token(); 
 27248 |  
 27249 |          if (!token_is(token_t::e_lcrlbracket)) 
 27250 |          { 
 27251 |             set_error(make_error( 
 27252 |                parser_error::e_syntax, 
 27253 |                current_token(), 
 27254 |                "ERR099 - Expected '{' for call to [*] statement", 
 27255 |                exprtk_error_location)); 
 27256 |  
 27257 |             return error_node(); 
 27258 |          } 
 27259 |  
 27260 |          for ( ; ; ) 
 27261 |          { 
 27262 |             if (!details::imatch("case",current_token().value)) 
 27263 |             { 
 27264 |                set_error(make_error( 
 27265 |                   parser_error::e_syntax, 
 27266 |                   current_token(), 
 27267 |                   "ERR100 - Expected a 'case' statement for multi-switch", 
 27268 |                   exprtk_error_location)); 
 27269 |  
 27270 |                return error_node(); 
 27271 |             } 
 27272 |  
 27273 |             next_token(); 
 27274 |  
 27275 |             expression_node_ptr condition = parse_expression(); 
 27276 |  
 27277 |             if (0 == condition) 
 27278 |                return error_node(); 
 27279 |  
 27280 |             if (!token_is(token_t::e_colon)) 
 27281 |             { 
 27282 |                set_error(make_error( 
 27283 |                   parser_error::e_syntax, 
 27284 |                   current_token(), 
 27285 |                   "ERR101 - Expected ':' for case of [*] statement", 
 27286 |                   exprtk_error_location)); 
 27287 |  
 27288 |                return error_node(); 
 27289 |             } 
 27290 |  
 27291 |             expression_node_ptr consequent = 
 27292 |                (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? 
 27293 |                parse_multi_sequence("multi-switch-consequent") : 
 27294 |                parse_expression(); 
 27295 |  
 27296 |             if (0 == consequent) 
 27297 |                return error_node(); 
 27298 |  
 27299 |             if (!token_is(token_t::e_eof)) 
 27300 |             { 
 27301 |                set_error(make_error( 
 27302 |                   parser_error::e_syntax, 
 27303 |                   current_token(), 
 27304 |                   "ERR102 - Expected ';' at end of case for [*] statement", 
 27305 |                   exprtk_error_location)); 
 27306 |  
 27307 |                return error_node(); 
 27308 |             } 
 27309 |  
 27310 |             // Can we optimise away the case statement? 
 27311 |             if (is_constant_node(condition) && is_false(condition)) 
 27312 |             { 
 27313 |                free_node(node_allocator_, condition ); 
 27314 |                free_node(node_allocator_, consequent); 
 27315 |             } 
 27316 |             else 
 27317 |             { 
 27318 |                arg_list.push_back(condition ); 
 27319 |                arg_list.push_back(consequent); 
 27320 |             } 
 27321 |  
 27322 |             if (token_is(token_t::e_rcrlbracket,prsrhlpr_t::e_hold)) 
 27323 |             { 
 27324 |                break; 
 27325 |             } 
 27326 |          } 
 27327 |  
 27328 |          if (!token_is(token_t::e_rcrlbracket)) 
 27329 |          { 
 27330 |             set_error(make_error( 
 27331 |                parser_error::e_syntax, 
 27332 |                current_token(), 
 27333 |                "ERR103 - Expected '}' at end of [*] statement", 
 27334 |                exprtk_error_location)); 
 27335 |  
 27336 |             return error_node(); 
 27337 |          } 
 27338 |  
 27339 |          const expression_node_ptr result = expression_generator_.multi_switch_statement(arg_list); 
 27340 |  
 27341 |          svd.delete_ptr = (0 == result); 
 27342 |  
 27343 |          return result; 
 27344 |       } 
 27345 |  
 27346 |       inline expression_node_ptr parse_vararg_function() 
 27347 |       { 
 27348 |          std::vector<expression_node_ptr> arg_list; 
 27349 |  
 27350 |          details::operator_type opt_type = details::e_default; 
 27351 |          const std::string symbol = current_token().value; 
 27352 |  
 27353 |          if (details::imatch(symbol,"~")) 
 27354 |          { 
 27355 |             next_token(); 
 27356 |             return check_block_statement_closure(parse_multi_sequence()); 
 27357 |          } 
 27358 |          else if (details::imatch(symbol,"[*]")) 
 27359 |          { 
 27360 |             return check_block_statement_closure(parse_multi_switch_statement()); 
 27361 |          } 
 27362 |          else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ; 
 27363 |          else if (details::imatch(symbol, "mand")) opt_type = details::e_mand; 
 27364 |          else if (details::imatch(symbol, "max" )) opt_type = details::e_max ; 
 27365 |          else if (details::imatch(symbol, "min" )) opt_type = details::e_min ; 
 27366 |          else if (details::imatch(symbol, "mor" )) opt_type = details::e_mor ; 
 27367 |          else if (details::imatch(symbol, "mul" )) opt_type = details::e_prod; 
 27368 |          else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ; 
 27369 |          else 
 27370 |          { 
 27371 |             set_error(make_error( 
 27372 |                parser_error::e_syntax, 
 27373 |                current_token(), 
 27374 |                "ERR104 - Unsupported built-in vararg function: " + symbol, 
 27375 |                exprtk_error_location)); 
 27376 |  
 27377 |             return error_node(); 
 27378 |          } 
 27379 |  
 27380 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 27381 |  
 27382 |          lodge_symbol(symbol, e_st_function); 
 27383 |  
 27384 |          next_token(); 
 27385 |  
 27386 |          if (!token_is(token_t::e_lbracket)) 
 27387 |          { 
 27388 |             set_error(make_error( 
 27389 |                parser_error::e_syntax, 
 27390 |                current_token(), 
 27391 |                "ERR105 - Expected '(' for call to vararg function: " + symbol, 
 27392 |                exprtk_error_location)); 
 27393 |  
 27394 |             return error_node(); 
 27395 |          } 
 27396 |  
 27397 |          if (token_is(token_t::e_rbracket)) 
 27398 |          { 
 27399 |             set_error(make_error( 
 27400 |                parser_error::e_syntax, 
 27401 |                current_token(), 
 27402 |                "ERR106 - vararg function: " + symbol + 
 27403 |                " requires at least one input parameter", 
 27404 |                exprtk_error_location)); 
 27405 |  
 27406 |             return error_node(); 
 27407 |          } 
 27408 |  
 27409 |          for ( ; ; ) 
 27410 |          { 
 27411 |             expression_node_ptr arg = parse_expression(); 
 27412 |  
 27413 |             if (0 == arg) 
 27414 |                return error_node(); 
 27415 |             else 
 27416 |                arg_list.push_back(arg); 
 27417 |  
 27418 |             if (token_is(token_t::e_rbracket)) 
 27419 |                break; 
 27420 |             else if (!token_is(token_t::e_comma)) 
 27421 |             { 
 27422 |                set_error(make_error( 
 27423 |                   parser_error::e_syntax, 
 27424 |                   current_token(), 
 27425 |                   "ERR107 - Expected ',' for call to vararg function: " + symbol, 
 27426 |                   exprtk_error_location)); 
 27427 |  
 27428 |                return error_node(); 
 27429 |             } 
 27430 |          } 
 27431 |  
 27432 |          const expression_node_ptr result = expression_generator_.vararg_function(opt_type,arg_list); 
 27433 |  
 27434 |          sdd.delete_ptr = (0 == result); 
 27435 |          return result; 
 27436 |       } 
 27437 |  
 27438 |       #ifndef exprtk_disable_string_capabilities 
 27439 |       inline expression_node_ptr parse_string_range_statement(expression_node_ptr& expression) 
 27440 |       { 
 27441 |          if (!token_is(token_t::e_lsqrbracket)) 
 27442 |          { 
 27443 |             set_error(make_error( 
 27444 |                parser_error::e_syntax, 
 27445 |                current_token(), 
 27446 |                "ERR108 - Expected '[' as start of string range definition", 
 27447 |                exprtk_error_location)); 
 27448 |  
 27449 |             free_node(node_allocator_, expression); 
 27450 |  
 27451 |             return error_node(); 
 27452 |          } 
 27453 |          else if (token_is(token_t::e_rsqrbracket)) 
 27454 |          { 
 27455 |             return node_allocator_.allocate<details::string_size_node<T> >(expression); 
 27456 |          } 
 27457 |  
 27458 |          range_t rp; 
 27459 |  
 27460 |          if (!parse_range(rp,true)) 
 27461 |          { 
 27462 |             free_node(node_allocator_, expression); 
 27463 |  
 27464 |             return error_node(); 
 27465 |          } 
 27466 |  
 27467 |          expression_node_ptr result = expression_generator_(expression,rp); 
 27468 |  
 27469 |          if (0 == result) 
 27470 |          { 
 27471 |             set_error(make_error( 
 27472 |                parser_error::e_syntax, 
 27473 |                current_token(), 
 27474 |                "ERR109 - Failed to generate string range node", 
 27475 |                exprtk_error_location)); 
 27476 |  
 27477 |             free_node(node_allocator_, expression); 
 27478 |             rp.free(); 
 27479 |          } 
 27480 |  
 27481 |          rp.clear(); 
 27482 |  
 27483 |          if (result && result->valid()) 
 27484 |          { 
 27485 |             return result; 
 27486 |          } 
 27487 |  
 27488 |          set_error(make_error( 
 27489 |             parser_error::e_synthesis, 
 27490 |             current_token(), 
 27491 |             "ERR110 - Failed to synthesize node: string_range_node", 
 27492 |             exprtk_error_location)); 
 27493 |  
 27494 |          free_node(node_allocator_, result); 
 27495 |          rp.free(); 
 27496 |          return error_node(); 
 27497 |       } 
 27498 |       #else 
 27499 |       inline expression_node_ptr parse_string_range_statement(expression_node_ptr&) 
 27500 |       { 
 27501 |          return error_node(); 
 27502 |       } 
 27503 |       #endif 
 27504 |  
 27505 |       inline bool parse_pending_string_rangesize(expression_node_ptr& expression) 
 27506 |       { 
 27507 |          // Allow no more than 100 range calls, eg: s[][][]...[][] 
 27508 |          const std::size_t max_rangesize_parses = 100; 
 27509 |  
 27510 |          std::size_t i = 0; 
 27511 |  
 27512 |          while 
 27513 |             ( 
 27514 |               (0 != expression)                     && 
 27515 |               (i++ < max_rangesize_parses)          && 
 27516 |               error_list_.empty()                   && 
 27517 |               is_generally_string_node(expression)  && 
 27518 |               token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold) 
 27519 |             ) 
 27520 |          { 
 27521 |             expression = parse_string_range_statement(expression); 
 27522 |          } 
 27523 |  
 27524 |          return (i > 1); 
 27525 |       } 
 27526 |  
 27527 |       inline void parse_pending_vector_index_operator(expression_node_ptr& expression) 
 27528 |       { 
 27529 |          if 
 27530 |             ( 
 27531 |               (0 != expression)           && 
 27532 |               error_list_.empty()         && 
 27533 |               is_ivector_node(expression) 
 27534 |             ) 
 27535 |          { 
 27536 |             if ( 
 27537 |                  settings_.commutative_check_enabled()       && 
 27538 |                  token_is(token_t::e_mul,prsrhlpr_t::e_hold) && 
 27539 |                  peek_token_is(token_t::e_lsqrbracket) 
 27540 |                ) 
 27541 |             { 
 27542 |                token_is(token_t::e_mul); 
 27543 |                token_is(token_t::e_lsqrbracket); 
 27544 |             } 
 27545 |             else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)) 
 27546 |             { 
 27547 |                token_is(token_t::e_lsqrbracket); 
 27548 |             } 
 27549 |             else if ( 
 27550 |                       token_is(token_t::e_rbracket,prsrhlpr_t::e_hold) && 
 27551 |                       peek_token_is(token_t::e_lsqrbracket) 
 27552 |                     ) 
 27553 |             { 
 27554 |                token_is(token_t::e_rbracket   ); 
 27555 |                token_is(token_t::e_lsqrbracket); 
 27556 |             } 
 27557 |             else 
 27558 |                return; 
 27559 |  
 27560 |             details::vector_interface<T>* vi = dynamic_cast<details::vector_interface<T>*>(expression); 
 27561 |  
 27562 |             if (vi) 
 27563 |             { 
 27564 |                details::vector_holder<T>& vec = vi->vec()->vec_holder(); 
 27565 |                const std::string vector_name  = sem_.get_vector_name(vec.data()); 
 27566 |                expression_node_ptr index      = parse_vector_index(vector_name); 
 27567 |  
 27568 |                if (index) 
 27569 |                { 
 27570 |                   expression = synthesize_vector_element(vector_name, &vec, expression, index); 
 27571 |                   return; 
 27572 |                } 
 27573 |             } 
 27574 |  
 27575 |             free_node(node_allocator_, expression); 
 27576 |             expression = error_node(); 
 27577 |          } 
 27578 |       } 
 27579 |  
 27580 |       template <typename Allocator1, 
 27581 |                 typename Allocator2, 
 27582 |                 template <typename, typename> class Sequence> 
 27583 |       inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator1>& expression_list, 
 27584 |                                           Sequence<bool,Allocator2>& side_effect_list, 
 27585 |                                           const bool specialise_on_final_type = false) 
 27586 |       { 
 27587 |          if (expression_list.empty()) 
 27588 |             return error_node(); 
 27589 |          else if (1 == expression_list.size()) 
 27590 |             return expression_list[0]; 
 27591 |  
 27592 |          Sequence<expression_node_ptr,Allocator1> tmp_expression_list; 
 27593 |  
 27594 |          exprtk_debug(("simplify() - expression_list.size: %d  side_effect_list.size(): %d\n", 
 27595 |                        static_cast<int>(expression_list .size()), 
 27596 |                        static_cast<int>(side_effect_list.size()))); 
 27597 |  
 27598 |          bool return_node_present = false; 
 27599 |  
 27600 |          for (std::size_t i = 0; i < (expression_list.size() - 1); ++i) 
 27601 |          { 
 27602 |             if (is_variable_node(expression_list[i])) 
 27603 |                continue; 
 27604 |             else if ( 
 27605 |                       is_return_node  (expression_list[i]) || 
 27606 |                       is_break_node   (expression_list[i]) || 
 27607 |                       is_continue_node(expression_list[i]) 
 27608 |                     ) 
 27609 |             { 
 27610 |                tmp_expression_list.push_back(expression_list[i]); 
 27611 |  
 27612 |                // Remove all subexpressions after first short-circuit 
 27613 |                // node has been encountered. 
 27614 |  
 27615 |                for (std::size_t j = i + 1; j < expression_list.size(); ++j) 
 27616 |                { 
 27617 |                   free_node(node_allocator_, expression_list[j]); 
 27618 |                } 
 27619 |  
 27620 |                return_node_present = true; 
 27621 |  
 27622 |                break; 
 27623 |             } 
 27624 |             else if ( 
 27625 |                       is_constant_node(expression_list[i]) || 
 27626 |                       is_null_node    (expression_list[i]) || 
 27627 |                       !side_effect_list[i] 
 27628 |                     ) 
 27629 |             { 
 27630 |                free_node(node_allocator_, expression_list[i]); 
 27631 |                continue; 
 27632 |             } 
 27633 |             else 
 27634 |                tmp_expression_list.push_back(expression_list[i]); 
 27635 |          } 
 27636 |  
 27637 |          if (!return_node_present) 
 27638 |          { 
 27639 |             tmp_expression_list.push_back(expression_list.back()); 
 27640 |          } 
 27641 |  
 27642 |          expression_list.swap(tmp_expression_list); 
 27643 |  
 27644 |          if (tmp_expression_list.size() > expression_list.size()) 
 27645 |          { 
 27646 |             exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n", 
 27647 |                           static_cast<int>(tmp_expression_list.size()), 
 27648 |                           static_cast<int>(expression_list    .size()))); 
 27649 |          } 
 27650 |  
 27651 |          if ( 
 27652 |               return_node_present     || 
 27653 |               side_effect_list.back() || 
 27654 |               (expression_list.size() > 1) 
 27655 |             ) 
 27656 |             state_.activate_side_effect("simplify()"); 
 27657 |  
 27658 |          if (1 == expression_list.size()) 
 27659 |             return expression_list[0]; 
 27660 |          else if (specialise_on_final_type && is_generally_string_node(expression_list.back())) 
 27661 |             return expression_generator_.vararg_function(details::e_smulti,expression_list); 
 27662 |          else 
 27663 |             return expression_generator_.vararg_function(details::e_multi,expression_list); 
 27664 |       } 
 27665 |  
 27666 |       inline expression_node_ptr parse_multi_sequence(const std::string& source = "", 
 27667 |                                                       const bool enforce_crlbrackets = false) 
 27668 |       { 
 27669 |          token_t::token_type open_bracket  = token_t::e_lcrlbracket; 
 27670 |          token_t::token_type close_bracket = token_t::e_rcrlbracket; 
 27671 |          token_t::token_type separator     = token_t::e_eof; 
 27672 |  
 27673 |          if (!token_is(open_bracket)) 
 27674 |          { 
 27675 |             if (!enforce_crlbrackets && token_is(token_t::e_lbracket)) 
 27676 |             { 
 27677 |                open_bracket  = token_t::e_lbracket; 
 27678 |                close_bracket = token_t::e_rbracket; 
 27679 |                separator     = token_t::e_comma; 
 27680 |             } 
 27681 |             else 
 27682 |             { 
 27683 |                set_error(make_error( 
 27684 |                   parser_error::e_syntax, 
 27685 |                   current_token(), 
 27686 |                   "ERR111 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" + 
 27687 |                   ((!source.empty()) ? std::string(" section of " + source): ""), 
 27688 |                   exprtk_error_location)); 
 27689 |  
 27690 |                return error_node(); 
 27691 |             } 
 27692 |          } 
 27693 |          else if (token_is(close_bracket)) 
 27694 |          { 
 27695 |             return node_allocator_.allocate<details::null_node<T> >(); 
 27696 |          } 
 27697 |  
 27698 |          std::vector<expression_node_ptr> arg_list; 
 27699 |          std::vector<bool> side_effect_list; 
 27700 |  
 27701 |          expression_node_ptr result = error_node(); 
 27702 |  
 27703 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 27704 |  
 27705 |          scope_handler sh(*this); 
 27706 |  
 27707 |          scoped_bool_or_restorer sbr(state_.side_effect_present); 
 27708 |  
 27709 |          for ( ; ; ) 
 27710 |          { 
 27711 |             state_.side_effect_present = false; 
 27712 |  
 27713 |             expression_node_ptr arg = parse_expression(); 
 27714 |  
 27715 |             if (0 == arg) 
 27716 |                return error_node(); 
 27717 |             else 
 27718 |             { 
 27719 |                arg_list.push_back(arg); 
 27720 |                side_effect_list.push_back(state_.side_effect_present); 
 27721 |             } 
 27722 |  
 27723 |             if (token_is(close_bracket)) 
 27724 |                break; 
 27725 |  
 27726 |             const bool is_next_close = peek_token_is(close_bracket); 
 27727 |  
 27728 |             if (!token_is(separator) && is_next_close) 
 27729 |             { 
 27730 |                set_error(make_error( 
 27731 |                   parser_error::e_syntax, 
 27732 |                   current_token(), 
 27733 |                   "ERR112 - Expected '" + lexer::token::seperator_to_str(separator) + "' for call to multi-sequence section of " + source, 
 27734 |                   exprtk_error_location)); 
 27735 |  
 27736 |                return error_node(); 
 27737 |             } 
 27738 |  
 27739 |             if (token_is(close_bracket)) 
 27740 |                break; 
 27741 |          } 
 27742 |  
 27743 |          result = simplify(arg_list, side_effect_list, source.empty()); 
 27744 |  
 27745 |          sdd.delete_ptr = (0 == result); 
 27746 |          return result; 
 27747 |       } 
 27748 |  
 27749 |       inline bool parse_range(range_t& rp, const bool skip_lsqr = false) 
 27750 |       { 
 27751 |          // Examples of valid ranges: 
 27752 |          // 1. [1:5]     -> [1,5) 
 27753 |          // 2. [ :5]     -> [0,5) 
 27754 |          // 3. [1: ]     -> [1,end) 
 27755 |          // 4. [x:y]     -> [x,y) where x <= y 
 27756 |          // 5. [x+1:y/2] -> [x+1,y/2) where x+1 <= y/2 
 27757 |          // 6. [ :y]     -> [0,y) where 0 <= y 
 27758 |          // 7. [x: ]     -> [x,end) where x <= end 
 27759 |  
 27760 |          rp.clear(); 
 27761 |  
 27762 |          if (!skip_lsqr && !token_is(token_t::e_lsqrbracket)) 
 27763 |          { 
 27764 |             set_error(make_error( 
 27765 |                parser_error::e_syntax, 
 27766 |                current_token(), 
 27767 |                "ERR113 - Expected '[' for start of range", 
 27768 |                exprtk_error_location)); 
 27769 |  
 27770 |             return false; 
 27771 |          } 
 27772 |  
 27773 |          if (token_is(token_t::e_colon)) 
 27774 |          { 
 27775 |             rp.n0_c.first  = true; 
 27776 |             rp.n0_c.second = 0; 
 27777 |             rp.cache.first = 0; 
 27778 |          } 
 27779 |          else 
 27780 |          { 
 27781 |             expression_node_ptr r0 = parse_expression(); 
 27782 |  
 27783 |             if (0 == r0) 
 27784 |             { 
 27785 |                set_error(make_error( 
 27786 |                   parser_error::e_syntax, 
 27787 |                   current_token(), 
 27788 |                   "ERR114 - Failed parse begin section of range", 
 27789 |                   exprtk_error_location)); 
 27790 |  
 27791 |                return false; 
 27792 |             } 
 27793 |             else if (is_constant_node(r0)) 
 27794 |             { 
 27795 |                const T r0_value = r0->value(); 
 27796 |  
 27797 |                if (r0_value >= T(0)) 
 27798 |                { 
 27799 |                   rp.n0_c.first  = true; 
 27800 |                   rp.n0_c.second = static_cast<std::size_t>(details::numeric::to_int64(r0_value)); 
 27801 |                   rp.cache.first = rp.n0_c.second; 
 27802 |                } 
 27803 |  
 27804 |                free_node(node_allocator_, r0); 
 27805 |  
 27806 |                if (r0_value < T(0)) 
 27807 |                { 
 27808 |                   set_error(make_error( 
 27809 |                      parser_error::e_syntax, 
 27810 |                      current_token(), 
 27811 |                      "ERR115 - Range lower bound less than zero! Constraint: r0 >= 0", 
 27812 |                      exprtk_error_location)); 
 27813 |  
 27814 |                   return false; 
 27815 |                } 
 27816 |             } 
 27817 |             else 
 27818 |             { 
 27819 |                rp.n0_e.first  = true; 
 27820 |                rp.n0_e.second = r0; 
 27821 |             } 
 27822 |  
 27823 |             if (!token_is(token_t::e_colon)) 
 27824 |             { 
 27825 |                set_error(make_error( 
 27826 |                   parser_error::e_syntax, 
 27827 |                   current_token(), 
 27828 |                   "ERR116 - Expected ':' for break  in range", 
 27829 |                   exprtk_error_location)); 
 27830 |  
 27831 |                rp.free(); 
 27832 |  
 27833 |                return false; 
 27834 |             } 
 27835 |          } 
 27836 |  
 27837 |          if (token_is(token_t::e_rsqrbracket)) 
 27838 |          { 
 27839 |             rp.n1_c.first  = true; 
 27840 |             rp.n1_c.second = std::numeric_limits<std::size_t>::max(); 
 27841 |          } 
 27842 |          else 
 27843 |          { 
 27844 |             expression_node_ptr r1 = parse_expression(); 
 27845 |  
 27846 |             if (0 == r1) 
 27847 |             { 
 27848 |                set_error(make_error( 
 27849 |                   parser_error::e_syntax, 
 27850 |                   current_token(), 
 27851 |                   "ERR117 - Failed parse end section of range", 
 27852 |                   exprtk_error_location)); 
 27853 |  
 27854 |                rp.free(); 
 27855 |  
 27856 |                return false; 
 27857 |             } 
 27858 |             else if (is_constant_node(r1)) 
 27859 |             { 
 27860 |                const T r1_value = r1->value(); 
 27861 |  
 27862 |                if (r1_value >= T(0)) 
 27863 |                { 
 27864 |                   rp.n1_c.first   = true; 
 27865 |                   rp.n1_c.second  = static_cast<std::size_t>(details::numeric::to_int64(r1_value)); 
 27866 |                   rp.cache.second = rp.n1_c.second; 
 27867 |                } 
 27868 |  
 27869 |                free_node(node_allocator_, r1); 
 27870 |  
 27871 |                if (r1_value < T(0)) 
 27872 |                { 
 27873 |                   set_error(make_error( 
 27874 |                      parser_error::e_syntax, 
 27875 |                      current_token(), 
 27876 |                      "ERR118 - Range upper bound less than zero! Constraint: r1 >= 0", 
 27877 |                      exprtk_error_location)); 
 27878 |  
 27879 |                   rp.free(); 
 27880 |  
 27881 |                   return false; 
 27882 |                } 
 27883 |             } 
 27884 |             else 
 27885 |             { 
 27886 |                rp.n1_e.first  = true; 
 27887 |                rp.n1_e.second = r1; 
 27888 |             } 
 27889 |  
 27890 |             if (!token_is(token_t::e_rsqrbracket)) 
 27891 |             { 
 27892 |                set_error(make_error( 
 27893 |                   parser_error::e_syntax, 
 27894 |                   current_token(), 
 27895 |                   "ERR119 - Expected ']' for start of range", 
 27896 |                   exprtk_error_location)); 
 27897 |  
 27898 |                rp.free(); 
 27899 |  
 27900 |                return false; 
 27901 |             } 
 27902 |          } 
 27903 |  
 27904 |          if (rp.const_range()) 
 27905 |          { 
 27906 |             std::size_t r0 = 0; 
 27907 |             std::size_t r1 = 0; 
 27908 |  
 27909 |             bool rp_result = false; 
 27910 |  
 27911 |             try 
 27912 |             { 
 27913 |                rp_result = rp(r0, r1); 
 27914 |             } 
 27915 |             catch (std::runtime_error&) 
 27916 |             {} 
 27917 |  
 27918 |             if (!rp_result || (r0 > r1)) 
 27919 |             { 
 27920 |                set_error(make_error( 
 27921 |                   parser_error::e_syntax, 
 27922 |                   current_token(), 
 27923 |                   "ERR120 - Invalid range, Constraint: r0 <= r1", 
 27924 |                   exprtk_error_location)); 
 27925 |  
 27926 |                return false; 
 27927 |             } 
 27928 |          } 
 27929 |  
 27930 |          return true; 
 27931 |       } 
 27932 |  
 27933 |       inline void lodge_symbol(const std::string& symbol, 
 27934 |                                const symbol_type st) 
 27935 |       { 
 27936 |          dec_.add_symbol(symbol,st); 
 27937 |       } 
 27938 |  
 27939 |       #ifndef exprtk_disable_string_capabilities 
 27940 |       inline expression_node_ptr parse_string() 
 27941 |       { 
 27942 |          const std::string symbol = current_token().value; 
 27943 |  
 27944 |          typedef details::stringvar_node<T>* strvar_node_t; 
 27945 |  
 27946 |          expression_node_ptr result   = error_node(); 
 27947 |          strvar_node_t const_str_node = static_cast<strvar_node_t>(0); 
 27948 |  
 27949 |          scope_element& se = sem_.get_active_element(symbol); 
 27950 |  
 27951 |          if (scope_element::e_string == se.type) 
 27952 |          { 
 27953 |             se.active = true; 
 27954 |             result    = se.str_node; 
 27955 |             lodge_symbol(symbol, e_st_local_string); 
 27956 |          } 
 27957 |          else 
 27958 |          { 
 27959 |             typedef typename symtab_store::string_context str_ctxt_t; 
 27960 |             str_ctxt_t str_ctx = symtab_store_.get_string_context(symbol); 
 27961 |  
 27962 |             if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol)) 
 27963 |             { 
 27964 |                set_error(make_error( 
 27965 |                   parser_error::e_syntax, 
 27966 |                   current_token(), 
 27967 |                   "ERR121 - Unknown string symbol", 
 27968 |                   exprtk_error_location)); 
 27969 |  
 27970 |                return error_node(); 
 27971 |             } 
 27972 |  
 27973 |             assert(str_ctx.str_var != 0); 
 27974 |             assert(str_ctx.symbol_table != 0); 
 27975 |  
 27976 |             result = str_ctx.str_var; 
 27977 |  
 27978 |             if (symtab_store_.is_constant_string(symbol)) 
 27979 |             { 
 27980 |                const_str_node = static_cast<strvar_node_t>(result); 
 27981 |                result = expression_generator_(const_str_node->str()); 
 27982 |             } 
 27983 |             else if (symbol_table_t::e_immutable == str_ctx.symbol_table->mutability()) 
 27984 |             { 
 27985 |                lodge_immutable_symbol( 
 27986 |                   current_token(), 
 27987 |                   make_memory_range(str_ctx.str_var->base(), str_ctx.str_var->size())); 
 27988 |             } 
 27989 |  
 27990 |             lodge_symbol(symbol, e_st_string); 
 27991 |          } 
 27992 |  
 27993 |          if (peek_token_is(token_t::e_lsqrbracket)) 
 27994 |          { 
 27995 |             next_token(); 
 27996 |  
 27997 |             if (peek_token_is(token_t::e_rsqrbracket)) 
 27998 |             { 
 27999 |                next_token(); 
 28000 |                next_token(); 
 28001 |  
 28002 |                if (const_str_node) 
 28003 |                { 
 28004 |                   free_node(node_allocator_, result); 
 28005 |  
 28006 |                   return expression_generator_(T(const_str_node->size())); 
 28007 |                } 
 28008 |                else 
 28009 |                   return node_allocator_.allocate<details::stringvar_size_node<T> > 
 28010 |                             (static_cast<details::stringvar_node<T>*>(result)->ref()); 
 28011 |             } 
 28012 |  
 28013 |             range_t rp; 
 28014 |  
 28015 |             if (!parse_range(rp)) 
 28016 |             { 
 28017 |                free_node(node_allocator_, result); 
 28018 |  
 28019 |                return error_node(); 
 28020 |             } 
 28021 |             else if (const_str_node) 
 28022 |             { 
 28023 |                free_node(node_allocator_, result); 
 28024 |                result = expression_generator_(const_str_node->ref(),rp); 
 28025 |             } 
 28026 |             else 
 28027 |                result = expression_generator_(static_cast<details::stringvar_node<T>*> 
 28028 |                            (result)->ref(), rp); 
 28029 |  
 28030 |             if (result) 
 28031 |                rp.clear(); 
 28032 |          } 
 28033 |          else 
 28034 |             next_token(); 
 28035 |  
 28036 |          return result; 
 28037 |       } 
 28038 |       #else 
 28039 |       inline expression_node_ptr parse_string() 
 28040 |       { 
 28041 |          return error_node(); 
 28042 |       } 
 28043 |       #endif 
 28044 |  
 28045 |       #ifndef exprtk_disable_string_capabilities 
 28046 |       inline expression_node_ptr parse_const_string() 
 28047 |       { 
 28048 |          const std::string   const_str = current_token().value; 
 28049 |          expression_node_ptr result    = expression_generator_(const_str); 
 28050 |  
 28051 |          if (peek_token_is(token_t::e_lsqrbracket)) 
 28052 |          { 
 28053 |             next_token(); 
 28054 |  
 28055 |             if (peek_token_is(token_t::e_rsqrbracket)) 
 28056 |             { 
 28057 |                next_token(); 
 28058 |                next_token(); 
 28059 |  
 28060 |                free_node(node_allocator_, result); 
 28061 |  
 28062 |                return expression_generator_(T(const_str.size())); 
 28063 |             } 
 28064 |  
 28065 |             range_t rp; 
 28066 |  
 28067 |             if (!parse_range(rp)) 
 28068 |             { 
 28069 |                free_node(node_allocator_, result); 
 28070 |                rp.free(); 
 28071 |  
 28072 |                return error_node(); 
 28073 |             } 
 28074 |  
 28075 |             free_node(node_allocator_, result); 
 28076 |  
 28077 |             if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits<std::size_t>::max())) 
 28078 |             { 
 28079 |                rp.n1_c.second  = const_str.size() - 1; 
 28080 |                rp.cache.second = rp.n1_c.second; 
 28081 |             } 
 28082 |  
 28083 |             if ( 
 28084 |                  (rp.n0_c.first && (rp.n0_c.second >= const_str.size())) || 
 28085 |                  (rp.n1_c.first && (rp.n1_c.second >= const_str.size())) 
 28086 |                ) 
 28087 |             { 
 28088 |                set_error(make_error( 
 28089 |                   parser_error::e_syntax, 
 28090 |                   current_token(), 
 28091 |                   "ERR122 - Overflow in range for string: '" + const_str + "'[" + 
 28092 |                   (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" + 
 28093 |                   (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]", 
 28094 |                   exprtk_error_location)); 
 28095 |  
 28096 |                rp.free(); 
 28097 |  
 28098 |                return error_node(); 
 28099 |             } 
 28100 |  
 28101 |             result = expression_generator_(const_str,rp); 
 28102 |  
 28103 |             if (result) 
 28104 |                rp.clear(); 
 28105 |          } 
 28106 |          else 
 28107 |             next_token(); 
 28108 |  
 28109 |          return result; 
 28110 |       } 
 28111 |       #else 
 28112 |       inline expression_node_ptr parse_const_string() 
 28113 |       { 
 28114 |          return error_node(); 
 28115 |       } 
 28116 |       #endif 
 28117 |  
 28118 |       inline expression_node_ptr parse_vector_index(const std::string& vector_name = "") 
 28119 |       { 
 28120 |          expression_node_ptr index_expr = error_node(); 
 28121 |  
 28122 |          if (0 == (index_expr = parse_expression())) 
 28123 |          { 
 28124 |             set_error(make_error( 
 28125 |                parser_error::e_syntax, 
 28126 |                current_token(), 
 28127 |                "ERR123 - Failed to parse index for vector: '" + vector_name + "'", 
 28128 |                exprtk_error_location)); 
 28129 |  
 28130 |             return error_node(); 
 28131 |          } 
 28132 |          else if (!token_is(token_t::e_rsqrbracket)) 
 28133 |          { 
 28134 |             set_error(make_error( 
 28135 |                parser_error::e_syntax, 
 28136 |                current_token(), 
 28137 |                "ERR124 - Expected ']' for index of vector: '" + vector_name + "'", 
 28138 |                exprtk_error_location)); 
 28139 |  
 28140 |             free_node(node_allocator_, index_expr); 
 28141 |  
 28142 |             return error_node(); 
 28143 |          } 
 28144 |  
 28145 |          return index_expr; 
 28146 |       } 
 28147 |  
 28148 |       inline expression_node_ptr parse_vector() 
 28149 |       { 
 28150 |          const std::string vector_name = current_token().value; 
 28151 |  
 28152 |          vector_holder_ptr vec = vector_holder_ptr(0); 
 28153 |  
 28154 |          const scope_element& se = sem_.get_active_element(vector_name); 
 28155 |  
 28156 |          if ( 
 28157 |               !details::imatch(se.name, vector_name) || 
 28158 |               (se.depth > state_.scope_depth)   || 
 28159 |               (scope_element::e_vector != se.type) 
 28160 |             ) 
 28161 |          { 
 28162 |             typedef typename symtab_store::vector_context vec_ctxt_t; 
 28163 |             vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(vector_name); 
 28164 |  
 28165 |             if (0 == vec_ctx.vector_holder) 
 28166 |             { 
 28167 |                set_error(make_error( 
 28168 |                   parser_error::e_syntax, 
 28169 |                   current_token(), 
 28170 |                   "ERR125 - Symbol '" + vector_name + " not a vector", 
 28171 |                   exprtk_error_location)); 
 28172 |  
 28173 |                return error_node(); 
 28174 |             } 
 28175 |  
 28176 |             assert(0 != vec_ctx.vector_holder); 
 28177 |             assert(0 != vec_ctx.symbol_table ); 
 28178 |  
 28179 |             vec = vec_ctx.vector_holder; 
 28180 |  
 28181 |             if (symbol_table_t::e_immutable == vec_ctx.symbol_table->mutability()) 
 28182 |             { 
 28183 |                lodge_immutable_symbol( 
 28184 |                   current_token(), 
 28185 |                   make_memory_range(vec->data(), vec->size())); 
 28186 |             } 
 28187 |          } 
 28188 |          else 
 28189 |          { 
 28190 |             vec = se.vec_node; 
 28191 |          } 
 28192 |  
 28193 |          assert(0 != vec); 
 28194 |  
 28195 |          next_token(); 
 28196 |  
 28197 |          if (!token_is(token_t::e_lsqrbracket)) 
 28198 |          { 
 28199 |             return node_allocator_.allocate<vector_node_t>(vec); 
 28200 |          } 
 28201 |          else if (token_is(token_t::e_rsqrbracket)) 
 28202 |          { 
 28203 |             return (vec->rebaseable()) ? 
 28204 |                node_allocator_.allocate<vector_size_node_t>(vec) : 
 28205 |                expression_generator_(T(vec->size())); 
 28206 |          } 
 28207 |  
 28208 |          expression_node_ptr index_expr = parse_vector_index(vector_name); 
 28209 |  
 28210 |          if (index_expr) 
 28211 |          { 
 28212 |             expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec); 
 28213 |  
 28214 |             return synthesize_vector_element(vector_name, vec, vec_node, index_expr); 
 28215 |          } 
 28216 |  
 28217 |          return error_node(); 
 28218 |       } 
 28219 |  
 28220 |       inline expression_node_ptr synthesize_vector_element(const std::string& vector_name, 
 28221 |                                                            vector_holder_ptr vec, 
 28222 |                                                            expression_node_ptr vec_node, 
 28223 |                                                            expression_node_ptr index_expr) 
 28224 |       { 
 28225 |          // Perform compile-time range check 
 28226 |          if (details::is_constant_node(index_expr)) 
 28227 |          { 
 28228 |             const std::size_t index    = static_cast<std::size_t>(details::numeric::to_int32(index_expr->value())); 
 28229 |             const std::size_t vec_size = vec->size(); 
 28230 |  
 28231 |             if (index >= vec_size) 
 28232 |             { 
 28233 |                set_error(make_error( 
 28234 |                   parser_error::e_syntax, 
 28235 |                   current_token(), 
 28236 |                   "ERR126 - Index of " + details::to_str(index) + " out of range for " 
 28237 |                   "vector '" + vector_name + "' of size " + details::to_str(vec_size), 
 28238 |                   exprtk_error_location)); 
 28239 |  
 28240 |                free_node(node_allocator_, vec_node  ); 
 28241 |                free_node(node_allocator_, index_expr); 
 28242 |  
 28243 |                return error_node(); 
 28244 |             } 
 28245 |          } 
 28246 |  
 28247 |          return expression_generator_.vector_element(vector_name, vec, vec_node, index_expr); 
 28248 |       } 
 28249 |  
 28250 |       inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name) 
 28251 |       { 
 28252 |          std::vector<expression_node_ptr> arg_list; 
 28253 |  
 28254 |          expression_node_ptr result = error_node(); 
 28255 |  
 28256 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28257 |  
 28258 |          next_token(); 
 28259 |  
 28260 |          if (token_is(token_t::e_lbracket)) 
 28261 |          { 
 28262 |             if (token_is(token_t::e_rbracket)) 
 28263 |             { 
 28264 |                if (!vararg_function->allow_zero_parameters()) 
 28265 |                { 
 28266 |                   set_error(make_error( 
 28267 |                      parser_error::e_syntax, 
 28268 |                      current_token(), 
 28269 |                      "ERR127 - Zero parameter call to vararg function: " 
 28270 |                      + vararg_function_name + " not allowed", 
 28271 |                      exprtk_error_location)); 
 28272 |  
 28273 |                   return error_node(); 
 28274 |                } 
 28275 |             } 
 28276 |             else 
 28277 |             { 
 28278 |                for ( ; ; ) 
 28279 |                { 
 28280 |                   expression_node_ptr arg = parse_expression(); 
 28281 |  
 28282 |                   if (0 == arg) 
 28283 |                      return error_node(); 
 28284 |                   else 
 28285 |                      arg_list.push_back(arg); 
 28286 |  
 28287 |                   if (token_is(token_t::e_rbracket)) 
 28288 |                      break; 
 28289 |                   else if (!token_is(token_t::e_comma)) 
 28290 |                   { 
 28291 |                      set_error(make_error( 
 28292 |                         parser_error::e_syntax, 
 28293 |                         current_token(), 
 28294 |                         "ERR128 - Expected ',' for call to vararg function: " 
 28295 |                         + vararg_function_name, 
 28296 |                         exprtk_error_location)); 
 28297 |  
 28298 |                      return error_node(); 
 28299 |                   } 
 28300 |                } 
 28301 |             } 
 28302 |          } 
 28303 |          else if (!vararg_function->allow_zero_parameters()) 
 28304 |          { 
 28305 |             set_error(make_error( 
 28306 |                parser_error::e_syntax, 
 28307 |                current_token(), 
 28308 |                "ERR129 - Zero parameter call to vararg function: " 
 28309 |                + vararg_function_name + " not allowed", 
 28310 |                exprtk_error_location)); 
 28311 |  
 28312 |             return error_node(); 
 28313 |          } 
 28314 |  
 28315 |          if (arg_list.size() < vararg_function->min_num_args()) 
 28316 |          { 
 28317 |             set_error(make_error( 
 28318 |                parser_error::e_syntax, 
 28319 |                current_token(), 
 28320 |                "ERR130 - Invalid number of parameters to call to vararg function: " 
 28321 |                + vararg_function_name + ", require at least " 
 28322 |                + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters", 
 28323 |                exprtk_error_location)); 
 28324 |  
 28325 |             return error_node(); 
 28326 |          } 
 28327 |          else if (arg_list.size() > vararg_function->max_num_args()) 
 28328 |          { 
 28329 |             set_error(make_error( 
 28330 |                parser_error::e_syntax, 
 28331 |                current_token(), 
 28332 |                "ERR131 - Invalid number of parameters to call to vararg function: " 
 28333 |                + vararg_function_name + ", require no more than " 
 28334 |                + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters", 
 28335 |                exprtk_error_location)); 
 28336 |  
 28337 |             return error_node(); 
 28338 |          } 
 28339 |  
 28340 |          result = expression_generator_.vararg_function_call(vararg_function,arg_list); 
 28341 |  
 28342 |          sdd.delete_ptr = (0 == result); 
 28343 |  
 28344 |          return result; 
 28345 |       } 
 28346 |  
 28347 |       class type_checker 
 28348 |       { 
 28349 |       public: 
 28350 |  
 28351 |          enum return_type_t 
 28352 |          { 
 28353 |             e_overload = ' ', 
 28354 |             e_numeric  = 'T', 
 28355 |             e_string   = 'S' 
 28356 |          }; 
 28357 |  
 28358 |          struct function_prototype_t 
 28359 |          { 
 28360 |              return_type_t return_type; 
 28361 |              std::string   param_seq; 
 28362 |          }; 
 28363 |  
 28364 |          typedef parser<T> parser_t; 
 28365 |          typedef std::vector<function_prototype_t> function_definition_list_t; 
 28366 |  
 28367 |          type_checker(parser_t& p, 
 28368 |                       const std::string& func_name, 
 28369 |                       const std::string& func_prototypes, 
 28370 |                       const return_type_t default_return_type) 
 28371 |          : invalid_state_(true) 
 28372 |          , parser_(p) 
 28373 |          , function_name_(func_name) 
 28374 |          , default_return_type_(default_return_type) 
 28375 |          { 
 28376 |             parse_function_prototypes(func_prototypes); 
 28377 |          } 
 28378 |  
 28379 |          bool verify(const std::string& param_seq, std::size_t& pseq_index) 
 28380 |          { 
 28381 |             if (function_definition_list_.empty()) 
 28382 |                return true; 
 28383 |  
 28384 |             std::vector<std::pair<std::size_t,char> > error_list; 
 28385 |  
 28386 |             for (std::size_t i = 0; i < function_definition_list_.size(); ++i) 
 28387 |             { 
 28388 |                details::char_t diff_value = 0; 
 28389 |                std::size_t     diff_index = 0; 
 28390 |  
 28391 |                const bool result = details::sequence_match(function_definition_list_[i].param_seq, 
 28392 |                                                            param_seq, 
 28393 |                                                            diff_index, diff_value); 
 28394 |  
 28395 |               if (result) 
 28396 |               { 
 28397 |                  pseq_index = i; 
 28398 |                  return true; 
 28399 |               } 
 28400 |               else 
 28401 |                  error_list.push_back(std::make_pair(diff_index, diff_value)); 
 28402 |             } 
 28403 |  
 28404 |             if (1 == error_list.size()) 
 28405 |             { 
 28406 |                parser_.set_error(make_error( 
 28407 |                   parser_error::e_syntax, 
 28408 |                   parser_.current_token(), 
 28409 |                   "ERR132 - Failed parameter type check for function '" + function_name_ + "', " 
 28410 |                   "Expected '" + function_definition_list_[0].param_seq + 
 28411 |                   "' call set: '" + param_seq + "'", 
 28412 |                   exprtk_error_location)); 
 28413 |             } 
 28414 |             else 
 28415 |             { 
 28416 |                // find first with largest diff_index; 
 28417 |                std::size_t max_diff_index = 0; 
 28418 |  
 28419 |                for (std::size_t i = 1; i < error_list.size(); ++i) 
 28420 |                { 
 28421 |                   if (error_list[i].first > error_list[max_diff_index].first) 
 28422 |                   { 
 28423 |                      max_diff_index = i; 
 28424 |                   } 
 28425 |                } 
 28426 |  
 28427 |                parser_.set_error(make_error( 
 28428 |                   parser_error::e_syntax, 
 28429 |                   parser_.current_token(), 
 28430 |                   "ERR133 - Failed parameter type check for function '" + function_name_ + "', " 
 28431 |                   "Best match: '" + function_definition_list_[max_diff_index].param_seq + 
 28432 |                   "' call set: '" + param_seq + "'", 
 28433 |                   exprtk_error_location)); 
 28434 |             } 
 28435 |  
 28436 |             return false; 
 28437 |          } 
 28438 |  
 28439 |          std::size_t paramseq_count() const 
 28440 |          { 
 28441 |             return function_definition_list_.size(); 
 28442 |          } 
 28443 |  
 28444 |          std::string paramseq(const std::size_t& index) const 
 28445 |          { 
 28446 |             return function_definition_list_[index].param_seq; 
 28447 |          } 
 28448 |  
 28449 |          return_type_t return_type(const std::size_t& index) const 
 28450 |          { 
 28451 |             return function_definition_list_[index].return_type; 
 28452 |          } 
 28453 |  
 28454 |          bool invalid() const 
 28455 |          { 
 28456 |             return !invalid_state_; 
 28457 |          } 
 28458 |  
 28459 |          bool allow_zero_parameters() const 
 28460 |          { 
 28461 |  
 28462 |             for (std::size_t i = 0; i < function_definition_list_.size(); ++i) 
 28463 |             { 
 28464 |                if (std::string::npos != function_definition_list_[i].param_seq.find("Z")) 
 28465 |                { 
 28466 |                   return true; 
 28467 |                } 
 28468 |             } 
 28469 |  
 28470 |             return false; 
 28471 |          } 
 28472 |  
 28473 |       private: 
 28474 |  
 28475 |          std::vector<std::string> split_param_seq(const std::string& param_seq, const details::char_t delimiter = '|') const 
 28476 |          { 
 28477 |              std::string::const_iterator current_begin = param_seq.begin(); 
 28478 |              std::string::const_iterator iter          = param_seq.begin(); 
 28479 |  
 28480 |              std::vector<std::string> result; 
 28481 |  
 28482 |              while (iter != param_seq.end()) 
 28483 |              { 
 28484 |                  if (*iter == delimiter) 
 28485 |                  { 
 28486 |                      result.push_back(std::string(current_begin, iter)); 
 28487 |                      current_begin = ++iter; 
 28488 |                  } 
 28489 |                  else 
 28490 |                      ++iter; 
 28491 |              } 
 28492 |  
 28493 |              if (current_begin != iter) 
 28494 |              { 
 28495 |                  result.push_back(std::string(current_begin, iter)); 
 28496 |              } 
 28497 |  
 28498 |              return result; 
 28499 |          } 
 28500 |  
 28501 |          inline bool is_valid_token(std::string param_seq, 
 28502 |                                     function_prototype_t& funcproto) const 
 28503 |          { 
 28504 |             // Determine return type 
 28505 |             funcproto.return_type = default_return_type_; 
 28506 |  
 28507 |             if (param_seq.size() > 2) 
 28508 |             { 
 28509 |                if (':' == param_seq[1]) 
 28510 |                { 
 28511 |                   // Note: Only overloaded igeneric functions can have return 
 28512 |                   // type definitions. 
 28513 |                   if (type_checker::e_overload != default_return_type_) 
 28514 |                      return false; 
 28515 |  
 28516 |                   switch (param_seq[0]) 
 28517 |                   { 
 28518 |                      case 'T' : funcproto.return_type = type_checker::e_numeric; 
 28519 |                                 break; 
 28520 |  
 28521 |                      case 'S' : funcproto.return_type = type_checker::e_string; 
 28522 |                                 break; 
 28523 |  
 28524 |                      default  : return false; 
 28525 |                   } 
 28526 |  
 28527 |                   param_seq.erase(0,2); 
 28528 |                } 
 28529 |             } 
 28530 |  
 28531 |             if ( 
 28532 |                  (std::string::npos != param_seq.find("?*")) || 
 28533 |                  (std::string::npos != param_seq.find("**")) 
 28534 |                ) 
 28535 |             { 
 28536 |                return false; 
 28537 |             } 
 28538 |             else if ( 
 28539 |                       (std::string::npos == param_seq.find_first_not_of("STV*?|")) || 
 28540 |                       ("Z" == param_seq) 
 28541 |                     ) 
 28542 |             { 
 28543 |                funcproto.param_seq = param_seq; 
 28544 |                return true; 
 28545 |             } 
 28546 |  
 28547 |             return false; 
 28548 |          } 
 28549 |  
 28550 |          void parse_function_prototypes(const std::string& func_prototypes) 
 28551 |          { 
 28552 |             if (func_prototypes.empty()) 
 28553 |                return; 
 28554 |  
 28555 |             std::vector<std::string> param_seq_list = split_param_seq(func_prototypes); 
 28556 |  
 28557 |             typedef std::map<std::string,std::size_t> param_seq_map_t; 
 28558 |             param_seq_map_t param_seq_map; 
 28559 |  
 28560 |             for (std::size_t i = 0; i < param_seq_list.size(); ++i) 
 28561 |             { 
 28562 |                function_prototype_t func_proto; 
 28563 |  
 28564 |                if (!is_valid_token(param_seq_list[i], func_proto)) 
 28565 |                { 
 28566 |                   invalid_state_ = false; 
 28567 |  
 28568 |                   parser_.set_error(make_error( 
 28569 |                      parser_error::e_syntax, 
 28570 |                      parser_.current_token(), 
 28571 |                      "ERR134 - Invalid parameter sequence of '" + param_seq_list[i] + 
 28572 |                      "' for function: " + function_name_, 
 28573 |                      exprtk_error_location)); 
 28574 |                   return; 
 28575 |                } 
 28576 |  
 28577 |                param_seq_map_t::const_iterator seq_itr = param_seq_map.find(param_seq_list[i]); 
 28578 |  
 28579 |                if (param_seq_map.end() != seq_itr) 
 28580 |                { 
 28581 |                   invalid_state_ = false; 
 28582 |  
 28583 |                   parser_.set_error(make_error( 
 28584 |                      parser_error::e_syntax, 
 28585 |                      parser_.current_token(), 
 28586 |                      "ERR135 - Function '" + function_name_ + "' has a parameter sequence conflict between " + 
 28587 |                      "pseq_idx[" + details::to_str(seq_itr->second) + "] and" + 
 28588 |                      "pseq_idx[" + details::to_str(i) + "] " + 
 28589 |                      "param seq: " + param_seq_list[i], 
 28590 |                      exprtk_error_location)); 
 28591 |                   return; 
 28592 |                } 
 28593 |  
 28594 |                function_definition_list_.push_back(func_proto); 
 28595 |             } 
 28596 |          } 
 28597 |  
 28598 |          type_checker(const type_checker&) exprtk_delete; 
 28599 |          type_checker& operator=(const type_checker&) exprtk_delete; 
 28600 |  
 28601 |          bool invalid_state_; 
 28602 |          parser_t& parser_; 
 28603 |          std::string function_name_; 
 28604 |          const return_type_t default_return_type_; 
 28605 |          function_definition_list_t function_definition_list_; 
 28606 |       }; 
 28607 |  
 28608 |       inline expression_node_ptr parse_generic_function_call(igeneric_function<T>* function, const std::string& function_name) 
 28609 |       { 
 28610 |          std::vector<expression_node_ptr> arg_list; 
 28611 |  
 28612 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28613 |  
 28614 |          next_token(); 
 28615 |  
 28616 |          std::string param_type_list; 
 28617 |  
 28618 |          type_checker tc( 
 28619 |             (*this), 
 28620 |             function_name, 
 28621 |             function->parameter_sequence, 
 28622 |             type_checker::e_string); 
 28623 |  
 28624 |          if (tc.invalid()) 
 28625 |          { 
 28626 |             set_error(make_error( 
 28627 |                parser_error::e_syntax, 
 28628 |                current_token(), 
 28629 |                "ERR136 - Type checker instantiation failure for generic function: " + function_name, 
 28630 |                exprtk_error_location)); 
 28631 |  
 28632 |             return error_node(); 
 28633 |          } 
 28634 |  
 28635 |          if (token_is(token_t::e_lbracket)) 
 28636 |          { 
 28637 |             if (token_is(token_t::e_rbracket)) 
 28638 |             { 
 28639 |                if ( 
 28640 |                     !function->allow_zero_parameters() && 
 28641 |                     !tc       .allow_zero_parameters() 
 28642 |                   ) 
 28643 |                { 
 28644 |                   set_error(make_error( 
 28645 |                      parser_error::e_syntax, 
 28646 |                      current_token(), 
 28647 |                      "ERR137 - Zero parameter call to generic function: " 
 28648 |                      + function_name + " not allowed", 
 28649 |                      exprtk_error_location)); 
 28650 |  
 28651 |                   return error_node(); 
 28652 |                } 
 28653 |             } 
 28654 |             else 
 28655 |             { 
 28656 |                for ( ; ; ) 
 28657 |                { 
 28658 |                   expression_node_ptr arg = parse_expression(); 
 28659 |  
 28660 |                   if (0 == arg) 
 28661 |                      return error_node(); 
 28662 |  
 28663 |                   if (is_ivector_node(arg)) 
 28664 |                      param_type_list += 'V'; 
 28665 |                   else if (is_generally_string_node(arg)) 
 28666 |                      param_type_list += 'S'; 
 28667 |                   else // Everything else is assumed to be a scalar returning expression 
 28668 |                      param_type_list += 'T'; 
 28669 |  
 28670 |                   arg_list.push_back(arg); 
 28671 |  
 28672 |                   if (token_is(token_t::e_rbracket)) 
 28673 |                      break; 
 28674 |                   else if (!token_is(token_t::e_comma)) 
 28675 |                   { 
 28676 |                      set_error(make_error( 
 28677 |                         parser_error::e_syntax, 
 28678 |                         current_token(), 
 28679 |                         "ERR138 - Expected ',' for call to generic function: " + function_name, 
 28680 |                         exprtk_error_location)); 
 28681 |  
 28682 |                      return error_node(); 
 28683 |                   } 
 28684 |                } 
 28685 |             } 
 28686 |          } 
 28687 |          else if ( 
 28688 |                    !function->parameter_sequence.empty() && 
 28689 |                    function->allow_zero_parameters    () && 
 28690 |                    !tc      .allow_zero_parameters    () 
 28691 |                  ) 
 28692 |          { 
 28693 |             set_error(make_error( 
 28694 |                parser_error::e_syntax, 
 28695 |                current_token(), 
 28696 |                "ERR139 - Zero parameter call to generic function: " 
 28697 |                + function_name + " not allowed", 
 28698 |                exprtk_error_location)); 
 28699 |  
 28700 |             return error_node(); 
 28701 |          } 
 28702 |  
 28703 |          std::size_t param_seq_index = 0; 
 28704 |  
 28705 |          if ( 
 28706 |               state_.type_check_enabled && 
 28707 |               !tc.verify(param_type_list, param_seq_index) 
 28708 |             ) 
 28709 |          { 
 28710 |             set_error(make_error( 
 28711 |                parser_error::e_syntax, 
 28712 |                current_token(), 
 28713 |                "ERR140 - Invalid input parameter sequence for call to generic function: " + function_name, 
 28714 |                exprtk_error_location)); 
 28715 |  
 28716 |             return error_node(); 
 28717 |          } 
 28718 |  
 28719 |          expression_node_ptr result = error_node(); 
 28720 |  
 28721 |          result = (tc.paramseq_count() <= 1) ? 
 28722 |                   expression_generator_ 
 28723 |                        .generic_function_call(function, arg_list) : 
 28724 |                   expression_generator_ 
 28725 |                        .generic_function_call(function, arg_list, param_seq_index); 
 28726 |  
 28727 |          sdd.delete_ptr = (0 == result); 
 28728 |  
 28729 |          return result; 
 28730 |       } 
 28731 |  
 28732 |       inline bool parse_igeneric_function_params(std::string& param_type_list, 
 28733 |                                                  std::vector<expression_node_ptr>& arg_list, 
 28734 |                                                  const std::string& function_name, 
 28735 |                                                  igeneric_function<T>* function, 
 28736 |                                                  const type_checker& tc) 
 28737 |       { 
 28738 |          if (token_is(token_t::e_lbracket)) 
 28739 |          { 
 28740 |             if (token_is(token_t::e_rbracket)) 
 28741 |             { 
 28742 |                if ( 
 28743 |                     !function->allow_zero_parameters() && 
 28744 |                     !tc       .allow_zero_parameters() 
 28745 |                   ) 
 28746 |                { 
 28747 |                   set_error(make_error( 
 28748 |                      parser_error::e_syntax, 
 28749 |                      current_token(), 
 28750 |                      "ERR141 - Zero parameter call to generic function: " 
 28751 |                      + function_name + " not allowed", 
 28752 |                      exprtk_error_location)); 
 28753 |  
 28754 |                   return false; 
 28755 |                } 
 28756 |             } 
 28757 |             else 
 28758 |             { 
 28759 |                for ( ; ; ) 
 28760 |                { 
 28761 |                   expression_node_ptr arg = parse_expression(); 
 28762 |  
 28763 |                   if (0 == arg) 
 28764 |                      return false; 
 28765 |  
 28766 |                   if (is_ivector_node(arg)) 
 28767 |                      param_type_list += 'V'; 
 28768 |                   else if (is_generally_string_node(arg)) 
 28769 |                      param_type_list += 'S'; 
 28770 |                   else // Everything else is a scalar returning expression 
 28771 |                      param_type_list += 'T'; 
 28772 |  
 28773 |                   arg_list.push_back(arg); 
 28774 |  
 28775 |                   if (token_is(token_t::e_rbracket)) 
 28776 |                      break; 
 28777 |                   else if (!token_is(token_t::e_comma)) 
 28778 |                   { 
 28779 |                      set_error(make_error( 
 28780 |                         parser_error::e_syntax, 
 28781 |                         current_token(), 
 28782 |                         "ERR142 - Expected ',' for call to string function: " + function_name, 
 28783 |                         exprtk_error_location)); 
 28784 |  
 28785 |                      return false; 
 28786 |                   } 
 28787 |                } 
 28788 |             } 
 28789 |  
 28790 |             return true; 
 28791 |          } 
 28792 |          else 
 28793 |             return false; 
 28794 |       } 
 28795 |  
 28796 |       #ifndef exprtk_disable_string_capabilities 
 28797 |       inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name) 
 28798 |       { 
 28799 |          // Move pass the function name 
 28800 |          next_token(); 
 28801 |  
 28802 |          std::string param_type_list; 
 28803 |  
 28804 |          type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string); 
 28805 |  
 28806 |          if ( 
 28807 |               (!function->parameter_sequence.empty()) && 
 28808 |               (0 == tc.paramseq_count()) 
 28809 |             ) 
 28810 |          { 
 28811 |             return error_node(); 
 28812 |          } 
 28813 |  
 28814 |          std::vector<expression_node_ptr> arg_list; 
 28815 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28816 |  
 28817 |          if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc)) 
 28818 |          { 
 28819 |             return error_node(); 
 28820 |          } 
 28821 |  
 28822 |          std::size_t param_seq_index = 0; 
 28823 |  
 28824 |          if (!tc.verify(param_type_list, param_seq_index)) 
 28825 |          { 
 28826 |             set_error(make_error( 
 28827 |                parser_error::e_syntax, 
 28828 |                current_token(), 
 28829 |                "ERR143 - Invalid input parameter sequence for call to string function: " + function_name, 
 28830 |                exprtk_error_location)); 
 28831 |  
 28832 |             return error_node(); 
 28833 |          } 
 28834 |  
 28835 |          expression_node_ptr result = error_node(); 
 28836 |  
 28837 |          result = (tc.paramseq_count() <= 1) ? 
 28838 |                   expression_generator_ 
 28839 |                        .string_function_call(function, arg_list) : 
 28840 |                   expression_generator_ 
 28841 |                        .string_function_call(function, arg_list, param_seq_index); 
 28842 |  
 28843 |          sdd.delete_ptr = (0 == result); 
 28844 |  
 28845 |          return result; 
 28846 |       } 
 28847 |  
 28848 |       inline expression_node_ptr parse_overload_function_call(igeneric_function<T>* function, const std::string& function_name) 
 28849 |       { 
 28850 |          // Move pass the function name 
 28851 |          next_token(); 
 28852 |  
 28853 |          std::string param_type_list; 
 28854 |  
 28855 |          type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_overload); 
 28856 |  
 28857 |          if ( 
 28858 |               (!function->parameter_sequence.empty()) && 
 28859 |               (0 == tc.paramseq_count()) 
 28860 |             ) 
 28861 |          { 
 28862 |             return error_node(); 
 28863 |          } 
 28864 |  
 28865 |          std::vector<expression_node_ptr> arg_list; 
 28866 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 28867 |  
 28868 |          if (!parse_igeneric_function_params(param_type_list, arg_list, function_name, function, tc)) 
 28869 |          { 
 28870 |             return error_node(); 
 28871 |          } 
 28872 |  
 28873 |          std::size_t param_seq_index = 0; 
 28874 |  
 28875 |          if (!tc.verify(param_type_list, param_seq_index)) 
 28876 |          { 
 28877 |             set_error(make_error( 
 28878 |                parser_error::e_syntax, 
 28879 |                current_token(), 
 28880 |                "ERR144 - Invalid input parameter sequence for call to overloaded function: " + function_name, 
 28881 |                exprtk_error_location)); 
 28882 |  
 28883 |             return error_node(); 
 28884 |          } 
 28885 |  
 28886 |          expression_node_ptr result = error_node(); 
 28887 |  
 28888 |          if (type_checker::e_numeric == tc.return_type(param_seq_index)) 
 28889 |          { 
 28890 |             if (tc.paramseq_count() <= 1) 
 28891 |                result = expression_generator_ 
 28892 |                           .generic_function_call(function, arg_list); 
 28893 |             else 
 28894 |                result = expression_generator_ 
 28895 |                           .generic_function_call(function, arg_list, param_seq_index); 
 28896 |          } 
 28897 |          else if (type_checker::e_string == tc.return_type(param_seq_index)) 
 28898 |          { 
 28899 |             if (tc.paramseq_count() <= 1) 
 28900 |                result = expression_generator_ 
 28901 |                           .string_function_call(function, arg_list); 
 28902 |             else 
 28903 |                result = expression_generator_ 
 28904 |                           .string_function_call(function, arg_list, param_seq_index); 
 28905 |          } 
 28906 |          else 
 28907 |          { 
 28908 |             set_error(make_error( 
 28909 |                parser_error::e_syntax, 
 28910 |                current_token(), 
 28911 |                "ERR145 - Invalid return type for call to overloaded function: " + function_name, 
 28912 |                exprtk_error_location)); 
 28913 |          } 
 28914 |  
 28915 |          sdd.delete_ptr = (0 == result); 
 28916 |          return result; 
 28917 |       } 
 28918 |       #endif 
 28919 |  
 28920 |       template <typename Type, std::size_t NumberOfParameters> 
 28921 |       struct parse_special_function_impl 
 28922 |       { 
 28923 |          static inline expression_node_ptr process(parser<Type>& p, const details::operator_type opt_type, const std::string& sf_name) 
 28924 |          { 
 28925 |             expression_node_ptr branch[NumberOfParameters]; 
 28926 |             expression_node_ptr result = error_node(); 
 28927 |  
 28928 |             std::fill_n(branch, NumberOfParameters, reinterpret_cast<expression_node_ptr>(0)); 
 28929 |  
 28930 |             scoped_delete<expression_node_t,NumberOfParameters> sd(p,branch); 
 28931 |  
 28932 |             p.next_token(); 
 28933 |  
 28934 |             if (!p.token_is(token_t::e_lbracket)) 
 28935 |             { 
 28936 |                p.set_error(make_error( 
 28937 |                   parser_error::e_syntax, 
 28938 |                   p.current_token(), 
 28939 |                   "ERR146 - Expected '(' for special function '" + sf_name + "'", 
 28940 |                   exprtk_error_location)); 
 28941 |  
 28942 |                return error_node(); 
 28943 |             } 
 28944 |  
 28945 |             for (std::size_t i = 0; i < NumberOfParameters; ++i) 
 28946 |             { 
 28947 |                branch[i] = p.parse_expression(); 
 28948 |  
 28949 |                if (0 == branch[i]) 
 28950 |                { 
 28951 |                   return p.error_node(); 
 28952 |                } 
 28953 |                else if (i < (NumberOfParameters - 1)) 
 28954 |                { 
 28955 |                   if (!p.token_is(token_t::e_comma)) 
 28956 |                   { 
 28957 |                      p.set_error(make_error( 
 28958 |                         parser_error::e_syntax, 
 28959 |                         p.current_token(), 
 28960 |                         "ERR147 - Expected ',' before next parameter of special function '" + sf_name + "'", 
 28961 |                         exprtk_error_location)); 
 28962 |  
 28963 |                      return p.error_node(); 
 28964 |                   } 
 28965 |                } 
 28966 |             } 
 28967 |  
 28968 |             if (!p.token_is(token_t::e_rbracket)) 
 28969 |             { 
 28970 |                p.set_error(make_error( 
 28971 |                   parser_error::e_syntax, 
 28972 |                   p.current_token(), 
 28973 |                   "ERR148 - Invalid number of parameters for special function '" + sf_name + "'", 
 28974 |                   exprtk_error_location)); 
 28975 |  
 28976 |                return p.error_node(); 
 28977 |             } 
 28978 |             else 
 28979 |                result = p.expression_generator_.special_function(opt_type,branch); 
 28980 |  
 28981 |             sd.delete_ptr = (0 == result); 
 28982 |  
 28983 |             return result; 
 28984 |          } 
 28985 |       }; 
 28986 |  
 28987 |       inline expression_node_ptr parse_special_function() 
 28988 |       { 
 28989 |          const std::string sf_name = current_token().value; 
 28990 |  
 28991 |          // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3) 
 28992 |          if ( 
 28993 |               !details::is_digit(sf_name[2]) || 
 28994 |               !details::is_digit(sf_name[3]) 
 28995 |             ) 
 28996 |          { 
 28997 |             set_error(make_error( 
 28998 |                parser_error::e_token, 
 28999 |                current_token(), 
 29000 |                "ERR149 - Invalid special function[1]: " + sf_name, 
 29001 |                exprtk_error_location)); 
 29002 |  
 29003 |             return error_node(); 
 29004 |          } 
 29005 |  
 29006 |          const int id = (sf_name[2] - '0') * 10 + 
 29007 |                         (sf_name[3] - '0'); 
 29008 |  
 29009 |          if (id >= details::e_sffinal) 
 29010 |          { 
 29011 |             set_error(make_error( 
 29012 |                parser_error::e_token, 
 29013 |                current_token(), 
 29014 |                "ERR150 - Invalid special function[2]: " + sf_name, 
 29015 |                exprtk_error_location)); 
 29016 |  
 29017 |             return error_node(); 
 29018 |          } 
 29019 |  
 29020 |          const int sf_3_to_4                   = details::e_sf48; 
 29021 |          const details::operator_type opt_type = details::operator_type(id + 1000); 
 29022 |          const std::size_t NumberOfParameters  = (id < (sf_3_to_4 - 1000)) ? 3U : 4U; 
 29023 |  
 29024 |          switch (NumberOfParameters) 
 29025 |          { 
 29026 |             case 3  : return parse_special_function_impl<T,3>::process((*this), opt_type, sf_name); 
 29027 |             case 4  : return parse_special_function_impl<T,4>::process((*this), opt_type, sf_name); 
 29028 |             default : return error_node(); 
 29029 |          } 
 29030 |       } 
 29031 |  
 29032 |       inline expression_node_ptr parse_null_statement() 
 29033 |       { 
 29034 |          next_token(); 
 29035 |          return node_allocator_.allocate<details::null_node<T> >(); 
 29036 |       } 
 29037 |  
 29038 |       #ifndef exprtk_disable_break_continue 
 29039 |       inline expression_node_ptr parse_break_statement() 
 29040 |       { 
 29041 |          if (state_.parsing_break_stmt) 
 29042 |          { 
 29043 |             set_error(make_error( 
 29044 |                parser_error::e_syntax, 
 29045 |                current_token(), 
 29046 |                "ERR151 - Invoking 'break' within a break call is not allowed", 
 29047 |                exprtk_error_location)); 
 29048 |  
 29049 |             return error_node(); 
 29050 |          } 
 29051 |          else if (0 == state_.parsing_loop_stmt_count) 
 29052 |          { 
 29053 |             set_error(make_error( 
 29054 |                parser_error::e_syntax, 
 29055 |                current_token(), 
 29056 |                "ERR152 - Invalid use of 'break', allowed only in the scope of a loop", 
 29057 |                exprtk_error_location)); 
 29058 |  
 29059 |             return error_node(); 
 29060 |          } 
 29061 |  
 29062 |          scoped_bool_negator sbn(state_.parsing_break_stmt); 
 29063 |  
 29064 |          if (!brkcnt_list_.empty()) 
 29065 |          { 
 29066 |             next_token(); 
 29067 |  
 29068 |             brkcnt_list_.front() = true; 
 29069 |  
 29070 |             expression_node_ptr return_expr = error_node(); 
 29071 |  
 29072 |             if (token_is(token_t::e_lsqrbracket)) 
 29073 |             { 
 29074 |                if (0 == (return_expr = parse_expression())) 
 29075 |                { 
 29076 |                   set_error(make_error( 
 29077 |                      parser_error::e_syntax, 
 29078 |                      current_token(), 
 29079 |                      "ERR153 - Failed to parse return expression for 'break' statement", 
 29080 |                      exprtk_error_location)); 
 29081 |  
 29082 |                   return error_node(); 
 29083 |                } 
 29084 |                else if (!token_is(token_t::e_rsqrbracket)) 
 29085 |                { 
 29086 |                   set_error(make_error( 
 29087 |                      parser_error::e_syntax, 
 29088 |                      current_token(), 
 29089 |                      "ERR154 - Expected ']' at the completion of break's return expression", 
 29090 |                      exprtk_error_location)); 
 29091 |  
 29092 |                   free_node(node_allocator_, return_expr); 
 29093 |  
 29094 |                   return error_node(); 
 29095 |                } 
 29096 |             } 
 29097 |  
 29098 |             state_.activate_side_effect("parse_break_statement()"); 
 29099 |  
 29100 |             return node_allocator_.allocate<details::break_node<T> >(return_expr); 
 29101 |          } 
 29102 |          else 
 29103 |          { 
 29104 |             set_error(make_error( 
 29105 |                parser_error::e_syntax, 
 29106 |                current_token(), 
 29107 |                "ERR155 - Invalid use of 'break', allowed only in the scope of a loop", 
 29108 |                exprtk_error_location)); 
 29109 |          } 
 29110 |  
 29111 |          return error_node(); 
 29112 |       } 
 29113 |  
 29114 |       inline expression_node_ptr parse_continue_statement() 
 29115 |       { 
 29116 |          if (0 == state_.parsing_loop_stmt_count) 
 29117 |          { 
 29118 |             set_error(make_error( 
 29119 |                parser_error::e_syntax, 
 29120 |                current_token(), 
 29121 |                "ERR156 - Invalid use of 'continue', allowed only in the scope of a loop", 
 29122 |                exprtk_error_location)); 
 29123 |  
 29124 |             return error_node(); 
 29125 |          } 
 29126 |          else 
 29127 |          { 
 29128 |             next_token(); 
 29129 |  
 29130 |             brkcnt_list_.front() = true; 
 29131 |             state_.activate_side_effect("parse_continue_statement()"); 
 29132 |  
 29133 |             return node_allocator_.allocate<details::continue_node<T> >(); 
 29134 |          } 
 29135 |       } 
 29136 |       #endif 
 29137 |  
 29138 |       inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name) 
 29139 |       { 
 29140 |          expression_node_ptr size_expression_node = error_node(); 
 29141 |  
 29142 |          if (!token_is(token_t::e_lsqrbracket)) 
 29143 |          { 
 29144 |             set_error(make_error( 
 29145 |                parser_error::e_syntax, 
 29146 |                current_token(), 
 29147 |                "ERR157 - Expected '[' as part of vector size definition", 
 29148 |                exprtk_error_location)); 
 29149 |  
 29150 |             return error_node(); 
 29151 |          } 
 29152 |          else if (0 == (size_expression_node = parse_expression())) 
 29153 |          { 
 29154 |             set_error(make_error( 
 29155 |                parser_error::e_syntax, 
 29156 |                current_token(), 
 29157 |                "ERR158 - Failed to determine size of vector '" + vec_name + "'", 
 29158 |                exprtk_error_location)); 
 29159 |  
 29160 |             return error_node(); 
 29161 |          } 
 29162 |          else if (!is_constant_node(size_expression_node)) 
 29163 |          { 
 29164 |             const bool is_rebaseble_vector = 
 29165 |                (size_expression_node->type() == details::expression_node<T>::e_vecsize) && 
 29166 |                static_cast<details::vector_size_node<T>*>(size_expression_node)->vec_holder()->rebaseable(); 
 29167 |  
 29168 |             free_node(node_allocator_, size_expression_node); 
 29169 |  
 29170 |             const std::string error_msg = (is_rebaseble_vector) ? 
 29171 |                                           std::string("Rebasable/Resizable vector cannot be used to define the size of vector") : 
 29172 |                                           std::string("Expected a constant literal number as size of vector"); 
 29173 |             set_error(make_error( 
 29174 |                parser_error::e_syntax, 
 29175 |                current_token(), 
 29176 |                "ERR159 - " + error_msg + " '" + vec_name + "'", 
 29177 |                exprtk_error_location)); 
 29178 |  
 29179 |             return error_node(); 
 29180 |          } 
 29181 |  
 29182 |          const T vector_size = size_expression_node->value(); 
 29183 |  
 29184 |          free_node(node_allocator_, size_expression_node); 
 29185 |  
 29186 |          const std::size_t max_vector_size = settings_.max_local_vector_size(); 
 29187 |  
 29188 |          if ( 
 29189 |               (vector_size <= T(0)) || 
 29190 |               std::not_equal_to<T>() 
 29191 |               (T(0),vector_size - details::numeric::trunc(vector_size)) || 
 29192 |               (static_cast<std::size_t>(vector_size) > max_vector_size) 
 29193 |             ) 
 29194 |          { 
 29195 |             set_error(make_error( 
 29196 |                parser_error::e_syntax, 
 29197 |                current_token(), 
 29198 |                "ERR160 - Invalid vector size. Must be an integer in the " 
 29199 |                "range [0," + details::to_str(static_cast<std::size_t>(max_vector_size)) + "], size: " + 
 29200 |                details::to_str(details::numeric::to_int32(vector_size)), 
 29201 |                exprtk_error_location)); 
 29202 |  
 29203 |             return error_node(); 
 29204 |          } 
 29205 |  
 29206 |          typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0); 
 29207 |  
 29208 |          const std::size_t vec_size = static_cast<std::size_t>(details::numeric::to_int32(vector_size)); 
 29209 |  
 29210 |          scope_element& se = sem_.get_element(vec_name); 
 29211 |  
 29212 |          if (se.name == vec_name) 
 29213 |          { 
 29214 |             if (se.active) 
 29215 |             { 
 29216 |                set_error(make_error( 
 29217 |                   parser_error::e_syntax, 
 29218 |                   current_token(), 
 29219 |                   "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'", 
 29220 |                   exprtk_error_location)); 
 29221 |  
 29222 |                return error_node(); 
 29223 |             } 
 29224 |             else if ( 
 29225 |                       (se.size == vec_size) && 
 29226 |                       (scope_element::e_vector == se.type) 
 29227 |                     ) 
 29228 |             { 
 29229 |                vec_holder = se.vec_node; 
 29230 |                se.active  = true; 
 29231 |                se.depth   = state_.scope_depth; 
 29232 |                se.ref_count++; 
 29233 |             } 
 29234 |          } 
 29235 |  
 29236 |          if (0 == vec_holder) 
 29237 |          { 
 29238 |             scope_element nse; 
 29239 |             nse.name      = vec_name; 
 29240 |             nse.active    = true; 
 29241 |             nse.ref_count = 1; 
 29242 |             nse.type      = scope_element::e_vector; 
 29243 |             nse.depth     = state_.scope_depth; 
 29244 |             nse.size      = vec_size; 
 29245 |             nse.data      = new T[vec_size]; 
 29246 |             nse.vec_node  = new typename scope_element::vector_holder_t(reinterpret_cast<T*>(nse.data),nse.size); 
 29247 |  
 29248 |             details::set_zero_value(reinterpret_cast<T*>(nse.data),vec_size); 
 29249 |  
 29250 |             if (!sem_.add_element(nse)) 
 29251 |             { 
 29252 |                set_error(make_error( 
 29253 |                   parser_error::e_syntax, 
 29254 |                   current_token(), 
 29255 |                   "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM", 
 29256 |                   exprtk_error_location)); 
 29257 |  
 29258 |                sem_.free_element(nse); 
 29259 |  
 29260 |                return error_node(); 
 29261 |             } 
 29262 |  
 29263 |             vec_holder = nse.vec_node; 
 29264 |  
 29265 |             exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n", 
 29266 |                           nse.name.c_str(), 
 29267 |                           static_cast<int>(nse.size))); 
 29268 |          } 
 29269 |  
 29270 |          state_.activate_side_effect("parse_define_vector_statement()"); 
 29271 |  
 29272 |          lodge_symbol(vec_name, e_st_local_vector); 
 29273 |  
 29274 |          std::vector<expression_node_ptr> vec_initilizer_list; 
 29275 |  
 29276 |          scoped_vec_delete<expression_node_t> svd((*this),vec_initilizer_list); 
 29277 |  
 29278 |          bool single_value_initialiser = false; 
 29279 |          bool range_value_initialiser  = false; 
 29280 |          bool vec_to_vec_initialiser   = false; 
 29281 |          bool null_initialisation      = false; 
 29282 |  
 29283 |          if (!token_is(token_t::e_rsqrbracket)) 
 29284 |          { 
 29285 |             set_error(make_error( 
 29286 |                parser_error::e_syntax, 
 29287 |                current_token(), 
 29288 |                "ERR163 - Expected ']' as part of vector size definition", 
 29289 |                exprtk_error_location)); 
 29290 |  
 29291 |             return error_node(); 
 29292 |          } 
 29293 |          else if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold)) 
 29294 |          { 
 29295 |             if (!token_is(token_t::e_assign)) 
 29296 |             { 
 29297 |                set_error(make_error( 
 29298 |                   parser_error::e_syntax, 
 29299 |                   current_token(), 
 29300 |                   "ERR164 - Expected ':=' as part of vector definition", 
 29301 |                   exprtk_error_location)); 
 29302 |  
 29303 |                return error_node(); 
 29304 |             } 
 29305 |             else if (token_is(token_t::e_lsqrbracket)) 
 29306 |             { 
 29307 |                expression_node_ptr initialiser_component = parse_expression(); 
 29308 |  
 29309 |                if (0 == initialiser_component) 
 29310 |                { 
 29311 |                   set_error(make_error( 
 29312 |                      parser_error::e_syntax, 
 29313 |                      current_token(), 
 29314 |                      "ERR165 - Failed to parse first component of vector initialiser for vector: " + vec_name, 
 29315 |                      exprtk_error_location)); 
 29316 |  
 29317 |                   return error_node(); 
 29318 |                } 
 29319 |  
 29320 |                vec_initilizer_list.push_back(initialiser_component); 
 29321 |  
 29322 |                if (token_is(token_t::e_colon)) 
 29323 |                { 
 29324 |                   initialiser_component = parse_expression(); 
 29325 |  
 29326 |                   if (0 == initialiser_component) 
 29327 |                   { 
 29328 |                      set_error(make_error( 
 29329 |                         parser_error::e_syntax, 
 29330 |                         current_token(), 
 29331 |                         "ERR166 - Failed to parse second component of vector initialiser for vector: " + vec_name, 
 29332 |                         exprtk_error_location)); 
 29333 |  
 29334 |                      return error_node(); 
 29335 |                   } 
 29336 |  
 29337 |                   vec_initilizer_list.push_back(initialiser_component); 
 29338 |                } 
 29339 |  
 29340 |                if (!token_is(token_t::e_rsqrbracket)) 
 29341 |                { 
 29342 |                   set_error(make_error( 
 29343 |                      parser_error::e_syntax, 
 29344 |                      current_token(), 
 29345 |                      "ERR167 - Expected ']' to close single value vector initialiser", 
 29346 |                      exprtk_error_location)); 
 29347 |  
 29348 |                   return error_node(); 
 29349 |                } 
 29350 |  
 29351 |                switch (vec_initilizer_list.size()) 
 29352 |                { 
 29353 |                   case 1 : single_value_initialiser = true; break; 
 29354 |                   case 2 : range_value_initialiser  = true; break; 
 29355 |                } 
 29356 |             } 
 29357 |             else if (!token_is(token_t::e_lcrlbracket)) 
 29358 |             { 
 29359 |                expression_node_ptr initialiser = error_node(); 
 29360 |  
 29361 |                // Is this a vector to vector assignment and initialisation? 
 29362 |                if (token_t::e_symbol == current_token().type) 
 29363 |                { 
 29364 |                   // Is it a locally defined vector? 
 29365 |                   const scope_element& lcl_se = sem_.get_active_element(current_token().value); 
 29366 |  
 29367 |                   if (scope_element::e_vector == lcl_se.type) 
 29368 |                   { 
 29369 |                      if (0 != (initialiser = parse_expression())) 
 29370 |                         vec_initilizer_list.push_back(initialiser); 
 29371 |                      else 
 29372 |                         return error_node(); 
 29373 |                   } 
 29374 |                   // Are we dealing with a user defined vector? 
 29375 |                   else if (symtab_store_.is_vector(current_token().value)) 
 29376 |                   { 
 29377 |                      lodge_symbol(current_token().value, e_st_vector); 
 29378 |  
 29379 |                      if (0 != (initialiser = parse_expression())) 
 29380 |                         vec_initilizer_list.push_back(initialiser); 
 29381 |                      else 
 29382 |                         return error_node(); 
 29383 |                   } 
 29384 |                   // Are we dealing with a null initialisation vector definition? 
 29385 |                   else if (token_is(token_t::e_symbol,"null")) 
 29386 |                      null_initialisation = true; 
 29387 |                } 
 29388 |  
 29389 |                if (!null_initialisation) 
 29390 |                { 
 29391 |                   if (0 == initialiser) 
 29392 |                   { 
 29393 |                      set_error(make_error( 
 29394 |                         parser_error::e_syntax, 
 29395 |                         current_token(), 
 29396 |                         "ERR168 - Expected '{' as part of vector initialiser list", 
 29397 |                         exprtk_error_location)); 
 29398 |  
 29399 |                      return error_node(); 
 29400 |                   } 
 29401 |                   else 
 29402 |                      vec_to_vec_initialiser = true; 
 29403 |                } 
 29404 |             } 
 29405 |             else if (!token_is(token_t::e_rcrlbracket)) 
 29406 |             { 
 29407 |                for ( ; ; ) 
 29408 |                { 
 29409 |                   expression_node_ptr initialiser = parse_expression(); 
 29410 |  
 29411 |                   if (0 == initialiser) 
 29412 |                   { 
 29413 |                      set_error(make_error( 
 29414 |                         parser_error::e_syntax, 
 29415 |                         current_token(), 
 29416 |                         "ERR169 - Expected '{' as part of vector initialiser list", 
 29417 |                         exprtk_error_location)); 
 29418 |  
 29419 |                      return error_node(); 
 29420 |                   } 
 29421 |                   else 
 29422 |                      vec_initilizer_list.push_back(initialiser); 
 29423 |  
 29424 |                   if (token_is(token_t::e_rcrlbracket)) 
 29425 |                      break; 
 29426 |  
 29427 |                   const bool is_next_close = peek_token_is(token_t::e_rcrlbracket); 
 29428 |  
 29429 |                   if (!token_is(token_t::e_comma) && is_next_close) 
 29430 |                   { 
 29431 |                      set_error(make_error( 
 29432 |                         parser_error::e_syntax, 
 29433 |                         current_token(), 
 29434 |                         "ERR170 - Expected ',' between vector initialisers", 
 29435 |                         exprtk_error_location)); 
 29436 |  
 29437 |                      return error_node(); 
 29438 |                   } 
 29439 |  
 29440 |                   if (token_is(token_t::e_rcrlbracket)) 
 29441 |                      break; 
 29442 |                } 
 29443 |             } 
 29444 |  
 29445 |             if ( 
 29446 |                  !token_is(token_t::e_rbracket   , prsrhlpr_t::e_hold) && 
 29447 |                  !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) && 
 29448 |                  !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold) 
 29449 |                ) 
 29450 |             { 
 29451 |                if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 29452 |                { 
 29453 |                   set_error(make_error( 
 29454 |                      parser_error::e_syntax, 
 29455 |                      current_token(), 
 29456 |                      "ERR171 - Expected ';' at end of vector definition", 
 29457 |                      exprtk_error_location)); 
 29458 |  
 29459 |                   return error_node(); 
 29460 |                } 
 29461 |             } 
 29462 |  
 29463 |             if ( 
 29464 |                  !single_value_initialiser && 
 29465 |                  !range_value_initialiser  && 
 29466 |                  (T(vec_initilizer_list.size()) > vector_size) 
 29467 |                ) 
 29468 |             { 
 29469 |                set_error(make_error( 
 29470 |                   parser_error::e_syntax, 
 29471 |                   current_token(), 
 29472 |                   "ERR172 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", 
 29473 |                   exprtk_error_location)); 
 29474 |  
 29475 |                return error_node(); 
 29476 |             } 
 29477 |          } 
 29478 |  
 29479 |          expression_node_ptr result = error_node(); 
 29480 |  
 29481 |          if ( 
 29482 |               (vec_initilizer_list.size() == 1) && 
 29483 |               single_value_initialiser 
 29484 |             ) 
 29485 |          { 
 29486 |             if (details::is_constant_node(vec_initilizer_list[0])) 
 29487 |             { 
 29488 |               // vector_init_zero_value_node   var v[10] := [0] 
 29489 |                if (T(0) == vec_initilizer_list[0]->value()) 
 29490 |                { 
 29491 |                   result = node_allocator_ 
 29492 |                               .allocate<details::vector_init_zero_value_node<T> >( 
 29493 |                                  (*vec_holder)[0], 
 29494 |                                  vec_size, 
 29495 |                                  vec_initilizer_list); 
 29496 |                } 
 29497 |                else 
 29498 |                { 
 29499 |                   // vector_init_single_constvalue_node   var v[10] := [123] 
 29500 |                   result = node_allocator_ 
 29501 |                               .allocate<details::vector_init_single_constvalue_node<T> >( 
 29502 |                                  (*vec_holder)[0], 
 29503 |                                  vec_size, 
 29504 |                                  vec_initilizer_list); 
 29505 |                } 
 29506 |             } 
 29507 |             else 
 29508 |             { 
 29509 |                // vector_init_single_value_node   var v[10] := [123 + (x / y)] 
 29510 |                result = node_allocator_ 
 29511 |                            .allocate<details::vector_init_single_value_node<T> >( 
 29512 |                               (*vec_holder)[0], 
 29513 |                               vec_size, 
 29514 |                               vec_initilizer_list); 
 29515 |             } 
 29516 |          } 
 29517 |          else if ( 
 29518 |                    (vec_initilizer_list.size() == 2) && 
 29519 |                    range_value_initialiser 
 29520 |                  ) 
 29521 |          { 
 29522 |             bool base_const = details::is_constant_node(vec_initilizer_list[0]); 
 29523 |             bool inc_const  = details::is_constant_node(vec_initilizer_list[1]); 
 29524 |  
 29525 |             if (base_const && inc_const) 
 29526 |             { 
 29527 |                // vector_init_single_value_node   var v[10] := [1 : 3.5] 
 29528 |                result = node_allocator_ 
 29529 |                            .allocate<details::vector_init_iota_constconst_node<T> >( 
 29530 |                               (*vec_holder)[0], 
 29531 |                               vec_size, 
 29532 |                               vec_initilizer_list); 
 29533 |             } 
 29534 |             else if (base_const && !inc_const) 
 29535 |             { 
 29536 |                // vector_init_single_value_node   var v[10] := [1 : x + y] 
 29537 |                result = node_allocator_ 
 29538 |                            .allocate<details::vector_init_iota_constnconst_node<T> >( 
 29539 |                               (*vec_holder)[0], 
 29540 |                               vec_size, 
 29541 |                               vec_initilizer_list); 
 29542 |             } 
 29543 |             else if (!base_const && inc_const) 
 29544 |             { 
 29545 |                // vector_init_single_value_node   var v[10] := [x + y : 3] 
 29546 |                result = node_allocator_ 
 29547 |                            .allocate<details::vector_init_iota_nconstconst_node<T> >( 
 29548 |                               (*vec_holder)[0], 
 29549 |                               vec_size, 
 29550 |                               vec_initilizer_list); 
 29551 |             } 
 29552 |             else if (!base_const && !inc_const) 
 29553 |             { 
 29554 |                // vector_init_single_value_node   var v[10] := [x + y :  z / w] 
 29555 |                result = node_allocator_ 
 29556 |                            .allocate<details::vector_init_iota_nconstnconst_node<T> >( 
 29557 |                               (*vec_holder)[0], 
 29558 |                               vec_size, 
 29559 |                               vec_initilizer_list); 
 29560 |             } 
 29561 |          } 
 29562 |          else if (null_initialisation) 
 29563 |             result = expression_generator_(T(0.0)); 
 29564 |          else if (vec_to_vec_initialiser) 
 29565 |          { 
 29566 |             expression_node_ptr vec_node = node_allocator_.allocate<vector_node_t>(vec_holder); 
 29567 |  
 29568 |             result = expression_generator_( 
 29569 |                         details::e_assign, 
 29570 |                         vec_node, 
 29571 |                         vec_initilizer_list[0]); 
 29572 |          } 
 29573 |          else 
 29574 |          { 
 29575 |             result = node_allocator_ 
 29576 |                         .allocate<details::vector_initialisation_node<T> >( 
 29577 |                            (*vec_holder)[0], 
 29578 |                            vec_size, 
 29579 |                            vec_initilizer_list, 
 29580 |                            single_value_initialiser); 
 29581 |          } 
 29582 |  
 29583 |          svd.delete_ptr = false; 
 29584 |  
 29585 |          if (result && result->valid()) 
 29586 |          { 
 29587 |             return result; 
 29588 |          } 
 29589 |  
 29590 |          details::free_node(node_allocator_, result); 
 29591 |  
 29592 |          set_error(make_error( 
 29593 |             parser_error::e_synthesis, 
 29594 |             current_token(), 
 29595 |             "ERR173 - Failed to generate initialisation node for vector: " + vec_name, 
 29596 |             exprtk_error_location)); 
 29597 |  
 29598 |          return error_node(); 
 29599 |       } 
 29600 |  
 29601 |       #ifndef exprtk_disable_string_capabilities 
 29602 |       inline expression_node_ptr parse_define_string_statement(const std::string& str_name, expression_node_ptr initialisation_expression) 
 29603 |       { 
 29604 |          stringvar_node_t* str_node = reinterpret_cast<stringvar_node_t*>(0); 
 29605 |  
 29606 |          scope_element& se = sem_.get_element(str_name); 
 29607 |  
 29608 |          if (se.name == str_name) 
 29609 |          { 
 29610 |             if (se.active) 
 29611 |             { 
 29612 |                set_error(make_error( 
 29613 |                   parser_error::e_syntax, 
 29614 |                   current_token(), 
 29615 |                   "ERR174 - Illegal redefinition of local variable: '" + str_name + "'", 
 29616 |                   exprtk_error_location)); 
 29617 |  
 29618 |                free_node(node_allocator_, initialisation_expression); 
 29619 |  
 29620 |                return error_node(); 
 29621 |             } 
 29622 |             else if (scope_element::e_string == se.type) 
 29623 |             { 
 29624 |                str_node  = se.str_node; 
 29625 |                se.active = true; 
 29626 |                se.depth  = state_.scope_depth; 
 29627 |                se.ref_count++; 
 29628 |             } 
 29629 |          } 
 29630 |  
 29631 |          if (0 == str_node) 
 29632 |          { 
 29633 |             scope_element nse; 
 29634 |             nse.name      = str_name; 
 29635 |             nse.active    = true; 
 29636 |             nse.ref_count = 1; 
 29637 |             nse.type      = scope_element::e_string; 
 29638 |             nse.depth     = state_.scope_depth; 
 29639 |             nse.data      = new std::string; 
 29640 |             nse.str_node  = new stringvar_node_t(*reinterpret_cast<std::string*>(nse.data)); 
 29641 |  
 29642 |             if (!sem_.add_element(nse)) 
 29643 |             { 
 29644 |                set_error(make_error( 
 29645 |                   parser_error::e_syntax, 
 29646 |                   current_token(), 
 29647 |                   "ERR175 - Failed to add new local string variable '" + str_name + "' to SEM", 
 29648 |                   exprtk_error_location)); 
 29649 |  
 29650 |                free_node(node_allocator_, initialisation_expression); 
 29651 |  
 29652 |                sem_.free_element(nse); 
 29653 |  
 29654 |                return error_node(); 
 29655 |             } 
 29656 |  
 29657 |             str_node = nse.str_node; 
 29658 |  
 29659 |             exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n", nse.name.c_str())); 
 29660 |          } 
 29661 |  
 29662 |          lodge_symbol(str_name, e_st_local_string); 
 29663 |  
 29664 |          state_.activate_side_effect("parse_define_string_statement()"); 
 29665 |  
 29666 |          expression_node_ptr branch[2] = {0}; 
 29667 |  
 29668 |          branch[0] = str_node; 
 29669 |          branch[1] = initialisation_expression; 
 29670 |  
 29671 |          return expression_generator_(details::e_assign,branch); 
 29672 |       } 
 29673 |       #else 
 29674 |       inline expression_node_ptr parse_define_string_statement(const std::string&, expression_node_ptr) 
 29675 |       { 
 29676 |          return error_node(); 
 29677 |       } 
 29678 |       #endif 
 29679 |  
 29680 |       inline bool local_variable_is_shadowed(const std::string& symbol) 
 29681 |       { 
 29682 |          const scope_element& se = sem_.get_element(symbol); 
 29683 |          return (se.name == symbol) && se.active; 
 29684 |       } 
 29685 |  
 29686 |       inline expression_node_ptr parse_define_var_statement() 
 29687 |       { 
 29688 |          if (settings_.vardef_disabled()) 
 29689 |          { 
 29690 |             set_error(make_error( 
 29691 |                parser_error::e_syntax, 
 29692 |                current_token(), 
 29693 |                "ERR176 - Illegal variable definition", 
 29694 |                exprtk_error_location)); 
 29695 |  
 29696 |             return error_node(); 
 29697 |          } 
 29698 |          else if (!details::imatch(current_token().value,"var")) 
 29699 |          { 
 29700 |             return error_node(); 
 29701 |          } 
 29702 |          else 
 29703 |             next_token(); 
 29704 |  
 29705 |          const std::string var_name = current_token().value; 
 29706 |  
 29707 |          expression_node_ptr initialisation_expression = error_node(); 
 29708 |  
 29709 |          if (!token_is(token_t::e_symbol)) 
 29710 |          { 
 29711 |             set_error(make_error( 
 29712 |                parser_error::e_syntax, 
 29713 |                current_token(), 
 29714 |                "ERR177 - Expected a symbol for variable definition", 
 29715 |                exprtk_error_location)); 
 29716 |  
 29717 |             return error_node(); 
 29718 |          } 
 29719 |          else if (details::is_reserved_symbol(var_name)) 
 29720 |          { 
 29721 |             set_error(make_error( 
 29722 |                parser_error::e_syntax, 
 29723 |                current_token(), 
 29724 |                "ERR178 - Illegal redefinition of reserved keyword: '" + var_name + "'", 
 29725 |                exprtk_error_location)); 
 29726 |  
 29727 |             return error_node(); 
 29728 |          } 
 29729 |          else if (symtab_store_.symbol_exists(var_name)) 
 29730 |          { 
 29731 |             set_error(make_error( 
 29732 |                parser_error::e_syntax, 
 29733 |                current_token(), 
 29734 |                "ERR179 - Illegal redefinition of variable '" + var_name + "'", 
 29735 |                exprtk_error_location)); 
 29736 |  
 29737 |             return error_node(); 
 29738 |          } 
 29739 |          else if (local_variable_is_shadowed(var_name)) 
 29740 |          { 
 29741 |             set_error(make_error( 
 29742 |                parser_error::e_syntax, 
 29743 |                current_token(), 
 29744 |                "ERR180 - Illegal redefinition of local variable: '" + var_name + "'", 
 29745 |                exprtk_error_location)); 
 29746 |  
 29747 |             return error_node(); 
 29748 |          } 
 29749 |          else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)) 
 29750 |          { 
 29751 |             return parse_define_vector_statement(var_name); 
 29752 |          } 
 29753 |          else if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) 
 29754 |          { 
 29755 |             return parse_uninitialised_var_statement(var_name); 
 29756 |          } 
 29757 |          else if (token_is(token_t::e_assign)) 
 29758 |          { 
 29759 |             if (0 == (initialisation_expression = parse_expression())) 
 29760 |             { 
 29761 |                set_error(make_error( 
 29762 |                   parser_error::e_syntax, 
 29763 |                   current_token(), 
 29764 |                   "ERR181 - Failed to parse initialisation expression for variable '" + var_name + "'", 
 29765 |                   exprtk_error_location)); 
 29766 |  
 29767 |                return error_node(); 
 29768 |             } 
 29769 |          } 
 29770 |  
 29771 |          if ( 
 29772 |               !token_is(token_t::e_rbracket   , prsrhlpr_t::e_hold) && 
 29773 |               !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) && 
 29774 |               !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold) 
 29775 |             ) 
 29776 |          { 
 29777 |             if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 29778 |             { 
 29779 |                set_error(make_error( 
 29780 |                   parser_error::e_syntax, 
 29781 |                   current_token(), 
 29782 |                   "ERR182 - Expected ';' after variable '" + var_name + "' definition", 
 29783 |                   exprtk_error_location)); 
 29784 |  
 29785 |                free_node(node_allocator_, initialisation_expression); 
 29786 |  
 29787 |                return error_node(); 
 29788 |             } 
 29789 |          } 
 29790 |  
 29791 |          if ( 
 29792 |               (0 != initialisation_expression) && 
 29793 |               details::is_generally_string_node(initialisation_expression) 
 29794 |             ) 
 29795 |          { 
 29796 |             return parse_define_string_statement(var_name,initialisation_expression); 
 29797 |          } 
 29798 |  
 29799 |          expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0); 
 29800 |  
 29801 |          scope_element& se = sem_.get_element(var_name); 
 29802 |  
 29803 |          if (se.name == var_name) 
 29804 |          { 
 29805 |             if (se.active) 
 29806 |             { 
 29807 |                set_error(make_error( 
 29808 |                   parser_error::e_syntax, 
 29809 |                   current_token(), 
 29810 |                   "ERR183 - Illegal redefinition of local variable: '" + var_name + "'", 
 29811 |                   exprtk_error_location)); 
 29812 |  
 29813 |                free_node(node_allocator_, initialisation_expression); 
 29814 |  
 29815 |                return error_node(); 
 29816 |             } 
 29817 |             else if (scope_element::e_variable == se.type) 
 29818 |             { 
 29819 |                var_node  = se.var_node; 
 29820 |                se.active = true; 
 29821 |                se.depth  = state_.scope_depth; 
 29822 |                se.ref_count++; 
 29823 |             } 
 29824 |          } 
 29825 |  
 29826 |          if (0 == var_node) 
 29827 |          { 
 29828 |             scope_element nse; 
 29829 |             nse.name      = var_name; 
 29830 |             nse.active    = true; 
 29831 |             nse.ref_count = 1; 
 29832 |             nse.type      = scope_element::e_variable; 
 29833 |             nse.depth     = state_.scope_depth; 
 29834 |             nse.data      = new T(T(0)); 
 29835 |             nse.var_node  = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data)); 
 29836 |  
 29837 |             if (!sem_.add_element(nse)) 
 29838 |             { 
 29839 |                set_error(make_error( 
 29840 |                   parser_error::e_syntax, 
 29841 |                   current_token(), 
 29842 |                   "ERR184 - Failed to add new local variable '" + var_name + "' to SEM", 
 29843 |                   exprtk_error_location)); 
 29844 |  
 29845 |                free_node(node_allocator_, initialisation_expression); 
 29846 |  
 29847 |                sem_.free_element(nse); 
 29848 |  
 29849 |                return error_node(); 
 29850 |             } 
 29851 |  
 29852 |             var_node = nse.var_node; 
 29853 |  
 29854 |             exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n", nse.name.c_str())); 
 29855 |          } 
 29856 |  
 29857 |          state_.activate_side_effect("parse_define_var_statement()"); 
 29858 |  
 29859 |          lodge_symbol(var_name, e_st_local_variable); 
 29860 |  
 29861 |          expression_node_ptr branch[2] = {0}; 
 29862 |  
 29863 |          branch[0] = var_node; 
 29864 |          branch[1] = initialisation_expression ? initialisation_expression : expression_generator_(T(0)); 
 29865 |  
 29866 |          return expression_generator_(details::e_assign,branch); 
 29867 |       } 
 29868 |  
 29869 |       inline expression_node_ptr parse_define_constvar_statement() 
 29870 |       { 
 29871 |          if (settings_.vardef_disabled()) 
 29872 |          { 
 29873 |             set_error(make_error( 
 29874 |                parser_error::e_syntax, 
 29875 |                current_token(), 
 29876 |                "ERR185 - Illegal const variable definition", 
 29877 |                exprtk_error_location)); 
 29878 |  
 29879 |             return error_node(); 
 29880 |          } 
 29881 |          else if (!token_is("const")) 
 29882 |          { 
 29883 |             set_error(make_error( 
 29884 |                parser_error::e_syntax, 
 29885 |                current_token(), 
 29886 |                "ERR186 - Expected 'const' keyword for const-variable definition", 
 29887 |                exprtk_error_location)); 
 29888 |  
 29889 |             return error_node(); 
 29890 |          } 
 29891 |          else if (!token_is("var")) 
 29892 |          { 
 29893 |             set_error(make_error( 
 29894 |                parser_error::e_syntax, 
 29895 |                current_token(), 
 29896 |                "ERR187 - Expected 'var' keyword for const-variable definition", 
 29897 |                exprtk_error_location)); 
 29898 |  
 29899 |             return error_node(); 
 29900 |          } 
 29901 |  
 29902 |          const std::string var_name = current_token().value; 
 29903 |  
 29904 |          expression_node_ptr initialisation_expression = error_node(); 
 29905 |  
 29906 |          if (!token_is(token_t::e_symbol)) 
 29907 |          { 
 29908 |             set_error(make_error( 
 29909 |                parser_error::e_syntax, 
 29910 |                current_token(), 
 29911 |                "ERR188 - Expected a symbol for const-variable definition", 
 29912 |                exprtk_error_location)); 
 29913 |  
 29914 |             return error_node(); 
 29915 |          } 
 29916 |          else if (details::is_reserved_symbol(var_name)) 
 29917 |          { 
 29918 |             set_error(make_error( 
 29919 |                parser_error::e_syntax, 
 29920 |                current_token(), 
 29921 |                "ERR189 - Illegal redefinition of reserved keyword: '" + var_name + "'", 
 29922 |                exprtk_error_location)); 
 29923 |  
 29924 |             return error_node(); 
 29925 |          } 
 29926 |          else if (symtab_store_.symbol_exists(var_name)) 
 29927 |          { 
 29928 |             set_error(make_error( 
 29929 |                parser_error::e_syntax, 
 29930 |                current_token(), 
 29931 |                "ERR190 - Illegal redefinition of variable '" + var_name + "'", 
 29932 |                exprtk_error_location)); 
 29933 |  
 29934 |             return error_node(); 
 29935 |          } 
 29936 |          else if (local_variable_is_shadowed(var_name)) 
 29937 |          { 
 29938 |             set_error(make_error( 
 29939 |                parser_error::e_syntax, 
 29940 |                current_token(), 
 29941 |                "ERR191 - Illegal redefinition of local variable: '" + var_name + "'", 
 29942 |                exprtk_error_location)); 
 29943 |  
 29944 |             return error_node(); 
 29945 |          } 
 29946 |          else if (token_is(token_t::e_assign)) 
 29947 |          { 
 29948 |             if (0 == (initialisation_expression = parse_expression())) 
 29949 |             { 
 29950 |                set_error(make_error( 
 29951 |                   parser_error::e_syntax, 
 29952 |                   current_token(), 
 29953 |                   "ERR192 - Failed to parse initialisation expression for const-variable: '" + var_name + "'", 
 29954 |                   exprtk_error_location)); 
 29955 |  
 29956 |                return error_node(); 
 29957 |             } 
 29958 |             else if (!details::is_literal_node(initialisation_expression)) 
 29959 |             { 
 29960 |                set_error(make_error( 
 29961 |                   parser_error::e_syntax, 
 29962 |                   current_token(), 
 29963 |                   "ERR193 - initialisation expression for const-variable: '" + var_name + "' must be a constant/literal", 
 29964 |                   exprtk_error_location)); 
 29965 |  
 29966 |                free_node(node_allocator_, initialisation_expression); 
 29967 |  
 29968 |                return error_node(); 
 29969 |             } 
 29970 |          } 
 29971 |  
 29972 |          const T init_value = initialisation_expression->value(); 
 29973 |  
 29974 |          free_node(node_allocator_, initialisation_expression); 
 29975 |  
 29976 |          expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0); 
 29977 |  
 29978 |          scope_element& se = sem_.get_element(var_name); 
 29979 |  
 29980 |          if (se.name == var_name) 
 29981 |          { 
 29982 |             if (se.active) 
 29983 |             { 
 29984 |                set_error(make_error( 
 29985 |                   parser_error::e_syntax, 
 29986 |                   current_token(), 
 29987 |                   "ERR194 - Illegal redefinition of local variable: '" + var_name + "'", 
 29988 |                   exprtk_error_location)); 
 29989 |  
 29990 |                return error_node(); 
 29991 |             } 
 29992 |             else if (scope_element::e_literal == se.type) 
 29993 |             { 
 29994 |                var_node  = se.var_node; 
 29995 |                se.active = true; 
 29996 |                se.depth  = state_.scope_depth; 
 29997 |                se.ref_count++; 
 29998 |             } 
 29999 |          } 
 30000 |  
 30001 |          if (0 == var_node) 
 30002 |          { 
 30003 |             scope_element nse; 
 30004 |             nse.name      = var_name; 
 30005 |             nse.active    = true; 
 30006 |             nse.ref_count = 1; 
 30007 |             nse.type      = scope_element::e_literal; 
 30008 |             nse.depth     = state_.scope_depth; 
 30009 |             nse.data      = 0; 
 30010 |             nse.var_node  = node_allocator_.allocate<literal_node_t>(init_value); 
 30011 |  
 30012 |             if (!sem_.add_element(nse)) 
 30013 |             { 
 30014 |                set_error(make_error( 
 30015 |                   parser_error::e_syntax, 
 30016 |                   current_token(), 
 30017 |                   "ERR195 - Failed to add new local const-variable '" + var_name + "' to SEM", 
 30018 |                   exprtk_error_location)); 
 30019 |  
 30020 |                sem_.free_element(nse); 
 30021 |  
 30022 |                return error_node(); 
 30023 |             } 
 30024 |  
 30025 |             var_node = nse.var_node; 
 30026 |  
 30027 |             exprtk_debug(("parse_define_constvar_statement() - INFO - Added new local const-variable: %s\n", nse.name.c_str())); 
 30028 |          } 
 30029 |  
 30030 |          state_.activate_side_effect("parse_define_constvar_statement()"); 
 30031 |  
 30032 |          lodge_symbol(var_name, e_st_local_variable); 
 30033 |  
 30034 |          return expression_generator_(var_node->value()); 
 30035 |       } 
 30036 |  
 30037 |       inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name) 
 30038 |       { 
 30039 |          if ( 
 30040 |               !token_is(token_t::e_lcrlbracket) || 
 30041 |               !token_is(token_t::e_rcrlbracket) 
 30042 |             ) 
 30043 |          { 
 30044 |             set_error(make_error( 
 30045 |                parser_error::e_syntax, 
 30046 |                current_token(), 
 30047 |                "ERR196 - Expected a '{}' for uninitialised var definition", 
 30048 |                exprtk_error_location)); 
 30049 |  
 30050 |             return error_node(); 
 30051 |          } 
 30052 |          else if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) 
 30053 |          { 
 30054 |             set_error(make_error( 
 30055 |                parser_error::e_syntax, 
 30056 |                current_token(), 
 30057 |                "ERR197 - Expected ';' after uninitialised variable definition", 
 30058 |                exprtk_error_location)); 
 30059 |  
 30060 |             return error_node(); 
 30061 |          } 
 30062 |  
 30063 |          expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0); 
 30064 |  
 30065 |          scope_element& se = sem_.get_element(var_name); 
 30066 |  
 30067 |          if (se.name == var_name) 
 30068 |          { 
 30069 |             if (se.active) 
 30070 |             { 
 30071 |                set_error(make_error( 
 30072 |                   parser_error::e_syntax, 
 30073 |                   current_token(), 
 30074 |                   "ERR198 - Illegal redefinition of local variable: '" + var_name + "'", 
 30075 |                   exprtk_error_location)); 
 30076 |  
 30077 |                return error_node(); 
 30078 |             } 
 30079 |             else if (scope_element::e_variable == se.type) 
 30080 |             { 
 30081 |                var_node  = se.var_node; 
 30082 |                se.active = true; 
 30083 |                se.ref_count++; 
 30084 |             } 
 30085 |          } 
 30086 |  
 30087 |          if (0 == var_node) 
 30088 |          { 
 30089 |             scope_element nse; 
 30090 |             nse.name      = var_name; 
 30091 |             nse.active    = true; 
 30092 |             nse.ref_count = 1; 
 30093 |             nse.type      = scope_element::e_variable; 
 30094 |             nse.depth     = state_.scope_depth; 
 30095 |             nse.ip_index  = sem_.next_ip_index(); 
 30096 |             nse.data      = new T(T(0)); 
 30097 |             nse.var_node  = node_allocator_.allocate<variable_node_t>(*reinterpret_cast<T*>(nse.data)); 
 30098 |  
 30099 |             if (!sem_.add_element(nse)) 
 30100 |             { 
 30101 |                set_error(make_error( 
 30102 |                   parser_error::e_syntax, 
 30103 |                   current_token(), 
 30104 |                   "ERR199 - Failed to add new local variable '" + var_name + "' to SEM", 
 30105 |                   exprtk_error_location)); 
 30106 |  
 30107 |                sem_.free_element(nse); 
 30108 |  
 30109 |                return error_node(); 
 30110 |             } 
 30111 |  
 30112 |             exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n", 
 30113 |                           nse.name.c_str())); 
 30114 |          } 
 30115 |  
 30116 |          lodge_symbol(var_name, e_st_local_variable); 
 30117 |  
 30118 |          state_.activate_side_effect("parse_uninitialised_var_statement()"); 
 30119 |  
 30120 |          return expression_generator_(T(0)); 
 30121 |       } 
 30122 |  
 30123 |       inline expression_node_ptr parse_swap_statement() 
 30124 |       { 
 30125 |          if (!details::imatch(current_token().value,"swap")) 
 30126 |          { 
 30127 |             return error_node(); 
 30128 |          } 
 30129 |          else 
 30130 |             next_token(); 
 30131 |  
 30132 |          if (!token_is(token_t::e_lbracket)) 
 30133 |          { 
 30134 |             set_error(make_error( 
 30135 |                parser_error::e_syntax, 
 30136 |                current_token(), 
 30137 |                "ERR200 - Expected '(' at start of swap statement", 
 30138 |                exprtk_error_location)); 
 30139 |  
 30140 |             return error_node(); 
 30141 |          } 
 30142 |  
 30143 |          expression_node_ptr variable0 = error_node(); 
 30144 |          expression_node_ptr variable1 = error_node(); 
 30145 |  
 30146 |          bool variable0_generated = false; 
 30147 |          bool variable1_generated = false; 
 30148 |  
 30149 |          const std::string var0_name = current_token().value; 
 30150 |  
 30151 |          if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) 
 30152 |          { 
 30153 |             set_error(make_error( 
 30154 |                parser_error::e_syntax, 
 30155 |                current_token(), 
 30156 |                "ERR201 - Expected a symbol for variable or vector element definition", 
 30157 |                exprtk_error_location)); 
 30158 |  
 30159 |             return error_node(); 
 30160 |          } 
 30161 |          else if (peek_token_is(token_t::e_lsqrbracket)) 
 30162 |          { 
 30163 |             if (0 == (variable0 = parse_vector())) 
 30164 |             { 
 30165 |                set_error(make_error( 
 30166 |                   parser_error::e_syntax, 
 30167 |                   current_token(), 
 30168 |                   "ERR202 - First parameter to swap is an invalid vector element: '" + var0_name + "'", 
 30169 |                   exprtk_error_location)); 
 30170 |  
 30171 |                return error_node(); 
 30172 |             } 
 30173 |  
 30174 |             variable0_generated = true; 
 30175 |          } 
 30176 |          else 
 30177 |          { 
 30178 |             if (symtab_store_.is_variable(var0_name)) 
 30179 |             { 
 30180 |                variable0 = symtab_store_.get_variable(var0_name); 
 30181 |             } 
 30182 |  
 30183 |             const scope_element& se = sem_.get_element(var0_name); 
 30184 |  
 30185 |             if ( 
 30186 |                  (se.active)            && 
 30187 |                  (se.name == var0_name) && 
 30188 |                  (scope_element::e_variable == se.type) 
 30189 |                ) 
 30190 |             { 
 30191 |                variable0 = se.var_node; 
 30192 |             } 
 30193 |  
 30194 |             lodge_symbol(var0_name, e_st_variable); 
 30195 |  
 30196 |             if (0 == variable0) 
 30197 |             { 
 30198 |                set_error(make_error( 
 30199 |                   parser_error::e_syntax, 
 30200 |                   current_token(), 
 30201 |                   "ERR203 - First parameter to swap is an invalid variable: '" + var0_name + "'", 
 30202 |                   exprtk_error_location)); 
 30203 |  
 30204 |                return error_node(); 
 30205 |             } 
 30206 |             else 
 30207 |                next_token(); 
 30208 |          } 
 30209 |  
 30210 |          if (!token_is(token_t::e_comma)) 
 30211 |          { 
 30212 |             set_error(make_error( 
 30213 |                parser_error::e_syntax, 
 30214 |                current_token(), 
 30215 |                "ERR204 - Expected ',' between parameters to swap", 
 30216 |                exprtk_error_location)); 
 30217 |  
 30218 |             if (variable0_generated) 
 30219 |             { 
 30220 |                free_node(node_allocator_, variable0); 
 30221 |             } 
 30222 |  
 30223 |             return error_node(); 
 30224 |          } 
 30225 |  
 30226 |          const std::string var1_name = current_token().value; 
 30227 |  
 30228 |          if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) 
 30229 |          { 
 30230 |             set_error(make_error( 
 30231 |                parser_error::e_syntax, 
 30232 |                current_token(), 
 30233 |                "ERR205 - Expected a symbol for variable or vector element definition", 
 30234 |                exprtk_error_location)); 
 30235 |  
 30236 |             if (variable0_generated) 
 30237 |             { 
 30238 |                free_node(node_allocator_, variable0); 
 30239 |             } 
 30240 |  
 30241 |             return error_node(); 
 30242 |          } 
 30243 |          else if (peek_token_is(token_t::e_lsqrbracket)) 
 30244 |          { 
 30245 |             if (0 == (variable1 = parse_vector())) 
 30246 |             { 
 30247 |                set_error(make_error( 
 30248 |                   parser_error::e_syntax, 
 30249 |                   current_token(), 
 30250 |                   "ERR206 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", 
 30251 |                   exprtk_error_location)); 
 30252 |  
 30253 |                if (variable0_generated) 
 30254 |                { 
 30255 |                   free_node(node_allocator_, variable0); 
 30256 |                } 
 30257 |  
 30258 |                return error_node(); 
 30259 |             } 
 30260 |  
 30261 |             variable1_generated = true; 
 30262 |          } 
 30263 |          else 
 30264 |          { 
 30265 |             if (symtab_store_.is_variable(var1_name)) 
 30266 |             { 
 30267 |                variable1 = symtab_store_.get_variable(var1_name); 
 30268 |             } 
 30269 |  
 30270 |             const scope_element& se = sem_.get_element(var1_name); 
 30271 |  
 30272 |             if ( 
 30273 |                  (se.active) && 
 30274 |                  (se.name == var1_name) && 
 30275 |                  (scope_element::e_variable == se.type) 
 30276 |                ) 
 30277 |             { 
 30278 |                variable1 = se.var_node; 
 30279 |             } 
 30280 |  
 30281 |             lodge_symbol(var1_name, e_st_variable); 
 30282 |  
 30283 |             if (0 == variable1) 
 30284 |             { 
 30285 |                set_error(make_error( 
 30286 |                   parser_error::e_syntax, 
 30287 |                   current_token(), 
 30288 |                   "ERR207 - Second parameter to swap is an invalid variable: '" + var1_name + "'", 
 30289 |                   exprtk_error_location)); 
 30290 |  
 30291 |                if (variable0_generated) 
 30292 |                { 
 30293 |                   free_node(node_allocator_, variable0); 
 30294 |                } 
 30295 |  
 30296 |                return error_node(); 
 30297 |             } 
 30298 |             else 
 30299 |                next_token(); 
 30300 |          } 
 30301 |  
 30302 |          if (!token_is(token_t::e_rbracket)) 
 30303 |          { 
 30304 |             set_error(make_error( 
 30305 |                parser_error::e_syntax, 
 30306 |                current_token(), 
 30307 |                "ERR208 - Expected ')' at end of swap statement", 
 30308 |                exprtk_error_location)); 
 30309 |  
 30310 |             if (variable0_generated) 
 30311 |             { 
 30312 |                free_node(node_allocator_, variable0); 
 30313 |             } 
 30314 |  
 30315 |             if (variable1_generated) 
 30316 |             { 
 30317 |                free_node(node_allocator_, variable1); 
 30318 |             } 
 30319 |  
 30320 |             return error_node(); 
 30321 |          } 
 30322 |  
 30323 |          typedef details::variable_node<T>* variable_node_ptr; 
 30324 |  
 30325 |          variable_node_ptr v0 = variable_node_ptr(0); 
 30326 |          variable_node_ptr v1 = variable_node_ptr(0); 
 30327 |  
 30328 |          expression_node_ptr result = error_node(); 
 30329 |  
 30330 |          if ( 
 30331 |               (0 != (v0 = dynamic_cast<variable_node_ptr>(variable0))) && 
 30332 |               (0 != (v1 = dynamic_cast<variable_node_ptr>(variable1))) 
 30333 |             ) 
 30334 |          { 
 30335 |             result = node_allocator_.allocate<details::swap_node<T> >(v0, v1); 
 30336 |  
 30337 |             if (variable0_generated) 
 30338 |             { 
 30339 |                free_node(node_allocator_, variable0); 
 30340 |             } 
 30341 |  
 30342 |             if (variable1_generated) 
 30343 |             { 
 30344 |                free_node(node_allocator_, variable1); 
 30345 |             } 
 30346 |          } 
 30347 |          else 
 30348 |             result = node_allocator_.allocate<details::swap_generic_node<T> > 
 30349 |                         (variable0, variable1); 
 30350 |  
 30351 |          state_.activate_side_effect("parse_swap_statement()"); 
 30352 |  
 30353 |          return result; 
 30354 |       } 
 30355 |  
 30356 |       #ifndef exprtk_disable_return_statement 
 30357 |       inline expression_node_ptr parse_return_statement() 
 30358 |       { 
 30359 |          if (state_.parsing_return_stmt) 
 30360 |          { 
 30361 |             set_error(make_error( 
 30362 |                parser_error::e_syntax, 
 30363 |                current_token(), 
 30364 |                "ERR209 - Return call within a return call is not allowed", 
 30365 |                exprtk_error_location)); 
 30366 |  
 30367 |             return error_node(); 
 30368 |          } 
 30369 |  
 30370 |          scoped_bool_negator sbn(state_.parsing_return_stmt); 
 30371 |  
 30372 |          std::vector<expression_node_ptr> arg_list; 
 30373 |  
 30374 |          scoped_vec_delete<expression_node_t> sdd((*this),arg_list); 
 30375 |  
 30376 |          if (!details::imatch(current_token().value,"return")) 
 30377 |          { 
 30378 |             return error_node(); 
 30379 |          } 
 30380 |          else 
 30381 |             next_token(); 
 30382 |  
 30383 |          if (!token_is(token_t::e_lsqrbracket)) 
 30384 |          { 
 30385 |             set_error(make_error( 
 30386 |                parser_error::e_syntax, 
 30387 |                current_token(), 
 30388 |                "ERR210 - Expected '[' at start of return statement", 
 30389 |                exprtk_error_location)); 
 30390 |  
 30391 |             return error_node(); 
 30392 |          } 
 30393 |          else if (!token_is(token_t::e_rsqrbracket)) 
 30394 |          { 
 30395 |             for ( ; ; ) 
 30396 |             { 
 30397 |                expression_node_ptr arg = parse_expression(); 
 30398 |  
 30399 |                if (0 == arg) 
 30400 |                   return error_node(); 
 30401 |  
 30402 |                arg_list.push_back(arg); 
 30403 |  
 30404 |                if (token_is(token_t::e_rsqrbracket)) 
 30405 |                   break; 
 30406 |                else if (!token_is(token_t::e_comma)) 
 30407 |                { 
 30408 |                   set_error(make_error( 
 30409 |                      parser_error::e_syntax, 
 30410 |                      current_token(), 
 30411 |                      "ERR211 - Expected ',' between values during call to return", 
 30412 |                      exprtk_error_location)); 
 30413 |  
 30414 |                   return error_node(); 
 30415 |                } 
 30416 |             } 
 30417 |          } 
 30418 |          else if (settings_.zero_return_disabled()) 
 30419 |          { 
 30420 |             set_error(make_error( 
 30421 |                parser_error::e_syntax, 
 30422 |                current_token(), 
 30423 |                "ERR212 - Zero parameter return statement not allowed", 
 30424 |                exprtk_error_location)); 
 30425 |  
 30426 |             return error_node(); 
 30427 |          } 
 30428 |  
 30429 |          const lexer::token prev_token = current_token(); 
 30430 |  
 30431 |          if (token_is(token_t::e_rsqrbracket)) 
 30432 |          { 
 30433 |             if (!arg_list.empty()) 
 30434 |             { 
 30435 |                set_error(make_error( 
 30436 |                   parser_error::e_syntax, 
 30437 |                   prev_token, 
 30438 |                   "ERR213 - Invalid ']' found during return call", 
 30439 |                   exprtk_error_location)); 
 30440 |  
 30441 |                return error_node(); 
 30442 |             } 
 30443 |          } 
 30444 |  
 30445 |          std::string ret_param_type_list; 
 30446 |  
 30447 |          for (std::size_t i = 0; i < arg_list.size(); ++i) 
 30448 |          { 
 30449 |             if (0 == arg_list[i]) 
 30450 |                return error_node(); 
 30451 |             else if (is_ivector_node(arg_list[i])) 
 30452 |                ret_param_type_list += 'V'; 
 30453 |             else if (is_generally_string_node(arg_list[i])) 
 30454 |                ret_param_type_list += 'S'; 
 30455 |             else 
 30456 |                ret_param_type_list += 'T'; 
 30457 |          } 
 30458 |  
 30459 |          dec_.retparam_list_.push_back(ret_param_type_list); 
 30460 |  
 30461 |          expression_node_ptr result = expression_generator_.return_call(arg_list); 
 30462 |  
 30463 |          sdd.delete_ptr = (0 == result); 
 30464 |  
 30465 |          state_.return_stmt_present = true; 
 30466 |  
 30467 |          state_.activate_side_effect("parse_return_statement()"); 
 30468 |  
 30469 |          return result; 
 30470 |       } 
 30471 |       #else 
 30472 |       inline expression_node_ptr parse_return_statement() 
 30473 |       { 
 30474 |          return error_node(); 
 30475 |       } 
 30476 |       #endif 
 30477 |  
 30478 |       inline expression_node_ptr parse_assert_statement() 
 30479 |       { 
 30480 |          assert(details::imatch(current_token().value, "assert")); 
 30481 |  
 30482 |          if (state_.parsing_assert_stmt) 
 30483 |          { 
 30484 |             set_error(make_error( 
 30485 |                parser_error::e_syntax, 
 30486 |                current_token(), 
 30487 |                "ERR214 - Assert statement within an assert statement is not allowed", 
 30488 |                exprtk_error_location)); 
 30489 |  
 30490 |             return error_node(); 
 30491 |          } 
 30492 |  
 30493 |          scoped_bool_negator sbn(state_.parsing_assert_stmt); 
 30494 |  
 30495 |          next_token(); 
 30496 |  
 30497 |          std::vector<expression_node_ptr> assert_arg_list(3, error_node()); 
 30498 |          scoped_vec_delete<expression_node_t> sdd((*this), assert_arg_list); 
 30499 |  
 30500 |          expression_node_ptr& assert_condition = assert_arg_list[0]; 
 30501 |          expression_node_ptr& assert_message   = assert_arg_list[1]; 
 30502 |          expression_node_ptr& assert_id        = assert_arg_list[2]; 
 30503 |  
 30504 |          if (!token_is(token_t::e_lbracket)) 
 30505 |          { 
 30506 |             set_error(make_error( 
 30507 |                parser_error::e_syntax, 
 30508 |                current_token(), 
 30509 |                "ERR215 - Expected '(' at start of assert statement", 
 30510 |                exprtk_error_location)); 
 30511 |  
 30512 |             return error_node(); 
 30513 |          } 
 30514 |  
 30515 |          const token_t start_token = current_token(); 
 30516 |  
 30517 |          // Parse the assert condition 
 30518 |          if (0 == (assert_condition = parse_expression())) 
 30519 |          { 
 30520 |             set_error(make_error( 
 30521 |                parser_error::e_syntax, 
 30522 |                current_token(), 
 30523 |                "ERR216 - Failed to parse condition for assert statement", 
 30524 |                exprtk_error_location)); 
 30525 |  
 30526 |             return error_node(); 
 30527 |          } 
 30528 |  
 30529 |          const token_t end_token = current_token(); 
 30530 |  
 30531 |          if (!token_is(token_t::e_rbracket)) 
 30532 |          { 
 30533 |             if (!token_is(token_t::e_comma)) 
 30534 |             { 
 30535 |                set_error(make_error( 
 30536 |                   parser_error::e_syntax, 
 30537 |                   current_token(), 
 30538 |                   "ERR217 - Expected ',' between condition and message for assert statement", 
 30539 |                   exprtk_error_location)); 
 30540 |  
 30541 |                return error_node(); 
 30542 |             } 
 30543 |             // Parse the assert message 
 30544 |             else if ( 
 30545 |                       (0 == (assert_message = parse_expression())) || 
 30546 |                       !details::is_generally_string_node(assert_message) 
 30547 |                     ) 
 30548 |             { 
 30549 |                set_error(make_error( 
 30550 |                   parser_error::e_syntax, 
 30551 |                   current_token(), 
 30552 |                   "ERR218 - " + 
 30553 |                   (assert_message ? 
 30554 |                   std::string("Expected string for assert message") : 
 30555 |                   std::string("Failed to parse message for assert statement")), 
 30556 |                   exprtk_error_location)); 
 30557 |  
 30558 |                return error_node(); 
 30559 |             } 
 30560 |             else if (!token_is(token_t::e_rbracket)) 
 30561 |             { 
 30562 |                if (!token_is(token_t::e_comma)) 
 30563 |                { 
 30564 |                   set_error(make_error( 
 30565 |                      parser_error::e_syntax, 
 30566 |                      current_token(), 
 30567 |                      "ERR219 - Expected ',' between message and ID for assert statement", 
 30568 |                      exprtk_error_location)); 
 30569 |  
 30570 |                   return error_node(); 
 30571 |                } 
 30572 |                // Parse assert ID 
 30573 |                else if ( 
 30574 |                          (0 == (assert_id = parse_expression())) || 
 30575 |                          !details::is_const_string_node(assert_id) 
 30576 |                        ) 
 30577 |                { 
 30578 |                   set_error(make_error( 
 30579 |                      parser_error::e_syntax, 
 30580 |                      current_token(), 
 30581 |                      "ERR220 - " + 
 30582 |                      (assert_id ? 
 30583 |                      std::string("Expected literal string for assert ID") : 
 30584 |                      std::string("Failed to parse string for assert ID")), 
 30585 |                      exprtk_error_location)); 
 30586 |  
 30587 |                   return error_node(); 
 30588 |                } 
 30589 |                else if (!token_is(token_t::e_rbracket)) 
 30590 |                { 
 30591 |                   set_error(make_error( 
 30592 |                      parser_error::e_syntax, 
 30593 |                      current_token(), 
 30594 |                      "ERR221 - Expected ')' at start of assert statement", 
 30595 |                      exprtk_error_location)); 
 30596 |  
 30597 |                   return error_node(); 
 30598 |                } 
 30599 |             } 
 30600 |          } 
 30601 |  
 30602 |          exprtk::assert_check::assert_context context; 
 30603 |          context.condition = lexer().substr(start_token.position, end_token.position); 
 30604 |          context.offet     = start_token.position; 
 30605 |  
 30606 |          if (0 == assert_check_) 
 30607 |          { 
 30608 |             exprtk_debug(("parse_assert_statement() - assert functionality is disabled. assert condition: %s\n", 
 30609 |                           context.condition.c_str())); 
 30610 |  
 30611 |             return new details::null_node<T>(); 
 30612 |          } 
 30613 |  
 30614 |          #ifndef exprtk_disable_string_capabilities 
 30615 |          if (assert_message && details::is_const_string_node(assert_message)) 
 30616 |          { 
 30617 |             context.message = dynamic_cast<details::string_base_node<T>*>(assert_message)->str(); 
 30618 |          } 
 30619 |  
 30620 |          if (assert_id && details::is_const_string_node(assert_id)) 
 30621 |          { 
 30622 |             context.id = dynamic_cast<details::string_base_node<T>*>(assert_id)->str(); 
 30623 |  
 30624 |             if (assert_ids_.end() != assert_ids_.find(context.id)) 
 30625 |             { 
 30626 |                set_error(make_error( 
 30627 |                   parser_error::e_syntax, 
 30628 |                   current_token(), 
 30629 |                   "ERR222 - Duplicate assert ID: " + context.id, 
 30630 |                   exprtk_error_location)); 
 30631 |  
 30632 |                return error_node(); 
 30633 |             } 
 30634 |  
 30635 |             assert_ids_.insert(context.id); 
 30636 |             free_node(node_allocator_, assert_id); 
 30637 |          } 
 30638 |          #endif 
 30639 |  
 30640 |          expression_node_ptr result_node = 
 30641 |             expression_generator_.assert_call( 
 30642 |                assert_condition, 
 30643 |                assert_message, 
 30644 |                context); 
 30645 |  
 30646 |          exprtk_debug(("parse_assert_statement() - assert condition: [%s]\n", context.condition.c_str()      )); 
 30647 |          exprtk_debug(("parse_assert_statement() - assert message:   [%s]\n", context.message  .c_str()      )); 
 30648 |          exprtk_debug(("parse_assert_statement() - assert id:        [%s]\n", context.id       .c_str()      )); 
 30649 |          exprtk_debug(("parse_assert_statement() - assert offset:    [%d]\n", static_cast<int>(context.offet))); 
 30650 |  
 30651 |          if (0 == result_node) 
 30652 |          { 
 30653 |             set_error(make_error( 
 30654 |                parser_error::e_syntax, 
 30655 |                current_token(), 
 30656 |                "ERR223 - Failed to synthesize assert", 
 30657 |                exprtk_error_location)); 
 30658 |  
 30659 |             return error_node(); 
 30660 |          } 
 30661 |  
 30662 |          sdd.delete_ptr = false; 
 30663 |          return result_node; 
 30664 |       } 
 30665 |  
 30666 |       inline bool post_variable_process(const std::string& symbol) 
 30667 |       { 
 30668 |          if ( 
 30669 |               peek_token_is(token_t::e_lbracket   ) || 
 30670 |               peek_token_is(token_t::e_lcrlbracket) || 
 30671 |               peek_token_is(token_t::e_lsqrbracket) 
 30672 |             ) 
 30673 |          { 
 30674 |             if (!settings_.commutative_check_enabled()) 
 30675 |             { 
 30676 |                set_error(make_error( 
 30677 |                   parser_error::e_syntax, 
 30678 |                   current_token(), 
 30679 |                   "ERR224 - Invalid sequence of variable '" + symbol + "' and bracket", 
 30680 |                   exprtk_error_location)); 
 30681 |  
 30682 |                return false; 
 30683 |             } 
 30684 |  
 30685 |             lexer().insert_front(token_t::e_mul); 
 30686 |          } 
 30687 |  
 30688 |          return true; 
 30689 |       } 
 30690 |  
 30691 |       inline bool post_bracket_process(const typename token_t::token_type& token, expression_node_ptr& branch) 
 30692 |       { 
 30693 |          bool implied_mul = false; 
 30694 |  
 30695 |          if (details::is_generally_string_node(branch)) 
 30696 |             return true; 
 30697 |  
 30698 |          if (details::is_ivector_node(branch)) 
 30699 |             return true; 
 30700 |  
 30701 |          const lexer::parser_helper::token_advance_mode hold = prsrhlpr_t::e_hold; 
 30702 |  
 30703 |          switch (token) 
 30704 |          { 
 30705 |             case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket   , hold) || 
 30706 |                                                         token_is(token_t::e_lcrlbracket, hold) || 
 30707 |                                                         token_is(token_t::e_lsqrbracket, hold) ; 
 30708 |                                           break; 
 30709 |  
 30710 |             case token_t::e_lbracket    : implied_mul = token_is(token_t::e_lbracket   , hold) || 
 30711 |                                                         token_is(token_t::e_lcrlbracket, hold) || 
 30712 |                                                         token_is(token_t::e_lsqrbracket, hold) ; 
 30713 |                                           break; 
 30714 |  
 30715 |             case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket   , hold) || 
 30716 |                                                         token_is(token_t::e_lcrlbracket, hold) || 
 30717 |                                                         token_is(token_t::e_lsqrbracket, hold) ; 
 30718 |                                           break; 
 30719 |  
 30720 |             default                     : return true; 
 30721 |          } 
 30722 |  
 30723 |          if (implied_mul) 
 30724 |          { 
 30725 |             if (!settings_.commutative_check_enabled()) 
 30726 |             { 
 30727 |                set_error(make_error( 
 30728 |                   parser_error::e_syntax, 
 30729 |                   current_token(), 
 30730 |                   "ERR225 - Invalid sequence of brackets", 
 30731 |                   exprtk_error_location)); 
 30732 |  
 30733 |                return false; 
 30734 |             } 
 30735 |             else if (token_t::e_eof != current_token().type) 
 30736 |             { 
 30737 |                lexer().insert_front(current_token().type); 
 30738 |                lexer().insert_front(token_t::e_mul); 
 30739 |                next_token(); 
 30740 |             } 
 30741 |          } 
 30742 |  
 30743 |          return true; 
 30744 |       } 
 30745 |  
 30746 |       typedef typename interval_container_t<const void*>::interval_t interval_t; 
 30747 |       typedef interval_container_t<const void*> immutable_memory_map_t; 
 30748 |       typedef std::map<interval_t,token_t> immutable_symtok_map_t; 
 30749 |  
 30750 |       inline interval_t make_memory_range(const T& t) 
 30751 |       { 
 30752 |          const T* begin = reinterpret_cast<const T*>(&t); 
 30753 |          const T* end   = begin + 1; 
 30754 |          return interval_t(begin, end); 
 30755 |       } 
 30756 |  
 30757 |       inline interval_t make_memory_range(const T* begin, const std::size_t size) 
 30758 |       { 
 30759 |          return interval_t(begin, begin + size); 
 30760 |       } 
 30761 |  
 30762 |       inline interval_t make_memory_range(details::char_cptr begin, const std::size_t size) 
 30763 |       { 
 30764 |          return interval_t(begin, begin + size); 
 30765 |       } 
 30766 |  
 30767 |       void lodge_immutable_symbol(const lexer::token& token, const interval_t interval) 
 30768 |       { 
 30769 |          immutable_memory_map_.add_interval(interval); 
 30770 |          immutable_symtok_map_[interval] = token; 
 30771 |       } 
 30772 |  
 30773 |       inline expression_node_ptr parse_symtab_symbol() 
 30774 |       { 
 30775 |          const std::string symbol = current_token().value; 
 30776 |  
 30777 |          // Are we dealing with a variable or a special constant? 
 30778 |          typedef typename symtab_store::variable_context var_ctxt_t; 
 30779 |          var_ctxt_t var_ctx = symtab_store_.get_variable_context(symbol); 
 30780 |  
 30781 |          if (var_ctx.variable) 
 30782 |          { 
 30783 |             assert(var_ctx.symbol_table); 
 30784 |  
 30785 |             expression_node_ptr result_variable = var_ctx.variable; 
 30786 |  
 30787 |             if (symtab_store_.is_constant_node(symbol)) 
 30788 |             { 
 30789 |                result_variable = expression_generator_(var_ctx.variable->value()); 
 30790 |             } 
 30791 |             else if (symbol_table_t::e_immutable == var_ctx.symbol_table->mutability()) 
 30792 |             { 
 30793 |                lodge_immutable_symbol(current_token(), make_memory_range(var_ctx.variable->ref())); 
 30794 |                result_variable = var_ctx.variable; 
 30795 |             } 
 30796 |  
 30797 |             if (!post_variable_process(symbol)) 
 30798 |                return error_node(); 
 30799 |  
 30800 |             lodge_symbol(symbol, e_st_variable); 
 30801 |  
 30802 |             next_token(); 
 30803 |  
 30804 |             return result_variable; 
 30805 |          } 
 30806 |  
 30807 |          // Are we dealing with a locally defined variable, vector or string? 
 30808 |          if (!sem_.empty()) 
 30809 |          { 
 30810 |             scope_element& se = sem_.get_active_element(symbol); 
 30811 |  
 30812 |             if (se.active && details::imatch(se.name, symbol)) 
 30813 |             { 
 30814 |                if ( 
 30815 |                     (scope_element::e_variable == se.type) || 
 30816 |                     (scope_element::e_literal  == se.type) 
 30817 |                   ) 
 30818 |                { 
 30819 |                   se.active = true; 
 30820 |                   lodge_symbol(symbol, e_st_local_variable); 
 30821 |  
 30822 |                   if (!post_variable_process(symbol)) 
 30823 |                      return error_node(); 
 30824 |  
 30825 |                   next_token(); 
 30826 |  
 30827 |                   return (scope_element::e_variable == se.type) ? 
 30828 |                            se.var_node : 
 30829 |                            expression_generator_(se.var_node->value()); 
 30830 |                } 
 30831 |                else if (scope_element::e_vector == se.type) 
 30832 |                { 
 30833 |                   return parse_vector(); 
 30834 |                } 
 30835 |                #ifndef exprtk_disable_string_capabilities 
 30836 |                else if (scope_element::e_string == se.type) 
 30837 |                { 
 30838 |                   return parse_string(); 
 30839 |                } 
 30840 |                #endif 
 30841 |             } 
 30842 |          } 
 30843 |  
 30844 |          #ifndef exprtk_disable_string_capabilities 
 30845 |          // Are we dealing with a string variable? 
 30846 |          if (symtab_store_.is_stringvar(symbol)) 
 30847 |          { 
 30848 |             return parse_string(); 
 30849 |          } 
 30850 |          #endif 
 30851 |  
 30852 |          { 
 30853 |             // Are we dealing with a function? 
 30854 |             ifunction<T>* function = symtab_store_.get_function(symbol); 
 30855 |  
 30856 |             if (function) 
 30857 |             { 
 30858 |                lodge_symbol(symbol, e_st_function); 
 30859 |  
 30860 |                expression_node_ptr func_node = 
 30861 |                                       parse_function_invocation(function,symbol); 
 30862 |  
 30863 |                if (func_node) 
 30864 |                   return func_node; 
 30865 |                else 
 30866 |                { 
 30867 |                   set_error(make_error( 
 30868 |                      parser_error::e_syntax, 
 30869 |                      current_token(), 
 30870 |                      "ERR226 - Failed to generate node for function: '" + symbol + "'", 
 30871 |                      exprtk_error_location)); 
 30872 |  
 30873 |                   return error_node(); 
 30874 |                } 
 30875 |             } 
 30876 |          } 
 30877 |  
 30878 |          { 
 30879 |             // Are we dealing with a vararg function? 
 30880 |             ivararg_function<T>* vararg_function = symtab_store_.get_vararg_function(symbol); 
 30881 |  
 30882 |             if (vararg_function) 
 30883 |             { 
 30884 |                lodge_symbol(symbol, e_st_function); 
 30885 |  
 30886 |                expression_node_ptr vararg_func_node = 
 30887 |                                       parse_vararg_function_call(vararg_function, symbol); 
 30888 |  
 30889 |                if (vararg_func_node) 
 30890 |                   return vararg_func_node; 
 30891 |                else 
 30892 |                { 
 30893 |                   set_error(make_error( 
 30894 |                      parser_error::e_syntax, 
 30895 |                      current_token(), 
 30896 |                      "ERR227 - Failed to generate node for vararg function: '" + symbol + "'", 
 30897 |                      exprtk_error_location)); 
 30898 |  
 30899 |                   return error_node(); 
 30900 |                } 
 30901 |             } 
 30902 |          } 
 30903 |  
 30904 |          { 
 30905 |             // Are we dealing with a vararg generic function? 
 30906 |             igeneric_function<T>* generic_function = symtab_store_.get_generic_function(symbol); 
 30907 |  
 30908 |             if (generic_function) 
 30909 |             { 
 30910 |                lodge_symbol(symbol, e_st_function); 
 30911 |  
 30912 |                expression_node_ptr genericfunc_node = 
 30913 |                                       parse_generic_function_call(generic_function, symbol); 
 30914 |  
 30915 |                if (genericfunc_node) 
 30916 |                   return genericfunc_node; 
 30917 |                else 
 30918 |                { 
 30919 |                   set_error(make_error( 
 30920 |                      parser_error::e_syntax, 
 30921 |                      current_token(), 
 30922 |                      "ERR228 - Failed to generate node for generic function: '" + symbol + "'", 
 30923 |                      exprtk_error_location)); 
 30924 |  
 30925 |                   return error_node(); 
 30926 |                } 
 30927 |             } 
 30928 |          } 
 30929 |  
 30930 |          #ifndef exprtk_disable_string_capabilities 
 30931 |          { 
 30932 |             // Are we dealing with a vararg string returning function? 
 30933 |             igeneric_function<T>* string_function = symtab_store_.get_string_function(symbol); 
 30934 |  
 30935 |             if (string_function) 
 30936 |             { 
 30937 |                lodge_symbol(symbol, e_st_function); 
 30938 |  
 30939 |                expression_node_ptr stringfunc_node = 
 30940 |                                       parse_string_function_call(string_function, symbol); 
 30941 |  
 30942 |                if (stringfunc_node) 
 30943 |                   return stringfunc_node; 
 30944 |                else 
 30945 |                { 
 30946 |                   set_error(make_error( 
 30947 |                      parser_error::e_syntax, 
 30948 |                      current_token(), 
 30949 |                      "ERR229 - Failed to generate node for string function: '" + symbol + "'", 
 30950 |                      exprtk_error_location)); 
 30951 |  
 30952 |                   return error_node(); 
 30953 |                } 
 30954 |             } 
 30955 |          } 
 30956 |  
 30957 |          { 
 30958 |             // Are we dealing with a vararg overloaded scalar/string returning function? 
 30959 |             igeneric_function<T>* overload_function = symtab_store_.get_overload_function(symbol); 
 30960 |  
 30961 |             if (overload_function) 
 30962 |             { 
 30963 |                lodge_symbol(symbol, e_st_function); 
 30964 |  
 30965 |                expression_node_ptr overloadfunc_node = 
 30966 |                                       parse_overload_function_call(overload_function, symbol); 
 30967 |  
 30968 |                if (overloadfunc_node) 
 30969 |                   return overloadfunc_node; 
 30970 |                else 
 30971 |                { 
 30972 |                   set_error(make_error( 
 30973 |                      parser_error::e_syntax, 
 30974 |                      current_token(), 
 30975 |                      "ERR230 - Failed to generate node for overload function: '" + symbol + "'", 
 30976 |                      exprtk_error_location)); 
 30977 |  
 30978 |                   return error_node(); 
 30979 |                } 
 30980 |             } 
 30981 |          } 
 30982 |          #endif 
 30983 |  
 30984 |          // Are we dealing with a vector? 
 30985 |          if (symtab_store_.is_vector(symbol)) 
 30986 |          { 
 30987 |             lodge_symbol(symbol, e_st_vector); 
 30988 |             return parse_vector(); 
 30989 |          } 
 30990 |  
 30991 |          if (details::is_reserved_symbol(symbol)) 
 30992 |          { 
 30993 |                if ( 
 30994 |                     settings_.function_enabled(symbol) || 
 30995 |                     !details::is_base_function(symbol) 
 30996 |                   ) 
 30997 |                { 
 30998 |                   set_error(make_error( 
 30999 |                      parser_error::e_syntax, 
 31000 |                      current_token(), 
 31001 |                      "ERR231 - Invalid use of reserved symbol '" + symbol + "'", 
 31002 |                      exprtk_error_location)); 
 31003 |  
 31004 |                   return error_node(); 
 31005 |                } 
 31006 |          } 
 31007 |  
 31008 |          // Should we handle unknown symbols? 
 31009 |          if (resolve_unknown_symbol_ && unknown_symbol_resolver_) 
 31010 |          { 
 31011 |             if (!(settings_.rsrvd_sym_usr_disabled() && details::is_reserved_symbol(symbol))) 
 31012 |             { 
 31013 |                symbol_table_t& symtab = symtab_store_.get_symbol_table(); 
 31014 |  
 31015 |                std::string error_message; 
 31016 |  
 31017 |                if (unknown_symbol_resolver::e_usrmode_default == unknown_symbol_resolver_->mode) 
 31018 |                { 
 31019 |                   T default_value = T(0); 
 31020 |  
 31021 |                   typename unknown_symbol_resolver::usr_symbol_type usr_symbol_type = unknown_symbol_resolver::e_usr_unknown_type; 
 31022 |  
 31023 |                   if (unknown_symbol_resolver_->process(symbol, usr_symbol_type, default_value, error_message)) 
 31024 |                   { 
 31025 |                      bool create_result = false; 
 31026 |  
 31027 |                      switch (usr_symbol_type) 
 31028 |                      { 
 31029 |                         case unknown_symbol_resolver::e_usr_variable_type : 
 31030 |                            create_result = symtab.create_variable(symbol, default_value); 
 31031 |                            break; 
 31032 |  
 31033 |                         case unknown_symbol_resolver::e_usr_constant_type : 
 31034 |                            create_result = symtab.add_constant(symbol, default_value); 
 31035 |                            break; 
 31036 |  
 31037 |                         default                                           : create_result = false; 
 31038 |                      } 
 31039 |  
 31040 |                      if (create_result) 
 31041 |                      { 
 31042 |                         expression_node_ptr var = symtab_store_.get_variable(symbol); 
 31043 |  
 31044 |                         if (var) 
 31045 |                         { 
 31046 |                            if (symtab_store_.is_constant_node(symbol)) 
 31047 |                            { 
 31048 |                               var = expression_generator_(var->value()); 
 31049 |                            } 
 31050 |  
 31051 |                            lodge_symbol(symbol, e_st_variable); 
 31052 |  
 31053 |                            if (!post_variable_process(symbol)) 
 31054 |                               return error_node(); 
 31055 |  
 31056 |                            next_token(); 
 31057 |  
 31058 |                            return var; 
 31059 |                         } 
 31060 |                      } 
 31061 |                   } 
 31062 |  
 31063 |                   set_error(make_error( 
 31064 |                      parser_error::e_symtab, 
 31065 |                      current_token(), 
 31066 |                      "ERR232 - Failed to create variable: '" + symbol + "'" + 
 31067 |                      (error_message.empty() ? "" : " - " + error_message), 
 31068 |                      exprtk_error_location)); 
 31069 |  
 31070 |                } 
 31071 |                else if (unknown_symbol_resolver::e_usrmode_extended == unknown_symbol_resolver_->mode) 
 31072 |                { 
 31073 |                   if (unknown_symbol_resolver_->process(symbol, symtab, error_message)) 
 31074 |                   { 
 31075 |                      expression_node_ptr result = parse_symtab_symbol(); 
 31076 |  
 31077 |                      if (result) 
 31078 |                      { 
 31079 |                         return result; 
 31080 |                      } 
 31081 |                   } 
 31082 |  
 31083 |                   set_error(make_error( 
 31084 |                      parser_error::e_symtab, 
 31085 |                      current_token(), 
 31086 |                      "ERR233 - Failed to resolve symbol: '" + symbol + "'" + 
 31087 |                      (error_message.empty() ? "" : " - " + error_message), 
 31088 |                      exprtk_error_location)); 
 31089 |                } 
 31090 |  
 31091 |                return error_node(); 
 31092 |             } 
 31093 |          } 
 31094 |  
 31095 |          set_error(make_error( 
 31096 |             parser_error::e_syntax, 
 31097 |             current_token(), 
 31098 |             "ERR234 - Undefined symbol: '" + symbol + "'", 
 31099 |             exprtk_error_location)); 
 31100 |  
 31101 |          return error_node(); 
 31102 |       } 
 31103 |  
 31104 |       inline expression_node_ptr check_block_statement_closure(expression_node_ptr expression) 
 31105 |       { 
 31106 |          if ( 
 31107 |               expression && 
 31108 |               ( 
 31109 |                 (current_token().type == token_t::e_symbol) || 
 31110 |                 (current_token().type == token_t::e_number) 
 31111 |               ) 
 31112 |             ) 
 31113 |          { 
 31114 |             free_node(node_allocator_, expression); 
 31115 |  
 31116 |             set_error(make_error( 
 31117 |                parser_error::e_syntax, 
 31118 |                current_token(), 
 31119 |                "ERR235 - Invalid syntax '" + current_token().value  + "' possible missing operator or context", 
 31120 |                exprtk_error_location)); 
 31121 |  
 31122 |                return error_node(); 
 31123 |          } 
 31124 |  
 31125 |          return expression; 
 31126 |       } 
 31127 |  
 31128 |       inline expression_node_ptr parse_symbol() 
 31129 |       { 
 31130 |          static const std::string symbol_if       = "if"      ; 
 31131 |          static const std::string symbol_while    = "while"   ; 
 31132 |          static const std::string symbol_repeat   = "repeat"  ; 
 31133 |          static const std::string symbol_for      = "for"     ; 
 31134 |          static const std::string symbol_switch   = "switch"  ; 
 31135 |          static const std::string symbol_null     = "null"    ; 
 31136 |          static const std::string symbol_break    = "break"   ; 
 31137 |          static const std::string symbol_continue = "continue" 
 31138 |          static const std::string symbol_var      = "var"     ; 
 31139 |          static const std::string symbol_const    = "const"   ; 
 31140 |          static const std::string symbol_swap     = "swap"    ; 
 31141 |          static const std::string symbol_return   = "return"  ; 
 31142 |          static const std::string symbol_not      = "not"     ; 
 31143 |          static const std::string symbol_assert   = "assert"  ; 
 31144 |  
 31145 |          const std::string symbol = current_token().value; 
 31146 |  
 31147 |          if (valid_vararg_operation(symbol)) 
 31148 |          { 
 31149 |             return parse_vararg_function(); 
 31150 |          } 
 31151 |          else if (details::imatch(symbol, symbol_not)) 
 31152 |          { 
 31153 |             return parse_not_statement(); 
 31154 |          } 
 31155 |          else if (valid_base_operation(symbol)) 
 31156 |          { 
 31157 |             return parse_base_operation(); 
 31158 |          } 
 31159 |          else if ( 
 31160 |                    details::imatch(symbol, symbol_if) && 
 31161 |                    settings_.control_struct_enabled(symbol) 
 31162 |                  ) 
 31163 |          { 
 31164 |             return parse_conditional_statement(); 
 31165 |          } 
 31166 |          else if ( 
 31167 |                    details::imatch(symbol, symbol_while) && 
 31168 |                    settings_.control_struct_enabled(symbol) 
 31169 |                  ) 
 31170 |          { 
 31171 |             return check_block_statement_closure(parse_while_loop()); 
 31172 |          } 
 31173 |          else if ( 
 31174 |                    details::imatch(symbol, symbol_repeat) && 
 31175 |                    settings_.control_struct_enabled(symbol) 
 31176 |                  ) 
 31177 |          { 
 31178 |             return check_block_statement_closure(parse_repeat_until_loop()); 
 31179 |          } 
 31180 |          else if ( 
 31181 |                    details::imatch(symbol, symbol_for) && 
 31182 |                    settings_.control_struct_enabled(symbol) 
 31183 |                  ) 
 31184 |          { 
 31185 |             return check_block_statement_closure(parse_for_loop()); 
 31186 |          } 
 31187 |          else if ( 
 31188 |                    details::imatch(symbol, symbol_switch) && 
 31189 |                    settings_.control_struct_enabled(symbol) 
 31190 |                  ) 
 31191 |          { 
 31192 |             return check_block_statement_closure(parse_switch_statement()); 
 31193 |          } 
 31194 |          else if (details::is_valid_sf_symbol(symbol)) 
 31195 |          { 
 31196 |             return parse_special_function(); 
 31197 |          } 
 31198 |          else if (details::imatch(symbol, symbol_null)) 
 31199 |          { 
 31200 |             return parse_null_statement(); 
 31201 |          } 
 31202 |          #ifndef exprtk_disable_break_continue 
 31203 |          else if (details::imatch(symbol, symbol_break)) 
 31204 |          { 
 31205 |             return parse_break_statement(); 
 31206 |          } 
 31207 |          else if (details::imatch(symbol, symbol_continue)) 
 31208 |          { 
 31209 |             return parse_continue_statement(); 
 31210 |          } 
 31211 |          #endif 
 31212 |          else if (details::imatch(symbol, symbol_var)) 
 31213 |          { 
 31214 |             return parse_define_var_statement(); 
 31215 |          } 
 31216 |          else if (details::imatch(symbol, symbol_const)) 
 31217 |          { 
 31218 |             return parse_define_constvar_statement(); 
 31219 |          } 
 31220 |          else if (details::imatch(symbol, symbol_swap)) 
 31221 |          { 
 31222 |             return parse_swap_statement(); 
 31223 |          } 
 31224 |          #ifndef exprtk_disable_return_statement 
 31225 |          else if ( 
 31226 |                    details::imatch(symbol, symbol_return) && 
 31227 |                    settings_.control_struct_enabled(symbol) 
 31228 |                  ) 
 31229 |          { 
 31230 |             return check_block_statement_closure(parse_return_statement()); 
 31231 |          } 
 31232 |          #endif 
 31233 |          else if (details::imatch(symbol, symbol_assert)) 
 31234 |          { 
 31235 |             return parse_assert_statement(); 
 31236 |          } 
 31237 |          else if (symtab_store_.valid() || !sem_.empty()) 
 31238 |          { 
 31239 |             return parse_symtab_symbol(); 
 31240 |          } 
 31241 |          else 
 31242 |          { 
 31243 |             set_error(make_error( 
 31244 |                parser_error::e_symtab, 
 31245 |                current_token(), 
 31246 |                "ERR236 - Unknown variable or function encountered. Symbol table(s) " 
 31247 |                "is either invalid or does not contain symbol: '" + symbol + "'", 
 31248 |                exprtk_error_location)); 
 31249 |  
 31250 |             return error_node(); 
 31251 |          } 
 31252 |       } 
 31253 |  
 31254 |       inline expression_node_ptr parse_branch(precedence_level precedence = e_level00) 
 31255 |       { 
 31256 |          stack_limit_handler slh(*this); 
 31257 |  
 31258 |          if (!slh) 
 31259 |          { 
 31260 |             return error_node(); 
 31261 |          } 
 31262 |  
 31263 |          expression_node_ptr branch = error_node(); 
 31264 |  
 31265 |          if (token_t::e_number == current_token().type) 
 31266 |          { 
 31267 |             T numeric_value = T(0); 
 31268 |  
 31269 |             if (details::string_to_real(current_token().value, numeric_value)) 
 31270 |             { 
 31271 |                expression_node_ptr literal_exp = expression_generator_(numeric_value); 
 31272 |  
 31273 |                if (0 == literal_exp) 
 31274 |                { 
 31275 |                   set_error(make_error( 
 31276 |                      parser_error::e_numeric, 
 31277 |                      current_token(), 
 31278 |                      "ERR237 - Failed generate node for scalar: '" + current_token().value + "'", 
 31279 |                      exprtk_error_location)); 
 31280 |  
 31281 |                   return error_node(); 
 31282 |                } 
 31283 |  
 31284 |                next_token(); 
 31285 |                branch = literal_exp; 
 31286 |             } 
 31287 |             else 
 31288 |             { 
 31289 |                set_error(make_error( 
 31290 |                   parser_error::e_numeric, 
 31291 |                   current_token(), 
 31292 |                   "ERR238 - Failed to convert '" + current_token().value + "' to a number", 
 31293 |                   exprtk_error_location)); 
 31294 |  
 31295 |                return error_node(); 
 31296 |             } 
 31297 |          } 
 31298 |          else if (token_t::e_symbol == current_token().type) 
 31299 |          { 
 31300 |             branch = parse_symbol(); 
 31301 |          } 
 31302 |          #ifndef exprtk_disable_string_capabilities 
 31303 |          else if (token_t::e_string == current_token().type) 
 31304 |          { 
 31305 |             branch = parse_const_string(); 
 31306 |          } 
 31307 |          #endif 
 31308 |          else if (token_t::e_lbracket == current_token().type) 
 31309 |          { 
 31310 |             next_token(); 
 31311 |  
 31312 |             if (0 == (branch = parse_expression())) 
 31313 |             { 
 31314 |                return error_node(); 
 31315 |             } 
 31316 |  
 31317 |             token_is(token_t::e_eof); 
 31318 |  
 31319 |             if (!token_is(token_t::e_rbracket)) 
 31320 |             { 
 31321 |                set_error(make_error( 
 31322 |                   parser_error::e_syntax, 
 31323 |                   current_token(), 
 31324 |                   "ERR239 - Expected ')' instead of: '" + current_token().value + "'", 
 31325 |                   exprtk_error_location)); 
 31326 |  
 31327 |                details::free_node(node_allocator_, branch); 
 31328 |  
 31329 |                return error_node(); 
 31330 |             } 
 31331 |             else if (!post_bracket_process(token_t::e_lbracket,branch)) 
 31332 |             { 
 31333 |                details::free_node(node_allocator_, branch); 
 31334 |  
 31335 |                return error_node(); 
 31336 |             } 
 31337 |  
 31338 |             parse_pending_vector_index_operator(branch); 
 31339 |          } 
 31340 |          else if (token_t::e_lsqrbracket == current_token().type) 
 31341 |          { 
 31342 |             next_token(); 
 31343 |  
 31344 |             if (0 == (branch = parse_expression())) 
 31345 |                return error_node(); 
 31346 |             else if (!token_is(token_t::e_rsqrbracket)) 
 31347 |             { 
 31348 |                set_error(make_error( 
 31349 |                   parser_error::e_syntax, 
 31350 |                   current_token(), 
 31351 |                   "ERR240 - Expected ']' instead of: '" + current_token().value + "'", 
 31352 |                   exprtk_error_location)); 
 31353 |  
 31354 |                details::free_node(node_allocator_, branch); 
 31355 |  
 31356 |                return error_node(); 
 31357 |             } 
 31358 |             else if (!post_bracket_process(token_t::e_lsqrbracket,branch)) 
 31359 |             { 
 31360 |                details::free_node(node_allocator_, branch); 
 31361 |  
 31362 |                return error_node(); 
 31363 |             } 
 31364 |          } 
 31365 |          else if (token_t::e_lcrlbracket == current_token().type) 
 31366 |          { 
 31367 |             next_token(); 
 31368 |  
 31369 |             if (0 == (branch = parse_expression())) 
 31370 |                return error_node(); 
 31371 |             else if (!token_is(token_t::e_rcrlbracket)) 
 31372 |             { 
 31373 |                set_error(make_error( 
 31374 |                   parser_error::e_syntax, 
 31375 |                   current_token(), 
 31376 |                   "ERR241 - Expected '}' instead of: '" + current_token().value + "'", 
 31377 |                   exprtk_error_location)); 
 31378 |  
 31379 |                details::free_node(node_allocator_, branch); 
 31380 |  
 31381 |                return error_node(); 
 31382 |             } 
 31383 |             else if (!post_bracket_process(token_t::e_lcrlbracket,branch)) 
 31384 |             { 
 31385 |                details::free_node(node_allocator_, branch); 
 31386 |  
 31387 |                return error_node(); 
 31388 |             } 
 31389 |          } 
 31390 |          else if (token_t::e_sub == current_token().type) 
 31391 |          { 
 31392 |             next_token(); 
 31393 |             branch = parse_expression(e_level11); 
 31394 |  
 31395 |             if ( 
 31396 |                  branch && 
 31397 |                  !( 
 31398 |                     details::is_neg_unary_node    (branch) && 
 31399 |                     simplify_unary_negation_branch(branch) 
 31400 |                   ) 
 31401 |                ) 
 31402 |             { 
 31403 |                expression_node_ptr result = expression_generator_(details::e_neg,branch); 
 31404 |  
 31405 |                if (0 == result) 
 31406 |                { 
 31407 |                   details::free_node(node_allocator_, branch); 
 31408 |  
 31409 |                   return error_node(); 
 31410 |                } 
 31411 |                else 
 31412 |                   branch = result; 
 31413 |             } 
 31414 |          } 
 31415 |          else if (token_t::e_add == current_token().type) 
 31416 |          { 
 31417 |             next_token(); 
 31418 |             branch = parse_expression(e_level13); 
 31419 |          } 
 31420 |          else if (token_t::e_eof == current_token().type) 
 31421 |          { 
 31422 |             set_error(make_error( 
 31423 |                parser_error::e_syntax, 
 31424 |                current_token(), 
 31425 |                "ERR242 - Premature end of expression[1]", 
 31426 |                exprtk_error_location)); 
 31427 |  
 31428 |             return error_node(); 
 31429 |          } 
 31430 |          else 
 31431 |          { 
 31432 |             set_error(make_error( 
 31433 |                parser_error::e_syntax, 
 31434 |                current_token(), 
 31435 |                "ERR243 - Premature end of expression[2]", 
 31436 |                exprtk_error_location)); 
 31437 |  
 31438 |             return error_node(); 
 31439 |          } 
 31440 |  
 31441 |          if ( 
 31442 |               branch                    && 
 31443 |               (e_level00 == precedence) && 
 31444 |               token_is(token_t::e_ternary,prsrhlpr_t::e_hold) 
 31445 |             ) 
 31446 |          { 
 31447 |             branch = parse_ternary_conditional_statement(branch); 
 31448 |          } 
 31449 |  
 31450 |          parse_pending_string_rangesize(branch); 
 31451 |  
 31452 |          return branch; 
 31453 |       } 
 31454 |  
 31455 |       template <typename Type> 
 31456 |       class expression_generator 
 31457 |       { 
 31458 |       public: 
 31459 |  
 31460 |          typedef details::expression_node<Type>* expression_node_ptr; 
 31461 |          typedef expression_node_ptr (*synthesize_functor_t)(expression_generator<T>&, const details::operator_type& operation, expression_node_ptr (&branch)[2]); 
 31462 |          typedef std::map<std::string,synthesize_functor_t> synthesize_map_t; 
 31463 |          typedef typename exprtk::parser<Type> parser_t; 
 31464 |          typedef const Type& vtype; 
 31465 |          typedef const Type  ctype; 
 31466 |  
 31467 |          inline void init_synthesize_map() 
 31468 |          { 
 31469 |             #ifndef exprtk_disable_enhanced_features 
 31470 |             synthesize_map_["(v)o(v)"] = synthesize_vov_expression::process; 
 31471 |             synthesize_map_["(c)o(v)"] = synthesize_cov_expression::process; 
 31472 |             synthesize_map_["(v)o(c)"] = synthesize_voc_expression::process; 
 31473 |  
 31474 |             #define register_synthezier(S)                      \ 
 31475 |             synthesize_map_[S ::node_type::id()] = S ::process; \ 
 31476 |  
 31477 |             register_synthezier(synthesize_vovov_expression0) 
 31478 |             register_synthezier(synthesize_vovov_expression1) 
 31479 |             register_synthezier(synthesize_vovoc_expression0) 
 31480 |             register_synthezier(synthesize_vovoc_expression1) 
 31481 |             register_synthezier(synthesize_vocov_expression0) 
 31482 |             register_synthezier(synthesize_vocov_expression1) 
 31483 |             register_synthezier(synthesize_covov_expression0) 
 31484 |             register_synthezier(synthesize_covov_expression1) 
 31485 |             register_synthezier(synthesize_covoc_expression0) 
 31486 |             register_synthezier(synthesize_covoc_expression1) 
 31487 |             register_synthezier(synthesize_cocov_expression1) 
 31488 |             register_synthezier(synthesize_vococ_expression0) 
 31489 |  
 31490 |             register_synthezier(synthesize_vovovov_expression0) 
 31491 |             register_synthezier(synthesize_vovovoc_expression0) 
 31492 |             register_synthezier(synthesize_vovocov_expression0) 
 31493 |             register_synthezier(synthesize_vocovov_expression0) 
 31494 |             register_synthezier(synthesize_covovov_expression0) 
 31495 |             register_synthezier(synthesize_covocov_expression0) 
 31496 |             register_synthezier(synthesize_vocovoc_expression0) 
 31497 |             register_synthezier(synthesize_covovoc_expression0) 
 31498 |             register_synthezier(synthesize_vococov_expression0) 
 31499 |  
 31500 |             register_synthezier(synthesize_vovovov_expression1) 
 31501 |             register_synthezier(synthesize_vovovoc_expression1) 
 31502 |             register_synthezier(synthesize_vovocov_expression1) 
 31503 |             register_synthezier(synthesize_vocovov_expression1) 
 31504 |             register_synthezier(synthesize_covovov_expression1) 
 31505 |             register_synthezier(synthesize_covocov_expression1) 
 31506 |             register_synthezier(synthesize_vocovoc_expression1) 
 31507 |             register_synthezier(synthesize_covovoc_expression1) 
 31508 |             register_synthezier(synthesize_vococov_expression1) 
 31509 |  
 31510 |             register_synthezier(synthesize_vovovov_expression2) 
 31511 |             register_synthezier(synthesize_vovovoc_expression2) 
 31512 |             register_synthezier(synthesize_vovocov_expression2) 
 31513 |             register_synthezier(synthesize_vocovov_expression2) 
 31514 |             register_synthezier(synthesize_covovov_expression2) 
 31515 |             register_synthezier(synthesize_covocov_expression2) 
 31516 |             register_synthezier(synthesize_vocovoc_expression2) 
 31517 |             register_synthezier(synthesize_covovoc_expression2) 
 31518 |  
 31519 |             register_synthezier(synthesize_vovovov_expression3) 
 31520 |             register_synthezier(synthesize_vovovoc_expression3) 
 31521 |             register_synthezier(synthesize_vovocov_expression3) 
 31522 |             register_synthezier(synthesize_vocovov_expression3) 
 31523 |             register_synthezier(synthesize_covovov_expression3) 
 31524 |             register_synthezier(synthesize_covocov_expression3) 
 31525 |             register_synthezier(synthesize_vocovoc_expression3) 
 31526 |             register_synthezier(synthesize_covovoc_expression3) 
 31527 |             register_synthezier(synthesize_vococov_expression3) 
 31528 |  
 31529 |             register_synthezier(synthesize_vovovov_expression4) 
 31530 |             register_synthezier(synthesize_vovovoc_expression4) 
 31531 |             register_synthezier(synthesize_vovocov_expression4) 
 31532 |             register_synthezier(synthesize_vocovov_expression4) 
 31533 |             register_synthezier(synthesize_covovov_expression4) 
 31534 |             register_synthezier(synthesize_covocov_expression4) 
 31535 |             register_synthezier(synthesize_vocovoc_expression4) 
 31536 |             register_synthezier(synthesize_covovoc_expression4) 
 31537 |  
 31538 |             #undef register_synthezier 
 31539 |             #endif 
 31540 |          } 
 31541 |  
 31542 |          inline void set_parser(parser_t& p) 
 31543 |          { 
 31544 |             parser_ = &p; 
 31545 |          } 
 31546 |  
 31547 |          inline void set_uom(unary_op_map_t& unary_op_map) 
 31548 |          { 
 31549 |             unary_op_map_ = &unary_op_map; 
 31550 |          } 
 31551 |  
 31552 |          inline void set_bom(binary_op_map_t& binary_op_map) 
 31553 |          { 
 31554 |             binary_op_map_ = &binary_op_map; 
 31555 |          } 
 31556 |  
 31557 |          inline void set_ibom(inv_binary_op_map_t& inv_binary_op_map) 
 31558 |          { 
 31559 |             inv_binary_op_map_ = &inv_binary_op_map; 
 31560 |          } 
 31561 |  
 31562 |          inline void set_sf3m(sf3_map_t& sf3_map) 
 31563 |          { 
 31564 |             sf3_map_ = &sf3_map; 
 31565 |          } 
 31566 |  
 31567 |          inline void set_sf4m(sf4_map_t& sf4_map) 
 31568 |          { 
 31569 |             sf4_map_ = &sf4_map; 
 31570 |          } 
 31571 |  
 31572 |          inline void set_allocator(details::node_allocator& na) 
 31573 |          { 
 31574 |             node_allocator_ = &na; 
 31575 |          } 
 31576 |  
 31577 |          inline void set_strength_reduction_state(const bool enabled) 
 31578 |          { 
 31579 |             strength_reduction_enabled_ = enabled; 
 31580 |          } 
 31581 |  
 31582 |          inline bool strength_reduction_enabled() const 
 31583 |          { 
 31584 |             return strength_reduction_enabled_; 
 31585 |          } 
 31586 |  
 31587 |          inline bool valid_operator(const details::operator_type& operation, binary_functor_t& bop) 
 31588 |          { 
 31589 |             typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation); 
 31590 |  
 31591 |             if (binary_op_map_->end() == bop_itr) 
 31592 |                return false; 
 31593 |  
 31594 |             bop = bop_itr->second; 
 31595 |  
 31596 |             return true; 
 31597 |          } 
 31598 |  
 31599 |          inline bool valid_operator(const details::operator_type& operation, unary_functor_t& uop) 
 31600 |          { 
 31601 |             typename unary_op_map_t::iterator uop_itr = unary_op_map_->find(operation); 
 31602 |  
 31603 |             if ((*unary_op_map_).end() == uop_itr) 
 31604 |                return false; 
 31605 |  
 31606 |             uop = uop_itr->second; 
 31607 |  
 31608 |             return true; 
 31609 |          } 
 31610 |  
 31611 |          inline details::operator_type get_operator(const binary_functor_t& bop) const 
 31612 |          { 
 31613 |             return (*inv_binary_op_map_).find(bop)->second; 
 31614 |          } 
 31615 |  
 31616 |          inline expression_node_ptr operator() (const Type& v) const 
 31617 |          { 
 31618 |             return node_allocator_->allocate<literal_node_t>(v); 
 31619 |          } 
 31620 |  
 31621 |          #ifndef exprtk_disable_string_capabilities 
 31622 |          inline expression_node_ptr operator() (const std::string& s) const 
 31623 |          { 
 31624 |             return node_allocator_->allocate<string_literal_node_t>(s); 
 31625 |          } 
 31626 |  
 31627 |          inline expression_node_ptr operator() (std::string& s, range_t& rp) const 
 31628 |          { 
 31629 |             return node_allocator_->allocate_rr<string_range_node_t>(s,rp); 
 31630 |          } 
 31631 |  
 31632 |          inline expression_node_ptr operator() (const std::string& s, range_t& rp) const 
 31633 |          { 
 31634 |             return node_allocator_->allocate_tt<const_string_range_node_t>(s,rp); 
 31635 |          } 
 31636 |  
 31637 |          inline expression_node_ptr operator() (expression_node_ptr branch, range_t& rp) const 
 31638 |          { 
 31639 |             if (is_generally_string_node(branch)) 
 31640 |                return node_allocator_->allocate_tt<generic_string_range_node_t>(branch,rp); 
 31641 |             else 
 31642 |                return error_node(); 
 31643 |          } 
 31644 |          #endif 
 31645 |  
 31646 |          inline bool unary_optimisable(const details::operator_type& operation) const 
 31647 |          { 
 31648 |             return (details::e_abs   == operation) || (details::e_acos  == operation) || 
 31649 |                    (details::e_acosh == operation) || (details::e_asin  == operation) || 
 31650 |                    (details::e_asinh == operation) || (details::e_atan  == operation) || 
 31651 |                    (details::e_atanh == operation) || (details::e_ceil  == operation) || 
 31652 |                    (details::e_cos   == operation) || (details::e_cosh  == operation) || 
 31653 |                    (details::e_exp   == operation) || (details::e_expm1 == operation) || 
 31654 |                    (details::e_floor == operation) || (details::e_log   == operation) || 
 31655 |                    (details::e_log10 == operation) || (details::e_log2  == operation) || 
 31656 |                    (details::e_log1p == operation) || (details::e_neg   == operation) || 
 31657 |                    (details::e_pos   == operation) || (details::e_round == operation) || 
 31658 |                    (details::e_sin   == operation) || (details::e_sinc  == operation) || 
 31659 |                    (details::e_sinh  == operation) || (details::e_sqrt  == operation) || 
 31660 |                    (details::e_tan   == operation) || (details::e_tanh  == operation) || 
 31661 |                    (details::e_cot   == operation) || (details::e_sec   == operation) || 
 31662 |                    (details::e_csc   == operation) || (details::e_r2d   == operation) || 
 31663 |                    (details::e_d2r   == operation) || (details::e_d2g   == operation) || 
 31664 |                    (details::e_g2d   == operation) || (details::e_notl  == operation) || 
 31665 |                    (details::e_sgn   == operation) || (details::e_erf   == operation) || 
 31666 |                    (details::e_erfc  == operation) || (details::e_ncdf  == operation) || 
 31667 |                    (details::e_frac  == operation) || (details::e_trunc == operation) ; 
 31668 |          } 
 31669 |  
 31670 |          inline bool sf3_optimisable(const std::string& sf3id, trinary_functor_t& tfunc) const 
 31671 |          { 
 31672 |             typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id); 
 31673 |  
 31674 |             if (sf3_map_->end() == itr) 
 31675 |                return false; 
 31676 |             else 
 31677 |                tfunc = itr->second.first; 
 31678 |  
 31679 |             return true; 
 31680 |          } 
 31681 |  
 31682 |          inline bool sf4_optimisable(const std::string& sf4id, quaternary_functor_t& qfunc) const 
 31683 |          { 
 31684 |             typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id); 
 31685 |  
 31686 |             if (sf4_map_->end() == itr) 
 31687 |                return false; 
 31688 |             else 
 31689 |                qfunc = itr->second.first; 
 31690 |  
 31691 |             return true; 
 31692 |          } 
 31693 |  
 31694 |          inline bool sf3_optimisable(const std::string& sf3id, details::operator_type& operation) const 
 31695 |          { 
 31696 |             typename sf3_map_t::const_iterator itr = sf3_map_->find(sf3id); 
 31697 |  
 31698 |             if (sf3_map_->end() == itr) 
 31699 |                return false; 
 31700 |             else 
 31701 |                operation = itr->second.second; 
 31702 |  
 31703 |             return true; 
 31704 |          } 
 31705 |  
 31706 |          inline bool sf4_optimisable(const std::string& sf4id, details::operator_type& operation) const 
 31707 |          { 
 31708 |             typename sf4_map_t::const_iterator itr = sf4_map_->find(sf4id); 
 31709 |  
 31710 |             if (sf4_map_->end() == itr) 
 31711 |                return false; 
 31712 |             else 
 31713 |                operation = itr->second.second; 
 31714 |  
 31715 |             return true; 
 31716 |          } 
 31717 |  
 31718 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[1]) 
 31719 |          { 
 31720 |             if (0 == branch[0]) 
 31721 |             { 
 31722 |                return error_node(); 
 31723 |             } 
 31724 |             else if (details::is_null_node(branch[0])) 
 31725 |             { 
 31726 |                return branch[0]; 
 31727 |             } 
 31728 |             else if (details::is_break_node(branch[0])) 
 31729 |             { 
 31730 |                return error_node(); 
 31731 |             } 
 31732 |             else if (details::is_continue_node(branch[0])) 
 31733 |             { 
 31734 |                return error_node(); 
 31735 |             } 
 31736 |             else if (details::is_constant_node(branch[0])) 
 31737 |             { 
 31738 |                return synthesize_expression<unary_node_t,1>(operation,branch); 
 31739 |             } 
 31740 |             else if (unary_optimisable(operation) && details::is_variable_node(branch[0])) 
 31741 |             { 
 31742 |                return synthesize_uv_expression(operation,branch); 
 31743 |             } 
 31744 |             else if (unary_optimisable(operation) && details::is_ivector_node(branch[0])) 
 31745 |             { 
 31746 |                return synthesize_uvec_expression(operation,branch); 
 31747 |             } 
 31748 |             else 
 31749 |                return synthesize_unary_expression(operation,branch); 
 31750 |          } 
 31751 |  
 31752 |          inline bool is_assignment_operation(const details::operator_type& operation) const 
 31753 |          { 
 31754 |             return ( 
 31755 |                      (details::e_addass == operation) || 
 31756 |                      (details::e_subass == operation) || 
 31757 |                      (details::e_mulass == operation) || 
 31758 |                      (details::e_divass == operation) || 
 31759 |                      (details::e_modass == operation) 
 31760 |                    ) && 
 31761 |                    parser_->settings_.assignment_enabled(operation); 
 31762 |          } 
 31763 |  
 31764 |          #ifndef exprtk_disable_string_capabilities 
 31765 |          inline bool valid_string_operation(const details::operator_type& operation) const 
 31766 |          { 
 31767 |             return (details::e_add    == operation) || 
 31768 |                    (details::e_lt     == operation) || 
 31769 |                    (details::e_lte    == operation) || 
 31770 |                    (details::e_gt     == operation) || 
 31771 |                    (details::e_gte    == operation) || 
 31772 |                    (details::e_eq     == operation) || 
 31773 |                    (details::e_ne     == operation) || 
 31774 |                    (details::e_in     == operation) || 
 31775 |                    (details::e_like   == operation) || 
 31776 |                    (details::e_ilike  == operation) || 
 31777 |                    (details::e_assign == operation) || 
 31778 |                    (details::e_addass == operation) || 
 31779 |                    (details::e_swap   == operation) ; 
 31780 |          } 
 31781 |          #else 
 31782 |          inline bool valid_string_operation(const details::operator_type&) const 
 31783 |          { 
 31784 |             return false; 
 31785 |          } 
 31786 |          #endif 
 31787 |  
 31788 |          inline std::string to_str(const details::operator_type& operation) const 
 31789 |          { 
 31790 |             switch (operation) 
 31791 |             { 
 31792 |                case details::e_add  : return "+"      ; 
 31793 |                case details::e_sub  : return "-"      ; 
 31794 |                case details::e_mul  : return "*"      ; 
 31795 |                case details::e_div  : return "/"      ; 
 31796 |                case details::e_mod  : return "%"      ; 
 31797 |                case details::e_pow  : return "^"      ; 
 31798 |                case details::e_lt   : return "<"      ; 
 31799 |                case details::e_lte  : return "<="     ; 
 31800 |                case details::e_gt   : return ">"      ; 
 31801 |                case details::e_gte  : return ">="     ; 
 31802 |                case details::e_eq   : return "=="     ; 
 31803 |                case details::e_ne   : return "!="     ; 
 31804 |                case details::e_and  : return "and"    ; 
 31805 |                case details::e_nand : return "nand"   ; 
 31806 |                case details::e_or   : return "or"     ; 
 31807 |                case details::e_nor  : return "nor"    ; 
 31808 |                case details::e_xor  : return "xor"    ; 
 31809 |                case details::e_xnor : return "xnor"   ; 
 31810 |                default              : return "UNKNOWN" 
 31811 |             } 
 31812 |          } 
 31813 |  
 31814 |          inline bool operation_optimisable(const details::operator_type& operation) const 
 31815 |          { 
 31816 |             return (details::e_add  == operation) || 
 31817 |                    (details::e_sub  == operation) || 
 31818 |                    (details::e_mul  == operation) || 
 31819 |                    (details::e_div  == operation) || 
 31820 |                    (details::e_mod  == operation) || 
 31821 |                    (details::e_pow  == operation) || 
 31822 |                    (details::e_lt   == operation) || 
 31823 |                    (details::e_lte  == operation) || 
 31824 |                    (details::e_gt   == operation) || 
 31825 |                    (details::e_gte  == operation) || 
 31826 |                    (details::e_eq   == operation) || 
 31827 |                    (details::e_ne   == operation) || 
 31828 |                    (details::e_and  == operation) || 
 31829 |                    (details::e_nand == operation) || 
 31830 |                    (details::e_or   == operation) || 
 31831 |                    (details::e_nor  == operation) || 
 31832 |                    (details::e_xor  == operation) || 
 31833 |                    (details::e_xnor == operation) ; 
 31834 |          } 
 31835 |  
 31836 |          inline std::string branch_to_id(expression_node_ptr branch) const 
 31837 |          { 
 31838 |             static const std::string null_str   ("(null)" ); 
 31839 |             static const std::string const_str  ("(c)"    ); 
 31840 |             static const std::string var_str    ("(v)"    ); 
 31841 |             static const std::string vov_str    ("(vov)"  ); 
 31842 |             static const std::string cov_str    ("(cov)"  ); 
 31843 |             static const std::string voc_str    ("(voc)"  ); 
 31844 |             static const std::string str_str    ("(s)"    ); 
 31845 |             static const std::string strrng_str ("(rngs)" ); 
 31846 |             static const std::string cs_str     ("(cs)"   ); 
 31847 |             static const std::string cstrrng_str("(crngs)"); 
 31848 |  
 31849 |             if (details::is_null_node(branch)) 
 31850 |                return null_str; 
 31851 |             else if (details::is_constant_node(branch)) 
 31852 |                return const_str; 
 31853 |             else if (details::is_variable_node(branch)) 
 31854 |                return var_str; 
 31855 |             else if (details::is_vov_node(branch)) 
 31856 |                return vov_str; 
 31857 |             else if (details::is_cov_node(branch)) 
 31858 |                return cov_str; 
 31859 |             else if (details::is_voc_node(branch)) 
 31860 |                return voc_str; 
 31861 |             else if (details::is_string_node(branch)) 
 31862 |                return str_str; 
 31863 |             else if (details::is_const_string_node(branch)) 
 31864 |                return cs_str; 
 31865 |             else if (details::is_string_range_node(branch)) 
 31866 |                return strrng_str; 
 31867 |             else if (details::is_const_string_range_node(branch)) 
 31868 |                return cstrrng_str; 
 31869 |             else if (details::is_t0ot1ot2_node(branch)) 
 31870 |                return "(" + dynamic_cast<details::T0oT1oT2_base_node<T>*>(branch)->type_id() + ")" 
 31871 |             else if (details::is_t0ot1ot2ot3_node(branch)) 
 31872 |                return "(" + dynamic_cast<details::T0oT1oT2oT3_base_node<T>*>(branch)->type_id() + ")" 
 31873 |             else 
 31874 |                return "ERROR" 
 31875 |          } 
 31876 |  
 31877 |          inline std::string branch_to_id(expression_node_ptr (&branch)[2]) const 
 31878 |          { 
 31879 |             return branch_to_id(branch[0]) + std::string("o") + branch_to_id(branch[1]); 
 31880 |          } 
 31881 |  
 31882 |          inline bool cov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31883 |          { 
 31884 |             if (!operation_optimisable(operation)) 
 31885 |                return false; 
 31886 |             else 
 31887 |                return details::is_constant_node(branch[0]) && 
 31888 |                       details::is_variable_node(branch[1]) ; 
 31889 |          } 
 31890 |  
 31891 |          inline bool voc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31892 |          { 
 31893 |             if (!operation_optimisable(operation)) 
 31894 |                return false; 
 31895 |             else 
 31896 |                return details::is_variable_node(branch[0]) && 
 31897 |                       details::is_constant_node(branch[1]) ; 
 31898 |          } 
 31899 |  
 31900 |          inline bool vov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31901 |          { 
 31902 |             if (!operation_optimisable(operation)) 
 31903 |                return false; 
 31904 |             else 
 31905 |                return details::is_variable_node(branch[0]) && 
 31906 |                       details::is_variable_node(branch[1]) ; 
 31907 |          } 
 31908 |  
 31909 |          inline bool cob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31910 |          { 
 31911 |             if (!operation_optimisable(operation)) 
 31912 |                return false; 
 31913 |             else 
 31914 |                return details::is_constant_node(branch[0]) && 
 31915 |                      !details::is_constant_node(branch[1]) ; 
 31916 |          } 
 31917 |  
 31918 |          inline bool boc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31919 |          { 
 31920 |             if (!operation_optimisable(operation)) 
 31921 |                return false; 
 31922 |             else 
 31923 |                return !details::is_constant_node(branch[0]) && 
 31924 |                        details::is_constant_node(branch[1]) ; 
 31925 |          } 
 31926 |  
 31927 |          inline bool cocob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31928 |          { 
 31929 |             if ( 
 31930 |                  (details::e_add == operation) || 
 31931 |                  (details::e_sub == operation) || 
 31932 |                  (details::e_mul == operation) || 
 31933 |                  (details::e_div == operation) 
 31934 |                ) 
 31935 |             { 
 31936 |                return (details::is_constant_node(branch[0]) && details::is_cob_node(branch[1])) || 
 31937 |                       (details::is_constant_node(branch[1]) && details::is_cob_node(branch[0])) ; 
 31938 |             } 
 31939 |             else 
 31940 |                return false; 
 31941 |          } 
 31942 |  
 31943 |          inline bool coboc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31944 |          { 
 31945 |             if ( 
 31946 |                  (details::e_add == operation) || 
 31947 |                  (details::e_sub == operation) || 
 31948 |                  (details::e_mul == operation) || 
 31949 |                  (details::e_div == operation) 
 31950 |                ) 
 31951 |             { 
 31952 |                return (details::is_constant_node(branch[0]) && details::is_boc_node(branch[1])) || 
 31953 |                       (details::is_constant_node(branch[1]) && details::is_boc_node(branch[0])) ; 
 31954 |             } 
 31955 |             else 
 31956 |                return false; 
 31957 |          } 
 31958 |  
 31959 |          inline bool uvouv_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31960 |          { 
 31961 |             if (!operation_optimisable(operation)) 
 31962 |                return false; 
 31963 |             else 
 31964 |                return details::is_uv_node(branch[0]) && 
 31965 |                       details::is_uv_node(branch[1]) ; 
 31966 |          } 
 31967 |  
 31968 |          inline bool vob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31969 |          { 
 31970 |             if (!operation_optimisable(operation)) 
 31971 |                return false; 
 31972 |             else 
 31973 |                return details::is_variable_node(branch[0]) && 
 31974 |                      !details::is_variable_node(branch[1]) ; 
 31975 |          } 
 31976 |  
 31977 |          inline bool bov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31978 |          { 
 31979 |             if (!operation_optimisable(operation)) 
 31980 |                return false; 
 31981 |             else 
 31982 |                return !details::is_variable_node(branch[0]) && 
 31983 |                        details::is_variable_node(branch[1]) ; 
 31984 |          } 
 31985 |  
 31986 |          inline bool binext_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31987 |          { 
 31988 |             if (!operation_optimisable(operation)) 
 31989 |                return false; 
 31990 |             else 
 31991 |                return !details::is_constant_node(branch[0]) || 
 31992 |                       !details::is_constant_node(branch[1]) ; 
 31993 |          } 
 31994 |  
 31995 |          inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 31996 |          { 
 31997 |             if (is_assignment_operation(operation)) 
 31998 |             { 
 31999 |                const bool b1_is_genstring = details::is_generally_string_node(branch[1]); 
 32000 |  
 32001 |                if (details::is_string_node(branch[0])) 
 32002 |                   return !b1_is_genstring; 
 32003 |                else if (details::is_literal_node(branch[0])) 
 32004 |                   return true; 
 32005 |                else 
 32006 |                   return ( 
 32007 |                            !details::is_variable_node              (branch[0]) && 
 32008 |                            !details::is_vector_elem_node           (branch[0]) && 
 32009 |                            !details::is_vector_celem_node          (branch[0]) && 
 32010 |                            !details::is_vector_elem_rtc_node       (branch[0]) && 
 32011 |                            !details::is_vector_celem_rtc_node      (branch[0]) && 
 32012 |                            !details::is_rebasevector_elem_node     (branch[0]) && 
 32013 |                            !details::is_rebasevector_celem_node    (branch[0]) && 
 32014 |                            !details::is_rebasevector_elem_rtc_node (branch[0]) && 
 32015 |                            !details::is_rebasevector_celem_rtc_node(branch[0]) && 
 32016 |                            !details::is_vector_node                (branch[0]) 
 32017 |                          ) 
 32018 |                          || b1_is_genstring; 
 32019 |             } 
 32020 |             else 
 32021 |                return false; 
 32022 |          } 
 32023 |  
 32024 |          inline bool is_constpow_operation(const details::operator_type& operation, expression_node_ptr(&branch)[2]) const 
 32025 |          { 
 32026 |             if ( 
 32027 |                  !details::is_constant_node(branch[1]) || 
 32028 |                   details::is_constant_node(branch[0]) || 
 32029 |                   details::is_variable_node(branch[0]) || 
 32030 |                   details::is_vector_node  (branch[0]) || 
 32031 |                   details::is_generally_string_node(branch[0]) 
 32032 |                ) 
 32033 |                return false; 
 32034 |  
 32035 |             const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 32036 |  
 32037 |             return cardinal_pow_optimisable(operation, c); 
 32038 |          } 
 32039 |  
 32040 |          inline bool is_invalid_break_continue_op(expression_node_ptr (&branch)[2]) const 
 32041 |          { 
 32042 |             return ( 
 32043 |                      details::is_break_node   (branch[0]) || 
 32044 |                      details::is_break_node   (branch[1]) || 
 32045 |                      details::is_continue_node(branch[0]) || 
 32046 |                      details::is_continue_node(branch[1]) 
 32047 |                    ); 
 32048 |          } 
 32049 |  
 32050 |          inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32051 |          { 
 32052 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32053 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32054 |  
 32055 |             bool result = false; 
 32056 |  
 32057 |             if (b0_string != b1_string) 
 32058 |                result = true; 
 32059 |             else if (!valid_string_operation(operation) && b0_string && b1_string) 
 32060 |                result = true; 
 32061 |  
 32062 |             if (result) 
 32063 |             { 
 32064 |                parser_->set_synthesis_error("Invalid string operation"); 
 32065 |             } 
 32066 |  
 32067 |             return result; 
 32068 |          } 
 32069 |  
 32070 |          inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const 
 32071 |          { 
 32072 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32073 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32074 |             const bool b2_string = is_generally_string_node(branch[2]); 
 32075 |  
 32076 |             bool result = false; 
 32077 |  
 32078 |             if ((b0_string != b1_string) || (b1_string != b2_string)) 
 32079 |                result = true; 
 32080 |             else if ((details::e_inrange != operation) && b0_string && b1_string && b2_string) 
 32081 |                result = true; 
 32082 |  
 32083 |             if (result) 
 32084 |             { 
 32085 |                parser_->set_synthesis_error("Invalid string operation"); 
 32086 |             } 
 32087 |  
 32088 |             return result; 
 32089 |          } 
 32090 |  
 32091 |          inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32092 |          { 
 32093 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32094 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32095 |  
 32096 |             return (b0_string && b1_string && valid_string_operation(operation)); 
 32097 |          } 
 32098 |  
 32099 |          inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3]) const 
 32100 |          { 
 32101 |             const bool b0_string = is_generally_string_node(branch[0]); 
 32102 |             const bool b1_string = is_generally_string_node(branch[1]); 
 32103 |             const bool b2_string = is_generally_string_node(branch[2]); 
 32104 |  
 32105 |             return (b0_string && b1_string && b2_string && (details::e_inrange == operation)); 
 32106 |          } 
 32107 |  
 32108 |          #ifndef exprtk_disable_sc_andor 
 32109 |          inline bool is_shortcircuit_expression(const details::operator_type& operation) const 
 32110 |          { 
 32111 |             return ( 
 32112 |                      (details::e_scand == operation) || 
 32113 |                      (details::e_scor  == operation) 
 32114 |                    ); 
 32115 |          } 
 32116 |          #else 
 32117 |          inline bool is_shortcircuit_expression(const details::operator_type&) const 
 32118 |          { 
 32119 |             return false; 
 32120 |          } 
 32121 |          #endif 
 32122 |  
 32123 |          inline bool is_null_present(expression_node_ptr (&branch)[2]) const 
 32124 |          { 
 32125 |             return ( 
 32126 |                      details::is_null_node(branch[0]) || 
 32127 |                      details::is_null_node(branch[1]) 
 32128 |                    ); 
 32129 |          } 
 32130 |  
 32131 |          inline bool is_vector_eqineq_logic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32132 |          { 
 32133 |             if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1])) 
 32134 |                return false; 
 32135 |             else 
 32136 |                return ( 
 32137 |                         (details::e_lt    == operation) || 
 32138 |                         (details::e_lte   == operation) || 
 32139 |                         (details::e_gt    == operation) || 
 32140 |                         (details::e_gte   == operation) || 
 32141 |                         (details::e_eq    == operation) || 
 32142 |                         (details::e_ne    == operation) || 
 32143 |                         (details::e_equal == operation) || 
 32144 |                         (details::e_and   == operation) || 
 32145 |                         (details::e_nand  == operation) || 
 32146 |                         (details::e_or    == operation) || 
 32147 |                         (details::e_nor   == operation) || 
 32148 |                         (details::e_xor   == operation) || 
 32149 |                         (details::e_xnor  == operation) 
 32150 |                       ); 
 32151 |          } 
 32152 |  
 32153 |          inline bool is_vector_arithmetic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const 
 32154 |          { 
 32155 |             if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1])) 
 32156 |                return false; 
 32157 |             else 
 32158 |                return ( 
 32159 |                         (details::e_add == operation) || 
 32160 |                         (details::e_sub == operation) || 
 32161 |                         (details::e_mul == operation) || 
 32162 |                         (details::e_div == operation) || 
 32163 |                         (details::e_pow == operation) 
 32164 |                       ); 
 32165 |          } 
 32166 |  
 32167 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 32168 |          { 
 32169 |             if ((0 == branch[0]) || (0 == branch[1])) 
 32170 |             { 
 32171 |                parser_->set_error(parser_error::make_error( 
 32172 |                   parser_error::e_syntax, 
 32173 |                   parser_->current_state().token, 
 32174 |                   "ERR244 - Invalid branches received for operator '" + details::to_str(operation) + "'", 
 32175 |                   exprtk_error_location)); 
 32176 |  
 32177 |                return error_node(); 
 32178 |             } 
 32179 |             else if (is_invalid_string_op(operation,branch)) 
 32180 |             { 
 32181 |                parser_->set_error(parser_error::make_error( 
 32182 |                   parser_error::e_syntax, 
 32183 |                   parser_->current_state().token, 
 32184 |                   "ERR245 - Invalid branch pair for string operator '" + details::to_str(operation) + "'", 
 32185 |                   exprtk_error_location)); 
 32186 |  
 32187 |                return error_node(); 
 32188 |             } 
 32189 |             else if (is_invalid_assignment_op(operation,branch)) 
 32190 |             { 
 32191 |                parser_->set_error(parser_error::make_error( 
 32192 |                   parser_error::e_syntax, 
 32193 |                   parser_->current_state().token, 
 32194 |                   "ERR246 - Invalid branch pair for assignment operator '" + details::to_str(operation) + "'", 
 32195 |                   exprtk_error_location)); 
 32196 |  
 32197 |                return error_node(); 
 32198 |             } 
 32199 |             else if (is_invalid_break_continue_op(branch)) 
 32200 |             { 
 32201 |                parser_->set_error(parser_error::make_error( 
 32202 |                   parser_error::e_syntax, 
 32203 |                   parser_->current_state().token, 
 32204 |                   "ERR247 - Invalid branch pair for break/continue operator '" + details::to_str(operation) + "'", 
 32205 |                   exprtk_error_location)); 
 32206 |  
 32207 |                return error_node(); 
 32208 |             } 
 32209 |             else if (details::e_assign == operation) 
 32210 |             { 
 32211 |                return synthesize_assignment_expression(operation, branch); 
 32212 |             } 
 32213 |             else if (details::e_swap == operation) 
 32214 |             { 
 32215 |                return synthesize_swap_expression(branch); 
 32216 |             } 
 32217 |             else if (is_assignment_operation(operation)) 
 32218 |             { 
 32219 |                return synthesize_assignment_operation_expression(operation, branch); 
 32220 |             } 
 32221 |             else if (is_vector_eqineq_logic_operation(operation, branch)) 
 32222 |             { 
 32223 |                return synthesize_veceqineqlogic_operation_expression(operation, branch); 
 32224 |             } 
 32225 |             else if (is_vector_arithmetic_operation(operation, branch)) 
 32226 |             { 
 32227 |                return synthesize_vecarithmetic_operation_expression(operation, branch); 
 32228 |             } 
 32229 |             else if (is_shortcircuit_expression(operation)) 
 32230 |             { 
 32231 |                return synthesize_shortcircuit_expression(operation, branch); 
 32232 |             } 
 32233 |             else if (is_string_operation(operation, branch)) 
 32234 |             { 
 32235 |                return synthesize_string_expression(operation, branch); 
 32236 |             } 
 32237 |             else if (is_null_present(branch)) 
 32238 |             { 
 32239 |                return synthesize_null_expression(operation, branch); 
 32240 |             } 
 32241 |             #ifndef exprtk_disable_cardinal_pow_optimisation 
 32242 |             else if (is_constpow_operation(operation, branch)) 
 32243 |             { 
 32244 |                return cardinal_pow_optimisation(branch); 
 32245 |             } 
 32246 |             #endif 
 32247 |  
 32248 |             expression_node_ptr result = error_node(); 
 32249 |  
 32250 |             #ifndef exprtk_disable_enhanced_features 
 32251 |             if (synthesize_expression(operation, branch, result)) 
 32252 |             { 
 32253 |                return result; 
 32254 |             } 
 32255 |             else 
 32256 |             #endif 
 32257 |  
 32258 |             { 
 32259 |                /* 
 32260 |                   Possible reductions: 
 32261 |                   1. c o cob -> cob 
 32262 |                   2. cob o c -> cob 
 32263 |                   3. c o boc -> boc 
 32264 |                   4. boc o c -> boc 
 32265 |                */ 
 32266 |                result = error_node(); 
 32267 |  
 32268 |                if (cocob_optimisable(operation, branch)) 
 32269 |                { 
 32270 |                   result = synthesize_cocob_expression::process((*this), operation, branch); 
 32271 |                } 
 32272 |                else if (coboc_optimisable(operation, branch) && (0 == result)) 
 32273 |                { 
 32274 |                   result = synthesize_coboc_expression::process((*this), operation, branch); 
 32275 |                } 
 32276 |  
 32277 |                if (result) 
 32278 |                   return result; 
 32279 |             } 
 32280 |  
 32281 |             if (uvouv_optimisable(operation, branch)) 
 32282 |             { 
 32283 |                return synthesize_uvouv_expression(operation, branch); 
 32284 |             } 
 32285 |             else if (vob_optimisable(operation, branch)) 
 32286 |             { 
 32287 |                return synthesize_vob_expression::process((*this), operation, branch); 
 32288 |             } 
 32289 |             else if (bov_optimisable(operation, branch)) 
 32290 |             { 
 32291 |                return synthesize_bov_expression::process((*this), operation, branch); 
 32292 |             } 
 32293 |             else if (cob_optimisable(operation, branch)) 
 32294 |             { 
 32295 |                return synthesize_cob_expression::process((*this), operation, branch); 
 32296 |             } 
 32297 |             else if (boc_optimisable(operation, branch)) 
 32298 |             { 
 32299 |                return synthesize_boc_expression::process((*this), operation, branch); 
 32300 |             } 
 32301 |             #ifndef exprtk_disable_enhanced_features 
 32302 |             else if (cov_optimisable(operation, branch)) 
 32303 |             { 
 32304 |                return synthesize_cov_expression::process((*this), operation, branch); 
 32305 |             } 
 32306 |             #endif 
 32307 |             else if (binext_optimisable(operation, branch)) 
 32308 |             { 
 32309 |                return synthesize_binary_ext_expression::process((*this), operation, branch); 
 32310 |             } 
 32311 |             else 
 32312 |                return synthesize_expression<binary_node_t,2>(operation, branch); 
 32313 |          } 
 32314 |  
 32315 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[3]) 
 32316 |          { 
 32317 |             if ( 
 32318 |                  (0 == branch[0]) || 
 32319 |                  (0 == branch[1]) || 
 32320 |                  (0 == branch[2]) 
 32321 |                ) 
 32322 |             { 
 32323 |                details::free_all_nodes(*node_allocator_,branch); 
 32324 |  
 32325 |                parser_->set_error(parser_error::make_error( 
 32326 |                   parser_error::e_syntax, 
 32327 |                   parser_->current_state().token, 
 32328 |                   "ERR248 - Invalid branches operator '" + details::to_str(operation) + "'", 
 32329 |                   exprtk_error_location)); 
 32330 |  
 32331 |                return error_node(); 
 32332 |             } 
 32333 |             else if (is_invalid_string_op(operation, branch)) 
 32334 |             { 
 32335 |                parser_->set_error(parser_error::make_error( 
 32336 |                   parser_error::e_syntax, 
 32337 |                   parser_->current_state().token, 
 32338 |                   "ERR249 - Invalid branches for string operator '" + details::to_str(operation) + "'", 
 32339 |                   exprtk_error_location)); 
 32340 |  
 32341 |                return error_node(); 
 32342 |             } 
 32343 |             else if (is_string_operation(operation, branch)) 
 32344 |             { 
 32345 |                return synthesize_string_expression(operation, branch); 
 32346 |             } 
 32347 |             else 
 32348 |                return synthesize_expression<trinary_node_t,3>(operation, branch); 
 32349 |          } 
 32350 |  
 32351 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 32352 |          { 
 32353 |             return synthesize_expression<quaternary_node_t,4>(operation,branch); 
 32354 |          } 
 32355 |  
 32356 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr b0) 
 32357 |          { 
 32358 |             expression_node_ptr branch[1] = { b0 }; 
 32359 |             return (*this)(operation,branch); 
 32360 |          } 
 32361 |  
 32362 |          inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr& b0, expression_node_ptr& b1) 
 32363 |          { 
 32364 |             expression_node_ptr result = error_node(); 
 32365 |  
 32366 |             if ((0 != b0) && (0 != b1)) 
 32367 |             { 
 32368 |                expression_node_ptr branch[2] = { b0, b1 }; 
 32369 |                result = expression_generator<Type>::operator()(operation, branch); 
 32370 |                b0 = branch[0]; 
 32371 |                b1 = branch[1]; 
 32372 |             } 
 32373 |  
 32374 |             return result; 
 32375 |          } 
 32376 |  
 32377 |          inline expression_node_ptr conditional(expression_node_ptr condition, 
 32378 |                                                 expression_node_ptr consequent, 
 32379 |                                                 expression_node_ptr alternative) const 
 32380 |          { 
 32381 |             if ((0 == condition) || (0 == consequent)) 
 32382 |             { 
 32383 |                details::free_node(*node_allocator_, condition  ); 
 32384 |                details::free_node(*node_allocator_, consequent ); 
 32385 |                details::free_node(*node_allocator_, alternative); 
 32386 |  
 32387 |                const std::string invalid_branches = 
 32388 |                                  ((0 == condition ) ? std::string("condition ") : "") + 
 32389 |                                  ((0 == consequent) ? std::string("consequent") : "") ; 
 32390 |  
 32391 |                parser_->set_error(parser_error::make_error( 
 32392 |                   parser_error::e_parser, 
 32393 |                   parser_->current_state().token, 
 32394 |                   "ERR250 - Invalid " + invalid_branches + " for conditional statement", 
 32395 |                   exprtk_error_location)); 
 32396 |  
 32397 |                return error_node(); 
 32398 |             } 
 32399 |             // Can the condition be immediately evaluated? if so optimise. 
 32400 |             else if (details::is_constant_node(condition)) 
 32401 |             { 
 32402 |                // True branch 
 32403 |                if (details::is_true(condition)) 
 32404 |                { 
 32405 |                   details::free_node(*node_allocator_, condition  ); 
 32406 |                   details::free_node(*node_allocator_, alternative); 
 32407 |  
 32408 |                   return consequent; 
 32409 |                } 
 32410 |                // False branch 
 32411 |                else 
 32412 |                { 
 32413 |                   details::free_node(*node_allocator_, condition ); 
 32414 |                   details::free_node(*node_allocator_, consequent); 
 32415 |  
 32416 |                   if (alternative) 
 32417 |                      return alternative; 
 32418 |                   else 
 32419 |                      return node_allocator_->allocate<details::null_node<T> >(); 
 32420 |                } 
 32421 |             } 
 32422 |  
 32423 |             expression_node_ptr result = error_node(); 
 32424 |             std::string node_name      = "Unknown!" 
 32425 |  
 32426 |             if ((0 != consequent) && (0 != alternative)) 
 32427 |             { 
 32428 |                result = node_allocator_->allocate<conditional_node_t>(condition, consequent, alternative); 
 32429 |                node_name = "conditional_node_t" 
 32430 |             } 
 32431 |             else 
 32432 |             { 
 32433 |                result = node_allocator_->allocate<cons_conditional_node_t>(condition, consequent); 
 32434 |                node_name = "cons_conditional_node_t" 
 32435 |             } 
 32436 |  
 32437 |             if (result && result->valid()) 
 32438 |             { 
 32439 |                return result; 
 32440 |             } 
 32441 |  
 32442 |             parser_->set_error(parser_error::make_error( 
 32443 |                parser_error::e_parser, 
 32444 |                token_t(), 
 32445 |                "ERR251 - Failed to synthesize node: " + node_name, 
 32446 |                exprtk_error_location)); 
 32447 |  
 32448 |             details::free_node(*node_allocator_, result); 
 32449 |             return error_node(); 
 32450 |          } 
 32451 |  
 32452 |          #ifndef exprtk_disable_string_capabilities 
 32453 |          inline expression_node_ptr conditional_string(expression_node_ptr condition, 
 32454 |                                                        expression_node_ptr consequent, 
 32455 |                                                        expression_node_ptr alternative) const 
 32456 |          { 
 32457 |             if ((0 == condition) || (0 == consequent)) 
 32458 |             { 
 32459 |                details::free_node(*node_allocator_, condition  ); 
 32460 |                details::free_node(*node_allocator_, consequent ); 
 32461 |                details::free_node(*node_allocator_, alternative); 
 32462 |  
 32463 |                const std::string invalid_branches = 
 32464 |                                  ((0 == condition ) ? std::string("condition ") : "") + 
 32465 |                                  ((0 == consequent) ? std::string("consequent") : "") ; 
 32466 |  
 32467 |                parser_->set_error(parser_error::make_error( 
 32468 |                   parser_error::e_parser, 
 32469 |                   parser_->current_state().token, 
 32470 |                   "ERR252 - Invalid " + invalid_branches + " for string conditional statement", 
 32471 |                   exprtk_error_location)); 
 32472 |  
 32473 |                return error_node(); 
 32474 |             } 
 32475 |             // Can the condition be immediately evaluated? if so optimise. 
 32476 |             else if (details::is_constant_node(condition)) 
 32477 |             { 
 32478 |                // True branch 
 32479 |                if (details::is_true(condition)) 
 32480 |                { 
 32481 |                   details::free_node(*node_allocator_, condition  ); 
 32482 |                   details::free_node(*node_allocator_, alternative); 
 32483 |  
 32484 |                   return consequent; 
 32485 |                } 
 32486 |                // False branch 
 32487 |                else 
 32488 |                { 
 32489 |                   details::free_node(*node_allocator_, condition ); 
 32490 |                   details::free_node(*node_allocator_, consequent); 
 32491 |  
 32492 |                   if (alternative) 
 32493 |                      return alternative; 
 32494 |                   else 
 32495 |                      return node_allocator_-> 
 32496 |                               allocate_c<details::string_literal_node<Type> >(""); 
 32497 |                } 
 32498 |             } 
 32499 |             else if ((0 != consequent) && (0 != alternative)) 
 32500 |             { 
 32501 |                expression_node_ptr result = 
 32502 |                   node_allocator_->allocate<conditional_string_node_t>(condition, consequent, alternative); 
 32503 |  
 32504 |                if (result && result->valid()) 
 32505 |                { 
 32506 |                   return result; 
 32507 |                } 
 32508 |  
 32509 |                parser_->set_error(parser_error::make_error( 
 32510 |                   parser_error::e_parser, 
 32511 |                   token_t(), 
 32512 |                   "ERR253 - Failed to synthesize node: conditional_string_node_t", 
 32513 |                   exprtk_error_location)); 
 32514 |  
 32515 |                details::free_node(*node_allocator_, result); 
 32516 |             } 
 32517 |  
 32518 |             return error_node(); 
 32519 |          } 
 32520 |          #else 
 32521 |          inline expression_node_ptr conditional_string(expression_node_ptr, 
 32522 |                                                        expression_node_ptr, 
 32523 |                                                        expression_node_ptr) const 
 32524 |          { 
 32525 |             return error_node(); 
 32526 |          } 
 32527 |          #endif 
 32528 |  
 32529 |          inline expression_node_ptr conditional_vector(expression_node_ptr condition, 
 32530 |                                                        expression_node_ptr consequent, 
 32531 |                                                        expression_node_ptr alternative) const 
 32532 |          { 
 32533 |             if ((0 == condition) || (0 == consequent)) 
 32534 |             { 
 32535 |                details::free_node(*node_allocator_, condition  ); 
 32536 |                details::free_node(*node_allocator_, consequent ); 
 32537 |                details::free_node(*node_allocator_, alternative); 
 32538 |  
 32539 |                const std::string invalid_branches = 
 32540 |                                  ((0 == condition ) ? std::string("condition ") : "") + 
 32541 |                                  ((0 == consequent) ? std::string("consequent") : "") ; 
 32542 |  
 32543 |                parser_->set_error(parser_error::make_error( 
 32544 |                   parser_error::e_parser, 
 32545 |                   parser_->current_state().token, 
 32546 |                   "ERR254 - Invalid " + invalid_branches + " for vector conditional statement", 
 32547 |                   exprtk_error_location)); 
 32548 |  
 32549 |                return error_node(); 
 32550 |             } 
 32551 |             // Can the condition be immediately evaluated? if so optimise. 
 32552 |             else if (details::is_constant_node(condition)) 
 32553 |             { 
 32554 |                // True branch 
 32555 |                if (details::is_true(condition)) 
 32556 |                { 
 32557 |                   details::free_node(*node_allocator_, condition  ); 
 32558 |                   details::free_node(*node_allocator_, alternative); 
 32559 |  
 32560 |                   return consequent; 
 32561 |                } 
 32562 |                // False branch 
 32563 |                else 
 32564 |                { 
 32565 |                   details::free_node(*node_allocator_, condition ); 
 32566 |                   details::free_node(*node_allocator_, consequent); 
 32567 |  
 32568 |                   if (alternative) 
 32569 |                      return alternative; 
 32570 |                   else 
 32571 |                      return node_allocator_->allocate<details::null_node<T> >(); 
 32572 |  
 32573 |                } 
 32574 |             } 
 32575 |             else if ((0 != consequent) && (0 != alternative)) 
 32576 |             { 
 32577 |                return node_allocator_-> 
 32578 |                         allocate<conditional_vector_node_t>(condition, consequent, alternative); 
 32579 |             } 
 32580 |             else 
 32581 |                return error_node(); 
 32582 |          } 
 32583 |  
 32584 |          inline loop_runtime_check_ptr get_loop_runtime_check(const loop_runtime_check::loop_types loop_type) const 
 32585 |          { 
 32586 |             if ( 
 32587 |                  parser_->loop_runtime_check_ && 
 32588 |                  (loop_type == (parser_->loop_runtime_check_->loop_set & loop_type)) 
 32589 |                ) 
 32590 |             { 
 32591 |                return parser_->loop_runtime_check_; 
 32592 |             } 
 32593 |  
 32594 |             return loop_runtime_check_ptr(0); 
 32595 |          } 
 32596 |  
 32597 |          inline vector_access_runtime_check_ptr get_vector_access_runtime_check() const 
 32598 |          { 
 32599 |             return parser_->vector_access_runtime_check_; 
 32600 |          } 
 32601 |  
 32602 |          inline expression_node_ptr while_loop(expression_node_ptr& condition, 
 32603 |                                                expression_node_ptr& branch, 
 32604 |                                                const bool break_continue_present = false) const 
 32605 |          { 
 32606 |             if ( 
 32607 |                  !break_continue_present              && 
 32608 |                  !parser_->state_.return_stmt_present && 
 32609 |                  details::is_constant_node(condition) 
 32610 |                ) 
 32611 |             { 
 32612 |                expression_node_ptr result = error_node(); 
 32613 |                if (details::is_true(condition)) 
 32614 |                { 
 32615 |                   // Infinite loops are not allowed. 
 32616 |  
 32617 |                   parser_->set_error(parser_error::make_error( 
 32618 |                      parser_error::e_parser, 
 32619 |                      parser_->current_state().token, 
 32620 |                      "ERR255 - Infinite loop condition without 'break' or 'return' not allowed in while-loops", 
 32621 |                      exprtk_error_location)); 
 32622 |  
 32623 |                   result = error_node(); 
 32624 |                } 
 32625 |                else 
 32626 |                   result = node_allocator_->allocate<details::null_node<Type> >(); 
 32627 |  
 32628 |                details::free_node(*node_allocator_, condition); 
 32629 |                details::free_node(*node_allocator_, branch   ); 
 32630 |  
 32631 |                return result; 
 32632 |             } 
 32633 |             else if (details::is_null_node(condition)) 
 32634 |             { 
 32635 |                details::free_node(*node_allocator_,condition); 
 32636 |  
 32637 |                return branch; 
 32638 |             } 
 32639 |  
 32640 |             loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_while_loop); 
 32641 |  
 32642 |             if (!break_continue_present) 
 32643 |             { 
 32644 |                if (rtc) 
 32645 |                   return node_allocator_->allocate<while_loop_rtc_node_t> 
 32646 |                            (condition, branch,  rtc); 
 32647 |                else 
 32648 |                   return node_allocator_->allocate<while_loop_node_t> 
 32649 |                            (condition, branch); 
 32650 |             } 
 32651 |             #ifndef exprtk_disable_break_continue 
 32652 |             else 
 32653 |             { 
 32654 |                if (rtc) 
 32655 |                   return node_allocator_->allocate<while_loop_bc_rtc_node_t> 
 32656 |                            (condition, branch, rtc); 
 32657 |                else 
 32658 |                   return node_allocator_->allocate<while_loop_bc_node_t> 
 32659 |                            (condition, branch); 
 32660 |             } 
 32661 |             #else 
 32662 |                return error_node(); 
 32663 |             #endif 
 32664 |          } 
 32665 |  
 32666 |          inline expression_node_ptr repeat_until_loop(expression_node_ptr& condition, 
 32667 |                                                       expression_node_ptr& branch, 
 32668 |                                                       const bool break_continue_present = false) const 
 32669 |          { 
 32670 |             if (!break_continue_present && details::is_constant_node(condition)) 
 32671 |             { 
 32672 |                if ( 
 32673 |                     details::is_true(condition) && 
 32674 |                     details::is_constant_node(branch) 
 32675 |                   ) 
 32676 |                { 
 32677 |                   free_node(*node_allocator_,condition); 
 32678 |  
 32679 |                   return branch; 
 32680 |                } 
 32681 |  
 32682 |                details::free_node(*node_allocator_, condition); 
 32683 |                details::free_node(*node_allocator_, branch   ); 
 32684 |  
 32685 |                return error_node(); 
 32686 |             } 
 32687 |             else if (details::is_null_node(condition)) 
 32688 |             { 
 32689 |                details::free_node(*node_allocator_,condition); 
 32690 |  
 32691 |                return branch; 
 32692 |             } 
 32693 |  
 32694 |             loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_repeat_until_loop); 
 32695 |  
 32696 |             if (!break_continue_present) 
 32697 |             { 
 32698 |                if (rtc) 
 32699 |                   return node_allocator_->allocate<repeat_until_loop_rtc_node_t> 
 32700 |                            (condition, branch,  rtc); 
 32701 |                else 
 32702 |                   return node_allocator_->allocate<repeat_until_loop_node_t> 
 32703 |                            (condition, branch); 
 32704 |             } 
 32705 |             #ifndef exprtk_disable_break_continue 
 32706 |             else 
 32707 |             { 
 32708 |                if (rtc) 
 32709 |                   return node_allocator_->allocate<repeat_until_loop_bc_rtc_node_t> 
 32710 |                            (condition, branch, rtc); 
 32711 |                else 
 32712 |                   return node_allocator_->allocate<repeat_until_loop_bc_node_t> 
 32713 |                            (condition, branch); 
 32714 |             } 
 32715 |             #else 
 32716 |                return error_node(); 
 32717 |             #endif 
 32718 |          } 
 32719 |  
 32720 |          inline expression_node_ptr for_loop(expression_node_ptr& initialiser, 
 32721 |                                              expression_node_ptr& condition, 
 32722 |                                              expression_node_ptr& incrementor, 
 32723 |                                              expression_node_ptr& loop_body, 
 32724 |                                              bool break_continue_present = false) const 
 32725 |          { 
 32726 |             if ( 
 32727 |                  !break_continue_present              && 
 32728 |                  !parser_->state_.return_stmt_present && 
 32729 |                  details::is_constant_node(condition) 
 32730 |                ) 
 32731 |             { 
 32732 |                expression_node_ptr result = error_node(); 
 32733 |  
 32734 |                if (details::is_true(condition)) 
 32735 |                { 
 32736 |                   // Infinite loops are not allowed. 
 32737 |  
 32738 |                   parser_->set_error(parser_error::make_error( 
 32739 |                      parser_error::e_parser, 
 32740 |                      parser_->current_state().token, 
 32741 |                      "ERR256 - Infinite loop condition without 'break' or 'return' not allowed in for-loop", 
 32742 |                      exprtk_error_location)); 
 32743 |  
 32744 |                   result = error_node(); 
 32745 |                } 
 32746 |                else 
 32747 |                   result = node_allocator_->allocate<details::null_node<Type> >(); 
 32748 |  
 32749 |                details::free_node(*node_allocator_, initialiser); 
 32750 |                details::free_node(*node_allocator_, condition  ); 
 32751 |                details::free_node(*node_allocator_, incrementor); 
 32752 |                details::free_node(*node_allocator_, loop_body  ); 
 32753 |  
 32754 |                return result; 
 32755 |             } 
 32756 |             else if (details::is_null_node(condition) || (0 == condition)) 
 32757 |             { 
 32758 |                details::free_node(*node_allocator_, initialiser); 
 32759 |                details::free_node(*node_allocator_, condition  ); 
 32760 |                details::free_node(*node_allocator_, incrementor); 
 32761 |  
 32762 |                return loop_body; 
 32763 |             } 
 32764 |  
 32765 |             loop_runtime_check_ptr rtc = get_loop_runtime_check(loop_runtime_check::e_for_loop); 
 32766 |  
 32767 |             if (!break_continue_present) 
 32768 |             { 
 32769 |                if (rtc) 
 32770 |                   return node_allocator_->allocate<for_loop_rtc_node_t> 
 32771 |                                           ( 
 32772 |                                              initialiser, 
 32773 |                                              condition, 
 32774 |                                              incrementor, 
 32775 |                                              loop_body, 
 32776 |                                              rtc 
 32777 |                                           ); 
 32778 |                else 
 32779 |                   return node_allocator_->allocate<for_loop_node_t> 
 32780 |                                           ( 
 32781 |                                              initialiser, 
 32782 |                                              condition, 
 32783 |                                              incrementor, 
 32784 |                                              loop_body 
 32785 |                                           ); 
 32786 |             } 
 32787 |             #ifndef exprtk_disable_break_continue 
 32788 |             else 
 32789 |             { 
 32790 |                if (rtc) 
 32791 |                   return node_allocator_->allocate<for_loop_bc_rtc_node_t> 
 32792 |                                           ( 
 32793 |                                              initialiser, 
 32794 |                                              condition, 
 32795 |                                              incrementor, 
 32796 |                                              loop_body, 
 32797 |                                              rtc 
 32798 |                                           ); 
 32799 |                else 
 32800 |                   return node_allocator_->allocate<for_loop_bc_node_t> 
 32801 |                                           ( 
 32802 |                                              initialiser, 
 32803 |                                              condition, 
 32804 |                                              incrementor, 
 32805 |                                              loop_body 
 32806 |                                           ); 
 32807 |             } 
 32808 |             #else 
 32809 |                return error_node(); 
 32810 |             #endif 
 32811 |          } 
 32812 |  
 32813 |          template <typename Allocator, 
 32814 |                    template <typename, typename> class Sequence> 
 32815 |          inline expression_node_ptr const_optimise_switch(Sequence<expression_node_ptr,Allocator>& arg_list) 
 32816 |          { 
 32817 |             expression_node_ptr result = error_node(); 
 32818 |  
 32819 |             for (std::size_t i = 0; i < (arg_list.size() / 2); ++i) 
 32820 |             { 
 32821 |                expression_node_ptr condition  = arg_list[(2 * i)    ]; 
 32822 |                expression_node_ptr consequent = arg_list[(2 * i) + 1]; 
 32823 |  
 32824 |                if ((0 == result) && details::is_true(condition)) 
 32825 |                { 
 32826 |                   result = consequent; 
 32827 |                   break; 
 32828 |                } 
 32829 |             } 
 32830 |  
 32831 |             if (0 == result) 
 32832 |             { 
 32833 |                result = arg_list.back(); 
 32834 |             } 
 32835 |  
 32836 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 32837 |             { 
 32838 |                expression_node_ptr current_expr = arg_list[i]; 
 32839 |  
 32840 |                if (current_expr && (current_expr != result)) 
 32841 |                { 
 32842 |                   free_node(*node_allocator_,current_expr); 
 32843 |                } 
 32844 |             } 
 32845 |  
 32846 |             return result; 
 32847 |          } 
 32848 |  
 32849 |          template <typename Allocator, 
 32850 |                    template <typename, typename> class Sequence> 
 32851 |          inline expression_node_ptr const_optimise_mswitch(Sequence<expression_node_ptr,Allocator>& arg_list) 
 32852 |          { 
 32853 |             expression_node_ptr result = error_node(); 
 32854 |  
 32855 |             for (std::size_t i = 0; i < (arg_list.size() / 2); ++i) 
 32856 |             { 
 32857 |                expression_node_ptr condition  = arg_list[(2 * i)    ]; 
 32858 |                expression_node_ptr consequent = arg_list[(2 * i) + 1]; 
 32859 |  
 32860 |                if (details::is_true(condition)) 
 32861 |                { 
 32862 |                   result = consequent; 
 32863 |                } 
 32864 |             } 
 32865 |  
 32866 |             if (0 == result) 
 32867 |             { 
 32868 |                const T zero = T(0); 
 32869 |                result       = node_allocator_->allocate<literal_node_t>(zero); 
 32870 |             } 
 32871 |  
 32872 |             for (std::size_t i = 0; i < arg_list.size(); ++i) 
 32873 |             { 
 32874 |                expression_node_ptr& current_expr = arg_list[i]; 
 32875 |  
 32876 |                if (current_expr && (current_expr != result)) 
 32877 |                { 
 32878 |                   details::free_node(*node_allocator_,current_expr); 
 32879 |                } 
 32880 |             } 
 32881 |  
 32882 |             return result; 
 32883 |          } 
 32884 |  
 32885 |          struct switch_nodes 
 32886 |          { 
 32887 |             typedef std::vector<std::pair<expression_node_ptr,bool> > arg_list_t; 
 32888 |  
 32889 |             #define case_stmt(N)                                                         \ 
 32890 |             if (is_true(arg[(2 * N)].first)) { return arg[(2 * N) + 1].first->value(); } \ 
 32891 |  
 32892 |             struct switch_impl_1 
 32893 |             { 
 32894 |                static inline T process(const arg_list_t& arg) 
 32895 |                { 
 32896 |                   case_stmt(0) 
 32897 |  
 32898 |                   assert(arg.size() == ((2 * 1) + 1)); 
 32899 |  
 32900 |                   return arg.back().first->value(); 
 32901 |                } 
 32902 |             }; 
 32903 |  
 32904 |             struct switch_impl_2 
 32905 |             { 
 32906 |                static inline T process(const arg_list_t& arg) 
 32907 |                { 
 32908 |                   case_stmt(0) case_stmt(1) 
 32909 |  
 32910 |                   assert(arg.size() == ((2 * 2) + 1)); 
 32911 |  
 32912 |                   return arg.back().first->value(); 
 32913 |                } 
 32914 |             }; 
 32915 |  
 32916 |             struct switch_impl_3 
 32917 |             { 
 32918 |                static inline T process(const arg_list_t& arg) 
 32919 |                { 
 32920 |                   case_stmt(0) case_stmt(1) 
 32921 |                   case_stmt(2) 
 32922 |  
 32923 |                   assert(arg.size() == ((2 * 3) + 1)); 
 32924 |  
 32925 |                   return arg.back().first->value(); 
 32926 |                } 
 32927 |             }; 
 32928 |  
 32929 |             struct switch_impl_4 
 32930 |             { 
 32931 |                static inline T process(const arg_list_t& arg) 
 32932 |                { 
 32933 |                   case_stmt(0) case_stmt(1) 
 32934 |                   case_stmt(2) case_stmt(3) 
 32935 |  
 32936 |                   assert(arg.size() == ((2 * 4) + 1)); 
 32937 |  
 32938 |                   return arg.back().first->value(); 
 32939 |                } 
 32940 |             }; 
 32941 |  
 32942 |             struct switch_impl_5 
 32943 |             { 
 32944 |                static inline T process(const arg_list_t& arg) 
 32945 |                { 
 32946 |                   case_stmt(0) case_stmt(1) 
 32947 |                   case_stmt(2) case_stmt(3) 
 32948 |                   case_stmt(4) 
 32949 |  
 32950 |                   assert(arg.size() == ((2 * 5) + 1)); 
 32951 |  
 32952 |                   return arg.back().first->value(); 
 32953 |                } 
 32954 |             }; 
 32955 |  
 32956 |             struct switch_impl_6 
 32957 |             { 
 32958 |                static inline T process(const arg_list_t& arg) 
 32959 |                { 
 32960 |                   case_stmt(0) case_stmt(1) 
 32961 |                   case_stmt(2) case_stmt(3) 
 32962 |                   case_stmt(4) case_stmt(5) 
 32963 |  
 32964 |                   assert(arg.size() == ((2 * 6) + 1)); 
 32965 |  
 32966 |                   return arg.back().first->value(); 
 32967 |                } 
 32968 |             }; 
 32969 |  
 32970 |             struct switch_impl_7 
 32971 |             { 
 32972 |                static inline T process(const arg_list_t& arg) 
 32973 |                { 
 32974 |                   case_stmt(0) case_stmt(1) 
 32975 |                   case_stmt(2) case_stmt(3) 
 32976 |                   case_stmt(4) case_stmt(5) 
 32977 |                   case_stmt(6) 
 32978 |  
 32979 |                   assert(arg.size() == ((2 * 7) + 1)); 
 32980 |  
 32981 |                   return arg.back().first->value(); 
 32982 |                } 
 32983 |             }; 
 32984 |  
 32985 |             #undef case_stmt 
 32986 |          }; 
 32987 |  
 32988 |          template <typename Allocator, 
 32989 |                    template <typename, typename> class Sequence> 
 32990 |          inline expression_node_ptr switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list, const bool default_statement_present) 
 32991 |          { 
 32992 |             if (arg_list.empty()) 
 32993 |                return error_node(); 
 32994 |             else if ( 
 32995 |                       !all_nodes_valid(arg_list) || 
 32996 |                       (!default_statement_present && (arg_list.size() < 2)) 
 32997 |                     ) 
 32998 |             { 
 32999 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33000 |  
 33001 |                return error_node(); 
 33002 |             } 
 33003 |             else if (is_constant_foldable(arg_list)) 
 33004 |                return const_optimise_switch(arg_list); 
 33005 |  
 33006 |             switch ((arg_list.size() - 1) / 2) 
 33007 |             { 
 33008 |                #define case_stmt(N)                                                       \ 
 33009 |                case N :                                                                   \ 
 33010 |                   return node_allocator_->                                                \ 
 33011 |                             allocate<details::switch_n_node                               \ 
 33012 |                               <Type,typename switch_nodes::switch_impl_##N > >(arg_list); \ 
 33013 |  
 33014 |                case_stmt(1) 
 33015 |                case_stmt(2) 
 33016 |                case_stmt(3) 
 33017 |                case_stmt(4) 
 33018 |                case_stmt(5) 
 33019 |                case_stmt(6) 
 33020 |                case_stmt(7) 
 33021 |                #undef case_stmt 
 33022 |  
 33023 |                default : return node_allocator_->allocate<details::switch_node<Type> >(arg_list); 
 33024 |             } 
 33025 |          } 
 33026 |  
 33027 |          template <typename Allocator, 
 33028 |                    template <typename, typename> class Sequence> 
 33029 |          inline expression_node_ptr multi_switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list) 
 33030 |          { 
 33031 |             if (!all_nodes_valid(arg_list)) 
 33032 |             { 
 33033 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33034 |  
 33035 |                return error_node(); 
 33036 |             } 
 33037 |             else if (is_constant_foldable(arg_list)) 
 33038 |                return const_optimise_mswitch(arg_list); 
 33039 |             else 
 33040 |                return node_allocator_->allocate<details::multi_switch_node<Type> >(arg_list); 
 33041 |          } 
 33042 |  
 33043 |          inline expression_node_ptr assert_call(expression_node_ptr& assert_condition, 
 33044 |                                                 expression_node_ptr& assert_message, 
 33045 |                                                 const assert_check::assert_context& context) 
 33046 |          { 
 33047 |             typedef details::assert_node<Type> alloc_type; 
 33048 |  
 33049 |             expression_node_ptr result = node_allocator_->allocate_rrrr<alloc_type> 
 33050 |                (assert_condition, assert_message, parser_->assert_check_, context); 
 33051 |  
 33052 |             if (result && result->valid()) 
 33053 |             { 
 33054 |                parser_->state_.activate_side_effect("assert_call()"); 
 33055 |                return result; 
 33056 |             } 
 33057 |  
 33058 |             details::free_node(*node_allocator_, result          ); 
 33059 |             details::free_node(*node_allocator_, assert_condition); 
 33060 |             details::free_node(*node_allocator_, assert_message  ); 
 33061 |  
 33062 |             return error_node(); 
 33063 |          } 
 33064 |  
 33065 |          #define unary_opr_switch_statements             \ 
 33066 |          case_stmt(details::e_abs   , details::abs_op  ) \ 
 33067 |          case_stmt(details::e_acos  , details::acos_op ) \ 
 33068 |          case_stmt(details::e_acosh , details::acosh_op) \ 
 33069 |          case_stmt(details::e_asin  , details::asin_op ) \ 
 33070 |          case_stmt(details::e_asinh , details::asinh_op) \ 
 33071 |          case_stmt(details::e_atan  , details::atan_op ) \ 
 33072 |          case_stmt(details::e_atanh , details::atanh_op) \ 
 33073 |          case_stmt(details::e_ceil  , details::ceil_op ) \ 
 33074 |          case_stmt(details::e_cos   , details::cos_op  ) \ 
 33075 |          case_stmt(details::e_cosh  , details::cosh_op ) \ 
 33076 |          case_stmt(details::e_exp   , details::exp_op  ) \ 
 33077 |          case_stmt(details::e_expm1 , details::expm1_op) \ 
 33078 |          case_stmt(details::e_floor , details::floor_op) \ 
 33079 |          case_stmt(details::e_log   , details::log_op  ) \ 
 33080 |          case_stmt(details::e_log10 , details::log10_op) \ 
 33081 |          case_stmt(details::e_log2  , details::log2_op ) \ 
 33082 |          case_stmt(details::e_log1p , details::log1p_op) \ 
 33083 |          case_stmt(details::e_neg   , details::neg_op  ) \ 
 33084 |          case_stmt(details::e_pos   , details::pos_op  ) \ 
 33085 |          case_stmt(details::e_round , details::round_op) \ 
 33086 |          case_stmt(details::e_sin   , details::sin_op  ) \ 
 33087 |          case_stmt(details::e_sinc  , details::sinc_op ) \ 
 33088 |          case_stmt(details::e_sinh  , details::sinh_op ) \ 
 33089 |          case_stmt(details::e_sqrt  , details::sqrt_op ) \ 
 33090 |          case_stmt(details::e_tan   , details::tan_op  ) \ 
 33091 |          case_stmt(details::e_tanh  , details::tanh_op ) \ 
 33092 |          case_stmt(details::e_cot   , details::cot_op  ) \ 
 33093 |          case_stmt(details::e_sec   , details::sec_op  ) \ 
 33094 |          case_stmt(details::e_csc   , details::csc_op  ) \ 
 33095 |          case_stmt(details::e_r2d   , details::r2d_op  ) \ 
 33096 |          case_stmt(details::e_d2r   , details::d2r_op  ) \ 
 33097 |          case_stmt(details::e_d2g   , details::d2g_op  ) \ 
 33098 |          case_stmt(details::e_g2d   , details::g2d_op  ) \ 
 33099 |          case_stmt(details::e_notl  , details::notl_op ) \ 
 33100 |          case_stmt(details::e_sgn   , details::sgn_op  ) \ 
 33101 |          case_stmt(details::e_erf   , details::erf_op  ) \ 
 33102 |          case_stmt(details::e_erfc  , details::erfc_op ) \ 
 33103 |          case_stmt(details::e_ncdf  , details::ncdf_op ) \ 
 33104 |          case_stmt(details::e_frac  , details::frac_op ) \ 
 33105 |          case_stmt(details::e_trunc , details::trunc_op) \ 
 33106 |  
 33107 |          inline expression_node_ptr synthesize_uv_expression(const details::operator_type& operation, 
 33108 |                                                              expression_node_ptr (&branch)[1]) 
 33109 |          { 
 33110 |             T& v = static_cast<details::variable_node<T>*>(branch[0])->ref(); 
 33111 |  
 33112 |             switch (operation) 
 33113 |             { 
 33114 |                #define case_stmt(op0, op1)                                                         \ 
 33115 |                case op0 : return node_allocator_->                                                 \ 
 33116 |                              allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \ 
 33117 |  
 33118 |                unary_opr_switch_statements 
 33119 |                #undef case_stmt 
 33120 |                default : return error_node(); 
 33121 |             } 
 33122 |          } 
 33123 |  
 33124 |          inline expression_node_ptr synthesize_uvec_expression(const details::operator_type& operation, 
 33125 |                                                                expression_node_ptr (&branch)[1]) 
 33126 |          { 
 33127 |             switch (operation) 
 33128 |             { 
 33129 |                #define case_stmt(op0, op1)                                                   \ 
 33130 |                case op0 : return node_allocator_->                                           \ 
 33131 |                              allocate<typename details::unary_vector_node<Type,op1<Type> > > \ 
 33132 |                                 (operation, branch[0]);                                      \ 
 33133 |  
 33134 |                unary_opr_switch_statements 
 33135 |                #undef case_stmt 
 33136 |                default : return error_node(); 
 33137 |             } 
 33138 |          } 
 33139 |  
 33140 |          inline expression_node_ptr synthesize_unary_expression(const details::operator_type& operation, 
 33141 |                                                                 expression_node_ptr (&branch)[1]) 
 33142 |          { 
 33143 |             switch (operation) 
 33144 |             { 
 33145 |                #define case_stmt(op0, op1)                                                               \ 
 33146 |                case op0 : return node_allocator_->                                                       \ 
 33147 |                              allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \ 
 33148 |  
 33149 |                unary_opr_switch_statements 
 33150 |                #undef case_stmt 
 33151 |                default : return error_node(); 
 33152 |             } 
 33153 |          } 
 33154 |  
 33155 |          inline expression_node_ptr const_optimise_sf3(const details::operator_type& operation, 
 33156 |                                                        expression_node_ptr (&branch)[3]) 
 33157 |          { 
 33158 |             expression_node_ptr temp_node = error_node(); 
 33159 |  
 33160 |             switch (operation) 
 33161 |             { 
 33162 |                #define case_stmt(op)                                                        \ 
 33163 |                case details::e_sf##op : temp_node = node_allocator_->                       \ 
 33164 |                              allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \ 
 33165 |                                 (operation, branch);                                        \ 
 33166 |                              break;                                                         \ 
 33167 |  
 33168 |                case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 33169 |                case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 33170 |                case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 33171 |                case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 33172 |                case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 33173 |                case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 33174 |                case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 33175 |                case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31) 
 33176 |                case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35) 
 33177 |                case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39) 
 33178 |                case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43) 
 33179 |                case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47) 
 33180 |                #undef case_stmt 
 33181 |                default : return error_node(); 
 33182 |             } 
 33183 |  
 33184 |             assert(temp_node); 
 33185 |  
 33186 |             const T v = temp_node->value(); 
 33187 |  
 33188 |             details::free_node(*node_allocator_,temp_node); 
 33189 |  
 33190 |             return node_allocator_->allocate<literal_node_t>(v); 
 33191 |          } 
 33192 |  
 33193 |          inline expression_node_ptr varnode_optimise_sf3(const details::operator_type& operation, expression_node_ptr (&branch)[3]) 
 33194 |          { 
 33195 |             typedef details::variable_node<Type>* variable_ptr; 
 33196 |  
 33197 |             const Type& v0 = static_cast<variable_ptr>(branch[0])->ref(); 
 33198 |             const Type& v1 = static_cast<variable_ptr>(branch[1])->ref(); 
 33199 |             const Type& v2 = static_cast<variable_ptr>(branch[2])->ref(); 
 33200 |  
 33201 |             switch (operation) 
 33202 |             { 
 33203 |                #define case_stmt(op)                                                                \ 
 33204 |                case details::e_sf##op : return node_allocator_->                                    \ 
 33205 |                              allocate_rrr<details::sf3_var_node<Type,details::sf##op##_op<Type> > > \ 
 33206 |                                 (v0, v1, v2);                                                       \ 
 33207 |  
 33208 |                case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 33209 |                case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 33210 |                case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 33211 |                case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 33212 |                case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 33213 |                case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 33214 |                case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 33215 |                case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31) 
 33216 |                case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35) 
 33217 |                case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39) 
 33218 |                case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43) 
 33219 |                case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47) 
 33220 |                #undef case_stmt 
 33221 |                default : return error_node(); 
 33222 |             } 
 33223 |          } 
 33224 |  
 33225 |          inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[3]) 
 33226 |          { 
 33227 |             if (!all_nodes_valid(branch)) 
 33228 |                return error_node(); 
 33229 |             else if (is_constant_foldable(branch)) 
 33230 |                return const_optimise_sf3(operation,branch); 
 33231 |             else if (all_nodes_variables(branch)) 
 33232 |                return varnode_optimise_sf3(operation,branch); 
 33233 |             else 
 33234 |             { 
 33235 |                switch (operation) 
 33236 |                { 
 33237 |                   #define case_stmt(op)                                                        \ 
 33238 |                   case details::e_sf##op : return node_allocator_->                            \ 
 33239 |                                 allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \ 
 33240 |                                    (operation, branch);                                        \ 
 33241 |  
 33242 |                   case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 33243 |                   case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 33244 |                   case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 33245 |                   case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 33246 |                   case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 33247 |                   case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 33248 |                   case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 33249 |                   case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31) 
 33250 |                   case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35) 
 33251 |                   case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39) 
 33252 |                   case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43) 
 33253 |                   case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47) 
 33254 |                   #undef case_stmt 
 33255 |                   default : return error_node(); 
 33256 |                } 
 33257 |             } 
 33258 |          } 
 33259 |  
 33260 |          inline expression_node_ptr const_optimise_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 33261 |          { 
 33262 |             expression_node_ptr temp_node = error_node(); 
 33263 |  
 33264 |             switch (operation) 
 33265 |             { 
 33266 |                #define case_stmt(op)                                                                    \ 
 33267 |                case details::e_sf##op : temp_node = node_allocator_->                                   \ 
 33268 |                                          allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \ 
 33269 |                                             (operation, branch);                                        \ 
 33270 |                                         break;                                                          \ 
 33271 |  
 33272 |                case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51) 
 33273 |                case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55) 
 33274 |                case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59) 
 33275 |                case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63) 
 33276 |                case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67) 
 33277 |                case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71) 
 33278 |                case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75) 
 33279 |                case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79) 
 33280 |                case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83) 
 33281 |                case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87) 
 33282 |                case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91) 
 33283 |                case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95) 
 33284 |                case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99) 
 33285 |                #undef case_stmt 
 33286 |                default : return error_node(); 
 33287 |             } 
 33288 |  
 33289 |             assert(temp_node); 
 33290 |  
 33291 |             const T v = temp_node->value(); 
 33292 |  
 33293 |             details::free_node(*node_allocator_,temp_node); 
 33294 |  
 33295 |             return node_allocator_->allocate<literal_node_t>(v); 
 33296 |          } 
 33297 |  
 33298 |          inline expression_node_ptr varnode_optimise_sf4(const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 33299 |          { 
 33300 |             typedef details::variable_node<Type>* variable_ptr; 
 33301 |  
 33302 |             const Type& v0 = static_cast<variable_ptr>(branch[0])->ref(); 
 33303 |             const Type& v1 = static_cast<variable_ptr>(branch[1])->ref(); 
 33304 |             const Type& v2 = static_cast<variable_ptr>(branch[2])->ref(); 
 33305 |             const Type& v3 = static_cast<variable_ptr>(branch[3])->ref(); 
 33306 |  
 33307 |             switch (operation) 
 33308 |             { 
 33309 |                #define case_stmt(op)                                                                 \ 
 33310 |                case details::e_sf##op : return node_allocator_->                                     \ 
 33311 |                              allocate_rrrr<details::sf4_var_node<Type,details::sf##op##_op<Type> > > \ 
 33312 |                                 (v0, v1, v2, v3);                                                    \ 
 33313 |  
 33314 |                case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51) 
 33315 |                case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55) 
 33316 |                case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59) 
 33317 |                case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63) 
 33318 |                case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67) 
 33319 |                case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71) 
 33320 |                case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75) 
 33321 |                case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79) 
 33322 |                case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83) 
 33323 |                case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87) 
 33324 |                case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91) 
 33325 |                case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95) 
 33326 |                case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99) 
 33327 |                #undef case_stmt 
 33328 |                default : return error_node(); 
 33329 |             } 
 33330 |          } 
 33331 |  
 33332 |          inline expression_node_ptr special_function(const details::operator_type& operation, expression_node_ptr (&branch)[4]) 
 33333 |          { 
 33334 |             if (!all_nodes_valid(branch)) 
 33335 |                return error_node(); 
 33336 |             else if (is_constant_foldable(branch)) 
 33337 |                return const_optimise_sf4(operation,branch); 
 33338 |             else if (all_nodes_variables(branch)) 
 33339 |                return varnode_optimise_sf4(operation,branch); 
 33340 |             switch (operation) 
 33341 |             { 
 33342 |                #define case_stmt(op)                                                        \ 
 33343 |                case details::e_sf##op : return node_allocator_->                            \ 
 33344 |                              allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \ 
 33345 |                                 (operation, branch);                                        \ 
 33346 |  
 33347 |                case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51) 
 33348 |                case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55) 
 33349 |                case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59) 
 33350 |                case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63) 
 33351 |                case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67) 
 33352 |                case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71) 
 33353 |                case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75) 
 33354 |                case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79) 
 33355 |                case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83) 
 33356 |                case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87) 
 33357 |                case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91) 
 33358 |                case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95) 
 33359 |                case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99) 
 33360 |                #undef case_stmt 
 33361 |                default : return error_node(); 
 33362 |             } 
 33363 |          } 
 33364 |  
 33365 |          template <typename Allocator, 
 33366 |                    template <typename, typename> class Sequence> 
 33367 |          inline expression_node_ptr const_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list) 
 33368 |          { 
 33369 |             expression_node_ptr temp_node = error_node(); 
 33370 |  
 33371 |             switch (operation) 
 33372 |             { 
 33373 |                #define case_stmt(op0, op1)                                                \ 
 33374 |                case op0 : temp_node = node_allocator_->                                   \ 
 33375 |                                          allocate<details::vararg_node<Type,op1<Type> > > \ 
 33376 |                                             (arg_list);                                   \ 
 33377 |                           break;                                                          \ 
 33378 |  
 33379 |                case_stmt(details::e_sum   , details::vararg_add_op  ) 
 33380 |                case_stmt(details::e_prod  , details::vararg_mul_op  ) 
 33381 |                case_stmt(details::e_avg   , details::vararg_avg_op  ) 
 33382 |                case_stmt(details::e_min   , details::vararg_min_op  ) 
 33383 |                case_stmt(details::e_max   , details::vararg_max_op  ) 
 33384 |                case_stmt(details::e_mand  , details::vararg_mand_op ) 
 33385 |                case_stmt(details::e_mor   , details::vararg_mor_op  ) 
 33386 |                case_stmt(details::e_multi , details::vararg_multi_op) 
 33387 |                #undef case_stmt 
 33388 |                default : return error_node(); 
 33389 |             } 
 33390 |  
 33391 |             const T v = temp_node->value(); 
 33392 |  
 33393 |             details::free_node(*node_allocator_,temp_node); 
 33394 |  
 33395 |             return node_allocator_->allocate<literal_node_t>(v); 
 33396 |          } 
 33397 |  
 33398 |          inline bool special_one_parameter_vararg(const details::operator_type& operation) const 
 33399 |          { 
 33400 |             return ( 
 33401 |                      (details::e_sum  == operation) || 
 33402 |                      (details::e_prod == operation) || 
 33403 |                      (details::e_avg  == operation) || 
 33404 |                      (details::e_min  == operation) || 
 33405 |                      (details::e_max  == operation) 
 33406 |                    ); 
 33407 |          } 
 33408 |  
 33409 |          template <typename Allocator, 
 33410 |                    template <typename, typename> class Sequence> 
 33411 |          inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation, 
 33412 |                                                                 Sequence<expression_node_ptr,Allocator>& arg_list) 
 33413 |          { 
 33414 |             switch (operation) 
 33415 |             { 
 33416 |                #define case_stmt(op0, op1)                                                  \ 
 33417 |                case op0 : return node_allocator_->                                          \ 
 33418 |                              allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \ 
 33419 |  
 33420 |                case_stmt(details::e_sum   , details::vararg_add_op  ) 
 33421 |                case_stmt(details::e_prod  , details::vararg_mul_op  ) 
 33422 |                case_stmt(details::e_avg   , details::vararg_avg_op  ) 
 33423 |                case_stmt(details::e_min   , details::vararg_min_op  ) 
 33424 |                case_stmt(details::e_max   , details::vararg_max_op  ) 
 33425 |                case_stmt(details::e_mand  , details::vararg_mand_op ) 
 33426 |                case_stmt(details::e_mor   , details::vararg_mor_op  ) 
 33427 |                case_stmt(details::e_multi , details::vararg_multi_op) 
 33428 |                #undef case_stmt 
 33429 |                default : return error_node(); 
 33430 |             } 
 33431 |          } 
 33432 |  
 33433 |          template <typename Allocator, 
 33434 |                    template <typename, typename> class Sequence> 
 33435 |          inline expression_node_ptr vectorize_func(const details::operator_type& operation, 
 33436 |                                                    Sequence<expression_node_ptr,Allocator>& arg_list) 
 33437 |          { 
 33438 |             if (1 == arg_list.size()) 
 33439 |             { 
 33440 |                switch (operation) 
 33441 |                { 
 33442 |                   #define case_stmt(op0, op1)                                                     \ 
 33443 |                   case op0 : return node_allocator_->                                             \ 
 33444 |                                 allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \ 
 33445 |  
 33446 |                   case_stmt(details::e_sum  , details::vec_add_op) 
 33447 |                   case_stmt(details::e_prod , details::vec_mul_op) 
 33448 |                   case_stmt(details::e_avg  , details::vec_avg_op) 
 33449 |                   case_stmt(details::e_min  , details::vec_min_op) 
 33450 |                   case_stmt(details::e_max  , details::vec_max_op) 
 33451 |                   #undef case_stmt 
 33452 |                   default : return error_node(); 
 33453 |                } 
 33454 |             } 
 33455 |             else 
 33456 |                return error_node(); 
 33457 |          } 
 33458 |  
 33459 |          template <typename Allocator, 
 33460 |                    template <typename, typename> class Sequence> 
 33461 |          inline expression_node_ptr vararg_function(const details::operator_type& operation, 
 33462 |                                                     Sequence<expression_node_ptr,Allocator>& arg_list) 
 33463 |          { 
 33464 |             if (!all_nodes_valid(arg_list)) 
 33465 |             { 
 33466 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33467 |  
 33468 |                return error_node(); 
 33469 |             } 
 33470 |             else if (is_constant_foldable(arg_list)) 
 33471 |                return const_optimise_varargfunc(operation,arg_list); 
 33472 |             else if ((1 == arg_list.size()) && details::is_ivector_node(arg_list[0])) 
 33473 |                return vectorize_func(operation,arg_list); 
 33474 |             else if ((1 == arg_list.size()) && special_one_parameter_vararg(operation)) 
 33475 |                return arg_list[0]; 
 33476 |             else if (all_nodes_variables(arg_list)) 
 33477 |                return varnode_optimise_varargfunc(operation,arg_list); 
 33478 |  
 33479 |             #ifndef exprtk_disable_string_capabilities 
 33480 |             if (details::e_smulti == operation) 
 33481 |             { 
 33482 |                expression_node_ptr result = node_allocator_-> 
 33483 |                  allocate<details::str_vararg_node<Type,details::vararg_multi_op<Type> > >(arg_list); 
 33484 |                if (result && result->valid()) 
 33485 |                { 
 33486 |                   return result; 
 33487 |                } 
 33488 |  
 33489 |                parser_->set_error(parser_error::make_error( 
 33490 |                   parser_error::e_synthesis, 
 33491 |                   token_t(), 
 33492 |                   "ERR257 - Failed to synthesize node: str_vararg_node<vararg_multi_op>", 
 33493 |                   exprtk_error_location)); 
 33494 |  
 33495 |                details::free_node(*node_allocator_, result); 
 33496 |             } 
 33497 |             else 
 33498 |             #endif 
 33499 |             { 
 33500 |                expression_node_ptr result = error_node(); 
 33501 |  
 33502 |                switch (operation) 
 33503 |                { 
 33504 |                   #define case_stmt(op0, op1)                                               \ 
 33505 |                   case op0 : result = node_allocator_->                                     \ 
 33506 |                                 allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \ 
 33507 |                              break;                                                         \ 
 33508 |  
 33509 |                   case_stmt(details::e_sum   , details::vararg_add_op  ) 
 33510 |                   case_stmt(details::e_prod  , details::vararg_mul_op  ) 
 33511 |                   case_stmt(details::e_avg   , details::vararg_avg_op  ) 
 33512 |                   case_stmt(details::e_min   , details::vararg_min_op  ) 
 33513 |                   case_stmt(details::e_max   , details::vararg_max_op  ) 
 33514 |                   case_stmt(details::e_mand  , details::vararg_mand_op ) 
 33515 |                   case_stmt(details::e_mor   , details::vararg_mor_op  ) 
 33516 |                   case_stmt(details::e_multi , details::vararg_multi_op) 
 33517 |                   #undef case_stmt 
 33518 |                   default : return error_node(); 
 33519 |                } 
 33520 |  
 33521 |                if (result && result->valid()) 
 33522 |                { 
 33523 |                   return result; 
 33524 |                } 
 33525 |  
 33526 |                parser_->set_error(parser_error::make_error( 
 33527 |                   parser_error::e_synthesis, 
 33528 |                   token_t(), 
 33529 |                   "ERR258 - Failed to synthesize node: vararg_node", 
 33530 |                   exprtk_error_location)); 
 33531 |  
 33532 |                details::free_node(*node_allocator_, result); 
 33533 |             } 
 33534 |  
 33535 |             return error_node(); 
 33536 |          } 
 33537 |  
 33538 |          template <std::size_t N> 
 33539 |          inline expression_node_ptr function(ifunction_t* f, expression_node_ptr (&b)[N]) 
 33540 |          { 
 33541 |             typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t; 
 33542 |             expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b); 
 33543 |  
 33544 |             if (0 == result) 
 33545 |                return error_node(); 
 33546 |             else 
 33547 |             { 
 33548 |                // Can the function call be completely optimised? 
 33549 |                if (details::is_constant_node(result)) 
 33550 |                   return result; 
 33551 |                else if (!all_nodes_valid(b)) 
 33552 |                { 
 33553 |                   details::free_node(*node_allocator_,result); 
 33554 |                   std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0)); 
 33555 |  
 33556 |                   return error_node(); 
 33557 |                } 
 33558 |                else if (N != f->param_count) 
 33559 |                { 
 33560 |                   details::free_node(*node_allocator_,result); 
 33561 |                   std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0)); 
 33562 |  
 33563 |                   return error_node(); 
 33564 |                } 
 33565 |  
 33566 |                function_N_node_t* func_node_ptr = reinterpret_cast<function_N_node_t*>(result); 
 33567 |  
 33568 |                if (!func_node_ptr->init_branches(b)) 
 33569 |                { 
 33570 |                   details::free_node(*node_allocator_,result); 
 33571 |                   std::fill_n(b, N, reinterpret_cast<expression_node_ptr>(0)); 
 33572 |  
 33573 |                   return error_node(); 
 33574 |                } 
 33575 |  
 33576 |                if (result && result->valid()) 
 33577 |                { 
 33578 |                   return result; 
 33579 |                } 
 33580 |  
 33581 |                parser_->set_error(parser_error::make_error( 
 33582 |                   parser_error::e_synthesis, 
 33583 |                   token_t(), 
 33584 |                   "ERR259 - Failed to synthesize node: function_N_node_t", 
 33585 |                   exprtk_error_location)); 
 33586 |  
 33587 |                details::free_node(*node_allocator_, result); 
 33588 |                return error_node(); 
 33589 |             } 
 33590 |          } 
 33591 |  
 33592 |          inline expression_node_ptr function(ifunction_t* f) 
 33593 |          { 
 33594 |             typedef typename details::function_N_node<Type,ifunction_t,0> function_N_node_t; 
 33595 |             return node_allocator_->allocate<function_N_node_t>(f); 
 33596 |          } 
 33597 |  
 33598 |          inline expression_node_ptr vararg_function_call(ivararg_function_t* vaf, 
 33599 |                                                          std::vector<expression_node_ptr>& arg_list) 
 33600 |          { 
 33601 |             if (!all_nodes_valid(arg_list)) 
 33602 |             { 
 33603 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33604 |  
 33605 |                return error_node(); 
 33606 |             } 
 33607 |  
 33608 |             typedef details::vararg_function_node<Type,ivararg_function_t> alloc_type; 
 33609 |  
 33610 |             expression_node_ptr result = node_allocator_->allocate<alloc_type>(vaf,arg_list); 
 33611 |  
 33612 |             if ( 
 33613 |                  !arg_list.empty()        && 
 33614 |                  !vaf->has_side_effects() && 
 33615 |                  is_constant_foldable(arg_list) 
 33616 |                ) 
 33617 |             { 
 33618 |                const Type v = result->value(); 
 33619 |                details::free_node(*node_allocator_,result); 
 33620 |                result = node_allocator_->allocate<literal_node_t>(v); 
 33621 |             } 
 33622 |  
 33623 |             parser_->state_.activate_side_effect("vararg_function_call()"); 
 33624 |  
 33625 |             if (result && result->valid()) 
 33626 |             { 
 33627 |                return result; 
 33628 |             } 
 33629 |  
 33630 |             parser_->set_error(parser_error::make_error( 
 33631 |                parser_error::e_synthesis, 
 33632 |                token_t(), 
 33633 |                "ERR260 - Failed to synthesize node: vararg_function_node<ivararg_function_t>", 
 33634 |                exprtk_error_location)); 
 33635 |  
 33636 |             details::free_node(*node_allocator_, result); 
 33637 |             return error_node(); 
 33638 |          } 
 33639 |  
 33640 |          inline expression_node_ptr generic_function_call(igeneric_function_t* gf, 
 33641 |                                                           std::vector<expression_node_ptr>& arg_list, 
 33642 |                                                           const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max()) 
 33643 |          { 
 33644 |             if (!all_nodes_valid(arg_list)) 
 33645 |             { 
 33646 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33647 |                return error_node(); 
 33648 |             } 
 33649 |  
 33650 |             typedef details::generic_function_node     <Type,igeneric_function_t> alloc_type1; 
 33651 |             typedef details::multimode_genfunction_node<Type,igeneric_function_t> alloc_type2; 
 33652 |  
 33653 |             const std::size_t no_psi = std::numeric_limits<std::size_t>::max(); 
 33654 |  
 33655 |             expression_node_ptr result = error_node(); 
 33656 |             std::string node_name = "Unknown" 
 33657 |  
 33658 |             if (no_psi == param_seq_index) 
 33659 |             { 
 33660 |                result = node_allocator_->allocate<alloc_type1>(arg_list,gf); 
 33661 |                node_name = "generic_function_node<igeneric_function_t>" 
 33662 |             } 
 33663 |             else 
 33664 |             { 
 33665 |                result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list); 
 33666 |                node_name = "multimode_genfunction_node<igeneric_function_t>" 
 33667 |             } 
 33668 |  
 33669 |             alloc_type1* genfunc_node_ptr = static_cast<alloc_type1*>(result); 
 33670 |  
 33671 |             assert(genfunc_node_ptr); 
 33672 |  
 33673 |             if ( 
 33674 |                  !arg_list.empty()                  && 
 33675 |                  !gf->has_side_effects()            && 
 33676 |                  parser_->state_.type_check_enabled && 
 33677 |                  is_constant_foldable(arg_list) 
 33678 |                ) 
 33679 |             { 
 33680 |                genfunc_node_ptr->init_branches(); 
 33681 |  
 33682 |                const Type v = result->value(); 
 33683 |  
 33684 |                details::free_node(*node_allocator_,result); 
 33685 |  
 33686 |                return node_allocator_->allocate<literal_node_t>(v); 
 33687 |             } 
 33688 |             else if (genfunc_node_ptr->init_branches()) 
 33689 |             { 
 33690 |                if (result && result->valid()) 
 33691 |                { 
 33692 |                   parser_->state_.activate_side_effect("generic_function_call()"); 
 33693 |                   return result; 
 33694 |                } 
 33695 |  
 33696 |                parser_->set_error(parser_error::make_error( 
 33697 |                   parser_error::e_synthesis, 
 33698 |                   token_t(), 
 33699 |                   "ERR261 - Failed to synthesize node: " + node_name, 
 33700 |                   exprtk_error_location)); 
 33701 |  
 33702 |                details::free_node(*node_allocator_, result); 
 33703 |                return error_node(); 
 33704 |             } 
 33705 |             else 
 33706 |             { 
 33707 |                details::free_node(*node_allocator_, result); 
 33708 |                details::free_all_nodes(*node_allocator_, arg_list); 
 33709 |  
 33710 |                return error_node(); 
 33711 |             } 
 33712 |          } 
 33713 |  
 33714 |          #ifndef exprtk_disable_string_capabilities 
 33715 |          inline expression_node_ptr string_function_call(igeneric_function_t* gf, 
 33716 |                                                          std::vector<expression_node_ptr>& arg_list, 
 33717 |                                                          const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max()) 
 33718 |          { 
 33719 |             if (!all_nodes_valid(arg_list)) 
 33720 |             { 
 33721 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33722 |                return error_node(); 
 33723 |             } 
 33724 |  
 33725 |             typedef details::string_function_node      <Type,igeneric_function_t> alloc_type1; 
 33726 |             typedef details::multimode_strfunction_node<Type,igeneric_function_t> alloc_type2; 
 33727 |  
 33728 |             const std::size_t no_psi = std::numeric_limits<std::size_t>::max(); 
 33729 |  
 33730 |             expression_node_ptr result = error_node(); 
 33731 |             std::string node_name = "Unknown" 
 33732 |  
 33733 |             if (no_psi == param_seq_index) 
 33734 |             { 
 33735 |                result = node_allocator_->allocate<alloc_type1>(gf,arg_list); 
 33736 |                node_name = "string_function_node<igeneric_function_t>" 
 33737 |             } 
 33738 |             else 
 33739 |             { 
 33740 |                result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list); 
 33741 |                node_name = "multimode_strfunction_node<igeneric_function_t>" 
 33742 |             } 
 33743 |  
 33744 |             alloc_type1* strfunc_node_ptr = static_cast<alloc_type1*>(result); 
 33745 |  
 33746 |             assert(strfunc_node_ptr); 
 33747 |  
 33748 |             if ( 
 33749 |                  !arg_list.empty()       && 
 33750 |                  !gf->has_side_effects() && 
 33751 |                  is_constant_foldable(arg_list) 
 33752 |                ) 
 33753 |             { 
 33754 |                strfunc_node_ptr->init_branches(); 
 33755 |  
 33756 |                const Type v = result->value(); 
 33757 |  
 33758 |                details::free_node(*node_allocator_,result); 
 33759 |  
 33760 |                return node_allocator_->allocate<literal_node_t>(v); 
 33761 |             } 
 33762 |             else if (strfunc_node_ptr->init_branches()) 
 33763 |             { 
 33764 |                if (result && result->valid()) 
 33765 |                { 
 33766 |                   parser_->state_.activate_side_effect("string_function_call()"); 
 33767 |                   return result; 
 33768 |                } 
 33769 |  
 33770 |                parser_->set_error(parser_error::make_error( 
 33771 |                   parser_error::e_synthesis, 
 33772 |                   token_t(), 
 33773 |                   "ERR262 - Failed to synthesize node: " + node_name, 
 33774 |                   exprtk_error_location)); 
 33775 |  
 33776 |                details::free_node(*node_allocator_, result); 
 33777 |                return error_node(); 
 33778 |             } 
 33779 |             else 
 33780 |             { 
 33781 |                details::free_node     (*node_allocator_,result  ); 
 33782 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33783 |  
 33784 |                return error_node(); 
 33785 |             } 
 33786 |          } 
 33787 |          #endif 
 33788 |  
 33789 |          #ifndef exprtk_disable_return_statement 
 33790 |          inline expression_node_ptr return_call(std::vector<expression_node_ptr>& arg_list) 
 33791 |          { 
 33792 |             if (!all_nodes_valid(arg_list)) 
 33793 |             { 
 33794 |                details::free_all_nodes(*node_allocator_,arg_list); 
 33795 |                return error_node(); 
 33796 |             } 
 33797 |  
 33798 |             typedef details::return_node<Type> alloc_type; 
 33799 |  
 33800 |             expression_node_ptr result = node_allocator_-> 
 33801 |                                             allocate_rr<alloc_type>(arg_list,parser_->results_ctx()); 
 33802 |  
 33803 |             alloc_type* return_node_ptr = static_cast<alloc_type*>(result); 
 33804 |  
 33805 |             assert(return_node_ptr); 
 33806 |  
 33807 |             if (return_node_ptr->init_branches()) 
 33808 |             { 
 33809 |                if (result && result->valid()) 
 33810 |                { 
 33811 |                   parser_->state_.activate_side_effect("return_call()"); 
 33812 |                   return result; 
 33813 |                } 
 33814 |  
 33815 |                parser_->set_error(parser_error::make_error( 
 33816 |                   parser_error::e_synthesis, 
 33817 |                   token_t(), 
 33818 |                   "ERR263 - Failed to synthesize node: return_node", 
 33819 |                   exprtk_error_location)); 
 33820 |  
 33821 |                details::free_node(*node_allocator_, result); 
 33822 |                return error_node(); 
 33823 |             } 
 33824 |             else 
 33825 |             { 
 33826 |                details::free_node     (*node_allocator_, result  ); 
 33827 |                details::free_all_nodes(*node_allocator_, arg_list); 
 33828 |  
 33829 |                return error_node(); 
 33830 |             } 
 33831 |          } 
 33832 |  
 33833 |          inline expression_node_ptr return_envelope(expression_node_ptr body, 
 33834 |                                                     results_context_t* rc, 
 33835 |                                                     bool*& return_invoked) 
 33836 |          { 
 33837 |             typedef details::return_envelope_node<Type> alloc_type; 
 33838 |  
 33839 |             expression_node_ptr result = node_allocator_-> 
 33840 |                                             allocate_cr<alloc_type>(body,(*rc)); 
 33841 |  
 33842 |             return_invoked = static_cast<alloc_type*>(result)->retinvk_ptr(); 
 33843 |  
 33844 |             return result; 
 33845 |          } 
 33846 |          #else 
 33847 |          inline expression_node_ptr return_call(std::vector<expression_node_ptr>&) 
 33848 |          { 
 33849 |             return error_node(); 
 33850 |          } 
 33851 |  
 33852 |          inline expression_node_ptr return_envelope(expression_node_ptr, 
 33853 |                                                     results_context_t*, 
 33854 |                                                     bool*&) 
 33855 |          { 
 33856 |             return error_node(); 
 33857 |          } 
 33858 |          #endif 
 33859 |  
 33860 |          inline expression_node_ptr vector_element(const std::string&  symbol, 
 33861 |                                                    vector_holder_ptr   vector_base, 
 33862 |                                                    expression_node_ptr vec_node, 
 33863 |                                                    expression_node_ptr index) 
 33864 |          { 
 33865 |             expression_node_ptr result = error_node(); 
 33866 |             std::string node_name = "Unknown" 
 33867 |  
 33868 |             if (details::is_constant_node(index)) 
 33869 |             { 
 33870 |                const std::size_t vec_index = static_cast<std::size_t>(details::numeric::to_int64(index->value())); 
 33871 |  
 33872 |                details::free_node(*node_allocator_,index); 
 33873 |  
 33874 |                if (vec_index >= vector_base->size()) 
 33875 |                { 
 33876 |                   parser_->set_error(parser_error::make_error( 
 33877 |                      parser_error::e_parser, 
 33878 |                      token_t(), 
 33879 |                      "ERR264 - Index of " + details::to_str(vec_index) + " out of range for " 
 33880 |                      "vector '" + symbol + "' of size " + details::to_str(vector_base->size()), 
 33881 |                      exprtk_error_location)); 
 33882 |  
 33883 |                   details::free_node(*node_allocator_,vec_node); 
 33884 |  
 33885 |                   return error_node(); 
 33886 |                } 
 33887 |  
 33888 |                if (vector_base->rebaseable()) 
 33889 |                { 
 33890 |                   vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); 
 33891 |  
 33892 |                   result = (rtc) ? 
 33893 |                      node_allocator_->allocate<rebasevector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) : 
 33894 |                      node_allocator_->allocate<rebasevector_celem_node_t    >(vec_node, vec_index, vector_base     ) ; 
 33895 |  
 33896 |                   node_name = (rtc) ? 
 33897 |                      "rebasevector_elem_rtc_node_t" : 
 33898 |                      "rebasevector_elem_node_t"     ; 
 33899 |  
 33900 |                   if (result && result->valid()) 
 33901 |                   { 
 33902 |                      return result; 
 33903 |                   } 
 33904 |  
 33905 |                   parser_->set_error(parser_error::make_error( 
 33906 |                      parser_error::e_synthesis, 
 33907 |                      token_t(), 
 33908 |                      "ERR265 - Failed to synthesize node: " + node_name + " for vector: " + symbol, 
 33909 |                      exprtk_error_location)); 
 33910 |  
 33911 |                   details::free_node(*node_allocator_, result); 
 33912 |                   return error_node(); 
 33913 |                } 
 33914 |                else if (details::is_ivector_node(vec_node) && !details::is_vector_node(vec_node)) 
 33915 |                { 
 33916 |                   vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); 
 33917 |  
 33918 |                   result = (rtc) ? 
 33919 |                      node_allocator_->allocate<vector_celem_rtc_node_t>(vec_node, vec_index, vector_base, rtc) : 
 33920 |                      node_allocator_->allocate<vector_celem_node_t    >(vec_node, vec_index, vector_base     ) ; 
 33921 |  
 33922 |                   node_name = (rtc) ? 
 33923 |                      "vector_elem_rtc_node_t" : 
 33924 |                      "vector_elem_node_t"     ; 
 33925 |  
 33926 |                   if (result && result->valid()) 
 33927 |                   { 
 33928 |                      return result; 
 33929 |                   } 
 33930 |  
 33931 |                   parser_->set_error(parser_error::make_error( 
 33932 |                      parser_error::e_synthesis, 
 33933 |                      token_t(), 
 33934 |                      "ERR266 - Failed to synthesize node: " + node_name + " for vector: " + symbol, 
 33935 |                      exprtk_error_location)); 
 33936 |  
 33937 |                   details::free_node(*node_allocator_, result); 
 33938 |                   return error_node(); 
 33939 |                } 
 33940 |  
 33941 |                const scope_element& se = parser_->sem_.get_element(symbol,vec_index); 
 33942 |  
 33943 |                if (se.index == vec_index) 
 33944 |                { 
 33945 |                   result = se.var_node; 
 33946 |                   details::free_node(*node_allocator_,vec_node); 
 33947 |                } 
 33948 |                else 
 33949 |                { 
 33950 |                   scope_element nse; 
 33951 |                   nse.name      = symbol; 
 33952 |                   nse.active    = true; 
 33953 |                   nse.ref_count = 1; 
 33954 |                   nse.type      = scope_element::e_vecelem; 
 33955 |                   nse.index     = vec_index; 
 33956 |                   nse.depth     = parser_->state_.scope_depth; 
 33957 |                   nse.data      = 0; 
 33958 |                   nse.var_node  = node_allocator_->allocate<variable_node_t>((*(*vector_base)[vec_index])); 
 33959 |  
 33960 |                   if (!parser_->sem_.add_element(nse)) 
 33961 |                   { 
 33962 |                      parser_->set_synthesis_error("Failed to add new local vector element to SEM [1]"); 
 33963 |  
 33964 |                      parser_->sem_.free_element(nse); 
 33965 |  
 33966 |                      result = error_node(); 
 33967 |                   } 
 33968 |  
 33969 |                   details::free_node(*node_allocator_,vec_node); 
 33970 |  
 33971 |                   exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n", nse.name.c_str())); 
 33972 |  
 33973 |                   parser_->state_.activate_side_effect("vector_element()"); 
 33974 |  
 33975 |                   result = nse.var_node; 
 33976 |                   node_name = "variable_node_t" 
 33977 |                } 
 33978 |             } 
 33979 |             else 
 33980 |             { 
 33981 |                vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); 
 33982 |  
 33983 |                if (vector_base->rebaseable()) 
 33984 |                { 
 33985 |                   result = (rtc) ? 
 33986 |                      node_allocator_->allocate<rebasevector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) : 
 33987 |                      node_allocator_->allocate<rebasevector_elem_node_t    >(vec_node, index, vector_base     ) ; 
 33988 |  
 33989 |                   node_name = (rtc) ? 
 33990 |                      "rebasevector_elem_rtc_node_t" : 
 33991 |                      "rebasevector_elem_node_t"     ; 
 33992 |                } 
 33993 |                else 
 33994 |                { 
 33995 |                   result = rtc ? 
 33996 |                      node_allocator_->allocate<vector_elem_rtc_node_t>(vec_node, index, vector_base, rtc) : 
 33997 |                      node_allocator_->allocate<vector_elem_node_t    >(vec_node, index, vector_base     ) ; 
 33998 |  
 33999 |                   node_name = (rtc) ? 
 34000 |                      "vector_elem_rtc_node_t" : 
 34001 |                      "vector_elem_node_t"     ; 
 34002 |                } 
 34003 |             } 
 34004 |  
 34005 |             if (result && result->valid()) 
 34006 |             { 
 34007 |                return result; 
 34008 |             } 
 34009 |  
 34010 |             parser_->set_error(parser_error::make_error( 
 34011 |                parser_error::e_synthesis, 
 34012 |                token_t(), 
 34013 |                "ERR267 - Failed to synthesize node: " + node_name, 
 34014 |                exprtk_error_location)); 
 34015 |  
 34016 |             details::free_node(*node_allocator_, result); 
 34017 |             return error_node(); 
 34018 |          } 
 34019 |  
 34020 |       private: 
 34021 |  
 34022 |          template <std::size_t N, typename NodePtr> 
 34023 |          inline bool is_constant_foldable(NodePtr (&b)[N]) const 
 34024 |          { 
 34025 |             for (std::size_t i = 0; i < N; ++i) 
 34026 |             { 
 34027 |                if (0 == b[i]) 
 34028 |                   return false; 
 34029 |                else if (!details::is_constant_node(b[i])) 
 34030 |                   return false; 
 34031 |             } 
 34032 |  
 34033 |             return true; 
 34034 |          } 
 34035 |  
 34036 |          template <typename NodePtr, 
 34037 |                    typename Allocator, 
 34038 |                    template <typename, typename> class Sequence> 
 34039 |          inline bool is_constant_foldable(const Sequence<NodePtr,Allocator>& b) const 
 34040 |          { 
 34041 |             for (std::size_t i = 0; i < b.size(); ++i) 
 34042 |             { 
 34043 |                if (0 == b[i]) 
 34044 |                   return false; 
 34045 |                else if (!details::is_constant_node(b[i])) 
 34046 |                   return false; 
 34047 |             } 
 34048 |  
 34049 |             return true; 
 34050 |          } 
 34051 |  
 34052 |          void lodge_assignment(symbol_type cst, expression_node_ptr node) 
 34053 |          { 
 34054 |             parser_->state_.activate_side_effect("lodge_assignment()"); 
 34055 |  
 34056 |             if (!parser_->dec_.collect_assignments()) 
 34057 |                return; 
 34058 |  
 34059 |             std::string symbol_name; 
 34060 |  
 34061 |             switch (cst) 
 34062 |             { 
 34063 |                case e_st_variable : symbol_name = parser_->symtab_store_ 
 34064 |                                                      .get_variable_name(node); 
 34065 |                                     break; 
 34066 |  
 34067 |                #ifndef exprtk_disable_string_capabilities 
 34068 |                case e_st_string   : symbol_name = parser_->symtab_store_ 
 34069 |                                                      .get_stringvar_name(node); 
 34070 |                                     break; 
 34071 |                #endif 
 34072 |  
 34073 |                case e_st_vector   : { 
 34074 |                                        typedef details::vector_holder<T> vector_holder_t; 
 34075 |  
 34076 |                                        vector_holder_t& vh = static_cast<vector_node_t*>(node)->vec_holder(); 
 34077 |  
 34078 |                                        symbol_name = parser_->symtab_store_.get_vector_name(&vh); 
 34079 |                                     } 
 34080 |                                     break; 
 34081 |  
 34082 |                case e_st_vecelem  : { 
 34083 |                                        typedef details::vector_holder<T> vector_holder_t; 
 34084 |  
 34085 |                                        vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder(); 
 34086 |  
 34087 |                                        symbol_name = parser_->symtab_store_.get_vector_name(&vh); 
 34088 |  
 34089 |                                        cst = e_st_vector; 
 34090 |                                     } 
 34091 |                                     break; 
 34092 |  
 34093 |                default            : return; 
 34094 |             } 
 34095 |  
 34096 |             if (!symbol_name.empty()) 
 34097 |             { 
 34098 |                parser_->dec_.add_assignment(symbol_name,cst); 
 34099 |             } 
 34100 |          } 
 34101 |  
 34102 |          const void* base_ptr(expression_node_ptr node) 
 34103 |          { 
 34104 |             if (node) 
 34105 |             { 
 34106 |                switch(node->type()) 
 34107 |                { 
 34108 |                   case details::expression_node<T>::e_variable: 
 34109 |                      return reinterpret_cast<const void*>(&static_cast<variable_node_t*>(node)->ref()); 
 34110 |  
 34111 |                   case details::expression_node<T>::e_vecelem: 
 34112 |                      return reinterpret_cast<const void*>(&static_cast<vector_elem_node_t*>(node)->ref()); 
 34113 |  
 34114 |                   case details::expression_node<T>::e_veccelem: 
 34115 |                      return reinterpret_cast<const void*>(&static_cast<vector_celem_node_t*>(node)->ref()); 
 34116 |  
 34117 |                   case details::expression_node<T>::e_vecelemrtc: 
 34118 |                      return reinterpret_cast<const void*>(&static_cast<vector_elem_rtc_node_t*>(node)->ref()); 
 34119 |  
 34120 |                   case details::expression_node<T>::e_veccelemrtc: 
 34121 |                      return reinterpret_cast<const void*>(&static_cast<vector_celem_rtc_node_t*>(node)->ref()); 
 34122 |  
 34123 |                   case details::expression_node<T>::e_rbvecelem: 
 34124 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_node_t*>(node)->ref()); 
 34125 |  
 34126 |                   case details::expression_node<T>::e_rbvecelemrtc: 
 34127 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_rtc_node_t*>(node)->ref()); 
 34128 |  
 34129 |                   case details::expression_node<T>::e_rbveccelem: 
 34130 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_node_t*>(node)->ref()); 
 34131 |  
 34132 |                   case details::expression_node<T>::e_rbveccelemrtc: 
 34133 |                      return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_rtc_node_t*>(node)->ref()); 
 34134 |  
 34135 |                   case details::expression_node<T>::e_vector: 
 34136 |                      return reinterpret_cast<const void*>(static_cast<vector_node_t*>(node)->vec_holder().data()); 
 34137 |  
 34138 |                   #ifndef exprtk_disable_string_capabilities 
 34139 |                   case details::expression_node<T>::e_stringvar: 
 34140 |                      return reinterpret_cast<const void*>((static_cast<stringvar_node_t*>(node)->base())); 
 34141 |  
 34142 |                   case details::expression_node<T>::e_stringvarrng: 
 34143 |                      return reinterpret_cast<const void*>((static_cast<string_range_node_t*>(node)->base())); 
 34144 |                   #endif 
 34145 |                   default : return reinterpret_cast<const void*>(0); 
 34146 |                } 
 34147 |             } 
 34148 |  
 34149 |             return reinterpret_cast<const void*>(0); 
 34150 |          } 
 34151 |  
 34152 |          bool assign_immutable_symbol(expression_node_ptr node) 
 34153 |          { 
 34154 |             interval_t interval; 
 34155 |             const void* baseptr_addr = base_ptr(node); 
 34156 |  
 34157 |             exprtk_debug(("assign_immutable_symbol - base ptr addr: %p\n", baseptr_addr)); 
 34158 |  
 34159 |             if (parser_->immutable_memory_map_.in_interval(baseptr_addr,interval)) 
 34160 |             { 
 34161 |                typename immutable_symtok_map_t::iterator itr = parser_->immutable_symtok_map_.find(interval); 
 34162 |  
 34163 |                if (parser_->immutable_symtok_map_.end() != itr) 
 34164 |                { 
 34165 |                   token_t& token = itr->second; 
 34166 |                   parser_->set_error(parser_error::make_error( 
 34167 |                      parser_error::e_parser, 
 34168 |                      token, 
 34169 |                      "ERR268 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.", 
 34170 |                      exprtk_error_location)); 
 34171 |                } 
 34172 |                else 
 34173 |                   parser_->set_synthesis_error("Unable to assign symbol is immutable."); 
 34174 |  
 34175 |                return true; 
 34176 |             } 
 34177 |  
 34178 |             return false; 
 34179 |          } 
 34180 |  
 34181 |          inline expression_node_ptr synthesize_assignment_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 34182 |          { 
 34183 |             if (assign_immutable_symbol(branch[0])) 
 34184 |             { 
 34185 |                return error_node(); 
 34186 |             } 
 34187 |             else if (details::is_variable_node(branch[0])) 
 34188 |             { 
 34189 |                lodge_assignment(e_st_variable,branch[0]); 
 34190 |                return synthesize_expression<assignment_node_t,2>(operation,branch); 
 34191 |             } 
 34192 |             else if (details::is_vector_elem_node(branch[0]) || details::is_vector_celem_node(branch[0])) 
 34193 |             { 
 34194 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34195 |                return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch); 
 34196 |             } 
 34197 |             else if (details::is_vector_elem_rtc_node(branch[0]) || details::is_vector_celem_rtc_node(branch[0])) 
 34198 |             { 
 34199 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34200 |                return synthesize_expression<assignment_vec_elem_rtc_node_t, 2>(operation, branch); 
 34201 |             } 
 34202 |             else if (details::is_rebasevector_elem_node(branch[0])) 
 34203 |             { 
 34204 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34205 |                return synthesize_expression<assignment_rebasevec_elem_node_t, 2>(operation, branch); 
 34206 |             } 
 34207 |             else if (details::is_rebasevector_elem_rtc_node(branch[0])) 
 34208 |             { 
 34209 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34210 |                return synthesize_expression<assignment_rebasevec_elem_rtc_node_t, 2>(operation, branch); 
 34211 |             } 
 34212 |             else if (details::is_rebasevector_celem_node(branch[0])) 
 34213 |             { 
 34214 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34215 |                return synthesize_expression<assignment_rebasevec_celem_node_t, 2>(operation, branch); 
 34216 |             } 
 34217 |             #ifndef exprtk_disable_string_capabilities 
 34218 |             else if (details::is_string_node(branch[0])) 
 34219 |             { 
 34220 |                lodge_assignment(e_st_string,branch[0]); 
 34221 |                return synthesize_expression<assignment_string_node_t,2>(operation, branch); 
 34222 |             } 
 34223 |             else if (details::is_string_range_node(branch[0])) 
 34224 |             { 
 34225 |                lodge_assignment(e_st_string,branch[0]); 
 34226 |                return synthesize_expression<assignment_string_range_node_t,2>(operation, branch); 
 34227 |             } 
 34228 |             #endif 
 34229 |             else if (details::is_vector_node(branch[0])) 
 34230 |             { 
 34231 |                lodge_assignment(e_st_vector,branch[0]); 
 34232 |  
 34233 |                if (details::is_ivector_node(branch[1])) 
 34234 |                   return synthesize_expression<assignment_vecvec_node_t,2>(operation, branch); 
 34235 |                else 
 34236 |                   return synthesize_expression<assignment_vec_node_t,2>(operation, branch); 
 34237 |             } 
 34238 |             else if (details::is_literal_node(branch[0])) 
 34239 |             { 
 34240 |                parser_->set_error(parser_error::make_error( 
 34241 |                   parser_error::e_syntax, 
 34242 |                   parser_->current_state().token, 
 34243 |                   "ERR269 - Cannot assign value to const variable", 
 34244 |                   exprtk_error_location)); 
 34245 |  
 34246 |                return error_node(); 
 34247 |             } 
 34248 |             else 
 34249 |             { 
 34250 |                parser_->set_error(parser_error::make_error( 
 34251 |                   parser_error::e_syntax, 
 34252 |                   parser_->current_state().token, 
 34253 |                   "ERR270 - Invalid branches for assignment operator '" + details::to_str(operation) + "'", 
 34254 |                   exprtk_error_location)); 
 34255 |  
 34256 |                return error_node(); 
 34257 |             } 
 34258 |          } 
 34259 |  
 34260 |          inline expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type& operation, 
 34261 |                                                                                expression_node_ptr (&branch)[2]) 
 34262 |          { 
 34263 |             if (assign_immutable_symbol(branch[0])) 
 34264 |             { 
 34265 |                return error_node(); 
 34266 |             } 
 34267 |  
 34268 |             expression_node_ptr result = error_node(); 
 34269 |             std::string node_name = "Unknown" 
 34270 |  
 34271 |             if (details::is_variable_node(branch[0])) 
 34272 |             { 
 34273 |                lodge_assignment(e_st_variable,branch[0]); 
 34274 |  
 34275 |                switch (operation) 
 34276 |                { 
 34277 |                   #define case_stmt(op0, op1)                                                                 \ 
 34278 |                   case op0 : result = node_allocator_->                                                       \ 
 34279 |                                 template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \ 
 34280 |                                    (operation, branch[0], branch[1]);                                         \ 
 34281 |                              node_name = "assignment_op_node"                                                \ 
 34282 |                              break;                                                                           \ 
 34283 |  
 34284 |                   case_stmt(details::e_addass , details::add_op) 
 34285 |                   case_stmt(details::e_subass , details::sub_op) 
 34286 |                   case_stmt(details::e_mulass , details::mul_op) 
 34287 |                   case_stmt(details::e_divass , details::div_op) 
 34288 |                   case_stmt(details::e_modass , details::mod_op) 
 34289 |                   #undef case_stmt 
 34290 |                   default : return error_node(); 
 34291 |                } 
 34292 |             } 
 34293 |             else if (details::is_vector_elem_node(branch[0])) 
 34294 |             { 
 34295 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34296 |  
 34297 |                switch (operation) 
 34298 |                { 
 34299 |                   #define case_stmt(op0, op1)                                                                           \ 
 34300 |                   case op0 : result = node_allocator_->                                                                 \ 
 34301 |                                  template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \ 
 34302 |                                     (operation, branch[0], branch[1]);                                                  \ 
 34303 |                              node_name = "assignment_vec_elem_op_node"                                                 \ 
 34304 |                              break;                                                                                     \ 
 34305 |  
 34306 |                   case_stmt(details::e_addass , details::add_op) 
 34307 |                   case_stmt(details::e_subass , details::sub_op) 
 34308 |                   case_stmt(details::e_mulass , details::mul_op) 
 34309 |                   case_stmt(details::e_divass , details::div_op) 
 34310 |                   case_stmt(details::e_modass , details::mod_op) 
 34311 |                   #undef case_stmt 
 34312 |                   default : return error_node(); 
 34313 |                } 
 34314 |             } 
 34315 |             else if (details::is_vector_elem_rtc_node(branch[0])) 
 34316 |             { 
 34317 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34318 |  
 34319 |                switch (operation) 
 34320 |                { 
 34321 |                   #define case_stmt(op0, op1)                                                                               \ 
 34322 |                   case op0 : result = node_allocator_->                                                                     \ 
 34323 |                                  template allocate_rrr<typename details::assignment_vec_elem_op_rtc_node<Type,op1<Type> > > \ 
 34324 |                                     (operation, branch[0], branch[1]);                                                      \ 
 34325 |                              node_name = "assignment_vec_elem_op_rtc_node"                                                 \ 
 34326 |                              break;                                                                                         \ 
 34327 |  
 34328 |                   case_stmt(details::e_addass , details::add_op) 
 34329 |                   case_stmt(details::e_subass , details::sub_op) 
 34330 |                   case_stmt(details::e_mulass , details::mul_op) 
 34331 |                   case_stmt(details::e_divass , details::div_op) 
 34332 |                   case_stmt(details::e_modass , details::mod_op) 
 34333 |                   #undef case_stmt 
 34334 |                   default : return error_node(); 
 34335 |                } 
 34336 |             } 
 34337 |             else if (details::is_vector_celem_rtc_node(branch[0])) 
 34338 |             { 
 34339 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34340 |  
 34341 |                switch (operation) 
 34342 |                { 
 34343 |                   #define case_stmt(op0, op1)                                                                                \ 
 34344 |                   case op0 : result = node_allocator_->                                                                      \ 
 34345 |                                  template allocate_rrr<typename details::assignment_vec_celem_op_rtc_node<Type,op1<Type> > > \ 
 34346 |                                     (operation, branch[0], branch[1]);                                                       \ 
 34347 |                              node_name = "assignment_vec_celem_op_rtc_node"                                                 \ 
 34348 |                              break;                                                                                          \ 
 34349 |  
 34350 |                   case_stmt(details::e_addass , details::add_op) 
 34351 |                   case_stmt(details::e_subass , details::sub_op) 
 34352 |                   case_stmt(details::e_mulass , details::mul_op) 
 34353 |                   case_stmt(details::e_divass , details::div_op) 
 34354 |                   case_stmt(details::e_modass , details::mod_op) 
 34355 |                   #undef case_stmt 
 34356 |                   default : return error_node(); 
 34357 |                } 
 34358 |             } 
 34359 |             else if (details::is_rebasevector_elem_node(branch[0])) 
 34360 |             { 
 34361 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34362 |  
 34363 |                switch (operation) 
 34364 |                { 
 34365 |                   #define case_stmt(op0, op1)                                                                                 \ 
 34366 |                   case op0 : result = node_allocator_->                                                                       \ 
 34367 |                                  template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \ 
 34368 |                                     (operation, branch[0], branch[1]);                                                        \ 
 34369 |                              node_name = "assignment_rebasevec_elem_op_node"                                                 \ 
 34370 |                              break;                                                                                           \ 
 34371 |  
 34372 |                   case_stmt(details::e_addass , details::add_op) 
 34373 |                   case_stmt(details::e_subass , details::sub_op) 
 34374 |                   case_stmt(details::e_mulass , details::mul_op) 
 34375 |                   case_stmt(details::e_divass , details::div_op) 
 34376 |                   case_stmt(details::e_modass , details::mod_op) 
 34377 |                   #undef case_stmt 
 34378 |                   default : return error_node(); 
 34379 |                } 
 34380 |             } 
 34381 |             else if (details::is_rebasevector_celem_node(branch[0])) 
 34382 |             { 
 34383 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34384 |  
 34385 |                switch (operation) 
 34386 |                { 
 34387 |                   #define case_stmt(op0, op1)                                                                                  \ 
 34388 |                   case op0 : result = node_allocator_->                                                                        \ 
 34389 |                                  template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \ 
 34390 |                                     (operation, branch[0], branch[1]);                                                         \ 
 34391 |                              node_name = "assignment_rebasevec_celem_op_node"                                                 \ 
 34392 |                              break;                                                                                            \ 
 34393 |  
 34394 |                   case_stmt(details::e_addass , details::add_op) 
 34395 |                   case_stmt(details::e_subass , details::sub_op) 
 34396 |                   case_stmt(details::e_mulass , details::mul_op) 
 34397 |                   case_stmt(details::e_divass , details::div_op) 
 34398 |                   case_stmt(details::e_modass , details::mod_op) 
 34399 |                   #undef case_stmt 
 34400 |                   default : return error_node(); 
 34401 |                } 
 34402 |             } 
 34403 |             else if (details::is_rebasevector_elem_rtc_node(branch[0])) 
 34404 |             { 
 34405 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34406 |  
 34407 |                switch (operation) 
 34408 |                { 
 34409 |                   #define case_stmt(op0, op1)                                                                                     \ 
 34410 |                   case op0 : result = node_allocator_->                                                                           \ 
 34411 |                                  template allocate_rrr<typename details::assignment_rebasevec_elem_op_rtc_node<Type,op1<Type> > > \ 
 34412 |                                     (operation, branch[0], branch[1]);                                                            \ 
 34413 |                              node_name = "assignment_rebasevec_elem_op_rtc_node"                                                 \ 
 34414 |                              break;                                                                                               \ 
 34415 |  
 34416 |                   case_stmt(details::e_addass , details::add_op) 
 34417 |                   case_stmt(details::e_subass , details::sub_op) 
 34418 |                   case_stmt(details::e_mulass , details::mul_op) 
 34419 |                   case_stmt(details::e_divass , details::div_op) 
 34420 |                   case_stmt(details::e_modass , details::mod_op) 
 34421 |                   #undef case_stmt 
 34422 |                   default : return error_node(); 
 34423 |                } 
 34424 |             } 
 34425 |             else if (details::is_rebasevector_celem_rtc_node(branch[0])) 
 34426 |             { 
 34427 |                lodge_assignment(e_st_vecelem,branch[0]); 
 34428 |  
 34429 |                switch (operation) 
 34430 |                { 
 34431 |                   #define case_stmt(op0, op1)                                                                                      \ 
 34432 |                   case op0 : result = node_allocator_->                                                                            \ 
 34433 |                                  template allocate_rrr<typename details::assignment_rebasevec_celem_op_rtc_node<Type,op1<Type> > > \ 
 34434 |                                     (operation, branch[0], branch[1]);                                                             \ 
 34435 |                              node_name = "assignment_rebasevec_celem_op_rtc_node"                                                 \ 
 34436 |                              break;                                                                                                \ 
 34437 |  
 34438 |                   case_stmt(details::e_addass , details::add_op) 
 34439 |                   case_stmt(details::e_subass , details::sub_op) 
 34440 |                   case_stmt(details::e_mulass , details::mul_op) 
 34441 |                   case_stmt(details::e_divass , details::div_op) 
 34442 |                   case_stmt(details::e_modass , details::mod_op) 
 34443 |                   #undef case_stmt 
 34444 |                   default : return error_node(); 
 34445 |                } 
 34446 |             } 
 34447 |             else if (details::is_vector_node(branch[0])) 
 34448 |             { 
 34449 |                lodge_assignment(e_st_vector,branch[0]); 
 34450 |  
 34451 |                if (details::is_ivector_node(branch[1])) 
 34452 |                { 
 34453 |                   switch (operation) 
 34454 |                   { 
 34455 |                      #define case_stmt(op0, op1)                                                                        \ 
 34456 |                      case op0 : result = node_allocator_->                                                              \ 
 34457 |                                    template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \ 
 34458 |                                       (operation, branch[0], branch[1]);                                                \ 
 34459 |                                 node_name = "assignment_rebasevec_celem_op_node"                                       \ 
 34460 |                                 break;                                                                                  \ 
 34461 |  
 34462 |                      case_stmt(details::e_addass , details::add_op) 
 34463 |                      case_stmt(details::e_subass , details::sub_op) 
 34464 |                      case_stmt(details::e_mulass , details::mul_op) 
 34465 |                      case_stmt(details::e_divass , details::div_op) 
 34466 |                      case_stmt(details::e_modass , details::mod_op) 
 34467 |                      #undef case_stmt 
 34468 |                      default : return error_node(); 
 34469 |                   } 
 34470 |                } 
 34471 |                else 
 34472 |                { 
 34473 |                   switch (operation) 
 34474 |                   { 
 34475 |                      #define case_stmt(op0, op1)                                                                     \ 
 34476 |                      case op0 : result = node_allocator_->                                                           \ 
 34477 |                                    template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \ 
 34478 |                                       (operation, branch[0], branch[1]);                                             \ 
 34479 |                                 node_name = "assignment_vec_op_node"                                                \ 
 34480 |                                 break;                                                                               \ 
 34481 |  
 34482 |                      case_stmt(details::e_addass , details::add_op) 
 34483 |                      case_stmt(details::e_subass , details::sub_op) 
 34484 |                      case_stmt(details::e_mulass , details::mul_op) 
 34485 |                      case_stmt(details::e_divass , details::div_op) 
 34486 |                      case_stmt(details::e_modass , details::mod_op) 
 34487 |                      #undef case_stmt 
 34488 |                      default : return error_node(); 
 34489 |                   } 
 34490 |                } 
 34491 |             } 
 34492 |             #ifndef exprtk_disable_string_capabilities 
 34493 |             else if ( 
 34494 |                       (details::e_addass == operation) && 
 34495 |                       details::is_string_node(branch[0]) 
 34496 |                     ) 
 34497 |             { 
 34498 |                typedef details::assignment_string_node<T,details::asn_addassignment> addass_t; 
 34499 |  
 34500 |                lodge_assignment(e_st_string,branch[0]); 
 34501 |  
 34502 |                result = synthesize_expression<addass_t,2>(operation,branch); 
 34503 |                node_name = "assignment_string_node<T,details::asn_addassignment>" 
 34504 |             } 
 34505 |             #endif 
 34506 |             else 
 34507 |             { 
 34508 |                parser_->set_error(parser_error::make_error( 
 34509 |                   parser_error::e_syntax, 
 34510 |                   parser_->current_state().token, 
 34511 |                   "ERR271 - Invalid branches for assignment operator '" + details::to_str(operation) + "'", 
 34512 |                   exprtk_error_location)); 
 34513 |  
 34514 |                return error_node(); 
 34515 |             } 
 34516 |  
 34517 |             if (result && result->valid()) 
 34518 |             { 
 34519 |                return result; 
 34520 |             } 
 34521 |  
 34522 |             parser_->set_error(parser_error::make_error( 
 34523 |                parser_error::e_synthesis, 
 34524 |                token_t(), 
 34525 |                "ERR272 - Failed to synthesize node: " + node_name, 
 34526 |                exprtk_error_location)); 
 34527 |  
 34528 |             details::free_node(*node_allocator_, result); 
 34529 |             return error_node(); 
 34530 |          } 
 34531 |  
 34532 |          inline expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type& operation, 
 34533 |                                                                                    expression_node_ptr (&branch)[2]) 
 34534 |          { 
 34535 |             const bool is_b0_ivec = details::is_ivector_node(branch[0]); 
 34536 |             const bool is_b1_ivec = details::is_ivector_node(branch[1]); 
 34537 |  
 34538 |             #define batch_eqineq_logic_case                 \ 
 34539 |             case_stmt(details::e_lt    , details::lt_op   ) \ 
 34540 |             case_stmt(details::e_lte   , details::lte_op  ) \ 
 34541 |             case_stmt(details::e_gt    , details::gt_op   ) \ 
 34542 |             case_stmt(details::e_gte   , details::gte_op  ) \ 
 34543 |             case_stmt(details::e_eq    , details::eq_op   ) \ 
 34544 |             case_stmt(details::e_ne    , details::ne_op   ) \ 
 34545 |             case_stmt(details::e_equal , details::equal_op) \ 
 34546 |             case_stmt(details::e_and   , details::and_op  ) \ 
 34547 |             case_stmt(details::e_nand  , details::nand_op ) \ 
 34548 |             case_stmt(details::e_or    , details::or_op   ) \ 
 34549 |             case_stmt(details::e_nor   , details::nor_op  ) \ 
 34550 |             case_stmt(details::e_xor   , details::xor_op  ) \ 
 34551 |             case_stmt(details::e_xnor  , details::xnor_op ) \ 
 34552 |  
 34553 |             expression_node_ptr result = error_node(); 
 34554 |             std::string node_name = "Unknown" 
 34555 |  
 34556 |             if (is_b0_ivec && is_b1_ivec) 
 34557 |             { 
 34558 |                switch (operation) 
 34559 |                { 
 34560 |                   #define case_stmt(op0, op1)                                                                    \ 
 34561 |                   case op0 : result = node_allocator_->                                                          \ 
 34562 |                                 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \ 
 34563 |                                    (operation, branch[0], branch[1]);                                            \ 
 34564 |                              node_name = "vec_binop_vecvec_node"                                                \ 
 34565 |                              break;                                                                              \ 
 34566 |  
 34567 |                   batch_eqineq_logic_case 
 34568 |                   #undef case_stmt 
 34569 |                   default : return error_node(); 
 34570 |                } 
 34571 |             } 
 34572 |             else if (is_b0_ivec && !is_b1_ivec) 
 34573 |             { 
 34574 |                switch (operation) 
 34575 |                { 
 34576 |                   #define case_stmt(op0, op1)                                                                    \ 
 34577 |                   case op0 : result = node_allocator_->                                                          \ 
 34578 |                                 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \ 
 34579 |                                    (operation, branch[0], branch[1]);                                            \ 
 34580 |                              node_name = "vec_binop_vecval_node"                                                \ 
 34581 |                              break;                                                                              \ 
 34582 |  
 34583 |                   batch_eqineq_logic_case 
 34584 |                   #undef case_stmt 
 34585 |                   default : return error_node(); 
 34586 |                } 
 34587 |             } 
 34588 |             else if (!is_b0_ivec && is_b1_ivec) 
 34589 |             { 
 34590 |                switch (operation) 
 34591 |                { 
 34592 |                   #define case_stmt(op0, op1)                                                                    \ 
 34593 |                   case op0 : result = node_allocator_->                                                          \ 
 34594 |                                 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \ 
 34595 |                                    (operation, branch[0], branch[1]);                                            \ 
 34596 |                              node_name = "vec_binop_valvec_node"                                                \ 
 34597 |                              break;                                                                              \ 
 34598 |  
 34599 |                   batch_eqineq_logic_case 
 34600 |                   #undef case_stmt 
 34601 |                   default : return error_node(); 
 34602 |                } 
 34603 |             } 
 34604 |             else 
 34605 |                return error_node(); 
 34606 |  
 34607 |             if (result && result->valid()) 
 34608 |             { 
 34609 |                return result; 
 34610 |             } 
 34611 |  
 34612 |             parser_->set_error(parser_error::make_error( 
 34613 |                parser_error::e_synthesis, 
 34614 |                token_t(), 
 34615 |                "ERR273 - Failed to synthesize node: " + node_name, 
 34616 |                exprtk_error_location)); 
 34617 |  
 34618 |             details::free_node(*node_allocator_, result); 
 34619 |             return error_node(); 
 34620 |  
 34621 |             #undef batch_eqineq_logic_case 
 34622 |          } 
 34623 |  
 34624 |          inline expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type& operation, 
 34625 |                                                                                   expression_node_ptr (&branch)[2]) 
 34626 |          { 
 34627 |             const bool is_b0_ivec = details::is_ivector_node(branch[0]); 
 34628 |             const bool is_b1_ivec = details::is_ivector_node(branch[1]); 
 34629 |  
 34630 |             #define vector_ops                          \ 
 34631 |             case_stmt(details::e_add , details::add_op) \ 
 34632 |             case_stmt(details::e_sub , details::sub_op) \ 
 34633 |             case_stmt(details::e_mul , details::mul_op) \ 
 34634 |             case_stmt(details::e_div , details::div_op) \ 
 34635 |             case_stmt(details::e_mod , details::mod_op) \ 
 34636 |  
 34637 |             expression_node_ptr result = error_node(); 
 34638 |             std::string node_name = "Unknown" 
 34639 |  
 34640 |             if (is_b0_ivec && is_b1_ivec) 
 34641 |             { 
 34642 |                switch (operation) 
 34643 |                { 
 34644 |                   #define case_stmt(op0, op1)                                                                    \ 
 34645 |                   case op0 : result = node_allocator_->                                                          \ 
 34646 |                                 template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \ 
 34647 |                                    (operation, branch[0], branch[1]);                                            \ 
 34648 |                              node_name = "vec_binop_vecvec_node"                                                \ 
 34649 |                              break;                                                                              \ 
 34650 |  
 34651 |                   vector_ops 
 34652 |                   case_stmt(details::e_pow,details:: pow_op) 
 34653 |                   #undef case_stmt 
 34654 |                   default : return error_node(); 
 34655 |                } 
 34656 |             } 
 34657 |             else if (is_b0_ivec && !is_b1_ivec) 
 34658 |             { 
 34659 |                switch (operation) 
 34660 |                { 
 34661 |                   #define case_stmt(op0, op1)                                                                    \ 
 34662 |                   case op0 : result = node_allocator_->                                                          \ 
 34663 |                                 template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \ 
 34664 |                                    (operation, branch[0], branch[1]);                                            \ 
 34665 |                              node_name = "vec_binop_vecval_node(b0ivec,!b1ivec)"                                \ 
 34666 |                              break;                                                                              \ 
 34667 |  
 34668 |                   vector_ops 
 34669 |                   case_stmt(details::e_pow,details:: pow_op) 
 34670 |                   #undef case_stmt 
 34671 |                   default : return error_node(); 
 34672 |                } 
 34673 |             } 
 34674 |             else if (!is_b0_ivec && is_b1_ivec) 
 34675 |             { 
 34676 |                switch (operation) 
 34677 |                { 
 34678 |                   #define case_stmt(op0, op1)                                                                    \ 
 34679 |                   case op0 : result = node_allocator_->                                                          \ 
 34680 |                                 template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \ 
 34681 |                                    (operation, branch[0], branch[1]);                                            \ 
 34682 |                              node_name = "vec_binop_vecval_node(!b0ivec,b1ivec)"                                \ 
 34683 |                              break;                                                                              \ 
 34684 |  
 34685 |                   vector_ops 
 34686 |                   #undef case_stmt 
 34687 |                   default : return error_node(); 
 34688 |                } 
 34689 |             } 
 34690 |             else 
 34691 |                return error_node(); 
 34692 |  
 34693 |             if (result && result->valid()) 
 34694 |             { 
 34695 |                return result; 
 34696 |             } 
 34697 |  
 34698 |             parser_->set_error(parser_error::make_error( 
 34699 |                parser_error::e_synthesis, 
 34700 |                token_t(), 
 34701 |                "ERR274 - Failed to synthesize node: " + node_name, 
 34702 |                exprtk_error_location)); 
 34703 |  
 34704 |             details::free_node(*node_allocator_, result); 
 34705 |             return error_node(); 
 34706 |  
 34707 |             #undef vector_ops 
 34708 |          } 
 34709 |  
 34710 |          inline expression_node_ptr synthesize_swap_expression(expression_node_ptr (&branch)[2]) 
 34711 |          { 
 34712 |             const bool v0_is_ivar = details::is_ivariable_node(branch[0]); 
 34713 |             const bool v1_is_ivar = details::is_ivariable_node(branch[1]); 
 34714 |  
 34715 |             const bool v0_is_ivec = details::is_ivector_node  (branch[0]); 
 34716 |             const bool v1_is_ivec = details::is_ivector_node  (branch[1]); 
 34717 |  
 34718 |             #ifndef exprtk_disable_string_capabilities 
 34719 |             const bool v0_is_str = details::is_generally_string_node(branch[0]); 
 34720 |             const bool v1_is_str = details::is_generally_string_node(branch[1]); 
 34721 |             #endif 
 34722 |  
 34723 |             expression_node_ptr result = error_node(); 
 34724 |             std::string node_name      = "Unknown" 
 34725 |  
 34726 |             if (v0_is_ivar && v1_is_ivar) 
 34727 |             { 
 34728 |                typedef details::variable_node<T>* variable_node_ptr; 
 34729 |  
 34730 |                variable_node_ptr v0 = variable_node_ptr(0); 
 34731 |                variable_node_ptr v1 = variable_node_ptr(0); 
 34732 |  
 34733 |                if ( 
 34734 |                     (0 != (v0 = dynamic_cast<variable_node_ptr>(branch[0]))) && 
 34735 |                     (0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1]))) 
 34736 |                   ) 
 34737 |                { 
 34738 |                   result    = node_allocator_->allocate<details::swap_node<T> >(v0,v1); 
 34739 |                   node_name = "swap_node" 
 34740 |                } 
 34741 |                else 
 34742 |                { 
 34743 |                   result    = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]); 
 34744 |                   node_name = "swap_generic_node" 
 34745 |                } 
 34746 |             } 
 34747 |             else if (v0_is_ivec && v1_is_ivec) 
 34748 |             { 
 34749 |                result    = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]); 
 34750 |                node_name = "swap_vecvec_node" 
 34751 |             } 
 34752 |             #ifndef exprtk_disable_string_capabilities 
 34753 |             else if (v0_is_str && v1_is_str) 
 34754 |             { 
 34755 |                if (is_string_node(branch[0]) && is_string_node(branch[1])) 
 34756 |                { 
 34757 |                   result = node_allocator_->allocate<details::swap_string_node<T> > 
 34758 |                                                (branch[0], branch[1]); 
 34759 |                   node_name = "swap_string_node" 
 34760 |                } 
 34761 |                else 
 34762 |                { 
 34763 |                   result = node_allocator_->allocate<details::swap_genstrings_node<T> > 
 34764 |                                                (branch[0], branch[1]); 
 34765 |                   node_name = "swap_genstrings_node" 
 34766 |                } 
 34767 |             } 
 34768 |             #endif 
 34769 |             else 
 34770 |             { 
 34771 |                parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped"); 
 34772 |                return error_node(); 
 34773 |             } 
 34774 |  
 34775 |             if (result && result->valid()) 
 34776 |             { 
 34777 |                parser_->state_.activate_side_effect("synthesize_swap_expression()"); 
 34778 |                return result; 
 34779 |             } 
 34780 |  
 34781 |             parser_->set_error(parser_error::make_error( 
 34782 |                parser_error::e_synthesis, 
 34783 |                token_t(), 
 34784 |                "ERR275 - Failed to synthesize node: " + node_name, 
 34785 |                exprtk_error_location)); 
 34786 |  
 34787 |             details::free_node(*node_allocator_, result); 
 34788 |             return error_node(); 
 34789 |          } 
 34790 |  
 34791 |          #ifndef exprtk_disable_sc_andor 
 34792 |          inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 34793 |          { 
 34794 |             expression_node_ptr result = error_node(); 
 34795 |  
 34796 |             if (details::is_constant_node(branch[0])) 
 34797 |             { 
 34798 |                if ( 
 34799 |                     (details::e_scand == operation) && 
 34800 |                     std::equal_to<T>()(T(0),branch[0]->value()) 
 34801 |                   ) 
 34802 |                   result = node_allocator_->allocate_c<literal_node_t>(T(0)); 
 34803 |                else if ( 
 34804 |                          (details::e_scor == operation) && 
 34805 |                          std::not_equal_to<T>()(T(0),branch[0]->value()) 
 34806 |                        ) 
 34807 |                   result = node_allocator_->allocate_c<literal_node_t>(T(1)); 
 34808 |             } 
 34809 |  
 34810 |             if (details::is_constant_node(branch[1]) && (0 == result)) 
 34811 |             { 
 34812 |                if ( 
 34813 |                     (details::e_scand == operation) && 
 34814 |                     std::equal_to<T>()(T(0),branch[1]->value()) 
 34815 |                   ) 
 34816 |                   result = node_allocator_->allocate_c<literal_node_t>(T(0)); 
 34817 |                else if ( 
 34818 |                          (details::e_scor == operation) && 
 34819 |                          std::not_equal_to<T>()(T(0),branch[1]->value()) 
 34820 |                        ) 
 34821 |                   result = node_allocator_->allocate_c<literal_node_t>(T(1)); 
 34822 |             } 
 34823 |  
 34824 |             if (result) 
 34825 |             { 
 34826 |                details::free_node(*node_allocator_, branch[0]); 
 34827 |                details::free_node(*node_allocator_, branch[1]); 
 34828 |  
 34829 |                return result; 
 34830 |             } 
 34831 |             else if (details::e_scand == operation) 
 34832 |             { 
 34833 |                return synthesize_expression<scand_node_t,2>(operation, branch); 
 34834 |             } 
 34835 |             else if (details::e_scor == operation) 
 34836 |             { 
 34837 |                return synthesize_expression<scor_node_t,2>(operation, branch); 
 34838 |             } 
 34839 |             else 
 34840 |                return error_node(); 
 34841 |          } 
 34842 |          #else 
 34843 |          inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type&, expression_node_ptr (&)[2]) 
 34844 |          { 
 34845 |             return error_node(); 
 34846 |          } 
 34847 |          #endif 
 34848 |  
 34849 |          #define basic_opr_switch_statements         \ 
 34850 |          case_stmt(details::e_add , details::add_op) \ 
 34851 |          case_stmt(details::e_sub , details::sub_op) \ 
 34852 |          case_stmt(details::e_mul , details::mul_op) \ 
 34853 |          case_stmt(details::e_div , details::div_op) \ 
 34854 |          case_stmt(details::e_mod , details::mod_op) \ 
 34855 |          case_stmt(details::e_pow , details::pow_op) \ 
 34856 |  
 34857 |          #define extended_opr_switch_statements        \ 
 34858 |          case_stmt(details::e_lt   , details::lt_op  ) \ 
 34859 |          case_stmt(details::e_lte  , details::lte_op ) \ 
 34860 |          case_stmt(details::e_gt   , details::gt_op  ) \ 
 34861 |          case_stmt(details::e_gte  , details::gte_op ) \ 
 34862 |          case_stmt(details::e_eq   , details::eq_op  ) \ 
 34863 |          case_stmt(details::e_ne   , details::ne_op  ) \ 
 34864 |          case_stmt(details::e_and  , details::and_op ) \ 
 34865 |          case_stmt(details::e_nand , details::nand_op) \ 
 34866 |          case_stmt(details::e_or   , details::or_op  ) \ 
 34867 |          case_stmt(details::e_nor  , details::nor_op ) \ 
 34868 |          case_stmt(details::e_xor  , details::xor_op ) \ 
 34869 |          case_stmt(details::e_xnor , details::xnor_op) \ 
 34870 |  
 34871 |          #ifndef exprtk_disable_cardinal_pow_optimisation 
 34872 |          template <typename TType, template <typename, typename> class IPowNode> 
 34873 |          inline expression_node_ptr cardinal_pow_optimisation_impl(const TType& v, const unsigned int& p) 
 34874 |          { 
 34875 |             switch (p) 
 34876 |             { 
 34877 |                #define case_stmt(cp)                                                     \ 
 34878 |                case cp : return node_allocator_->                                        \ 
 34879 |                             allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \ 
 34880 |  
 34881 |                case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4) 
 34882 |                case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8) 
 34883 |                case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12) 
 34884 |                case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16) 
 34885 |                case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20) 
 34886 |                case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24) 
 34887 |                case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28) 
 34888 |                case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32) 
 34889 |                case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36) 
 34890 |                case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40) 
 34891 |                case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44) 
 34892 |                case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48) 
 34893 |                case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52) 
 34894 |                case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56) 
 34895 |                case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60) 
 34896 |                #undef case_stmt 
 34897 |                default : return error_node(); 
 34898 |             } 
 34899 |          } 
 34900 |  
 34901 |          inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c) 
 34902 |          { 
 34903 |             const bool not_recipricol = (c >= T(0)); 
 34904 |             const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c))); 
 34905 |  
 34906 |             if (0 == p) 
 34907 |                return node_allocator_->allocate_c<literal_node_t>(T(1)); 
 34908 |             else if (std::equal_to<T>()(T(2),c)) 
 34909 |             { 
 34910 |                return node_allocator_-> 
 34911 |                   template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v); 
 34912 |             } 
 34913 |             else 
 34914 |             { 
 34915 |                if (not_recipricol) 
 34916 |                   return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p); 
 34917 |                else 
 34918 |                   return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p); 
 34919 |             } 
 34920 |          } 
 34921 |  
 34922 |          inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c) const 
 34923 |          { 
 34924 |             return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c); 
 34925 |          } 
 34926 |  
 34927 |          inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr (&branch)[2]) 
 34928 |          { 
 34929 |             const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 34930 |             const bool not_recipricol = (c >= T(0)); 
 34931 |             const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c))); 
 34932 |  
 34933 |             node_allocator_->free(branch[1]); 
 34934 |  
 34935 |             if (0 == p) 
 34936 |             { 
 34937 |                details::free_all_nodes(*node_allocator_, branch); 
 34938 |  
 34939 |                return node_allocator_->allocate_c<literal_node_t>(T(1)); 
 34940 |             } 
 34941 |             else if (not_recipricol) 
 34942 |                return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p); 
 34943 |             else 
 34944 |                return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowinv_node>(branch[0],p); 
 34945 |          } 
 34946 |          #else 
 34947 |          inline expression_node_ptr cardinal_pow_optimisation(T&, const T&) 
 34948 |          { 
 34949 |             return error_node(); 
 34950 |          } 
 34951 |  
 34952 |          inline bool cardinal_pow_optimisable(const details::operator_type&, const T&) 
 34953 |          { 
 34954 |             return false; 
 34955 |          } 
 34956 |  
 34957 |          inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&)[2]) 
 34958 |          { 
 34959 |             return error_node(); 
 34960 |          } 
 34961 |          #endif 
 34962 |  
 34963 |          struct synthesize_binary_ext_expression 
 34964 |          { 
 34965 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 34966 |                                                       const details::operator_type& operation, 
 34967 |                                                       expression_node_ptr (&branch)[2]) 
 34968 |             { 
 34969 |                const bool left_neg  = is_neg_unary_node(branch[0]); 
 34970 |                const bool right_neg = is_neg_unary_node(branch[1]); 
 34971 |  
 34972 |                if (left_neg && right_neg) 
 34973 |                { 
 34974 |                   if ( 
 34975 |                        (details::e_add == operation) || 
 34976 |                        (details::e_sub == operation) || 
 34977 |                        (details::e_mul == operation) || 
 34978 |                        (details::e_div == operation) 
 34979 |                      ) 
 34980 |                   { 
 34981 |                      if ( 
 34982 |                           !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) || 
 34983 |                           !expr_gen.parser_->simplify_unary_negation_branch(branch[1]) 
 34984 |                         ) 
 34985 |                      { 
 34986 |                         details::free_all_nodes(*expr_gen.node_allocator_,branch); 
 34987 |  
 34988 |                         return error_node(); 
 34989 |                      } 
 34990 |                   } 
 34991 |  
 34992 |                   switch (operation) 
 34993 |                   { 
 34994 |                                            // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1)) 
 34995 |                      case details::e_add : return expr_gen(details::e_neg, 
 34996 |                                               expr_gen.node_allocator_-> 
 34997 |                                                  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > > 
 34998 |                                                     (branch[0],branch[1])); 
 34999 |  
 35000 |                                            // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1) 
 35001 |                      case details::e_sub : return expr_gen.node_allocator_-> 
 35002 |                                               template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > > 
 35003 |                                                  (branch[1],branch[0]); 
 35004 |  
 35005 |                      default             : break; 
 35006 |                   } 
 35007 |                } 
 35008 |                else if (left_neg && !right_neg) 
 35009 |                { 
 35010 |                   if ( 
 35011 |                        (details::e_add == operation) || 
 35012 |                        (details::e_sub == operation) || 
 35013 |                        (details::e_mul == operation) || 
 35014 |                        (details::e_div == operation) 
 35015 |                      ) 
 35016 |                   { 
 35017 |                      if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0])) 
 35018 |                      { 
 35019 |                         details::free_all_nodes(*expr_gen.node_allocator_,branch); 
 35020 |  
 35021 |                         return error_node(); 
 35022 |                      } 
 35023 |  
 35024 |                      switch (operation) 
 35025 |                      { 
 35026 |                                               // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1) 
 35027 |                         case details::e_add : return expr_gen.node_allocator_-> 
 35028 |                                                  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > > 
 35029 |                                                    (branch[1], branch[0]); 
 35030 |  
 35031 |                                               // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1)) 
 35032 |                         case details::e_sub : return expr_gen(details::e_neg, 
 35033 |                                                  expr_gen.node_allocator_-> 
 35034 |                                                     template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > > 
 35035 |                                                        (branch[0], branch[1])); 
 35036 |  
 35037 |                                               // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1)) 
 35038 |                         case details::e_mul : return expr_gen(details::e_neg, 
 35039 |                                                  expr_gen.node_allocator_-> 
 35040 |                                                     template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > > 
 35041 |                                                        (branch[0], branch[1])); 
 35042 |  
 35043 |                                               // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1)) 
 35044 |                         case details::e_div : return expr_gen(details::e_neg, 
 35045 |                                                  expr_gen.node_allocator_-> 
 35046 |                                                     template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > > 
 35047 |                                                        (branch[0], branch[1])); 
 35048 |  
 35049 |                         default             : return error_node(); 
 35050 |                      } 
 35051 |                   } 
 35052 |                } 
 35053 |                else if (!left_neg && right_neg) 
 35054 |                { 
 35055 |                   if ( 
 35056 |                        (details::e_add == operation) || 
 35057 |                        (details::e_sub == operation) || 
 35058 |                        (details::e_mul == operation) || 
 35059 |                        (details::e_div == operation) 
 35060 |                      ) 
 35061 |                   { 
 35062 |                      if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1])) 
 35063 |                      { 
 35064 |                         details::free_all_nodes(*expr_gen.node_allocator_,branch); 
 35065 |  
 35066 |                         return error_node(); 
 35067 |                      } 
 35068 |  
 35069 |                      switch (operation) 
 35070 |                      { 
 35071 |                                               // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1) 
 35072 |                         case details::e_add : return expr_gen.node_allocator_-> 
 35073 |                                                  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > > 
 35074 |                                                    (branch[0], branch[1]); 
 35075 |  
 35076 |                                               // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1) 
 35077 |                         case details::e_sub : return expr_gen.node_allocator_-> 
 35078 |                                                  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > > 
 35079 |                                                    (branch[0], branch[1]); 
 35080 |  
 35081 |                                               // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1)) 
 35082 |                         case details::e_mul : return expr_gen(details::e_neg, 
 35083 |                                                  expr_gen.node_allocator_-> 
 35084 |                                                     template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > > 
 35085 |                                                        (branch[0], branch[1])); 
 35086 |  
 35087 |                                               // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1)) 
 35088 |                         case details::e_div : return expr_gen(details::e_neg, 
 35089 |                                                  expr_gen.node_allocator_-> 
 35090 |                                                     template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > > 
 35091 |                                                        (branch[0], branch[1])); 
 35092 |  
 35093 |                         default             : return error_node(); 
 35094 |                      } 
 35095 |                   } 
 35096 |                } 
 35097 |  
 35098 |                switch (operation) 
 35099 |                { 
 35100 |                   #define case_stmt(op0, op1)                                                          \ 
 35101 |                   case op0 : return expr_gen.node_allocator_->                                         \ 
 35102 |                                 template allocate<typename details::binary_ext_node<Type,op1<Type> > > \ 
 35103 |                                    (branch[0], branch[1]);                                             \ 
 35104 |  
 35105 |                   basic_opr_switch_statements 
 35106 |                   extended_opr_switch_statements 
 35107 |                   #undef case_stmt 
 35108 |                   default : return error_node(); 
 35109 |                } 
 35110 |             } 
 35111 |          }; 
 35112 |  
 35113 |          struct synthesize_vob_expression 
 35114 |          { 
 35115 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35116 |                                                       const details::operator_type& operation, 
 35117 |                                                       expression_node_ptr (&branch)[2]) 
 35118 |             { 
 35119 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 35120 |  
 35121 |                #ifndef exprtk_disable_enhanced_features 
 35122 |                if (details::is_sf3ext_node(branch[1])) 
 35123 |                { 
 35124 |                   expression_node_ptr result = error_node(); 
 35125 |  
 35126 |                   const bool synthesis_result = 
 35127 |                      synthesize_sf4ext_expression::template compile_right<vtype> 
 35128 |                         (expr_gen, v, operation, branch[1], result); 
 35129 |  
 35130 |                   if (synthesis_result) 
 35131 |                   { 
 35132 |                      details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35133 |                      return result; 
 35134 |                   } 
 35135 |                } 
 35136 |                #endif 
 35137 |  
 35138 |                if ( 
 35139 |                     (details::e_mul == operation) || 
 35140 |                     (details::e_div == operation) 
 35141 |                   ) 
 35142 |                { 
 35143 |                   if (details::is_uv_node(branch[1])) 
 35144 |                   { 
 35145 |                      typedef details::uv_base_node<Type>* uvbn_ptr_t; 
 35146 |  
 35147 |                      details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation(); 
 35148 |  
 35149 |                      if (details::e_neg == o) 
 35150 |                      { 
 35151 |                         const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v(); 
 35152 |  
 35153 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35154 |  
 35155 |                         switch (operation) 
 35156 |                         { 
 35157 |                            case details::e_mul : return expr_gen(details::e_neg, 
 35158 |                                                     expr_gen.node_allocator_-> 
 35159 |                                                        template allocate_rr<typename details:: 
 35160 |                                                           vov_node<Type,details::mul_op<Type> > >(v,v1)); 
 35161 |  
 35162 |                            case details::e_div : return expr_gen(details::e_neg, 
 35163 |                                                     expr_gen.node_allocator_-> 
 35164 |                                                        template allocate_rr<typename details:: 
 35165 |                                                           vov_node<Type,details::div_op<Type> > >(v,v1)); 
 35166 |  
 35167 |                            default             : break; 
 35168 |                         } 
 35169 |                      } 
 35170 |                   } 
 35171 |                } 
 35172 |  
 35173 |                switch (operation) 
 35174 |                { 
 35175 |                   #define case_stmt(op0, op1)                                                      \ 
 35176 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35177 |                                 template allocate_rc<typename details::vob_node<Type,op1<Type> > > \ 
 35178 |                                    (v, branch[1]);                                                 \ 
 35179 |  
 35180 |                   basic_opr_switch_statements 
 35181 |                   extended_opr_switch_statements 
 35182 |                   #undef case_stmt 
 35183 |                   default : return error_node(); 
 35184 |                } 
 35185 |             } 
 35186 |          }; 
 35187 |  
 35188 |          struct synthesize_bov_expression 
 35189 |          { 
 35190 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35191 |                                                       const details::operator_type& operation, 
 35192 |                                                       expression_node_ptr (&branch)[2]) 
 35193 |             { 
 35194 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 35195 |  
 35196 |                #ifndef exprtk_disable_enhanced_features 
 35197 |                if (details::is_sf3ext_node(branch[0])) 
 35198 |                { 
 35199 |                   expression_node_ptr result = error_node(); 
 35200 |  
 35201 |                   const bool synthesis_result = 
 35202 |                      synthesize_sf4ext_expression::template compile_left<vtype> 
 35203 |                         (expr_gen, v, operation, branch[0], result); 
 35204 |  
 35205 |                   if (synthesis_result) 
 35206 |                   { 
 35207 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35208 |  
 35209 |                      return result; 
 35210 |                   } 
 35211 |                } 
 35212 |                #endif 
 35213 |  
 35214 |                if ( 
 35215 |                     (details::e_add == operation) || 
 35216 |                     (details::e_sub == operation) || 
 35217 |                     (details::e_mul == operation) || 
 35218 |                     (details::e_div == operation) 
 35219 |                   ) 
 35220 |                { 
 35221 |                   if (details::is_uv_node(branch[0])) 
 35222 |                   { 
 35223 |                      typedef details::uv_base_node<Type>* uvbn_ptr_t; 
 35224 |  
 35225 |                      details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation(); 
 35226 |  
 35227 |                      if (details::e_neg == o) 
 35228 |                      { 
 35229 |                         const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v(); 
 35230 |  
 35231 |                         details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35232 |  
 35233 |                         switch (operation) 
 35234 |                         { 
 35235 |                            case details::e_add : return expr_gen.node_allocator_-> 
 35236 |                                                     template allocate_rr<typename details:: 
 35237 |                                                        vov_node<Type,details::sub_op<Type> > >(v,v0); 
 35238 |  
 35239 |                            case details::e_sub : return expr_gen(details::e_neg, 
 35240 |                                                     expr_gen.node_allocator_-> 
 35241 |                                                        template allocate_rr<typename details:: 
 35242 |                                                           vov_node<Type,details::add_op<Type> > >(v0,v)); 
 35243 |  
 35244 |                            case details::e_mul : return expr_gen(details::e_neg, 
 35245 |                                                     expr_gen.node_allocator_-> 
 35246 |                                                        template allocate_rr<typename details:: 
 35247 |                                                           vov_node<Type,details::mul_op<Type> > >(v0,v)); 
 35248 |  
 35249 |                            case details::e_div : return expr_gen(details::e_neg, 
 35250 |                                                     expr_gen.node_allocator_-> 
 35251 |                                                        template allocate_rr<typename details:: 
 35252 |                                                           vov_node<Type,details::div_op<Type> > >(v0,v)); 
 35253 |                            default : break; 
 35254 |                         } 
 35255 |                      } 
 35256 |                   } 
 35257 |                } 
 35258 |  
 35259 |                switch (operation) 
 35260 |                { 
 35261 |                   #define case_stmt(op0, op1)                                                      \ 
 35262 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35263 |                                 template allocate_cr<typename details::bov_node<Type,op1<Type> > > \ 
 35264 |                                    (branch[0], v);                                                 \ 
 35265 |  
 35266 |                   basic_opr_switch_statements 
 35267 |                   extended_opr_switch_statements 
 35268 |                   #undef case_stmt 
 35269 |                   default : return error_node(); 
 35270 |                } 
 35271 |             } 
 35272 |          }; 
 35273 |  
 35274 |          struct synthesize_cob_expression 
 35275 |          { 
 35276 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35277 |                                                       const details::operator_type& operation, 
 35278 |                                                       expression_node_ptr (&branch)[2]) 
 35279 |             { 
 35280 |                const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 35281 |  
 35282 |                details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35283 |  
 35284 |                if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35285 |                { 
 35286 |                   details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35287 |  
 35288 |                   return expr_gen(T(0)); 
 35289 |                } 
 35290 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35291 |                { 
 35292 |                   details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35293 |  
 35294 |                   return expr_gen(T(0)); 
 35295 |                } 
 35296 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35297 |                   return branch[1]; 
 35298 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35299 |                   return branch[1]; 
 35300 |  
 35301 |                if (details::is_cob_node(branch[1])) 
 35302 |                { 
 35303 |                   // Simplify expressions of the form: 
 35304 |                   // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x) 
 35305 |                   // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x 
 35306 |                   if ( 
 35307 |                        (details::e_mul == operation) || 
 35308 |                        (details::e_add == operation) 
 35309 |                      ) 
 35310 |                   { 
 35311 |                      details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35312 |  
 35313 |                      if (operation == cobnode->operation()) 
 35314 |                      { 
 35315 |                         switch (operation) 
 35316 |                         { 
 35317 |                            case details::e_add : cobnode->set_c(c + cobnode->c()); break; 
 35318 |                            case details::e_mul : cobnode->set_c(c * cobnode->c()); break; 
 35319 |                            default             : return error_node(); 
 35320 |                         } 
 35321 |  
 35322 |                         return cobnode; 
 35323 |                      } 
 35324 |                   } 
 35325 |  
 35326 |                   if (operation == details::e_mul) 
 35327 |                   { 
 35328 |                      details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35329 |                      details::operator_type cob_opr = cobnode->operation(); 
 35330 |  
 35331 |                      if ( 
 35332 |                           (details::e_div == cob_opr) || 
 35333 |                           (details::e_mul == cob_opr) 
 35334 |                         ) 
 35335 |                      { 
 35336 |                         switch (cob_opr) 
 35337 |                         { 
 35338 |                            case details::e_div : cobnode->set_c(c * cobnode->c()); break; 
 35339 |                            case details::e_mul : cobnode->set_c(cobnode->c() / c); break; 
 35340 |                            default             : return error_node(); 
 35341 |                         } 
 35342 |  
 35343 |                         return cobnode; 
 35344 |                      } 
 35345 |                   } 
 35346 |                   else if (operation == details::e_div) 
 35347 |                   { 
 35348 |                      details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35349 |                      details::operator_type cob_opr = cobnode->operation(); 
 35350 |  
 35351 |                      if ( 
 35352 |                           (details::e_div == cob_opr) || 
 35353 |                           (details::e_mul == cob_opr) 
 35354 |                         ) 
 35355 |                      { 
 35356 |                         details::expression_node<Type>* new_cobnode = error_node(); 
 35357 |  
 35358 |                         switch (cob_opr) 
 35359 |                         { 
 35360 |                            case details::e_div : new_cobnode = expr_gen.node_allocator_-> 
 35361 |                                                     template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > > 
 35362 |                                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35363 |                                                  break; 
 35364 |  
 35365 |                            case details::e_mul : new_cobnode = expr_gen.node_allocator_-> 
 35366 |                                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35367 |                                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35368 |                                                  break; 
 35369 |  
 35370 |                            default             : return error_node(); 
 35371 |                         } 
 35372 |  
 35373 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35374 |  
 35375 |                         return new_cobnode; 
 35376 |                      } 
 35377 |                   } 
 35378 |                } 
 35379 |                #ifndef exprtk_disable_enhanced_features 
 35380 |                else if (details::is_sf3ext_node(branch[1])) 
 35381 |                { 
 35382 |                   expression_node_ptr result = error_node(); 
 35383 |  
 35384 |                   const bool synthesis_result = 
 35385 |                      synthesize_sf4ext_expression::template compile_right<ctype> 
 35386 |                         (expr_gen, c, operation, branch[1], result); 
 35387 |  
 35388 |                   if (synthesis_result) 
 35389 |                   { 
 35390 |                      details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35391 |  
 35392 |                      return result; 
 35393 |                   } 
 35394 |                } 
 35395 |                #endif 
 35396 |  
 35397 |                switch (operation) 
 35398 |                { 
 35399 |                   #define case_stmt(op0, op1)                                                      \ 
 35400 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35401 |                                 template allocate_tt<typename details::cob_node<Type,op1<Type> > > \ 
 35402 |                                    (c,  branch[1]);                                                \ 
 35403 |  
 35404 |                   basic_opr_switch_statements 
 35405 |                   extended_opr_switch_statements 
 35406 |                   #undef case_stmt 
 35407 |                   default : return error_node(); 
 35408 |                } 
 35409 |             } 
 35410 |          }; 
 35411 |  
 35412 |          struct synthesize_boc_expression 
 35413 |          { 
 35414 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35415 |                                                       const details::operator_type& operation, 
 35416 |                                                       expression_node_ptr (&branch)[2]) 
 35417 |             { 
 35418 |                const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 35419 |  
 35420 |                details::free_node(*(expr_gen.node_allocator_), branch[1]); 
 35421 |  
 35422 |                if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35423 |                { 
 35424 |                   details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35425 |  
 35426 |                   return expr_gen(T(0)); 
 35427 |                } 
 35428 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35429 |                { 
 35430 |                   details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35431 |  
 35432 |                   return expr_gen(std::numeric_limits<T>::quiet_NaN()); 
 35433 |                } 
 35434 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35435 |                   return branch[0]; 
 35436 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35437 |                   return branch[0]; 
 35438 |  
 35439 |                if (details::is_boc_node(branch[0])) 
 35440 |                { 
 35441 |                   // Simplify expressions of the form: 
 35442 |                   // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320 
 35443 |                   // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45 
 35444 |                   if ( 
 35445 |                        (details::e_mul == operation) || 
 35446 |                        (details::e_add == operation) 
 35447 |                      ) 
 35448 |                   { 
 35449 |                      details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35450 |  
 35451 |                      if (operation == bocnode->operation()) 
 35452 |                      { 
 35453 |                         switch (operation) 
 35454 |                         { 
 35455 |                            case details::e_add : bocnode->set_c(c + bocnode->c()); break; 
 35456 |                            case details::e_mul : bocnode->set_c(c * bocnode->c()); break; 
 35457 |                            default             : return error_node(); 
 35458 |                         } 
 35459 |  
 35460 |                         return bocnode; 
 35461 |                      } 
 35462 |                   } 
 35463 |                   else if (operation == details::e_div) 
 35464 |                   { 
 35465 |                      details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35466 |                      details::operator_type        boc_opr = bocnode->operation(); 
 35467 |  
 35468 |                      if ( 
 35469 |                           (details::e_div == boc_opr) || 
 35470 |                           (details::e_mul == boc_opr) 
 35471 |                         ) 
 35472 |                      { 
 35473 |                         switch (boc_opr) 
 35474 |                         { 
 35475 |                            case details::e_div : bocnode->set_c(c * bocnode->c()); break; 
 35476 |                            case details::e_mul : bocnode->set_c(bocnode->c() / c); break; 
 35477 |                            default             : return error_node(); 
 35478 |                         } 
 35479 |  
 35480 |                         return bocnode; 
 35481 |                      } 
 35482 |                   } 
 35483 |                   else if (operation == details::e_pow) 
 35484 |                   { 
 35485 |                      // (v ^ c0) ^ c1 --> v ^(c0 * c1) 
 35486 |                      details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35487 |                      details::operator_type        boc_opr = bocnode->operation(); 
 35488 |  
 35489 |                      if (details::e_pow == boc_opr) 
 35490 |                      { 
 35491 |                         bocnode->set_c(bocnode->c() * c); 
 35492 |  
 35493 |                         return bocnode; 
 35494 |                      } 
 35495 |                   } 
 35496 |                } 
 35497 |  
 35498 |                #ifndef exprtk_disable_enhanced_features 
 35499 |                if (details::is_sf3ext_node(branch[0])) 
 35500 |                { 
 35501 |                   expression_node_ptr result = error_node(); 
 35502 |  
 35503 |                   const bool synthesis_result = 
 35504 |                      synthesize_sf4ext_expression::template compile_left<ctype> 
 35505 |                         (expr_gen, c, operation, branch[0], result); 
 35506 |  
 35507 |                   if (synthesis_result) 
 35508 |                   { 
 35509 |                      free_node(*expr_gen.node_allocator_, branch[0]); 
 35510 |  
 35511 |                      return result; 
 35512 |                   } 
 35513 |                } 
 35514 |                #endif 
 35515 |  
 35516 |                switch (operation) 
 35517 |                { 
 35518 |                   #define case_stmt(op0, op1)                                                      \ 
 35519 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35520 |                                 template allocate_cr<typename details::boc_node<Type,op1<Type> > > \ 
 35521 |                                    (branch[0], c);                                                 \ 
 35522 |  
 35523 |                   basic_opr_switch_statements 
 35524 |                   extended_opr_switch_statements 
 35525 |                   #undef case_stmt 
 35526 |                   default : return error_node(); 
 35527 |                } 
 35528 |             } 
 35529 |          }; 
 35530 |  
 35531 |          struct synthesize_cocob_expression 
 35532 |          { 
 35533 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35534 |                                                       const details::operator_type& operation, 
 35535 |                                                       expression_node_ptr (&branch)[2]) 
 35536 |             { 
 35537 |                expression_node_ptr result = error_node(); 
 35538 |  
 35539 |                // (cob) o c --> cob 
 35540 |                if (details::is_cob_node(branch[0])) 
 35541 |                { 
 35542 |                   details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]); 
 35543 |  
 35544 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 35545 |  
 35546 |                   if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35547 |                   { 
 35548 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35549 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35550 |  
 35551 |                      return expr_gen(T(0)); 
 35552 |                   } 
 35553 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35554 |                   { 
 35555 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35556 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35557 |  
 35558 |                      return expr_gen(T(std::numeric_limits<T>::quiet_NaN())); 
 35559 |                   } 
 35560 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35561 |                   { 
 35562 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35563 |  
 35564 |                      return branch[0]; 
 35565 |                   } 
 35566 |                   else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35567 |                   { 
 35568 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35569 |  
 35570 |                      return branch[0]; 
 35571 |                   } 
 35572 |                   else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation)) 
 35573 |                   { 
 35574 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35575 |  
 35576 |                      return branch[0]; 
 35577 |                   } 
 35578 |  
 35579 |                   const bool op_addsub = (details::e_add == cobnode->operation()) || 
 35580 |                                          (details::e_sub == cobnode->operation()) ; 
 35581 |  
 35582 |                   if (op_addsub) 
 35583 |                   { 
 35584 |                      switch (operation) 
 35585 |                      { 
 35586 |                         case details::e_add : cobnode->set_c(cobnode->c() + c); break; 
 35587 |                         case details::e_sub : cobnode->set_c(cobnode->c() - c); break; 
 35588 |                         default             : return error_node(); 
 35589 |                      } 
 35590 |  
 35591 |                      result = cobnode; 
 35592 |                   } 
 35593 |                   else if (details::e_mul == cobnode->operation()) 
 35594 |                   { 
 35595 |                      switch (operation) 
 35596 |                      { 
 35597 |                         case details::e_mul : cobnode->set_c(cobnode->c() * c); break; 
 35598 |                         case details::e_div : cobnode->set_c(cobnode->c() / c); break; 
 35599 |                         default             : return error_node(); 
 35600 |                      } 
 35601 |  
 35602 |                      result = cobnode; 
 35603 |                   } 
 35604 |                   else if (details::e_div == cobnode->operation()) 
 35605 |                   { 
 35606 |                      if (details::e_mul == operation) 
 35607 |                      { 
 35608 |                         cobnode->set_c(cobnode->c() * c); 
 35609 |                         result = cobnode; 
 35610 |                      } 
 35611 |                      else if (details::e_div == operation) 
 35612 |                      { 
 35613 |                         result = expr_gen.node_allocator_-> 
 35614 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35615 |                                        (cobnode->c() / c, cobnode->move_branch(0)); 
 35616 |  
 35617 |                         details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35618 |                      } 
 35619 |                   } 
 35620 |  
 35621 |                   if (result) 
 35622 |                   { 
 35623 |                      details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35624 |                   } 
 35625 |                } 
 35626 |  
 35627 |                // c o (cob) --> cob 
 35628 |                else if (details::is_cob_node(branch[1])) 
 35629 |                { 
 35630 |                   details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]); 
 35631 |  
 35632 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 35633 |  
 35634 |                   if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35635 |                   { 
 35636 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35637 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35638 |  
 35639 |                      return expr_gen(T(0)); 
 35640 |                   } 
 35641 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35642 |                   { 
 35643 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35644 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35645 |  
 35646 |                      return expr_gen(T(0)); 
 35647 |                   } 
 35648 |                   else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35649 |                   { 
 35650 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35651 |  
 35652 |                      return branch[1]; 
 35653 |                   } 
 35654 |                   else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35655 |                   { 
 35656 |                      details::free_node(*expr_gen.node_allocator_, branch[0]); 
 35657 |  
 35658 |                      return branch[1]; 
 35659 |                   } 
 35660 |  
 35661 |                   if (details::e_add == cobnode->operation()) 
 35662 |                   { 
 35663 |                      if (details::e_add == operation) 
 35664 |                      { 
 35665 |                         cobnode->set_c(c + cobnode->c()); 
 35666 |                         result = cobnode; 
 35667 |                      } 
 35668 |                      else if (details::e_sub == operation) 
 35669 |                      { 
 35670 |                         result = expr_gen.node_allocator_-> 
 35671 |                                     template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > > 
 35672 |                                        (c - cobnode->c(), cobnode->move_branch(0)); 
 35673 |  
 35674 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35675 |                      } 
 35676 |                   } 
 35677 |                   else if (details::e_sub == cobnode->operation()) 
 35678 |                   { 
 35679 |                      if (details::e_add == operation) 
 35680 |                      { 
 35681 |                         cobnode->set_c(c + cobnode->c()); 
 35682 |                         result = cobnode; 
 35683 |                      } 
 35684 |                      else if (details::e_sub == operation) 
 35685 |                      { 
 35686 |                         result = expr_gen.node_allocator_-> 
 35687 |                                     template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > > 
 35688 |                                        (c - cobnode->c(), cobnode->move_branch(0)); 
 35689 |  
 35690 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35691 |                      } 
 35692 |                   } 
 35693 |                   else if (details::e_mul == cobnode->operation()) 
 35694 |                   { 
 35695 |                      if (details::e_mul == operation) 
 35696 |                      { 
 35697 |                         cobnode->set_c(c * cobnode->c()); 
 35698 |                         result = cobnode; 
 35699 |                      } 
 35700 |                      else if (details::e_div == operation) 
 35701 |                      { 
 35702 |                         result = expr_gen.node_allocator_-> 
 35703 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35704 |                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35705 |  
 35706 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35707 |                      } 
 35708 |                   } 
 35709 |                   else if (details::e_div == cobnode->operation()) 
 35710 |                   { 
 35711 |                      if (details::e_mul == operation) 
 35712 |                      { 
 35713 |                         cobnode->set_c(c * cobnode->c()); 
 35714 |                         result = cobnode; 
 35715 |                      } 
 35716 |                      else if (details::e_div == operation) 
 35717 |                      { 
 35718 |                         result = expr_gen.node_allocator_-> 
 35719 |                                     template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > > 
 35720 |                                        (c / cobnode->c(), cobnode->move_branch(0)); 
 35721 |  
 35722 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35723 |                      } 
 35724 |                   } 
 35725 |  
 35726 |                   if (result) 
 35727 |                   { 
 35728 |                      details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35729 |                   } 
 35730 |                } 
 35731 |  
 35732 |                return result; 
 35733 |             } 
 35734 |          }; 
 35735 |  
 35736 |          struct synthesize_coboc_expression 
 35737 |          { 
 35738 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35739 |                                                       const details::operator_type& operation, 
 35740 |                                                       expression_node_ptr (&branch)[2]) 
 35741 |             { 
 35742 |                expression_node_ptr result = error_node(); 
 35743 |  
 35744 |                // (boc) o c --> boc 
 35745 |                if (details::is_boc_node(branch[0])) 
 35746 |                { 
 35747 |                   details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]); 
 35748 |  
 35749 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 35750 |  
 35751 |                   if (details::e_add == bocnode->operation()) 
 35752 |                   { 
 35753 |                      switch (operation) 
 35754 |                      { 
 35755 |                         case details::e_add : bocnode->set_c(bocnode->c() + c); break; 
 35756 |                         case details::e_sub : bocnode->set_c(bocnode->c() - c); break; 
 35757 |                         default             : return error_node(); 
 35758 |                      } 
 35759 |  
 35760 |                      result = bocnode; 
 35761 |                   } 
 35762 |                   else if (details::e_mul == bocnode->operation()) 
 35763 |                   { 
 35764 |                      switch (operation) 
 35765 |                      { 
 35766 |                         case details::e_mul : bocnode->set_c(bocnode->c() * c); break; 
 35767 |                         case details::e_div : bocnode->set_c(bocnode->c() / c); break; 
 35768 |                         default             : return error_node(); 
 35769 |                      } 
 35770 |  
 35771 |                      result = bocnode; 
 35772 |                   } 
 35773 |                   else if (details::e_sub == bocnode->operation()) 
 35774 |                   { 
 35775 |                      if (details::e_add == operation) 
 35776 |                      { 
 35777 |                         result = expr_gen.node_allocator_-> 
 35778 |                                     template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > > 
 35779 |                                        (bocnode->move_branch(0), c - bocnode->c()); 
 35780 |  
 35781 |                         details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35782 |                      } 
 35783 |                      else if (details::e_sub == operation) 
 35784 |                      { 
 35785 |                         bocnode->set_c(bocnode->c() + c); 
 35786 |                         result = bocnode; 
 35787 |                      } 
 35788 |                   } 
 35789 |                   else if (details::e_div == bocnode->operation()) 
 35790 |                   { 
 35791 |                      switch (operation) 
 35792 |                      { 
 35793 |                         case details::e_div : bocnode->set_c(bocnode->c() * c); break; 
 35794 |                         case details::e_mul : bocnode->set_c(bocnode->c() / c); break; 
 35795 |                         default             : return error_node(); 
 35796 |                      } 
 35797 |  
 35798 |                      result = bocnode; 
 35799 |                   } 
 35800 |  
 35801 |                   if (result) 
 35802 |                   { 
 35803 |                      details::free_node(*expr_gen.node_allocator_, branch[1]); 
 35804 |                   } 
 35805 |                } 
 35806 |  
 35807 |                // c o (boc) --> boc 
 35808 |                else if (details::is_boc_node(branch[1])) 
 35809 |                { 
 35810 |                   details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]); 
 35811 |  
 35812 |                   const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 35813 |  
 35814 |                   if (details::e_add == bocnode->operation()) 
 35815 |                   { 
 35816 |                      if (details::e_add == operation) 
 35817 |                      { 
 35818 |                         bocnode->set_c(c + bocnode->c()); 
 35819 |                         result = bocnode; 
 35820 |                      } 
 35821 |                      else if (details::e_sub == operation) 
 35822 |                      { 
 35823 |                         result = expr_gen.node_allocator_-> 
 35824 |                                     template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > > 
 35825 |                                        (c - bocnode->c(), bocnode->move_branch(0)); 
 35826 |  
 35827 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35828 |                      } 
 35829 |                   } 
 35830 |                   else if (details::e_sub == bocnode->operation()) 
 35831 |                   { 
 35832 |                      if (details::e_add == operation) 
 35833 |                      { 
 35834 |                         result = expr_gen.node_allocator_-> 
 35835 |                                     template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > > 
 35836 |                                        (bocnode->move_branch(0), c - bocnode->c()); 
 35837 |  
 35838 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35839 |                      } 
 35840 |                      else if (details::e_sub == operation) 
 35841 |                      { 
 35842 |                         result = expr_gen.node_allocator_-> 
 35843 |                                     template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > > 
 35844 |                                        (c + bocnode->c(), bocnode->move_branch(0)); 
 35845 |  
 35846 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35847 |                      } 
 35848 |                   } 
 35849 |                   else if (details::e_mul == bocnode->operation()) 
 35850 |                   { 
 35851 |                      if (details::e_mul == operation) 
 35852 |                      { 
 35853 |                         bocnode->set_c(c * bocnode->c()); 
 35854 |                         result = bocnode; 
 35855 |                      } 
 35856 |                      else if (details::e_div == operation) 
 35857 |                      { 
 35858 |                         result = expr_gen.node_allocator_-> 
 35859 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35860 |                                        (c / bocnode->c(), bocnode->move_branch(0)); 
 35861 |  
 35862 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35863 |                      } 
 35864 |                   } 
 35865 |                   else if (details::e_div == bocnode->operation()) 
 35866 |                   { 
 35867 |                      if (details::e_mul == operation) 
 35868 |                      { 
 35869 |                         bocnode->set_c(bocnode->c() / c); 
 35870 |                         result = bocnode; 
 35871 |                      } 
 35872 |                      else if (details::e_div == operation) 
 35873 |                      { 
 35874 |                         result = expr_gen.node_allocator_-> 
 35875 |                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > 
 35876 |                                        (c * bocnode->c(), bocnode->move_branch(0)); 
 35877 |  
 35878 |                         details::free_node(*expr_gen.node_allocator_,branch[1]); 
 35879 |                      } 
 35880 |                   } 
 35881 |  
 35882 |                   if (result) 
 35883 |                   { 
 35884 |                      details::free_node(*expr_gen.node_allocator_,branch[0]); 
 35885 |                   } 
 35886 |                } 
 35887 |  
 35888 |                return result; 
 35889 |             } 
 35890 |          }; 
 35891 |  
 35892 |          #ifndef exprtk_disable_enhanced_features 
 35893 |          inline bool synthesize_expression(const details::operator_type& operation, 
 35894 |                                            expression_node_ptr (&branch)[2], 
 35895 |                                            expression_node_ptr& result) 
 35896 |          { 
 35897 |             result = error_node(); 
 35898 |  
 35899 |             if (!operation_optimisable(operation)) 
 35900 |                return false; 
 35901 |  
 35902 |             const std::string node_id = branch_to_id(branch); 
 35903 |  
 35904 |             const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id); 
 35905 |  
 35906 |             if (synthesize_map_.end() != itr) 
 35907 |             { 
 35908 |                result = itr->second((*this), operation, branch); 
 35909 |  
 35910 |                return true; 
 35911 |             } 
 35912 |             else 
 35913 |                return false; 
 35914 |          } 
 35915 |  
 35916 |          struct synthesize_vov_expression 
 35917 |          { 
 35918 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35919 |                                                       const details::operator_type& operation, 
 35920 |                                                       expression_node_ptr (&branch)[2]) 
 35921 |             { 
 35922 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 35923 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 35924 |  
 35925 |                switch (operation) 
 35926 |                { 
 35927 |                   #define case_stmt(op0, op1)                                                      \ 
 35928 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35929 |                                 template allocate_rr<typename details::vov_node<Type,op1<Type> > > \ 
 35930 |                                    (v1, v2);                                                       \ 
 35931 |  
 35932 |                   basic_opr_switch_statements 
 35933 |                   extended_opr_switch_statements 
 35934 |                   #undef case_stmt 
 35935 |                   default : return error_node(); 
 35936 |                } 
 35937 |             } 
 35938 |          }; 
 35939 |  
 35940 |          struct synthesize_cov_expression 
 35941 |          { 
 35942 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35943 |                                                       const details::operator_type& operation, 
 35944 |                                                       expression_node_ptr (&branch)[2]) 
 35945 |             { 
 35946 |                const Type  c = static_cast<details::literal_node<Type>*> (branch[0])->value(); 
 35947 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref  (); 
 35948 |  
 35949 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 35950 |  
 35951 |                if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35952 |                   return expr_gen(T(0)); 
 35953 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35954 |                   return expr_gen(T(0)); 
 35955 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35956 |                   return static_cast<details::variable_node<Type>*>(branch[1]); 
 35957 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 35958 |                   return static_cast<details::variable_node<Type>*>(branch[1]); 
 35959 |  
 35960 |                switch (operation) 
 35961 |                { 
 35962 |                   #define case_stmt(op0, op1)                                                      \ 
 35963 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 35964 |                                 template allocate_cr<typename details::cov_node<Type,op1<Type> > > \ 
 35965 |                                    (c, v);                                                         \ 
 35966 |  
 35967 |                   basic_opr_switch_statements 
 35968 |                   extended_opr_switch_statements 
 35969 |                   #undef case_stmt 
 35970 |                   default : return error_node(); 
 35971 |                } 
 35972 |             } 
 35973 |          }; 
 35974 |  
 35975 |          struct synthesize_voc_expression 
 35976 |          { 
 35977 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 35978 |                                                       const details::operator_type& operation, 
 35979 |                                                       expression_node_ptr (&branch)[2]) 
 35980 |             { 
 35981 |                const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref  (); 
 35982 |                const Type  c = static_cast<details::literal_node<Type>*> (branch[1])->value(); 
 35983 |  
 35984 |                details::free_node(*(expr_gen.node_allocator_), branch[1]); 
 35985 |  
 35986 |                if (expr_gen.cardinal_pow_optimisable(operation,c)) 
 35987 |                { 
 35988 |                   if (std::equal_to<T>()(T(1),c)) 
 35989 |                      return branch[0]; 
 35990 |                   else 
 35991 |                      return expr_gen.cardinal_pow_optimisation(v,c); 
 35992 |                } 
 35993 |                else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) 
 35994 |                   return expr_gen(T(0)); 
 35995 |                else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation)) 
 35996 |                   return expr_gen(std::numeric_limits<T>::quiet_NaN()); 
 35997 |                else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation)) 
 35998 |                   return static_cast<details::variable_node<Type>*>(branch[0]); 
 35999 |                else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation)) 
 36000 |                   return static_cast<details::variable_node<Type>*>(branch[0]); 
 36001 |                else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation)) 
 36002 |                   return static_cast<details::variable_node<Type>*>(branch[0]); 
 36003 |  
 36004 |                switch (operation) 
 36005 |                { 
 36006 |                   #define case_stmt(op0, op1)                                                      \ 
 36007 |                   case op0 : return expr_gen.node_allocator_->                                     \ 
 36008 |                                 template allocate_rc<typename details::voc_node<Type,op1<Type> > > \ 
 36009 |                                    (v, c);                                                         \ 
 36010 |  
 36011 |                   basic_opr_switch_statements 
 36012 |                   extended_opr_switch_statements 
 36013 |                   #undef case_stmt 
 36014 |                   default : return error_node(); 
 36015 |                } 
 36016 |             } 
 36017 |          }; 
 36018 |  
 36019 |          struct synthesize_sf3ext_expression 
 36020 |          { 
 36021 |             template <typename T0, typename T1, typename T2> 
 36022 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36023 |                                                       const details::operator_type& sf3opr, 
 36024 |                                                       T0 t0, T1 t1, T2 t2) 
 36025 |             { 
 36026 |                switch (sf3opr) 
 36027 |                { 
 36028 |                   #define case_stmt(op)                                                                              \ 
 36029 |                   case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \ 
 36030 |                                 allocate(*(expr_gen.node_allocator_), t0, t1, t2);                                   \ 
 36031 |  
 36032 |                   case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03) 
 36033 |                   case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07) 
 36034 |                   case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11) 
 36035 |                   case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15) 
 36036 |                   case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19) 
 36037 |                   case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23) 
 36038 |                   case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27) 
 36039 |                   case_stmt(28) case_stmt(29) case_stmt(30) 
 36040 |                   #undef case_stmt 
 36041 |                   default : return error_node(); 
 36042 |                } 
 36043 |             } 
 36044 |  
 36045 |             template <typename T0, typename T1, typename T2> 
 36046 |             static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id, 
 36047 |                                        T0 t0, T1 t1, T2 t2, 
 36048 |                                        expression_node_ptr& result) 
 36049 |             { 
 36050 |                details::operator_type sf3opr; 
 36051 |  
 36052 |                if (!expr_gen.sf3_optimisable(id,sf3opr)) 
 36053 |                   return false; 
 36054 |                else 
 36055 |                   result = synthesize_sf3ext_expression::template process<T0, T1, T2> 
 36056 |                               (expr_gen, sf3opr, t0, t1, t2); 
 36057 |  
 36058 |                return true; 
 36059 |             } 
 36060 |          }; 
 36061 |  
 36062 |          struct synthesize_sf4ext_expression 
 36063 |          { 
 36064 |             template <typename T0, typename T1, typename T2, typename T3> 
 36065 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36066 |                                                       const details::operator_type& sf4opr, 
 36067 |                                                       T0 t0, T1 t1, T2 t2, T3 t3) 
 36068 |             { 
 36069 |                switch (sf4opr) 
 36070 |                { 
 36071 |                   #define case_stmt0(op)                                                                                      \ 
 36072 |                   case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \ 
 36073 |                                 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3);                                        \ 
 36074 |  
 36075 |                   #define case_stmt1(op)                                                                                             \ 
 36076 |                   case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \ 
 36077 |                                 allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3);                                               \ 
 36078 |  
 36079 |                   case_stmt0(48) case_stmt0(49) case_stmt0(50) case_stmt0(51) 
 36080 |                   case_stmt0(52) case_stmt0(53) case_stmt0(54) case_stmt0(55) 
 36081 |                   case_stmt0(56) case_stmt0(57) case_stmt0(58) case_stmt0(59) 
 36082 |                   case_stmt0(60) case_stmt0(61) case_stmt0(62) case_stmt0(63) 
 36083 |                   case_stmt0(64) case_stmt0(65) case_stmt0(66) case_stmt0(67) 
 36084 |                   case_stmt0(68) case_stmt0(69) case_stmt0(70) case_stmt0(71) 
 36085 |                   case_stmt0(72) case_stmt0(73) case_stmt0(74) case_stmt0(75) 
 36086 |                   case_stmt0(76) case_stmt0(77) case_stmt0(78) case_stmt0(79) 
 36087 |                   case_stmt0(80) case_stmt0(81) case_stmt0(82) case_stmt0(83) 
 36088 |  
 36089 |                   case_stmt1(00) case_stmt1(01) case_stmt1(02) case_stmt1(03) 
 36090 |                   case_stmt1(04) case_stmt1(05) case_stmt1(06) case_stmt1(07) 
 36091 |                   case_stmt1(08) case_stmt1(09) case_stmt1(10) case_stmt1(11) 
 36092 |                   case_stmt1(12) case_stmt1(13) case_stmt1(14) case_stmt1(15) 
 36093 |                   case_stmt1(16) case_stmt1(17) case_stmt1(18) case_stmt1(19) 
 36094 |                   case_stmt1(20) case_stmt1(21) case_stmt1(22) case_stmt1(23) 
 36095 |                   case_stmt1(24) case_stmt1(25) case_stmt1(26) case_stmt1(27) 
 36096 |                   case_stmt1(28) case_stmt1(29) case_stmt1(30) case_stmt1(31) 
 36097 |                   case_stmt1(32) case_stmt1(33) case_stmt1(34) case_stmt1(35) 
 36098 |                   case_stmt1(36) case_stmt1(37) case_stmt1(38) case_stmt1(39) 
 36099 |                   case_stmt1(40) case_stmt1(41) case_stmt1(42) case_stmt1(43) 
 36100 |                   case_stmt1(44) case_stmt1(45) case_stmt1(46) case_stmt1(47) 
 36101 |                   case_stmt1(48) case_stmt1(49) case_stmt1(50) case_stmt1(51) 
 36102 |                   case_stmt1(52) case_stmt1(53) case_stmt1(54) case_stmt1(55) 
 36103 |                   case_stmt1(56) case_stmt1(57) case_stmt1(58) case_stmt1(59) 
 36104 |                   case_stmt1(60) case_stmt1(61) 
 36105 |  
 36106 |                   #undef case_stmt0 
 36107 |                   #undef case_stmt1 
 36108 |                   default : return error_node(); 
 36109 |                } 
 36110 |             } 
 36111 |  
 36112 |             template <typename T0, typename T1, typename T2, typename T3> 
 36113 |             static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id, 
 36114 |                                        T0 t0, T1 t1, T2 t2, T3 t3, 
 36115 |                                        expression_node_ptr& result) 
 36116 |             { 
 36117 |                details::operator_type sf4opr; 
 36118 |  
 36119 |                if (!expr_gen.sf4_optimisable(id,sf4opr)) 
 36120 |                   return false; 
 36121 |                else 
 36122 |                   result = synthesize_sf4ext_expression::template process<T0, T1, T2, T3> 
 36123 |                               (expr_gen, sf4opr, t0, t1, t2, t3); 
 36124 |  
 36125 |                return true; 
 36126 |             } 
 36127 |  
 36128 |             // T o (sf3ext) 
 36129 |             template <typename ExternalType> 
 36130 |             static inline bool compile_right(expression_generator<Type>& expr_gen, 
 36131 |                                              ExternalType t, 
 36132 |                                              const details::operator_type& operation, 
 36133 |                                              expression_node_ptr& sf3node, 
 36134 |                                              expression_node_ptr& result) 
 36135 |             { 
 36136 |                if (!details::is_sf3ext_node(sf3node)) 
 36137 |                   return false; 
 36138 |  
 36139 |                typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr; 
 36140 |  
 36141 |                sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node); 
 36142 |                const std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")" 
 36143 |  
 36144 |                switch (n->type()) 
 36145 |                { 
 36146 |                   case details::expression_node<Type>::e_covoc : return compile_right_impl 
 36147 |                                                                     <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype> 
 36148 |                                                                        (expr_gen, id, t, sf3node, result); 
 36149 |  
 36150 |                   case details::expression_node<Type>::e_covov : return compile_right_impl 
 36151 |                                                                     <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype> 
 36152 |                                                                        (expr_gen, id, t, sf3node, result); 
 36153 |  
 36154 |                   case details::expression_node<Type>::e_vocov : return compile_right_impl 
 36155 |                                                                     <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype> 
 36156 |                                                                        (expr_gen, id, t, sf3node, result); 
 36157 |  
 36158 |                   case details::expression_node<Type>::e_vovoc : return compile_right_impl 
 36159 |                                                                     <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype> 
 36160 |                                                                        (expr_gen, id, t, sf3node, result); 
 36161 |  
 36162 |                   case details::expression_node<Type>::e_vovov : return compile_right_impl 
 36163 |                                                                     <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype> 
 36164 |                                                                        (expr_gen, id, t, sf3node, result); 
 36165 |  
 36166 |                   default                                      : return false; 
 36167 |                } 
 36168 |             } 
 36169 |  
 36170 |             // (sf3ext) o T 
 36171 |             template <typename ExternalType> 
 36172 |             static inline bool compile_left(expression_generator<Type>& expr_gen, 
 36173 |                                             ExternalType t, 
 36174 |                                             const details::operator_type& operation, 
 36175 |                                             expression_node_ptr& sf3node, 
 36176 |                                             expression_node_ptr& result) 
 36177 |             { 
 36178 |                if (!details::is_sf3ext_node(sf3node)) 
 36179 |                   return false; 
 36180 |  
 36181 |                typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr; 
 36182 |  
 36183 |                sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node); 
 36184 |  
 36185 |                const std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t" 
 36186 |  
 36187 |                switch (n->type()) 
 36188 |                { 
 36189 |                   case details::expression_node<Type>::e_covoc : return compile_left_impl 
 36190 |                                                                     <typename covoc_t::sf3_type_node,ExternalType, ctype, vtype, ctype> 
 36191 |                                                                        (expr_gen, id, t, sf3node, result); 
 36192 |  
 36193 |                   case details::expression_node<Type>::e_covov : return compile_left_impl 
 36194 |                                                                     <typename covov_t::sf3_type_node,ExternalType, ctype, vtype, vtype> 
 36195 |                                                                        (expr_gen, id, t, sf3node, result); 
 36196 |  
 36197 |                   case details::expression_node<Type>::e_vocov : return compile_left_impl 
 36198 |                                                                     <typename vocov_t::sf3_type_node,ExternalType, vtype, ctype, vtype> 
 36199 |                                                                        (expr_gen, id, t, sf3node, result); 
 36200 |  
 36201 |                   case details::expression_node<Type>::e_vovoc : return compile_left_impl 
 36202 |                                                                     <typename vovoc_t::sf3_type_node,ExternalType, vtype, vtype, ctype> 
 36203 |                                                                        (expr_gen, id, t, sf3node, result); 
 36204 |  
 36205 |                   case details::expression_node<Type>::e_vovov : return compile_left_impl 
 36206 |                                                                     <typename vovov_t::sf3_type_node,ExternalType, vtype, vtype, vtype> 
 36207 |                                                                        (expr_gen, id, t, sf3node, result); 
 36208 |  
 36209 |                   default                                      : return false; 
 36210 |                } 
 36211 |             } 
 36212 |  
 36213 |             template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2> 
 36214 |             static inline bool compile_right_impl(expression_generator<Type>& expr_gen, 
 36215 |                                                   const std::string& id, 
 36216 |                                                   ExternalType t, 
 36217 |                                                   expression_node_ptr& node, 
 36218 |                                                   expression_node_ptr& result) 
 36219 |             { 
 36220 |                SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node); 
 36221 |  
 36222 |                if (n) 
 36223 |                { 
 36224 |                   T0 t0 = n->t0(); 
 36225 |                   T1 t1 = n->t1(); 
 36226 |                   T2 t2 = n->t2(); 
 36227 |  
 36228 |                   return synthesize_sf4ext_expression::template compile<ExternalType, T0, T1, T2> 
 36229 |                             (expr_gen, id, t, t0, t1, t2, result); 
 36230 |                } 
 36231 |                else 
 36232 |                   return false; 
 36233 |             } 
 36234 |  
 36235 |             template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2> 
 36236 |             static inline bool compile_left_impl(expression_generator<Type>& expr_gen, 
 36237 |                                                  const std::string& id, 
 36238 |                                                  ExternalType t, 
 36239 |                                                  expression_node_ptr& node, 
 36240 |                                                  expression_node_ptr& result) 
 36241 |             { 
 36242 |                SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node); 
 36243 |  
 36244 |                if (n) 
 36245 |                { 
 36246 |                   T0 t0 = n->t0(); 
 36247 |                   T1 t1 = n->t1(); 
 36248 |                   T2 t2 = n->t2(); 
 36249 |  
 36250 |                   return synthesize_sf4ext_expression::template compile<T0, T1, T2, ExternalType> 
 36251 |                             (expr_gen, id, t0, t1, t2, t, result); 
 36252 |                } 
 36253 |                else 
 36254 |                   return false; 
 36255 |             } 
 36256 |          }; 
 36257 |  
 36258 |          struct synthesize_vovov_expression0 
 36259 |          { 
 36260 |             typedef typename vovov_t::type0 node_type; 
 36261 |             typedef typename vovov_t::sf3_type sf3_type; 
 36262 |  
 36263 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36264 |                                                       const details::operator_type& operation, 
 36265 |                                                       expression_node_ptr (&branch)[2]) 
 36266 |             { 
 36267 |                // (v0 o0 v1) o1 (v2) 
 36268 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 36269 |                const Type& v0 = vov->v0(); 
 36270 |                const Type& v1 = vov->v1(); 
 36271 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 36272 |                const details::operator_type o0 = vov->operation(); 
 36273 |                const details::operator_type o1 = operation; 
 36274 |  
 36275 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36276 |  
 36277 |                expression_node_ptr result = error_node(); 
 36278 |  
 36279 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36280 |                { 
 36281 |                   // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2) 
 36282 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36283 |                   { 
 36284 |                      const bool synthesis_result = 
 36285 |                         synthesize_sf3ext_expression:: 
 36286 |                            template compile<vtype, vtype, vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result); 
 36287 |  
 36288 |                      exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n")); 
 36289 |  
 36290 |                      return (synthesis_result) ? result : error_node(); 
 36291 |                   } 
 36292 |                } 
 36293 |  
 36294 |                const bool synthesis_result = 
 36295 |                   synthesize_sf3ext_expression::template compile<vtype, vtype, vtype> 
 36296 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result); 
 36297 |  
 36298 |                if (synthesis_result) 
 36299 |                   return result; 
 36300 |  
 36301 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36302 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36303 |  
 36304 |                if (!expr_gen.valid_operator(o0,f0)) 
 36305 |                   return error_node(); 
 36306 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36307 |                   return error_node(); 
 36308 |                else 
 36309 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1); 
 36310 |             } 
 36311 |  
 36312 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36313 |                                          const details::operator_type o0, 
 36314 |                                          const details::operator_type o1) 
 36315 |             { 
 36316 |                return details::build_string() 
 36317 |                   << "(t" << expr_gen.to_str(o0) 
 36318 |                   << "t)" << expr_gen.to_str(o1) 
 36319 |                   << "t" 
 36320 |             } 
 36321 |          }; 
 36322 |  
 36323 |          struct synthesize_vovov_expression1 
 36324 |          { 
 36325 |             typedef typename vovov_t::type1 node_type; 
 36326 |             typedef typename vovov_t::sf3_type sf3_type; 
 36327 |  
 36328 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36329 |                                                       const details::operator_type& operation, 
 36330 |                                                       expression_node_ptr (&branch)[2]) 
 36331 |             { 
 36332 |                // (v0) o0 (v1 o1 v2) 
 36333 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 36334 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 36335 |                const Type& v1 = vov->v0(); 
 36336 |                const Type& v2 = vov->v1(); 
 36337 |                const details::operator_type o0 = operation; 
 36338 |                const details::operator_type o1 = vov->operation(); 
 36339 |  
 36340 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36341 |  
 36342 |                expression_node_ptr result = error_node(); 
 36343 |  
 36344 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36345 |                { 
 36346 |                   // v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1 
 36347 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36348 |                   { 
 36349 |                      const bool synthesis_result = 
 36350 |                         synthesize_sf3ext_expression:: 
 36351 |                            template compile<vtype, vtype, vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result); 
 36352 |  
 36353 |                      exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n")); 
 36354 |  
 36355 |                      return (synthesis_result) ? result : error_node(); 
 36356 |                   } 
 36357 |                } 
 36358 |  
 36359 |                const bool synthesis_result = 
 36360 |                   synthesize_sf3ext_expression::template compile<vtype, vtype, vtype> 
 36361 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result); 
 36362 |  
 36363 |                if (synthesis_result) 
 36364 |                   return result; 
 36365 |  
 36366 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36367 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36368 |  
 36369 |                if (!expr_gen.valid_operator(o0,f0)) 
 36370 |                   return error_node(); 
 36371 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36372 |                   return error_node(); 
 36373 |                else 
 36374 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1); 
 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 |             { 
 36381 |                return details::build_string() 
 36382 |                   << "t"  << expr_gen.to_str(o0) 
 36383 |                   << "(t" << expr_gen.to_str(o1) 
 36384 |                   << "t)" 
 36385 |             } 
 36386 |          }; 
 36387 |  
 36388 |          struct synthesize_vovoc_expression0 
 36389 |          { 
 36390 |             typedef typename vovoc_t::type0 node_type; 
 36391 |             typedef typename vovoc_t::sf3_type sf3_type; 
 36392 |  
 36393 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36394 |                                                       const details::operator_type& operation, 
 36395 |                                                       expression_node_ptr (&branch)[2]) 
 36396 |             { 
 36397 |                // (v0 o0 v1) o1 (c) 
 36398 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 36399 |                const Type& v0 = vov->v0(); 
 36400 |                const Type& v1 = vov->v1(); 
 36401 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 36402 |                const details::operator_type o0 = vov->operation(); 
 36403 |                const details::operator_type o1 = operation; 
 36404 |  
 36405 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36406 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36407 |  
 36408 |                expression_node_ptr result = error_node(); 
 36409 |  
 36410 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36411 |                { 
 36412 |                   // (v0 / v1) / c --> (vovoc) v0 / (v1 * c) 
 36413 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36414 |                   { 
 36415 |                      const bool synthesis_result = 
 36416 |                         synthesize_sf3ext_expression:: 
 36417 |                            template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result); 
 36418 |  
 36419 |                      exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n")); 
 36420 |  
 36421 |                      return (synthesis_result) ? result : error_node(); 
 36422 |                   } 
 36423 |                } 
 36424 |  
 36425 |                const bool synthesis_result = 
 36426 |                   synthesize_sf3ext_expression::template compile<vtype, vtype, ctype> 
 36427 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result); 
 36428 |  
 36429 |                if (synthesis_result) 
 36430 |                   return result; 
 36431 |  
 36432 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36433 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36434 |  
 36435 |                if (!expr_gen.valid_operator(o0,f0)) 
 36436 |                   return error_node(); 
 36437 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36438 |                   return error_node(); 
 36439 |                else 
 36440 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1); 
 36441 |             } 
 36442 |  
 36443 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36444 |                                          const details::operator_type o0, 
 36445 |                                          const details::operator_type o1) 
 36446 |             { 
 36447 |                return details::build_string() 
 36448 |                   << "(t" << expr_gen.to_str(o0) 
 36449 |                   << "t)" << expr_gen.to_str(o1) 
 36450 |                   << "t" 
 36451 |             } 
 36452 |          }; 
 36453 |  
 36454 |          struct synthesize_vovoc_expression1 
 36455 |          { 
 36456 |             typedef typename vovoc_t::type1 node_type; 
 36457 |             typedef typename vovoc_t::sf3_type sf3_type; 
 36458 |  
 36459 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36460 |                                                       const details::operator_type& operation, 
 36461 |                                                       expression_node_ptr (&branch)[2]) 
 36462 |             { 
 36463 |                // (v0) o0 (v1 o1 c) 
 36464 |                const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]); 
 36465 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 36466 |                const Type& v1 = voc->v(); 
 36467 |                const Type   c = voc->c(); 
 36468 |                const details::operator_type o0 = operation; 
 36469 |                const details::operator_type o1 = voc->operation(); 
 36470 |  
 36471 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36472 |  
 36473 |                expression_node_ptr result = error_node(); 
 36474 |  
 36475 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36476 |                { 
 36477 |                   // v0 / (v1 / c) --> (vocov) (v0 * c) / v1 
 36478 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36479 |                   { 
 36480 |                      const bool synthesis_result = 
 36481 |                         synthesize_sf3ext_expression:: 
 36482 |                            template compile<vtype, ctype, vtype>(expr_gen, "(t*t)/t", v0, c, v1, result); 
 36483 |  
 36484 |                      exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n")); 
 36485 |  
 36486 |                      return (synthesis_result) ? result : error_node(); 
 36487 |                   } 
 36488 |                } 
 36489 |  
 36490 |                const bool synthesis_result = 
 36491 |                   synthesize_sf3ext_expression::template compile<vtype, vtype, ctype> 
 36492 |                      (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result); 
 36493 |  
 36494 |                if (synthesis_result) 
 36495 |                   return result; 
 36496 |  
 36497 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36498 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36499 |  
 36500 |                if (!expr_gen.valid_operator(o0,f0)) 
 36501 |                   return error_node(); 
 36502 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36503 |                   return error_node(); 
 36504 |                else 
 36505 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1); 
 36506 |             } 
 36507 |  
 36508 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36509 |                                          const details::operator_type o0, 
 36510 |                                          const details::operator_type o1) 
 36511 |             { 
 36512 |                return details::build_string() 
 36513 |                   << "t"  << expr_gen.to_str(o0) 
 36514 |                   << "(t" << expr_gen.to_str(o1) 
 36515 |                   << "t)" 
 36516 |             } 
 36517 |          }; 
 36518 |  
 36519 |          struct synthesize_vocov_expression0 
 36520 |          { 
 36521 |             typedef typename vocov_t::type0 node_type; 
 36522 |             typedef typename vocov_t::sf3_type sf3_type; 
 36523 |  
 36524 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36525 |                                                       const details::operator_type& operation, 
 36526 |                                                       expression_node_ptr (&branch)[2]) 
 36527 |             { 
 36528 |                // (v0 o0 c) o1 (v1) 
 36529 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 36530 |                const Type& v0 = voc->v(); 
 36531 |                const Type   c = voc->c(); 
 36532 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 36533 |                const details::operator_type o0 = voc->operation(); 
 36534 |                const details::operator_type o1 = operation; 
 36535 |  
 36536 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36537 |  
 36538 |                expression_node_ptr result = error_node(); 
 36539 |  
 36540 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36541 |                { 
 36542 |                   // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c) 
 36543 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36544 |                   { 
 36545 |                      const bool synthesis_result = 
 36546 |                         synthesize_sf3ext_expression:: 
 36547 |                            template compile<vtype, vtype, ctype>(expr_gen, "t/(t*t)", v0, v1, c, result); 
 36548 |  
 36549 |                      exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n")); 
 36550 |  
 36551 |                      return (synthesis_result) ? result : error_node(); 
 36552 |                   } 
 36553 |                } 
 36554 |  
 36555 |                const bool synthesis_result = 
 36556 |                   synthesize_sf3ext_expression::template compile<vtype, ctype, vtype> 
 36557 |                      (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result); 
 36558 |  
 36559 |                if (synthesis_result) 
 36560 |                   return result; 
 36561 |  
 36562 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36563 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36564 |  
 36565 |                if (!expr_gen.valid_operator(o0,f0)) 
 36566 |                   return error_node(); 
 36567 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36568 |                   return error_node(); 
 36569 |                else 
 36570 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1); 
 36571 |             } 
 36572 |  
 36573 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36574 |                                          const details::operator_type o0, 
 36575 |                                          const details::operator_type o1) 
 36576 |             { 
 36577 |                return details::build_string() 
 36578 |                   << "(t" << expr_gen.to_str(o0) 
 36579 |                   << "t)" << expr_gen.to_str(o1) 
 36580 |                   << "t" 
 36581 |             } 
 36582 |          }; 
 36583 |  
 36584 |          struct synthesize_vocov_expression1 
 36585 |          { 
 36586 |             typedef typename vocov_t::type1 node_type; 
 36587 |             typedef typename vocov_t::sf3_type sf3_type; 
 36588 |  
 36589 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36590 |                                                       const details::operator_type& operation, 
 36591 |                                                       expression_node_ptr (&branch)[2]) 
 36592 |             { 
 36593 |                // (v0) o0 (c o1 v1) 
 36594 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 36595 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 36596 |                const Type   c = cov->c(); 
 36597 |                const Type& v1 = cov->v(); 
 36598 |                const details::operator_type o0 = operation; 
 36599 |                const details::operator_type o1 = cov->operation(); 
 36600 |  
 36601 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36602 |  
 36603 |                expression_node_ptr result = error_node(); 
 36604 |  
 36605 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36606 |                { 
 36607 |                   // v0 / (c / v1) --> (vovoc) (v0 * v1) / c 
 36608 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36609 |                   { 
 36610 |                      const bool synthesis_result = 
 36611 |                         synthesize_sf3ext_expression:: 
 36612 |                            template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result); 
 36613 |  
 36614 |                      exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n")); 
 36615 |  
 36616 |                      return (synthesis_result) ? result : error_node(); 
 36617 |                   } 
 36618 |                } 
 36619 |  
 36620 |                const bool synthesis_result = 
 36621 |                   synthesize_sf3ext_expression::template compile<vtype, ctype, vtype> 
 36622 |                      (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result); 
 36623 |  
 36624 |                if (synthesis_result) 
 36625 |                   return result; 
 36626 |  
 36627 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36628 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36629 |  
 36630 |                if (!expr_gen.valid_operator(o0,f0)) 
 36631 |                   return error_node(); 
 36632 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36633 |                   return error_node(); 
 36634 |                else 
 36635 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1); 
 36636 |             } 
 36637 |  
 36638 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36639 |                                          const details::operator_type o0, 
 36640 |                                          const details::operator_type o1) 
 36641 |             { 
 36642 |                return details::build_string() 
 36643 |                   << "t"  << expr_gen.to_str(o0) 
 36644 |                   << "(t" << expr_gen.to_str(o1) 
 36645 |                   << "t)" 
 36646 |             } 
 36647 |          }; 
 36648 |  
 36649 |          struct synthesize_covov_expression0 
 36650 |          { 
 36651 |             typedef typename covov_t::type0 node_type; 
 36652 |             typedef typename covov_t::sf3_type sf3_type; 
 36653 |  
 36654 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36655 |                                                       const details::operator_type& operation, 
 36656 |                                                       expression_node_ptr (&branch)[2]) 
 36657 |             { 
 36658 |                // (c o0 v0) o1 (v1) 
 36659 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 36660 |                const Type   c = cov->c(); 
 36661 |                const Type& v0 = cov->v(); 
 36662 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 36663 |                const details::operator_type o0 = cov->operation(); 
 36664 |                const details::operator_type o1 = operation; 
 36665 |  
 36666 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36667 |  
 36668 |                expression_node_ptr result = error_node(); 
 36669 |  
 36670 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36671 |                { 
 36672 |                   // (c / v0) / v1 --> (covov) c / (v0 * v1) 
 36673 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36674 |                   { 
 36675 |                      const bool synthesis_result = 
 36676 |                         synthesize_sf3ext_expression:: 
 36677 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result); 
 36678 |  
 36679 |                      exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n")); 
 36680 |  
 36681 |                      return (synthesis_result) ? result : error_node(); 
 36682 |                   } 
 36683 |                } 
 36684 |  
 36685 |                const bool synthesis_result = 
 36686 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, vtype> 
 36687 |                      (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result); 
 36688 |  
 36689 |                if (synthesis_result) 
 36690 |                   return result; 
 36691 |  
 36692 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36693 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36694 |  
 36695 |                if (!expr_gen.valid_operator(o0,f0)) 
 36696 |                   return error_node(); 
 36697 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36698 |                   return error_node(); 
 36699 |                else 
 36700 |                   return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1); 
 36701 |             } 
 36702 |  
 36703 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36704 |                                          const details::operator_type o0, 
 36705 |                                          const details::operator_type o1) 
 36706 |             { 
 36707 |                return details::build_string() 
 36708 |                   << "(t" << expr_gen.to_str(o0) 
 36709 |                   << "t)" << expr_gen.to_str(o1) 
 36710 |                   << "t" 
 36711 |             } 
 36712 |          }; 
 36713 |  
 36714 |          struct synthesize_covov_expression1 
 36715 |          { 
 36716 |             typedef typename covov_t::type1 node_type; 
 36717 |             typedef typename covov_t::sf3_type sf3_type; 
 36718 |  
 36719 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36720 |                                                       const details::operator_type& operation, 
 36721 |                                                       expression_node_ptr (&branch)[2]) 
 36722 |             { 
 36723 |                // (c) o0 (v0 o1 v1) 
 36724 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 36725 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 36726 |                const Type& v0 = vov->v0(); 
 36727 |                const Type& v1 = vov->v1(); 
 36728 |                const details::operator_type o0 = operation; 
 36729 |                const details::operator_type o1 = vov->operation(); 
 36730 |  
 36731 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36732 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36733 |  
 36734 |                expression_node_ptr result = error_node(); 
 36735 |  
 36736 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36737 |                { 
 36738 |                   // c / (v0 / v1) --> (covov) (c * v1) / v0 
 36739 |                   if ((details::e_div == o0) && (details::e_div == o1)) 
 36740 |                   { 
 36741 |                      const bool synthesis_result = 
 36742 |                         synthesize_sf3ext_expression:: 
 36743 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result); 
 36744 |  
 36745 |                      exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n")); 
 36746 |  
 36747 |                      return (synthesis_result) ? result : error_node(); 
 36748 |                   } 
 36749 |                } 
 36750 |  
 36751 |                const bool synthesis_result = 
 36752 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, vtype> 
 36753 |                      (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result); 
 36754 |  
 36755 |                if (synthesis_result) 
 36756 |                   return result; 
 36757 |  
 36758 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36759 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36760 |  
 36761 |                if (!expr_gen.valid_operator(o0,f0)) 
 36762 |                   return error_node(); 
 36763 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36764 |                   return error_node(); 
 36765 |                else 
 36766 |                   return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1); 
 36767 |             } 
 36768 |  
 36769 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36770 |                                          const details::operator_type o0, 
 36771 |                                          const details::operator_type o1) 
 36772 |             { 
 36773 |                return details::build_string() 
 36774 |                   << "t"  << expr_gen.to_str(o0) 
 36775 |                   << "(t" << expr_gen.to_str(o1) 
 36776 |                   << "t)" 
 36777 |             } 
 36778 |          }; 
 36779 |  
 36780 |          struct synthesize_covoc_expression0 
 36781 |          { 
 36782 |             typedef typename covoc_t::type0 node_type; 
 36783 |             typedef typename covoc_t::sf3_type sf3_type; 
 36784 |  
 36785 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36786 |                                                       const details::operator_type& operation, 
 36787 |                                                       expression_node_ptr (&branch)[2]) 
 36788 |             { 
 36789 |                // (c0 o0 v) o1 (c1) 
 36790 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 36791 |                const Type  c0 = cov->c(); 
 36792 |                const Type&  v = cov->v(); 
 36793 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 36794 |                const details::operator_type o0 = cov->operation(); 
 36795 |                const details::operator_type o1 = operation; 
 36796 |  
 36797 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36798 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36799 |  
 36800 |                expression_node_ptr result = error_node(); 
 36801 |  
 36802 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36803 |                { 
 36804 |                   // (c0 + v) + c1 --> (cov) (c0 + c1) + v 
 36805 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 36806 |                   { 
 36807 |                      exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n")); 
 36808 |  
 36809 |                      return expr_gen.node_allocator_-> 
 36810 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v); 
 36811 |                   } 
 36812 |                   // (c0 + v) - c1 --> (cov) (c0 - c1) + v 
 36813 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 36814 |                   { 
 36815 |                      exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n")); 
 36816 |  
 36817 |                      return expr_gen.node_allocator_-> 
 36818 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v); 
 36819 |                   } 
 36820 |                   // (c0 - v) + c1 --> (cov) (c0 + c1) - v 
 36821 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 36822 |                   { 
 36823 |                      exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n")); 
 36824 |  
 36825 |                      return expr_gen.node_allocator_-> 
 36826 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v); 
 36827 |                   } 
 36828 |                   // (c0 - v) - c1 --> (cov) (c0 - c1) - v 
 36829 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 36830 |                   { 
 36831 |                      exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n")); 
 36832 |  
 36833 |                      return expr_gen.node_allocator_-> 
 36834 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v); 
 36835 |                   } 
 36836 |                   // (c0 * v) * c1 --> (cov) (c0 * c1) * v 
 36837 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 36838 |                   { 
 36839 |                      exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n")); 
 36840 |  
 36841 |                      return expr_gen.node_allocator_-> 
 36842 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v); 
 36843 |                   } 
 36844 |                   // (c0 * v) / c1 --> (cov) (c0 / c1) * v 
 36845 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 36846 |                   { 
 36847 |                      exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n")); 
 36848 |  
 36849 |                      return expr_gen.node_allocator_-> 
 36850 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v); 
 36851 |                   } 
 36852 |                   // (c0 / v) * c1 --> (cov) (c0 * c1) / v 
 36853 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 36854 |                   { 
 36855 |                      exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n")); 
 36856 |  
 36857 |                      return expr_gen.node_allocator_-> 
 36858 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v); 
 36859 |                   } 
 36860 |                   // (c0 / v) / c1 --> (cov) (c0 / c1) / v 
 36861 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 36862 |                   { 
 36863 |                      exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n")); 
 36864 |  
 36865 |                      return expr_gen.node_allocator_-> 
 36866 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v); 
 36867 |                   } 
 36868 |                } 
 36869 |  
 36870 |                const bool synthesis_result = 
 36871 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, ctype> 
 36872 |                      (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result); 
 36873 |  
 36874 |                if (synthesis_result) 
 36875 |                   return result; 
 36876 |  
 36877 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36878 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36879 |  
 36880 |                if (!expr_gen.valid_operator(o0,f0)) 
 36881 |                   return error_node(); 
 36882 |                else if (!expr_gen.valid_operator(o1,f1)) 
 36883 |                   return error_node(); 
 36884 |                else 
 36885 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1); 
 36886 |             } 
 36887 |  
 36888 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 36889 |                                          const details::operator_type o0, 
 36890 |                                          const details::operator_type o1) 
 36891 |             { 
 36892 |                return details::build_string() 
 36893 |                   << "(t" << expr_gen.to_str(o0) 
 36894 |                   << "t)" << expr_gen.to_str(o1) 
 36895 |                   << "t" 
 36896 |             } 
 36897 |          }; 
 36898 |  
 36899 |          struct synthesize_covoc_expression1 
 36900 |          { 
 36901 |             typedef typename covoc_t::type1 node_type; 
 36902 |             typedef typename covoc_t::sf3_type sf3_type; 
 36903 |  
 36904 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 36905 |                                                       const details::operator_type& operation, 
 36906 |                                                       expression_node_ptr (&branch)[2]) 
 36907 |             { 
 36908 |                // (c0) o0 (v o1 c1) 
 36909 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 36910 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 36911 |                const Type&  v = voc->v(); 
 36912 |                const Type  c1 = voc->c(); 
 36913 |                const details::operator_type o0 = operation; 
 36914 |                const details::operator_type o1 = voc->operation(); 
 36915 |  
 36916 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 36917 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 36918 |  
 36919 |                expression_node_ptr result = error_node(); 
 36920 |  
 36921 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 36922 |                { 
 36923 |                   // (c0) + (v + c1) --> (cov) (c0 + c1) + v 
 36924 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 36925 |                   { 
 36926 |                      exprtk_debug(("(c0) + (v + c1) --> (cov) (c0 + c1) + v\n")); 
 36927 |  
 36928 |                      return expr_gen.node_allocator_-> 
 36929 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v); 
 36930 |                   } 
 36931 |                   // (c0) + (v - c1) --> (cov) (c0 - c1) + v 
 36932 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 36933 |                   { 
 36934 |                      exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n")); 
 36935 |  
 36936 |                      return expr_gen.node_allocator_-> 
 36937 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v); 
 36938 |                   } 
 36939 |                   // (c0) - (v + c1) --> (cov) (c0 - c1) - v 
 36940 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 36941 |                   { 
 36942 |                      exprtk_debug(("(c0) - (v + c1) --> (cov) (c0 - c1) - v\n")); 
 36943 |  
 36944 |                      return expr_gen.node_allocator_-> 
 36945 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v); 
 36946 |                   } 
 36947 |                   // (c0) - (v - c1) --> (cov) (c0 + c1) - v 
 36948 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 36949 |                   { 
 36950 |                      exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n")); 
 36951 |  
 36952 |                      return expr_gen.node_allocator_-> 
 36953 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v); 
 36954 |                   } 
 36955 |                   // (c0) * (v * c1) --> (voc) v * (c0 * c1) 
 36956 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 36957 |                   { 
 36958 |                      exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\n")); 
 36959 |  
 36960 |                      return expr_gen.node_allocator_-> 
 36961 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v); 
 36962 |                   } 
 36963 |                   // (c0) * (v / c1) --> (cov) (c0 / c1) * v 
 36964 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 36965 |                   { 
 36966 |                      exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n")); 
 36967 |  
 36968 |                      return expr_gen.node_allocator_-> 
 36969 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v); 
 36970 |                   } 
 36971 |                   // (c0) / (v * c1) --> (cov) (c0 / c1) / v 
 36972 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 36973 |                   { 
 36974 |                      exprtk_debug(("(c0) / (v * c1) --> (cov) (c0 / c1) / v\n")); 
 36975 |  
 36976 |                      return expr_gen.node_allocator_-> 
 36977 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v); 
 36978 |                   } 
 36979 |                   // (c0) / (v / c1) --> (cov) (c0 * c1) / v 
 36980 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 36981 |                   { 
 36982 |                      exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n")); 
 36983 |  
 36984 |                      return expr_gen.node_allocator_-> 
 36985 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v); 
 36986 |                   } 
 36987 |                } 
 36988 |  
 36989 |                const bool synthesis_result = 
 36990 |                   synthesize_sf3ext_expression::template compile<ctype, vtype, ctype> 
 36991 |                      (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result); 
 36992 |  
 36993 |                if (synthesis_result) 
 36994 |                   return result; 
 36995 |  
 36996 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 36997 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 36998 |  
 36999 |                if (!expr_gen.valid_operator(o0,f0)) 
 37000 |                   return error_node(); 
 37001 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37002 |                   return error_node(); 
 37003 |                else 
 37004 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1); 
 37005 |             } 
 37006 |  
 37007 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37008 |                                          const details::operator_type o0, 
 37009 |                                          const details::operator_type o1) 
 37010 |             { 
 37011 |                return details::build_string() 
 37012 |                   << "t"  << expr_gen.to_str(o0) 
 37013 |                   << "(t" << expr_gen.to_str(o1) 
 37014 |                   << "t)" 
 37015 |             } 
 37016 |          }; 
 37017 |  
 37018 |          struct synthesize_cocov_expression0 
 37019 |          { 
 37020 |             typedef typename cocov_t::type0 node_type; 
 37021 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 37022 |                                                       const details::operator_type&, 
 37023 |                                                       expression_node_ptr (&)[2]) 
 37024 |             { 
 37025 |                // (c0 o0 c1) o1 (v) - Not possible. 
 37026 |                return error_node(); 
 37027 |             } 
 37028 |          }; 
 37029 |  
 37030 |          struct synthesize_cocov_expression1 
 37031 |          { 
 37032 |             typedef typename cocov_t::type1 node_type; 
 37033 |             typedef typename cocov_t::sf3_type sf3_type; 
 37034 |  
 37035 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37036 |                                                       const details::operator_type& operation, 
 37037 |                                                       expression_node_ptr (&branch)[2]) 
 37038 |             { 
 37039 |                // (c0) o0 (c1 o1 v) 
 37040 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 37041 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 37042 |                const Type  c1 = cov->c(); 
 37043 |                const Type&  v = cov->v(); 
 37044 |                const details::operator_type o0 = operation; 
 37045 |                const details::operator_type o1 = cov->operation(); 
 37046 |  
 37047 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37048 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37049 |  
 37050 |                expression_node_ptr result = error_node(); 
 37051 |  
 37052 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37053 |                { 
 37054 |                   // (c0) + (c1 + v) --> (cov) (c0 + c1) + v 
 37055 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 37056 |                   { 
 37057 |                      exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n")); 
 37058 |  
 37059 |                      return expr_gen.node_allocator_-> 
 37060 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v); 
 37061 |                   } 
 37062 |                   // (c0) + (c1 - v) --> (cov) (c0 + c1) - v 
 37063 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 37064 |                   { 
 37065 |                      exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n")); 
 37066 |  
 37067 |                      return expr_gen.node_allocator_-> 
 37068 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v); 
 37069 |                   } 
 37070 |                   // (c0) - (c1 + v) --> (cov) (c0 - c1) - v 
 37071 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 37072 |                   { 
 37073 |                      exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n")); 
 37074 |  
 37075 |                      return expr_gen.node_allocator_-> 
 37076 |                                template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v); 
 37077 |                   } 
 37078 |                   // (c0) - (c1 - v) --> (cov) (c0 - c1) + v 
 37079 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 37080 |                   { 
 37081 |                      exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n")); 
 37082 |  
 37083 |                      return expr_gen.node_allocator_-> 
 37084 |                                template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v); 
 37085 |                   } 
 37086 |                   // (c0) * (c1 * v) --> (cov) (c0 * c1) * v 
 37087 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 37088 |                   { 
 37089 |                      exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n")); 
 37090 |  
 37091 |                      return expr_gen.node_allocator_-> 
 37092 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v); 
 37093 |                   } 
 37094 |                   // (c0) * (c1 / v) --> (cov) (c0 * c1) / v 
 37095 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 37096 |                   { 
 37097 |                      exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n")); 
 37098 |  
 37099 |                      return expr_gen.node_allocator_-> 
 37100 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v); 
 37101 |                   } 
 37102 |                   // (c0) / (c1 * v) --> (cov) (c0 / c1) / v 
 37103 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 37104 |                   { 
 37105 |                      exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n")); 
 37106 |  
 37107 |                      return expr_gen.node_allocator_-> 
 37108 |                                template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v); 
 37109 |                   } 
 37110 |                   // (c0) / (c1 / v) --> (cov) (c0 / c1) * v 
 37111 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 37112 |                   { 
 37113 |                      exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n")); 
 37114 |  
 37115 |                      return expr_gen.node_allocator_-> 
 37116 |                                template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v); 
 37117 |                   } 
 37118 |                } 
 37119 |  
 37120 |                const bool synthesis_result = 
 37121 |                   synthesize_sf3ext_expression::template compile<ctype, ctype, vtype> 
 37122 |                      (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result); 
 37123 |  
 37124 |                if (synthesis_result) 
 37125 |                   return result; 
 37126 |  
 37127 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37128 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37129 |  
 37130 |                if (!expr_gen.valid_operator(o0,f0)) 
 37131 |                   return error_node(); 
 37132 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37133 |                   return error_node(); 
 37134 |                else 
 37135 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1); 
 37136 |             } 
 37137 |  
 37138 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37139 |                                          const details::operator_type o0, 
 37140 |                                          const details::operator_type o1) 
 37141 |             { 
 37142 |                return details::build_string() 
 37143 |                   << "t"  << expr_gen.to_str(o0) 
 37144 |                   << "(t" << expr_gen.to_str(o1) 
 37145 |                   << "t)" 
 37146 |             } 
 37147 |          }; 
 37148 |  
 37149 |          struct synthesize_vococ_expression0 
 37150 |          { 
 37151 |             typedef typename vococ_t::type0 node_type; 
 37152 |             typedef typename vococ_t::sf3_type sf3_type; 
 37153 |  
 37154 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37155 |                                                       const details::operator_type& operation, 
 37156 |                                                       expression_node_ptr (&branch)[2]) 
 37157 |             { 
 37158 |                // (v o0 c0) o1 (c1) 
 37159 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 37160 |                const Type&  v = voc->v(); 
 37161 |                const Type& c0 = voc->c(); 
 37162 |                const Type& c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 37163 |                const details::operator_type o0 = voc->operation(); 
 37164 |                const details::operator_type o1 = operation; 
 37165 |  
 37166 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37167 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37168 |  
 37169 |                expression_node_ptr result = error_node(); 
 37170 |  
 37171 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37172 |                { 
 37173 |                   // (v + c0) + c1 --> (voc) v + (c0 + c1) 
 37174 |                   if ((details::e_add == o0) && (details::e_add == o1)) 
 37175 |                   { 
 37176 |                      exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n")); 
 37177 |  
 37178 |                      return expr_gen.node_allocator_-> 
 37179 |                                template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1); 
 37180 |                   } 
 37181 |                   // (v + c0) - c1 --> (voc) v + (c0 - c1) 
 37182 |                   else if ((details::e_add == o0) && (details::e_sub == o1)) 
 37183 |                   { 
 37184 |                      exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n")); 
 37185 |  
 37186 |                      return expr_gen.node_allocator_-> 
 37187 |                                template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1); 
 37188 |                   } 
 37189 |                   // (v - c0) + c1 --> (voc) v - (c0 + c1) 
 37190 |                   else if ((details::e_sub == o0) && (details::e_add == o1)) 
 37191 |                   { 
 37192 |                      exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n")); 
 37193 |  
 37194 |                      return expr_gen.node_allocator_-> 
 37195 |                                template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0); 
 37196 |                   } 
 37197 |                   // (v - c0) - c1 --> (voc) v - (c0 + c1) 
 37198 |                   else if ((details::e_sub == o0) && (details::e_sub == o1)) 
 37199 |                   { 
 37200 |                      exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n")); 
 37201 |  
 37202 |                      return expr_gen.node_allocator_-> 
 37203 |                                template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1); 
 37204 |                   } 
 37205 |                   // (v * c0) * c1 --> (voc) v * (c0 * c1) 
 37206 |                   else if ((details::e_mul == o0) && (details::e_mul == o1)) 
 37207 |                   { 
 37208 |                      exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n")); 
 37209 |  
 37210 |                      return expr_gen.node_allocator_-> 
 37211 |                                template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1); 
 37212 |                   } 
 37213 |                   // (v * c0) / c1 --> (voc) v * (c0 / c1) 
 37214 |                   else if ((details::e_mul == o0) && (details::e_div == o1)) 
 37215 |                   { 
 37216 |                      exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n")); 
 37217 |  
 37218 |                      return expr_gen.node_allocator_-> 
 37219 |                                template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1); 
 37220 |                   } 
 37221 |                   // (v / c0) * c1 --> (voc) v * (c1 / c0) 
 37222 |                   else if ((details::e_div == o0) && (details::e_mul == o1)) 
 37223 |                   { 
 37224 |                      exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n")); 
 37225 |  
 37226 |                      return expr_gen.node_allocator_-> 
 37227 |                                template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0); 
 37228 |                   } 
 37229 |                   // (v / c0) / c1 --> (voc) v / (c0 * c1) 
 37230 |                   else if ((details::e_div == o0) && (details::e_div == o1)) 
 37231 |                   { 
 37232 |                      exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n")); 
 37233 |  
 37234 |                      return expr_gen.node_allocator_-> 
 37235 |                                template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1); 
 37236 |                   } 
 37237 |                   // (v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1) 
 37238 |                   else if ((details::e_pow == o0) && (details::e_pow == o1)) 
 37239 |                   { 
 37240 |                      exprtk_debug(("(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n")); 
 37241 |  
 37242 |                      return expr_gen.node_allocator_-> 
 37243 |                                template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1); 
 37244 |                   } 
 37245 |                } 
 37246 |  
 37247 |                const bool synthesis_result = 
 37248 |                   synthesize_sf3ext_expression::template compile<vtype, ctype, ctype> 
 37249 |                      (expr_gen, id(expr_gen, o0, o1), v, c0, c1, result); 
 37250 |  
 37251 |                if (synthesis_result) 
 37252 |                   return result; 
 37253 |  
 37254 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37255 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37256 |  
 37257 |                if (!expr_gen.valid_operator(o0,f0)) 
 37258 |                   return error_node(); 
 37259 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37260 |                   return error_node(); 
 37261 |                else 
 37262 |                   return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1); 
 37263 |             } 
 37264 |  
 37265 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37266 |                                          const details::operator_type o0, 
 37267 |                                          const details::operator_type o1) 
 37268 |             { 
 37269 |                return details::build_string() 
 37270 |                   << "(t" << expr_gen.to_str(o0) 
 37271 |                   << "t)" << expr_gen.to_str(o1) 
 37272 |                   << "t" 
 37273 |             } 
 37274 |          }; 
 37275 |  
 37276 |          struct synthesize_vococ_expression1 
 37277 |          { 
 37278 |             typedef typename vococ_t::type0 node_type; 
 37279 |  
 37280 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 37281 |                                                       const details::operator_type&, 
 37282 |                                                       expression_node_ptr (&)[2]) 
 37283 |             { 
 37284 |                // (v) o0 (c0 o1 c1) - Not possible. 
 37285 |                exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n")); 
 37286 |                return error_node(); 
 37287 |             } 
 37288 |          }; 
 37289 |  
 37290 |          struct synthesize_vovovov_expression0 
 37291 |          { 
 37292 |             typedef typename vovovov_t::type0 node_type; 
 37293 |             typedef typename vovovov_t::sf4_type sf4_type; 
 37294 |             typedef typename node_type::T0 T0; 
 37295 |             typedef typename node_type::T1 T1; 
 37296 |             typedef typename node_type::T2 T2; 
 37297 |             typedef typename node_type::T3 T3; 
 37298 |  
 37299 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37300 |                                                       const details::operator_type& operation, 
 37301 |                                                       expression_node_ptr (&branch)[2]) 
 37302 |             { 
 37303 |                // (v0 o0 v1) o1 (v2 o2 v3) 
 37304 |                const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 37305 |                const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 37306 |                const Type& v0 = vov0->v0(); 
 37307 |                const Type& v1 = vov0->v1(); 
 37308 |                const Type& v2 = vov1->v0(); 
 37309 |                const Type& v3 = vov1->v1(); 
 37310 |                const details::operator_type o0 = vov0->operation(); 
 37311 |                const details::operator_type o1 = operation; 
 37312 |                const details::operator_type o2 = vov1->operation(); 
 37313 |  
 37314 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37315 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37316 |  
 37317 |                expression_node_ptr result = error_node(); 
 37318 |  
 37319 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37320 |                { 
 37321 |                   // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3) 
 37322 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37323 |                   { 
 37324 |                      const bool synthesis_result = 
 37325 |                         synthesize_sf4ext_expression:: 
 37326 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result); 
 37327 |  
 37328 |                      exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n")); 
 37329 |  
 37330 |                      return (synthesis_result) ? result : error_node(); 
 37331 |                   } 
 37332 |                   // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2) 
 37333 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37334 |                   { 
 37335 |                      const bool synthesis_result = 
 37336 |                         synthesize_sf4ext_expression:: 
 37337 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result); 
 37338 |  
 37339 |                      exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n")); 
 37340 |  
 37341 |                      return (synthesis_result) ? result : error_node(); 
 37342 |                   } 
 37343 |                   // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2) 
 37344 |                   else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37345 |                   { 
 37346 |                      const bool synthesis_result = 
 37347 |                         synthesize_sf4ext_expression:: 
 37348 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result); 
 37349 |  
 37350 |                      exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n")); 
 37351 |  
 37352 |                      return (synthesis_result) ? result : error_node(); 
 37353 |                   } 
 37354 |                   // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2) 
 37355 |                   else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37356 |                   { 
 37357 |                      const bool synthesis_result = 
 37358 |                         synthesize_sf4ext_expression:: 
 37359 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result); 
 37360 |  
 37361 |                      exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n")); 
 37362 |  
 37363 |                      return (synthesis_result) ? result : error_node(); 
 37364 |                   } 
 37365 |                   // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2 
 37366 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37367 |                   { 
 37368 |                      const bool synthesis_result = 
 37369 |                         synthesize_sf4ext_expression:: 
 37370 |                            template compile<vtype, vtype, vtype, vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result); 
 37371 |  
 37372 |                      exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n")); 
 37373 |  
 37374 |                      return (synthesis_result) ? result : error_node(); 
 37375 |                   } 
 37376 |                } 
 37377 |  
 37378 |                const bool synthesis_result = 
 37379 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37380 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 37381 |  
 37382 |                if (synthesis_result) 
 37383 |                   return result; 
 37384 |  
 37385 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37386 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37387 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37388 |  
 37389 |                if (!expr_gen.valid_operator(o0,f0)) 
 37390 |                   return error_node(); 
 37391 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37392 |                   return error_node(); 
 37393 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37394 |                   return error_node(); 
 37395 |                else 
 37396 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 37397 |             } 
 37398 |  
 37399 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37400 |                                          const details::operator_type o0, 
 37401 |                                          const details::operator_type o1, 
 37402 |                                          const details::operator_type o2) 
 37403 |             { 
 37404 |                return details::build_string() 
 37405 |                   << "(t" << expr_gen.to_str(o0) 
 37406 |                   << "t)" << expr_gen.to_str(o1) 
 37407 |                   << "(t" << expr_gen.to_str(o2) 
 37408 |                   << "t)" 
 37409 |             } 
 37410 |          }; 
 37411 |  
 37412 |          struct synthesize_vovovoc_expression0 
 37413 |          { 
 37414 |             typedef typename vovovoc_t::type0 node_type; 
 37415 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 37416 |             typedef typename node_type::T0 T0; 
 37417 |             typedef typename node_type::T1 T1; 
 37418 |             typedef typename node_type::T2 T2; 
 37419 |             typedef typename node_type::T3 T3; 
 37420 |  
 37421 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37422 |                                                       const details::operator_type& operation, 
 37423 |                                                       expression_node_ptr (&branch)[2]) 
 37424 |             { 
 37425 |                // (v0 o0 v1) o1 (v2 o2 c) 
 37426 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 37427 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 37428 |                const Type& v0 = vov->v0(); 
 37429 |                const Type& v1 = vov->v1(); 
 37430 |                const Type& v2 = voc->v (); 
 37431 |                const Type   c = voc->c (); 
 37432 |                const details::operator_type o0 = vov->operation(); 
 37433 |                const details::operator_type o1 = operation; 
 37434 |                const details::operator_type o2 = voc->operation(); 
 37435 |  
 37436 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37437 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37438 |  
 37439 |                expression_node_ptr result = error_node(); 
 37440 |  
 37441 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37442 |                { 
 37443 |                   // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c) 
 37444 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37445 |                   { 
 37446 |                      const bool synthesis_result = 
 37447 |                         synthesize_sf4ext_expression:: 
 37448 |                            template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result); 
 37449 |  
 37450 |                      exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n")); 
 37451 |  
 37452 |                      return (synthesis_result) ? result : error_node(); 
 37453 |                   } 
 37454 |                   // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2) 
 37455 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37456 |                   { 
 37457 |                      const bool synthesis_result = 
 37458 |                         synthesize_sf4ext_expression:: 
 37459 |                            template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result); 
 37460 |  
 37461 |                      exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n")); 
 37462 |  
 37463 |                      return (synthesis_result) ? result : error_node(); 
 37464 |                   } 
 37465 |                } 
 37466 |  
 37467 |                const bool synthesis_result = 
 37468 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37469 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 37470 |  
 37471 |                if (synthesis_result) 
 37472 |                   return result; 
 37473 |  
 37474 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37475 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37476 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37477 |  
 37478 |                if (!expr_gen.valid_operator(o0,f0)) 
 37479 |                   return error_node(); 
 37480 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37481 |                   return error_node(); 
 37482 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37483 |                   return error_node(); 
 37484 |                else 
 37485 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 37486 |             } 
 37487 |  
 37488 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37489 |                                          const details::operator_type o0, 
 37490 |                                          const details::operator_type o1, 
 37491 |                                          const details::operator_type o2) 
 37492 |             { 
 37493 |                return details::build_string() 
 37494 |                   << "(t" << expr_gen.to_str(o0) 
 37495 |                   << "t)" << expr_gen.to_str(o1) 
 37496 |                   << "(t" << expr_gen.to_str(o2) 
 37497 |                   << "t)" 
 37498 |             } 
 37499 |          }; 
 37500 |  
 37501 |          struct synthesize_vovocov_expression0 
 37502 |          { 
 37503 |             typedef typename vovocov_t::type0 node_type; 
 37504 |             typedef typename vovocov_t::sf4_type sf4_type; 
 37505 |             typedef typename node_type::T0 T0; 
 37506 |             typedef typename node_type::T1 T1; 
 37507 |             typedef typename node_type::T2 T2; 
 37508 |             typedef typename node_type::T3 T3; 
 37509 |  
 37510 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37511 |                                                       const details::operator_type& operation, 
 37512 |                                                       expression_node_ptr (&branch)[2]) 
 37513 |             { 
 37514 |                // (v0 o0 v1) o1 (c o2 v2) 
 37515 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]); 
 37516 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 37517 |                const Type& v0 = vov->v0(); 
 37518 |                const Type& v1 = vov->v1(); 
 37519 |                const Type& v2 = cov->v (); 
 37520 |                const Type   c = cov->c (); 
 37521 |                const details::operator_type o0 = vov->operation(); 
 37522 |                const details::operator_type o1 = operation; 
 37523 |                const details::operator_type o2 = cov->operation(); 
 37524 |  
 37525 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37526 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37527 |  
 37528 |                expression_node_ptr result = error_node(); 
 37529 |  
 37530 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37531 |                { 
 37532 |                   // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2) 
 37533 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37534 |                   { 
 37535 |                      const bool synthesis_result = 
 37536 |                         synthesize_sf4ext_expression:: 
 37537 |                            template compile<vtype, ctype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result); 
 37538 |  
 37539 |                      exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n")); 
 37540 |  
 37541 |                      return (synthesis_result) ? result : error_node(); 
 37542 |                   } 
 37543 |                   // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c) 
 37544 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37545 |                   { 
 37546 |                      const bool synthesis_result = 
 37547 |                         synthesize_sf4ext_expression:: 
 37548 |                            template compile<vtype, vtype, vtype, ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result); 
 37549 |  
 37550 |                      exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n")); 
 37551 |  
 37552 |                      return (synthesis_result) ? result : error_node(); 
 37553 |                   } 
 37554 |                } 
 37555 |  
 37556 |                const bool synthesis_result = 
 37557 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37558 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 37559 |  
 37560 |                if (synthesis_result) 
 37561 |                   return result; 
 37562 |  
 37563 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37564 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37565 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37566 |  
 37567 |                if (!expr_gen.valid_operator(o0,f0)) 
 37568 |                   return error_node(); 
 37569 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37570 |                   return error_node(); 
 37571 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37572 |                   return error_node(); 
 37573 |                else 
 37574 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 37575 |             } 
 37576 |  
 37577 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37578 |                                          const details::operator_type o0, 
 37579 |                                          const details::operator_type o1, 
 37580 |                                          const details::operator_type o2) 
 37581 |             { 
 37582 |                return details::build_string() 
 37583 |                   << "(t" << expr_gen.to_str(o0) 
 37584 |                   << "t)" << expr_gen.to_str(o1) 
 37585 |                   << "(t" << expr_gen.to_str(o2) 
 37586 |                   << "t)" 
 37587 |             } 
 37588 |          }; 
 37589 |  
 37590 |          struct synthesize_vocovov_expression0 
 37591 |          { 
 37592 |             typedef typename vocovov_t::type0 node_type; 
 37593 |             typedef typename vocovov_t::sf4_type sf4_type; 
 37594 |             typedef typename node_type::T0 T0; 
 37595 |             typedef typename node_type::T1 T1; 
 37596 |             typedef typename node_type::T2 T2; 
 37597 |             typedef typename node_type::T3 T3; 
 37598 |  
 37599 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37600 |                                                       const details::operator_type& operation, 
 37601 |                                                       expression_node_ptr (&branch)[2]) 
 37602 |             { 
 37603 |                // (v0 o0 c) o1 (v1 o2 v2) 
 37604 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 37605 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 37606 |                const Type   c = voc->c (); 
 37607 |                const Type& v0 = voc->v (); 
 37608 |                const Type& v1 = vov->v0(); 
 37609 |                const Type& v2 = vov->v1(); 
 37610 |                const details::operator_type o0 = voc->operation(); 
 37611 |                const details::operator_type o1 = operation; 
 37612 |                const details::operator_type o2 = vov->operation(); 
 37613 |  
 37614 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37615 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37616 |  
 37617 |                expression_node_ptr result = error_node(); 
 37618 |  
 37619 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37620 |                { 
 37621 |                   // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2) 
 37622 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37623 |                   { 
 37624 |                      const bool synthesis_result = 
 37625 |                         synthesize_sf4ext_expression:: 
 37626 |                            template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result); 
 37627 |  
 37628 |                      exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n")); 
 37629 |  
 37630 |                      return (synthesis_result) ? result : error_node(); 
 37631 |                   } 
 37632 |                   // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1) 
 37633 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37634 |                   { 
 37635 |                      const bool synthesis_result = 
 37636 |                         synthesize_sf4ext_expression:: 
 37637 |                            template compile<vtype, vtype, ctype, vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result); 
 37638 |  
 37639 |                      exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n")); 
 37640 |  
 37641 |                      return (synthesis_result) ? result : error_node(); 
 37642 |                   } 
 37643 |                } 
 37644 |  
 37645 |                const bool synthesis_result = 
 37646 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37647 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 37648 |  
 37649 |                if (synthesis_result) 
 37650 |                   return result; 
 37651 |  
 37652 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37653 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37654 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37655 |  
 37656 |                if (!expr_gen.valid_operator(o0,f0)) 
 37657 |                   return error_node(); 
 37658 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37659 |                   return error_node(); 
 37660 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37661 |                   return error_node(); 
 37662 |                else 
 37663 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 37664 |             } 
 37665 |  
 37666 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37667 |                                          const details::operator_type o0, 
 37668 |                                          const details::operator_type o1, 
 37669 |                                          const details::operator_type o2) 
 37670 |             { 
 37671 |                return details::build_string() 
 37672 |                   << "(t" << expr_gen.to_str(o0) 
 37673 |                   << "t)" << expr_gen.to_str(o1) 
 37674 |                   << "(t" << expr_gen.to_str(o2) 
 37675 |                   << "t)" 
 37676 |             } 
 37677 |          }; 
 37678 |  
 37679 |          struct synthesize_covovov_expression0 
 37680 |          { 
 37681 |             typedef typename covovov_t::type0 node_type; 
 37682 |             typedef typename covovov_t::sf4_type sf4_type; 
 37683 |             typedef typename node_type::T0 T0; 
 37684 |             typedef typename node_type::T1 T1; 
 37685 |             typedef typename node_type::T2 T2; 
 37686 |             typedef typename node_type::T3 T3; 
 37687 |  
 37688 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37689 |                                                       const details::operator_type& operation, 
 37690 |                                                       expression_node_ptr (&branch)[2]) 
 37691 |             { 
 37692 |                // (c o0 v0) o1 (v1 o2 v2) 
 37693 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 37694 |                const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]); 
 37695 |                const Type   c = cov->c (); 
 37696 |                const Type& v0 = cov->v (); 
 37697 |                const Type& v1 = vov->v0(); 
 37698 |                const Type& v2 = vov->v1(); 
 37699 |                const details::operator_type o0 = cov->operation(); 
 37700 |                const details::operator_type o1 = operation; 
 37701 |                const details::operator_type o2 = vov->operation(); 
 37702 |  
 37703 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37704 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37705 |  
 37706 |                expression_node_ptr result = error_node(); 
 37707 |  
 37708 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37709 |                { 
 37710 |                   // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2) 
 37711 |                   if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37712 |                   { 
 37713 |                      const bool synthesis_result = 
 37714 |                         synthesize_sf4ext_expression:: 
 37715 |                            template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result); 
 37716 |  
 37717 |                      exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n")); 
 37718 |  
 37719 |                      return (synthesis_result) ? result : error_node(); 
 37720 |                   } 
 37721 |                   // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1) 
 37722 |                   if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37723 |                   { 
 37724 |                      const bool synthesis_result = 
 37725 |                         synthesize_sf4ext_expression:: 
 37726 |                            template compile<ctype, vtype, vtype, vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result); 
 37727 |  
 37728 |                      exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n")); 
 37729 |  
 37730 |                      return (synthesis_result) ? result : error_node(); 
 37731 |                   } 
 37732 |                } 
 37733 |  
 37734 |                const bool synthesis_result = 
 37735 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37736 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 37737 |  
 37738 |                if (synthesis_result) 
 37739 |                   return result; 
 37740 |  
 37741 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37742 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37743 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37744 |  
 37745 |                if (!expr_gen.valid_operator(o0,f0)) 
 37746 |                   return error_node(); 
 37747 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37748 |                   return error_node(); 
 37749 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37750 |                   return error_node(); 
 37751 |                else 
 37752 |                   return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 37753 |             } 
 37754 |  
 37755 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37756 |                                          const details::operator_type o0, 
 37757 |                                          const details::operator_type o1, 
 37758 |                                          const details::operator_type o2) 
 37759 |             { 
 37760 |                return details::build_string() 
 37761 |                   << "(t" << expr_gen.to_str(o0) 
 37762 |                   << "t)" << expr_gen.to_str(o1) 
 37763 |                   << "(t" << expr_gen.to_str(o2) 
 37764 |                   << "t)" 
 37765 |             } 
 37766 |          }; 
 37767 |  
 37768 |          struct synthesize_covocov_expression0 
 37769 |          { 
 37770 |             typedef typename covocov_t::type0 node_type; 
 37771 |             typedef typename covocov_t::sf4_type sf4_type; 
 37772 |             typedef typename node_type::T0 T0; 
 37773 |             typedef typename node_type::T1 T1; 
 37774 |             typedef typename node_type::T2 T2; 
 37775 |             typedef typename node_type::T3 T3; 
 37776 |  
 37777 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37778 |                                                       const details::operator_type& operation, 
 37779 |                                                       expression_node_ptr (&branch)[2]) 
 37780 |             { 
 37781 |                // (c0 o0 v0) o1 (c1 o2 v1) 
 37782 |                const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 37783 |                const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 37784 |                const Type  c0 = cov0->c(); 
 37785 |                const Type& v0 = cov0->v(); 
 37786 |                const Type  c1 = cov1->c(); 
 37787 |                const Type& v1 = cov1->v(); 
 37788 |                const details::operator_type o0 = cov0->operation(); 
 37789 |                const details::operator_type o1 = operation; 
 37790 |                const details::operator_type o2 = cov1->operation(); 
 37791 |  
 37792 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37793 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37794 |  
 37795 |                expression_node_ptr result = error_node(); 
 37796 |  
 37797 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37798 |                { 
 37799 |                   // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1 
 37800 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 37801 |                   { 
 37802 |                      const bool synthesis_result = 
 37803 |                         synthesize_sf3ext_expression:: 
 37804 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 37805 |  
 37806 |                      exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 37807 |  
 37808 |                      return (synthesis_result) ? result : error_node(); 
 37809 |                   } 
 37810 |                   // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1 
 37811 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 37812 |                   { 
 37813 |                      const bool synthesis_result = 
 37814 |                         synthesize_sf3ext_expression:: 
 37815 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 37816 |  
 37817 |                      exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 37818 |  
 37819 |                      return (synthesis_result) ? result : error_node(); 
 37820 |                   } 
 37821 |                   // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1 
 37822 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 37823 |                   { 
 37824 |                      const bool synthesis_result = 
 37825 |                         synthesize_sf3ext_expression:: 
 37826 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result); 
 37827 |  
 37828 |                      exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n")); 
 37829 |  
 37830 |                      return (synthesis_result) ? result : error_node(); 
 37831 |                   } 
 37832 |                   // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1 
 37833 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 37834 |                   { 
 37835 |                      const bool synthesis_result = 
 37836 |                         synthesize_sf3ext_expression:: 
 37837 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 37838 |  
 37839 |                      exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 37840 |  
 37841 |                      return (synthesis_result) ? result : error_node(); 
 37842 |                   } 
 37843 |                   // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1) 
 37844 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 37845 |                   { 
 37846 |                      const bool synthesis_result = 
 37847 |                         synthesize_sf3ext_expression:: 
 37848 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 37849 |  
 37850 |                      exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n")); 
 37851 |  
 37852 |                      return (synthesis_result) ? result : error_node(); 
 37853 |                   } 
 37854 |                   // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1) 
 37855 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 37856 |                   { 
 37857 |                      const bool synthesis_result = 
 37858 |                         synthesize_sf3ext_expression:: 
 37859 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result); 
 37860 |  
 37861 |                      exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n")); 
 37862 |  
 37863 |                      return (synthesis_result) ? result : error_node(); 
 37864 |                   } 
 37865 |                   // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0 
 37866 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37867 |                   { 
 37868 |                      const bool synthesis_result = 
 37869 |                         synthesize_sf3ext_expression:: 
 37870 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result); 
 37871 |  
 37872 |                      exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n")); 
 37873 |  
 37874 |                      return (synthesis_result) ? result : error_node(); 
 37875 |                   } 
 37876 |                   // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1) 
 37877 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 37878 |                   { 
 37879 |                      const bool synthesis_result = 
 37880 |                         synthesize_sf3ext_expression:: 
 37881 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result); 
 37882 |  
 37883 |                      exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n")); 
 37884 |  
 37885 |                      return (synthesis_result) ? result : error_node(); 
 37886 |                   } 
 37887 |                   // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1) 
 37888 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 37889 |                   { 
 37890 |                      const bool synthesis_result = 
 37891 |                         synthesize_sf3ext_expression:: 
 37892 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result); 
 37893 |  
 37894 |                      exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n")); 
 37895 |  
 37896 |                      return (synthesis_result) ? result : error_node(); 
 37897 |                   } 
 37898 |                   // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1) 
 37899 |                   else if ( 
 37900 |                             (std::equal_to<T>()(c0,c1)) && 
 37901 |                             (details::e_mul == o0)      && 
 37902 |                             (details::e_mul == o2)      && 
 37903 |                             ( 
 37904 |                               (details::e_add == o1) || 
 37905 |                               (details::e_sub == o1) 
 37906 |                             ) 
 37907 |                           ) 
 37908 |                   { 
 37909 |                      std::string specfunc; 
 37910 |  
 37911 |                      switch (o1) 
 37912 |                      { 
 37913 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 37914 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 37915 |                         default             : return error_node(); 
 37916 |                      } 
 37917 |  
 37918 |                      const bool synthesis_result = 
 37919 |                         synthesize_sf3ext_expression:: 
 37920 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 37921 |  
 37922 |                      exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n")); 
 37923 |  
 37924 |                      return (synthesis_result) ? result : error_node(); 
 37925 |                   } 
 37926 |                } 
 37927 |  
 37928 |                const bool synthesis_result = 
 37929 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 37930 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 37931 |  
 37932 |                if (synthesis_result) 
 37933 |                   return result; 
 37934 |  
 37935 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 37936 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 37937 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 37938 |  
 37939 |                if (!expr_gen.valid_operator(o0,f0)) 
 37940 |                   return error_node(); 
 37941 |                else if (!expr_gen.valid_operator(o1,f1)) 
 37942 |                   return error_node(); 
 37943 |                else if (!expr_gen.valid_operator(o2,f2)) 
 37944 |                   return error_node(); 
 37945 |                else 
 37946 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 37947 |             } 
 37948 |  
 37949 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 37950 |                                          const details::operator_type o0, 
 37951 |                                          const details::operator_type o1, 
 37952 |                                          const details::operator_type o2) 
 37953 |             { 
 37954 |                return details::build_string() 
 37955 |                   << "(t" << expr_gen.to_str(o0) 
 37956 |                   << "t)" << expr_gen.to_str(o1) 
 37957 |                   << "(t" << expr_gen.to_str(o2) 
 37958 |                   << "t)" 
 37959 |             } 
 37960 |          }; 
 37961 |  
 37962 |          struct synthesize_vocovoc_expression0 
 37963 |          { 
 37964 |             typedef typename vocovoc_t::type0 node_type; 
 37965 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 37966 |             typedef typename node_type::T0 T0; 
 37967 |             typedef typename node_type::T1 T1; 
 37968 |             typedef typename node_type::T2 T2; 
 37969 |             typedef typename node_type::T3 T3; 
 37970 |  
 37971 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 37972 |                                                       const details::operator_type& operation, 
 37973 |                                                       expression_node_ptr (&branch)[2]) 
 37974 |             { 
 37975 |                // (v0 o0 c0) o1 (v1 o2 c1) 
 37976 |                const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 37977 |                const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 37978 |                const Type  c0 = voc0->c(); 
 37979 |                const Type& v0 = voc0->v(); 
 37980 |                const Type  c1 = voc1->c(); 
 37981 |                const Type& v1 = voc1->v(); 
 37982 |                const details::operator_type o0 = voc0->operation(); 
 37983 |                const details::operator_type o1 = operation; 
 37984 |                const details::operator_type o2 = voc1->operation(); 
 37985 |  
 37986 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 37987 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 37988 |  
 37989 |                expression_node_ptr result = error_node(); 
 37990 |  
 37991 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 37992 |                { 
 37993 |                   // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1 
 37994 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 37995 |                   { 
 37996 |                      const bool synthesis_result = 
 37997 |                         synthesize_sf3ext_expression:: 
 37998 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 37999 |  
 38000 |                      exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 38001 |  
 38002 |                      return (synthesis_result) ? result : error_node(); 
 38003 |                   } 
 38004 |                   // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1 
 38005 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 38006 |                   { 
 38007 |                      const bool synthesis_result = 
 38008 |                         synthesize_sf3ext_expression:: 
 38009 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 38010 |  
 38011 |                      exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 38012 |  
 38013 |                      return (synthesis_result) ? result : error_node(); 
 38014 |                   } 
 38015 |                   // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1 
 38016 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 38017 |                   { 
 38018 |                      const bool synthesis_result = 
 38019 |                         synthesize_sf3ext_expression:: 
 38020 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result); 
 38021 |  
 38022 |                      exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n")); 
 38023 |  
 38024 |                      return (synthesis_result) ? result : error_node(); 
 38025 |                   } 
 38026 |                   // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1 
 38027 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 38028 |                   { 
 38029 |                      const bool synthesis_result = 
 38030 |                         synthesize_sf3ext_expression:: 
 38031 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 38032 |  
 38033 |                      exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 38034 |  
 38035 |                      return (synthesis_result) ? result : error_node(); 
 38036 |                   } 
 38037 |                   // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1) 
 38038 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38039 |                   { 
 38040 |                      const bool synthesis_result = 
 38041 |                         synthesize_sf3ext_expression:: 
 38042 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 38043 |  
 38044 |                      exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n")); 
 38045 |  
 38046 |                      return (synthesis_result) ? result : error_node(); 
 38047 |                   } 
 38048 |                   // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1 
 38049 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 38050 |                   { 
 38051 |                      const bool synthesis_result = 
 38052 |                         synthesize_sf3ext_expression:: 
 38053 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result); 
 38054 |  
 38055 |                      exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n")); 
 38056 |  
 38057 |                      return (synthesis_result) ? result : error_node(); 
 38058 |                   } 
 38059 |                   // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1 
 38060 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38061 |                   { 
 38062 |                      const bool synthesis_result = 
 38063 |                         synthesize_sf3ext_expression:: 
 38064 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result); 
 38065 |  
 38066 |                      exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n")); 
 38067 |  
 38068 |                      return (synthesis_result) ? result : error_node(); 
 38069 |                   } 
 38070 |                   // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1) 
 38071 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38072 |                   { 
 38073 |                      const bool synthesis_result = 
 38074 |                         synthesize_sf3ext_expression:: 
 38075 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result); 
 38076 |  
 38077 |                      exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n")); 
 38078 |  
 38079 |                      return (synthesis_result) ? result : error_node(); 
 38080 |                   } 
 38081 |                   // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1 
 38082 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38083 |                   { 
 38084 |                      const bool synthesis_result = 
 38085 |                         synthesize_sf3ext_expression:: 
 38086 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result); 
 38087 |  
 38088 |                      exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n")); 
 38089 |  
 38090 |                      return (synthesis_result) ? result : error_node(); 
 38091 |                   } 
 38092 |                   // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1) 
 38093 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2)) 
 38094 |                   { 
 38095 |                      const bool synthesis_result = 
 38096 |                         synthesize_sf4ext_expression:: 
 38097 |                            template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result); 
 38098 |  
 38099 |                      exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n")); 
 38100 |  
 38101 |                      return (synthesis_result) ? result : error_node(); 
 38102 |                   } 
 38103 |                   // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1) 
 38104 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2)) 
 38105 |                   { 
 38106 |                      const bool synthesis_result = 
 38107 |                         synthesize_sf4ext_expression:: 
 38108 |                            template compile<vtype, ctype, vtype, ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result); 
 38109 |  
 38110 |                      exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n")); 
 38111 |  
 38112 |                      return (synthesis_result) ? result : error_node(); 
 38113 |                   } 
 38114 |                   // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1) 
 38115 |                   else if ( 
 38116 |                             (std::equal_to<T>()(c0,c1)) && 
 38117 |                             (details::e_mul == o0)      && 
 38118 |                             (details::e_mul == o2)      && 
 38119 |                             ( 
 38120 |                               (details::e_add == o1) || 
 38121 |                               (details::e_sub == o1) 
 38122 |                             ) 
 38123 |                           ) 
 38124 |                   { 
 38125 |                      std::string specfunc; 
 38126 |  
 38127 |                      switch (o1) 
 38128 |                      { 
 38129 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 38130 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 38131 |                         default             : return error_node(); 
 38132 |                      } 
 38133 |  
 38134 |                      const bool synthesis_result = 
 38135 |                         synthesize_sf3ext_expression:: 
 38136 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 38137 |  
 38138 |                      exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n")); 
 38139 |  
 38140 |                      return (synthesis_result) ? result : error_node(); 
 38141 |                   } 
 38142 |                   // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c 
 38143 |                   else if ( 
 38144 |                             (std::equal_to<T>()(c0,c1)) && 
 38145 |                             (details::e_div == o0)      && 
 38146 |                             (details::e_div == o2)      && 
 38147 |                             ( 
 38148 |                               (details::e_add == o1) || 
 38149 |                               (details::e_sub == o1) 
 38150 |                             ) 
 38151 |                           ) 
 38152 |                   { 
 38153 |                      std::string specfunc; 
 38154 |  
 38155 |                      switch (o1) 
 38156 |                      { 
 38157 |                         case details::e_add : specfunc = "(t+t)/t" break; 
 38158 |                         case details::e_sub : specfunc = "(t-t)/t" break; 
 38159 |                         default             : return error_node(); 
 38160 |                      } 
 38161 |  
 38162 |                      const bool synthesis_result = 
 38163 |                         synthesize_sf3ext_expression:: 
 38164 |                            template compile<vtype, vtype, ctype>(expr_gen, specfunc, v0, v1, c0, result); 
 38165 |  
 38166 |                      exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n")); 
 38167 |  
 38168 |                      return (synthesis_result) ? result : error_node(); 
 38169 |                   } 
 38170 |                } 
 38171 |  
 38172 |                const bool synthesis_result = 
 38173 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38174 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 38175 |  
 38176 |                if (synthesis_result) 
 38177 |                   return result; 
 38178 |  
 38179 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38180 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 38181 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 38182 |  
 38183 |                if (!expr_gen.valid_operator(o0,f0)) 
 38184 |                   return error_node(); 
 38185 |                else if (!expr_gen.valid_operator(o1,f1)) 
 38186 |                   return error_node(); 
 38187 |                else if (!expr_gen.valid_operator(o2,f2)) 
 38188 |                   return error_node(); 
 38189 |                else 
 38190 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 38191 |             } 
 38192 |  
 38193 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38194 |                                          const details::operator_type o0, 
 38195 |                                          const details::operator_type o1, 
 38196 |                                          const details::operator_type o2) 
 38197 |             { 
 38198 |                return details::build_string() 
 38199 |                   << "(t" << expr_gen.to_str(o0) 
 38200 |                   << "t)" << expr_gen.to_str(o1) 
 38201 |                   << "(t" << expr_gen.to_str(o2) 
 38202 |                   << "t)" 
 38203 |             } 
 38204 |          }; 
 38205 |  
 38206 |          struct synthesize_covovoc_expression0 
 38207 |          { 
 38208 |             typedef typename covovoc_t::type0 node_type; 
 38209 |             typedef typename covovoc_t::sf4_type sf4_type; 
 38210 |             typedef typename node_type::T0 T0; 
 38211 |             typedef typename node_type::T1 T1; 
 38212 |             typedef typename node_type::T2 T2; 
 38213 |             typedef typename node_type::T3 T3; 
 38214 |  
 38215 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38216 |                                                       const details::operator_type& operation, 
 38217 |                                                       expression_node_ptr (&branch)[2]) 
 38218 |             { 
 38219 |                // (c0 o0 v0) o1 (v1 o2 c1) 
 38220 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]); 
 38221 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]); 
 38222 |                const Type  c0 = cov->c(); 
 38223 |                const Type& v0 = cov->v(); 
 38224 |                const Type  c1 = voc->c(); 
 38225 |                const Type& v1 = voc->v(); 
 38226 |                const details::operator_type o0 = cov->operation(); 
 38227 |                const details::operator_type o1 = operation; 
 38228 |                const details::operator_type o2 = voc->operation(); 
 38229 |  
 38230 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38231 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38232 |  
 38233 |                expression_node_ptr result = error_node(); 
 38234 |  
 38235 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 38236 |                { 
 38237 |                   // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1 
 38238 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 38239 |                   { 
 38240 |                      const bool synthesis_result = 
 38241 |                         synthesize_sf3ext_expression:: 
 38242 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 38243 |  
 38244 |                      exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 38245 |  
 38246 |                      return (synthesis_result) ? result : error_node(); 
 38247 |                   } 
 38248 |                   // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1 
 38249 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 38250 |                   { 
 38251 |                      const bool synthesis_result = 
 38252 |                         synthesize_sf3ext_expression:: 
 38253 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 38254 |  
 38255 |                      exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 38256 |  
 38257 |                      return (synthesis_result) ? result : error_node(); 
 38258 |                   } 
 38259 |                   // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1 
 38260 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 38261 |                   { 
 38262 |                      const bool synthesis_result = 
 38263 |                         synthesize_sf3ext_expression:: 
 38264 |                            template compile<ctype, vtype, vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result); 
 38265 |  
 38266 |                      exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n")); 
 38267 |  
 38268 |                      return (synthesis_result) ? result : error_node(); 
 38269 |                   } 
 38270 |                   // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1 
 38271 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 38272 |                   { 
 38273 |                      const bool synthesis_result = 
 38274 |                         synthesize_sf3ext_expression:: 
 38275 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 38276 |  
 38277 |                      exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 38278 |  
 38279 |                      return (synthesis_result) ? result : error_node(); 
 38280 |                   } 
 38281 |                   // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1) 
 38282 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38283 |                   { 
 38284 |                      const bool synthesis_result = 
 38285 |                         synthesize_sf3ext_expression:: 
 38286 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 38287 |  
 38288 |                      exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n")); 
 38289 |  
 38290 |                      return (synthesis_result) ? result : error_node(); 
 38291 |                   } 
 38292 |                   // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0) 
 38293 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 38294 |                   { 
 38295 |                      const bool synthesis_result = 
 38296 |                         synthesize_sf3ext_expression:: 
 38297 |                            template compile<ctype, vtype, vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result); 
 38298 |  
 38299 |                      exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n")); 
 38300 |  
 38301 |                      return (synthesis_result) ? result : error_node(); 
 38302 |                   } 
 38303 |                   // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1) 
 38304 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38305 |                   { 
 38306 |                      const bool synthesis_result = 
 38307 |                         synthesize_sf3ext_expression:: 
 38308 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result); 
 38309 |  
 38310 |                      exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n")); 
 38311 |  
 38312 |                      return (synthesis_result) ? result : error_node(); 
 38313 |                   } 
 38314 |                   // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1) 
 38315 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38316 |                   { 
 38317 |                      const bool synthesis_result = 
 38318 |                         synthesize_sf3ext_expression:: 
 38319 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result); 
 38320 |  
 38321 |                      exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n")); 
 38322 |  
 38323 |                      return (synthesis_result) ? result : error_node(); 
 38324 |                   } 
 38325 |                   // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1) 
 38326 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38327 |                   { 
 38328 |                      const bool synthesis_result = 
 38329 |                         synthesize_sf3ext_expression:: 
 38330 |                            template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result); 
 38331 |  
 38332 |                      exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n")); 
 38333 |  
 38334 |                      return (synthesis_result) ? result : error_node(); 
 38335 |                   } 
 38336 |                   // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1) 
 38337 |                   else if ( 
 38338 |                             (std::equal_to<T>()(c0,c1)) && 
 38339 |                             (details::e_mul == o0)      && 
 38340 |                             (details::e_mul == o2)      && 
 38341 |                             ( 
 38342 |                               (details::e_add == o1) || 
 38343 |                               (details::e_sub == o1) 
 38344 |                             ) 
 38345 |                           ) 
 38346 |                   { 
 38347 |                      std::string specfunc; 
 38348 |  
 38349 |                      switch (o1) 
 38350 |                      { 
 38351 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 38352 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 38353 |                         default             : return error_node(); 
 38354 |                      } 
 38355 |  
 38356 |                      const bool synthesis_result = 
 38357 |                         synthesize_sf3ext_expression:: 
 38358 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 38359 |  
 38360 |                      exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n")); 
 38361 |  
 38362 |                      return (synthesis_result) ? result : error_node(); 
 38363 |                   } 
 38364 |                } 
 38365 |  
 38366 |                const bool synthesis_result = 
 38367 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38368 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 38369 |  
 38370 |                if (synthesis_result) 
 38371 |                   return result; 
 38372 |  
 38373 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38374 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 38375 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 38376 |  
 38377 |                if (!expr_gen.valid_operator(o0,f0)) 
 38378 |                   return error_node(); 
 38379 |                else if (!expr_gen.valid_operator(o1,f1)) 
 38380 |                   return error_node(); 
 38381 |                else if (!expr_gen.valid_operator(o2,f2)) 
 38382 |                   return error_node(); 
 38383 |                else 
 38384 |                   return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 38385 |             } 
 38386 |  
 38387 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38388 |                                          const details::operator_type o0, 
 38389 |                                          const details::operator_type o1, 
 38390 |                                          const details::operator_type o2) 
 38391 |             { 
 38392 |                return details::build_string() 
 38393 |                   << "(t" << expr_gen.to_str(o0) 
 38394 |                   << "t)" << expr_gen.to_str(o1) 
 38395 |                   << "(t" << expr_gen.to_str(o2) 
 38396 |                   << "t)" 
 38397 |             } 
 38398 |          }; 
 38399 |  
 38400 |          struct synthesize_vococov_expression0 
 38401 |          { 
 38402 |             typedef typename vococov_t::type0 node_type; 
 38403 |             typedef typename vococov_t::sf4_type sf4_type; 
 38404 |             typedef typename node_type::T0 T0; 
 38405 |             typedef typename node_type::T1 T1; 
 38406 |             typedef typename node_type::T2 T2; 
 38407 |             typedef typename node_type::T3 T3; 
 38408 |  
 38409 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38410 |                                                       const details::operator_type& operation, 
 38411 |                                                       expression_node_ptr (&branch)[2]) 
 38412 |             { 
 38413 |                // (v0 o0 c0) o1 (c1 o2 v1) 
 38414 |                const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]); 
 38415 |                const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]); 
 38416 |                const Type  c0 = voc->c(); 
 38417 |                const Type& v0 = voc->v(); 
 38418 |                const Type  c1 = cov->c(); 
 38419 |                const Type& v1 = cov->v(); 
 38420 |                const details::operator_type o0 = voc->operation(); 
 38421 |                const details::operator_type o1 = operation; 
 38422 |                const details::operator_type o2 = cov->operation(); 
 38423 |  
 38424 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38425 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38426 |  
 38427 |                expression_node_ptr result = error_node(); 
 38428 |  
 38429 |                if (expr_gen.parser_->settings_.strength_reduction_enabled()) 
 38430 |                { 
 38431 |                   // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1 
 38432 |                   if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2)) 
 38433 |                   { 
 38434 |                      const bool synthesis_result = 
 38435 |                         synthesize_sf3ext_expression:: 
 38436 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result); 
 38437 |  
 38438 |                      exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n")); 
 38439 |  
 38440 |                      return (synthesis_result) ? result : error_node(); 
 38441 |                   } 
 38442 |                   // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1 
 38443 |                   else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2)) 
 38444 |                   { 
 38445 |                      const bool synthesis_result = 
 38446 |                         synthesize_sf3ext_expression:: 
 38447 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result); 
 38448 |  
 38449 |                      exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n")); 
 38450 |  
 38451 |                      return (synthesis_result) ? result : error_node(); 
 38452 |                   } 
 38453 |                   // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0) 
 38454 |                   else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2)) 
 38455 |                   { 
 38456 |                      const bool synthesis_result = 
 38457 |                         synthesize_sf3ext_expression:: 
 38458 |                            template compile<vtype, vtype, ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result); 
 38459 |  
 38460 |                      exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n")); 
 38461 |  
 38462 |                      return (synthesis_result) ? result : error_node(); 
 38463 |                   } 
 38464 |                   // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1 
 38465 |                   else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2)) 
 38466 |                   { 
 38467 |                      const bool synthesis_result = 
 38468 |                         synthesize_sf3ext_expression:: 
 38469 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result); 
 38470 |  
 38471 |                      exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n")); 
 38472 |  
 38473 |                      return (synthesis_result) ? result : error_node(); 
 38474 |                   } 
 38475 |                   // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1) 
 38476 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38477 |                   { 
 38478 |                      const bool synthesis_result = 
 38479 |                         synthesize_sf3ext_expression:: 
 38480 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result); 
 38481 |  
 38482 |                      exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n")); 
 38483 |  
 38484 |                      return (synthesis_result) ? result : error_node(); 
 38485 |                   } 
 38486 |                   // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1) 
 38487 |                   else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) 
 38488 |                   { 
 38489 |                      const bool synthesis_result = 
 38490 |                         synthesize_sf3ext_expression:: 
 38491 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result); 
 38492 |  
 38493 |                      exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n")); 
 38494 |  
 38495 |                      return (synthesis_result) ? result : error_node(); 
 38496 |                   } 
 38497 |                   // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1) 
 38498 |                   else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38499 |                   { 
 38500 |                      const bool synthesis_result = 
 38501 |                         synthesize_sf3ext_expression:: 
 38502 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result); 
 38503 |  
 38504 |                      exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n")); 
 38505 |  
 38506 |                      return (synthesis_result) ? result : error_node(); 
 38507 |                   } 
 38508 |                   // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1) 
 38509 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2)) 
 38510 |                   { 
 38511 |                      const bool synthesis_result = 
 38512 |                         synthesize_sf3ext_expression:: 
 38513 |                            template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result); 
 38514 |  
 38515 |                      exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n")); 
 38516 |  
 38517 |                      return (synthesis_result) ? result : error_node(); 
 38518 |                   } 
 38519 |                   // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1)) 
 38520 |                   else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) 
 38521 |                   { 
 38522 |                      const bool synthesis_result = 
 38523 |                         synthesize_sf3ext_expression:: 
 38524 |                            template compile<vtype, vtype, ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result); 
 38525 |  
 38526 |                      exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n")); 
 38527 |  
 38528 |                      return (synthesis_result) ? result : error_node(); 
 38529 |                   } 
 38530 |                   // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1) 
 38531 |                   else if ( 
 38532 |                             (std::equal_to<T>()(c0,c1)) && 
 38533 |                             (details::e_mul == o0)      && 
 38534 |                             (details::e_mul == o2)      && 
 38535 |                             ( 
 38536 |                               (details::e_add == o1) || (details::e_sub == o1) 
 38537 |                             ) 
 38538 |                           ) 
 38539 |                   { 
 38540 |                      std::string specfunc; 
 38541 |  
 38542 |                      switch (o1) 
 38543 |                      { 
 38544 |                         case details::e_add : specfunc = "t*(t+t)" break; 
 38545 |                         case details::e_sub : specfunc = "t*(t-t)" break; 
 38546 |                         default             : return error_node(); 
 38547 |                      } 
 38548 |  
 38549 |                      const bool synthesis_result = 
 38550 |                         synthesize_sf3ext_expression:: 
 38551 |                            template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result); 
 38552 |  
 38553 |                      exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n")); 
 38554 |  
 38555 |                      return (synthesis_result) ? result : error_node(); 
 38556 |                   } 
 38557 |                } 
 38558 |  
 38559 |                const bool synthesis_result = 
 38560 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38561 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result); 
 38562 |  
 38563 |                if (synthesis_result) 
 38564 |                   return result; 
 38565 |  
 38566 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38567 |                binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0); 
 38568 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 38569 |  
 38570 |                if (!expr_gen.valid_operator(o0,f0)) 
 38571 |                   return error_node(); 
 38572 |                else if (!expr_gen.valid_operator(o1,f1)) 
 38573 |                   return error_node(); 
 38574 |                else if (!expr_gen.valid_operator(o2,f2)) 
 38575 |                   return error_node(); 
 38576 |                else 
 38577 |                   return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2); 
 38578 |             } 
 38579 |  
 38580 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38581 |                                          const details::operator_type o0, 
 38582 |                                          const details::operator_type o1, 
 38583 |                                          const details::operator_type o2) 
 38584 |             { 
 38585 |                return details::build_string() 
 38586 |                   << "(t" << expr_gen.to_str(o0) 
 38587 |                   << "t)" << expr_gen.to_str(o1) 
 38588 |                   << "(t" << expr_gen.to_str(o2) 
 38589 |                   << "t)" 
 38590 |             } 
 38591 |          }; 
 38592 |  
 38593 |          struct synthesize_vovovov_expression1 
 38594 |          { 
 38595 |             typedef typename vovovov_t::type1 node_type; 
 38596 |             typedef typename vovovov_t::sf4_type sf4_type; 
 38597 |             typedef typename node_type::T0 T0; 
 38598 |             typedef typename node_type::T1 T1; 
 38599 |             typedef typename node_type::T2 T2; 
 38600 |             typedef typename node_type::T3 T3; 
 38601 |  
 38602 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38603 |                                                       const details::operator_type& operation, 
 38604 |                                                       expression_node_ptr (&branch)[2]) 
 38605 |             { 
 38606 |                // v0 o0 (v1 o1 (v2 o2 v3)) 
 38607 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 38608 |  
 38609 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 38610 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38611 |                const Type& v1 = vovov->t0(); 
 38612 |                const Type& v2 = vovov->t1(); 
 38613 |                const Type& v3 = vovov->t2(); 
 38614 |                const details::operator_type o0 = operation; 
 38615 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 38616 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 38617 |  
 38618 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38619 |                binary_functor_t f1 = vovov->f0(); 
 38620 |                binary_functor_t f2 = vovov->f1(); 
 38621 |  
 38622 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38623 |  
 38624 |                expression_node_ptr result = error_node(); 
 38625 |  
 38626 |                const bool synthesis_result = 
 38627 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38628 |                      (expr_gen,id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 38629 |  
 38630 |                if (synthesis_result) 
 38631 |                   return result; 
 38632 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38633 |                   return error_node(); 
 38634 |  
 38635 |                exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n")); 
 38636 |  
 38637 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 38638 |             } 
 38639 |  
 38640 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38641 |                                          const details::operator_type o0, 
 38642 |                                          const details::operator_type o1, 
 38643 |                                          const details::operator_type o2) 
 38644 |             { 
 38645 |                return details::build_string() 
 38646 |                   << "t"  << expr_gen.to_str(o0) 
 38647 |                   << "(t" << expr_gen.to_str(o1) 
 38648 |                   << "(t" << expr_gen.to_str(o2) 
 38649 |                   << "t))" 
 38650 |             } 
 38651 |          }; 
 38652 |  
 38653 |          struct synthesize_vovovoc_expression1 
 38654 |          { 
 38655 |             typedef typename vovovoc_t::type1 node_type; 
 38656 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 38657 |             typedef typename node_type::T0 T0; 
 38658 |             typedef typename node_type::T1 T1; 
 38659 |             typedef typename node_type::T2 T2; 
 38660 |             typedef typename node_type::T3 T3; 
 38661 |  
 38662 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38663 |                                                       const details::operator_type& operation, 
 38664 |                                                       expression_node_ptr (&branch)[2]) 
 38665 |             { 
 38666 |                // v0 o0 (v1 o1 (v2 o2 c)) 
 38667 |                typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t; 
 38668 |  
 38669 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 38670 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38671 |                const Type& v1 = vovoc->t0(); 
 38672 |                const Type& v2 = vovoc->t1(); 
 38673 |                const Type   c = vovoc->t2(); 
 38674 |                const details::operator_type o0 = operation; 
 38675 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 38676 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 38677 |  
 38678 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38679 |                binary_functor_t f1 = vovoc->f0(); 
 38680 |                binary_functor_t f2 = vovoc->f1(); 
 38681 |  
 38682 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38683 |  
 38684 |                expression_node_ptr result = error_node(); 
 38685 |  
 38686 |                const bool synthesis_result = 
 38687 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38688 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 38689 |  
 38690 |                if (synthesis_result) 
 38691 |                   return result; 
 38692 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38693 |                   return error_node(); 
 38694 |  
 38695 |                exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n")); 
 38696 |  
 38697 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 38698 |             } 
 38699 |  
 38700 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38701 |                                          const details::operator_type o0, 
 38702 |                                          const details::operator_type o1, 
 38703 |                                          const details::operator_type o2) 
 38704 |             { 
 38705 |                return details::build_string() 
 38706 |                   << "t"  << expr_gen.to_str(o0) 
 38707 |                   << "(t" << expr_gen.to_str(o1) 
 38708 |                   << "(t" << expr_gen.to_str(o2) 
 38709 |                   << "t))" 
 38710 |             } 
 38711 |          }; 
 38712 |  
 38713 |          struct synthesize_vovocov_expression1 
 38714 |          { 
 38715 |             typedef typename vovocov_t::type1 node_type; 
 38716 |             typedef typename vovocov_t::sf4_type sf4_type; 
 38717 |             typedef typename node_type::T0 T0; 
 38718 |             typedef typename node_type::T1 T1; 
 38719 |             typedef typename node_type::T2 T2; 
 38720 |             typedef typename node_type::T3 T3; 
 38721 |  
 38722 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38723 |                                                       const details::operator_type& operation, 
 38724 |                                                       expression_node_ptr (&branch)[2]) 
 38725 |             { 
 38726 |                // v0 o0 (v1 o1 (c o2 v2)) 
 38727 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 38728 |  
 38729 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 38730 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38731 |                const Type& v1 = vocov->t0(); 
 38732 |                const Type   c = vocov->t1(); 
 38733 |                const Type& v2 = vocov->t2(); 
 38734 |                const details::operator_type o0 = operation; 
 38735 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 38736 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 38737 |  
 38738 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38739 |                binary_functor_t f1 = vocov->f0(); 
 38740 |                binary_functor_t f2 = vocov->f1(); 
 38741 |  
 38742 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38743 |  
 38744 |                expression_node_ptr result = error_node(); 
 38745 |  
 38746 |                const bool synthesis_result = 
 38747 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38748 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 38749 |  
 38750 |                if (synthesis_result) 
 38751 |                   return result; 
 38752 |                if (!expr_gen.valid_operator(o0,f0)) 
 38753 |                   return error_node(); 
 38754 |  
 38755 |                exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n")); 
 38756 |  
 38757 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 38758 |             } 
 38759 |  
 38760 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38761 |                                          const details::operator_type o0, 
 38762 |                                          const details::operator_type o1, 
 38763 |                                          const details::operator_type o2) 
 38764 |             { 
 38765 |                return details::build_string() 
 38766 |                   << "t"  << expr_gen.to_str(o0) 
 38767 |                   << "(t" << expr_gen.to_str(o1) 
 38768 |                   << "(t" << expr_gen.to_str(o2) 
 38769 |                   << "t))" 
 38770 |             } 
 38771 |          }; 
 38772 |  
 38773 |          struct synthesize_vocovov_expression1 
 38774 |          { 
 38775 |             typedef typename vocovov_t::type1 node_type; 
 38776 |             typedef typename vocovov_t::sf4_type sf4_type; 
 38777 |             typedef typename node_type::T0 T0; 
 38778 |             typedef typename node_type::T1 T1; 
 38779 |             typedef typename node_type::T2 T2; 
 38780 |             typedef typename node_type::T3 T3; 
 38781 |  
 38782 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38783 |                                                       const details::operator_type& operation, 
 38784 |                                                       expression_node_ptr (&branch)[2]) 
 38785 |             { 
 38786 |                // v0 o0 (c o1 (v1 o2 v2)) 
 38787 |                typedef typename synthesize_covov_expression1::node_type lcl_covov_t; 
 38788 |  
 38789 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]); 
 38790 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38791 |                const Type   c = covov->t0(); 
 38792 |                const Type& v1 = covov->t1(); 
 38793 |                const Type& v2 = covov->t2(); 
 38794 |                const details::operator_type o0 = operation; 
 38795 |                const details::operator_type o1 = expr_gen.get_operator(covov->f0()); 
 38796 |                const details::operator_type o2 = expr_gen.get_operator(covov->f1()); 
 38797 |  
 38798 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38799 |                binary_functor_t f1 = covov->f0(); 
 38800 |                binary_functor_t f2 = covov->f1(); 
 38801 |  
 38802 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38803 |  
 38804 |                expression_node_ptr result = error_node(); 
 38805 |  
 38806 |                const bool synthesis_result = 
 38807 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38808 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 38809 |  
 38810 |                if (synthesis_result) 
 38811 |                   return result; 
 38812 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38813 |                   return error_node(); 
 38814 |  
 38815 |                exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n")); 
 38816 |  
 38817 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 38818 |             } 
 38819 |  
 38820 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38821 |                                          const details::operator_type o0, 
 38822 |                                          const details::operator_type o1, 
 38823 |                                          const details::operator_type o2) 
 38824 |             { 
 38825 |                return details::build_string() 
 38826 |                   << "t"  << expr_gen.to_str(o0) 
 38827 |                   << "(t" << expr_gen.to_str(o1) 
 38828 |                   << "(t" << expr_gen.to_str(o2) 
 38829 |                   << "t))" 
 38830 |             } 
 38831 |          }; 
 38832 |  
 38833 |          struct synthesize_covovov_expression1 
 38834 |          { 
 38835 |             typedef typename covovov_t::type1 node_type; 
 38836 |             typedef typename covovov_t::sf4_type sf4_type; 
 38837 |             typedef typename node_type::T0 T0; 
 38838 |             typedef typename node_type::T1 T1; 
 38839 |             typedef typename node_type::T2 T2; 
 38840 |             typedef typename node_type::T3 T3; 
 38841 |  
 38842 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38843 |                                                       const details::operator_type& operation, 
 38844 |                                                       expression_node_ptr (&branch)[2]) 
 38845 |             { 
 38846 |                // c o0 (v0 o1 (v1 o2 v2)) 
 38847 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 38848 |  
 38849 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 38850 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 38851 |                const Type& v0 = vovov->t0(); 
 38852 |                const Type& v1 = vovov->t1(); 
 38853 |                const Type& v2 = vovov->t2(); 
 38854 |                const details::operator_type o0 = operation; 
 38855 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 38856 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 38857 |  
 38858 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38859 |                binary_functor_t f1 = vovov->f0(); 
 38860 |                binary_functor_t f2 = vovov->f1(); 
 38861 |  
 38862 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38863 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38864 |  
 38865 |                expression_node_ptr result = error_node(); 
 38866 |  
 38867 |                const bool synthesis_result = 
 38868 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38869 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 38870 |  
 38871 |                if (synthesis_result) 
 38872 |                   return result; 
 38873 |                if (!expr_gen.valid_operator(o0,f0)) 
 38874 |                   return error_node(); 
 38875 |  
 38876 |                exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n")); 
 38877 |  
 38878 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 38879 |             } 
 38880 |  
 38881 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38882 |                                          const details::operator_type o0, 
 38883 |                                          const details::operator_type o1, 
 38884 |                                          const details::operator_type o2) 
 38885 |             { 
 38886 |                return details::build_string() 
 38887 |                   << "t"  << expr_gen.to_str(o0) 
 38888 |                   << "(t" << expr_gen.to_str(o1) 
 38889 |                   << "(t" << expr_gen.to_str(o2) 
 38890 |                   << "t))" 
 38891 |             } 
 38892 |          }; 
 38893 |  
 38894 |          struct synthesize_covocov_expression1 
 38895 |          { 
 38896 |             typedef typename covocov_t::type1 node_type; 
 38897 |             typedef typename covocov_t::sf4_type sf4_type; 
 38898 |             typedef typename node_type::T0 T0; 
 38899 |             typedef typename node_type::T1 T1; 
 38900 |             typedef typename node_type::T2 T2; 
 38901 |             typedef typename node_type::T3 T3; 
 38902 |  
 38903 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38904 |                                                       const details::operator_type& operation, 
 38905 |                                                       expression_node_ptr (&branch)[2]) 
 38906 |             { 
 38907 |                // c0 o0 (v0 o1 (c1 o2 v1)) 
 38908 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 38909 |  
 38910 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 38911 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 38912 |                const Type& v0 = vocov->t0(); 
 38913 |                const Type  c1 = vocov->t1(); 
 38914 |                const Type& v1 = vocov->t2(); 
 38915 |                const details::operator_type o0 = operation; 
 38916 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 38917 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 38918 |  
 38919 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38920 |                binary_functor_t f1 = vocov->f0(); 
 38921 |                binary_functor_t f2 = vocov->f1(); 
 38922 |  
 38923 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 38924 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38925 |  
 38926 |                expression_node_ptr result = error_node(); 
 38927 |  
 38928 |                const bool synthesis_result = 
 38929 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38930 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 38931 |  
 38932 |                if (synthesis_result) 
 38933 |                   return result; 
 38934 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38935 |                   return error_node(); 
 38936 |  
 38937 |                exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n")); 
 38938 |  
 38939 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 38940 |             } 
 38941 |  
 38942 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 38943 |                                          const details::operator_type o0, 
 38944 |                                          const details::operator_type o1, 
 38945 |                                          const details::operator_type o2) 
 38946 |             { 
 38947 |                return details::build_string() 
 38948 |                   << "t"  << expr_gen.to_str(o0) 
 38949 |                   << "(t" << expr_gen.to_str(o1) 
 38950 |                   << "(t" << expr_gen.to_str(o2) 
 38951 |                   << "t))" 
 38952 |             } 
 38953 |          }; 
 38954 |  
 38955 |          struct synthesize_vocovoc_expression1 
 38956 |          { 
 38957 |             typedef typename vocovoc_t::type1 node_type; 
 38958 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 38959 |             typedef typename node_type::T0 T0; 
 38960 |             typedef typename node_type::T1 T1; 
 38961 |             typedef typename node_type::T2 T2; 
 38962 |             typedef typename node_type::T3 T3; 
 38963 |  
 38964 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 38965 |                                                       const details::operator_type& operation, 
 38966 |                                                       expression_node_ptr (&branch)[2]) 
 38967 |             { 
 38968 |                // v0 o0 (c0 o1 (v1 o2 c2)) 
 38969 |                typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t; 
 38970 |  
 38971 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]); 
 38972 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 38973 |                const Type  c0 = covoc->t0(); 
 38974 |                const Type& v1 = covoc->t1(); 
 38975 |                const Type  c1 = covoc->t2(); 
 38976 |                const details::operator_type o0 = operation; 
 38977 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f0()); 
 38978 |                const details::operator_type o2 = expr_gen.get_operator(covoc->f1()); 
 38979 |  
 38980 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 38981 |                binary_functor_t f1 = covoc->f0(); 
 38982 |                binary_functor_t f2 = covoc->f1(); 
 38983 |  
 38984 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 38985 |  
 38986 |                expression_node_ptr result = error_node(); 
 38987 |  
 38988 |                const bool synthesis_result = 
 38989 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 38990 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 38991 |  
 38992 |                if (synthesis_result) 
 38993 |                   return result; 
 38994 |                else if (!expr_gen.valid_operator(o0,f0)) 
 38995 |                   return error_node(); 
 38996 |  
 38997 |                exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n")); 
 38998 |  
 38999 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 39000 |             } 
 39001 |  
 39002 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39003 |                                          const details::operator_type o0, 
 39004 |                                          const details::operator_type o1, 
 39005 |                                          const details::operator_type o2) 
 39006 |             { 
 39007 |                return details::build_string() 
 39008 |                   << "t"  << expr_gen.to_str(o0) 
 39009 |                   << "(t" << expr_gen.to_str(o1) 
 39010 |                   << "(t" << expr_gen.to_str(o2) 
 39011 |                   << "t))" 
 39012 |             } 
 39013 |          }; 
 39014 |  
 39015 |          struct synthesize_covovoc_expression1 
 39016 |          { 
 39017 |             typedef typename covovoc_t::type1 node_type; 
 39018 |             typedef typename covovoc_t::sf4_type sf4_type; 
 39019 |             typedef typename node_type::T0 T0; 
 39020 |             typedef typename node_type::T1 T1; 
 39021 |             typedef typename node_type::T2 T2; 
 39022 |             typedef typename node_type::T3 T3; 
 39023 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39024 |                                                       const details::operator_type& operation, 
 39025 |                                                       expression_node_ptr (&branch)[2]) 
 39026 |             { 
 39027 |                // c0 o0 (v0 o1 (v1 o2 c1)) 
 39028 |                typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t; 
 39029 |  
 39030 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 39031 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39032 |                const Type& v0 = vovoc->t0(); 
 39033 |                const Type& v1 = vovoc->t1(); 
 39034 |                const Type  c1 = vovoc->t2(); 
 39035 |                const details::operator_type o0 = operation; 
 39036 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 39037 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 39038 |  
 39039 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39040 |                binary_functor_t f1 = vovoc->f0(); 
 39041 |                binary_functor_t f2 = vovoc->f1(); 
 39042 |  
 39043 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39044 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39045 |  
 39046 |                expression_node_ptr result = error_node(); 
 39047 |  
 39048 |                const bool synthesis_result = 
 39049 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39050 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 39051 |  
 39052 |                if (synthesis_result) 
 39053 |                   return result; 
 39054 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39055 |                   return error_node(); 
 39056 |  
 39057 |                exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n")); 
 39058 |  
 39059 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 39060 |             } 
 39061 |  
 39062 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39063 |                                          const details::operator_type o0, 
 39064 |                                          const details::operator_type o1, 
 39065 |                                          const details::operator_type o2) 
 39066 |             { 
 39067 |                return details::build_string() 
 39068 |                   << "t"  << expr_gen.to_str(o0) 
 39069 |                   << "(t" << expr_gen.to_str(o1) 
 39070 |                   << "(t" << expr_gen.to_str(o2) 
 39071 |                   << "t))" 
 39072 |             } 
 39073 |          }; 
 39074 |  
 39075 |          struct synthesize_vococov_expression1 
 39076 |          { 
 39077 |             typedef typename vococov_t::type1 node_type; 
 39078 |             typedef typename vococov_t::sf4_type sf4_type; 
 39079 |             typedef typename node_type::T0 T0; 
 39080 |             typedef typename node_type::T1 T1; 
 39081 |             typedef typename node_type::T2 T2; 
 39082 |             typedef typename node_type::T3 T3; 
 39083 |  
 39084 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39085 |                                                       const details::operator_type& operation, 
 39086 |                                                       expression_node_ptr (&branch)[2]) 
 39087 |             { 
 39088 |                // v0 o0 (c0 o1 (c1 o2 v1)) 
 39089 |                typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t; 
 39090 |  
 39091 |                const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]); 
 39092 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39093 |                const Type  c0 = cocov->t0(); 
 39094 |                const Type  c1 = cocov->t1(); 
 39095 |                const Type& v1 = cocov->t2(); 
 39096 |                const details::operator_type o0 = operation; 
 39097 |                const details::operator_type o1 = expr_gen.get_operator(cocov->f0()); 
 39098 |                const details::operator_type o2 = expr_gen.get_operator(cocov->f1()); 
 39099 |  
 39100 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39101 |                binary_functor_t f1 = cocov->f0(); 
 39102 |                binary_functor_t f2 = cocov->f1(); 
 39103 |  
 39104 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39105 |  
 39106 |                expression_node_ptr result = error_node(); 
 39107 |  
 39108 |                const bool synthesis_result = 
 39109 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39110 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result); 
 39111 |  
 39112 |                if (synthesis_result) 
 39113 |                   return result; 
 39114 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39115 |                   return error_node(); 
 39116 |  
 39117 |                exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n")); 
 39118 |  
 39119 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2); 
 39120 |             } 
 39121 |  
 39122 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39123 |                                          const details::operator_type o0, 
 39124 |                                          const details::operator_type o1, 
 39125 |                                          const details::operator_type o2) 
 39126 |             { 
 39127 |                return details::build_string() 
 39128 |                   << "t"  << expr_gen.to_str(o0) 
 39129 |                   << "(t" << expr_gen.to_str(o1) 
 39130 |                   << "(t" << expr_gen.to_str(o2) 
 39131 |                   << "t))" 
 39132 |             } 
 39133 |          }; 
 39134 |  
 39135 |          struct synthesize_vovovov_expression2 
 39136 |          { 
 39137 |             typedef typename vovovov_t::type2 node_type; 
 39138 |             typedef typename vovovov_t::sf4_type sf4_type; 
 39139 |             typedef typename node_type::T0 T0; 
 39140 |             typedef typename node_type::T1 T1; 
 39141 |             typedef typename node_type::T2 T2; 
 39142 |             typedef typename node_type::T3 T3; 
 39143 |  
 39144 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39145 |                                                       const details::operator_type& operation, 
 39146 |                                                       expression_node_ptr (&branch)[2]) 
 39147 |             { 
 39148 |                // v0 o0 ((v1 o1 v2) o2 v3) 
 39149 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39150 |  
 39151 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 39152 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39153 |                const Type& v1 = vovov->t0(); 
 39154 |                const Type& v2 = vovov->t1(); 
 39155 |                const Type& v3 = vovov->t2(); 
 39156 |                const details::operator_type o0 = operation; 
 39157 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 39158 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 39159 |  
 39160 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39161 |                binary_functor_t f1 = vovov->f0(); 
 39162 |                binary_functor_t f2 = vovov->f1(); 
 39163 |  
 39164 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39165 |  
 39166 |                expression_node_ptr result = error_node(); 
 39167 |  
 39168 |                const bool synthesis_result = 
 39169 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39170 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 39171 |  
 39172 |                if (synthesis_result) 
 39173 |                   return result; 
 39174 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39175 |                   return error_node(); 
 39176 |  
 39177 |                exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n")); 
 39178 |  
 39179 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 39180 |             } 
 39181 |  
 39182 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39183 |                                          const details::operator_type o0, 
 39184 |                                          const details::operator_type o1, 
 39185 |                                          const details::operator_type o2) 
 39186 |             { 
 39187 |                return details::build_string() 
 39188 |                   << "t"   << expr_gen.to_str(o0) 
 39189 |                   << "((t" << expr_gen.to_str(o1) 
 39190 |                   << "t)"  << expr_gen.to_str(o2) 
 39191 |                   << "t)" 
 39192 |             } 
 39193 |          }; 
 39194 |  
 39195 |          struct synthesize_vovovoc_expression2 
 39196 |          { 
 39197 |             typedef typename vovovoc_t::type2 node_type; 
 39198 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 39199 |             typedef typename node_type::T0 T0; 
 39200 |             typedef typename node_type::T1 T1; 
 39201 |             typedef typename node_type::T2 T2; 
 39202 |             typedef typename node_type::T3 T3; 
 39203 |  
 39204 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39205 |                                                       const details::operator_type& operation, 
 39206 |                                                       expression_node_ptr (&branch)[2]) 
 39207 |             { 
 39208 |                // v0 o0 ((v1 o1 v2) o2 c) 
 39209 |                typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t; 
 39210 |  
 39211 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 39212 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39213 |                const Type& v1 = vovoc->t0(); 
 39214 |                const Type& v2 = vovoc->t1(); 
 39215 |                const Type   c = vovoc->t2(); 
 39216 |                const details::operator_type o0 = operation; 
 39217 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 39218 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 39219 |  
 39220 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39221 |                binary_functor_t f1 = vovoc->f0(); 
 39222 |                binary_functor_t f2 = vovoc->f1(); 
 39223 |  
 39224 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39225 |  
 39226 |                expression_node_ptr result = error_node(); 
 39227 |  
 39228 |                const bool synthesis_result = 
 39229 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39230 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 39231 |  
 39232 |                if (synthesis_result) 
 39233 |                   return result; 
 39234 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39235 |                   return error_node(); 
 39236 |  
 39237 |                exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n")); 
 39238 |  
 39239 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 39240 |             } 
 39241 |  
 39242 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39243 |                                          const details::operator_type o0, 
 39244 |                                          const details::operator_type o1, 
 39245 |                                          const details::operator_type o2) 
 39246 |             { 
 39247 |                return details::build_string() 
 39248 |                   << "t"   << expr_gen.to_str(o0) 
 39249 |                   << "((t" << expr_gen.to_str(o1) 
 39250 |                   << "t)"  << expr_gen.to_str(o2) 
 39251 |                   << "t)" 
 39252 |             } 
 39253 |          }; 
 39254 |  
 39255 |          struct synthesize_vovocov_expression2 
 39256 |          { 
 39257 |             typedef typename vovocov_t::type2 node_type; 
 39258 |             typedef typename vovocov_t::sf4_type sf4_type; 
 39259 |             typedef typename node_type::T0 T0; 
 39260 |             typedef typename node_type::T1 T1; 
 39261 |             typedef typename node_type::T2 T2; 
 39262 |             typedef typename node_type::T3 T3; 
 39263 |  
 39264 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39265 |                                                       const details::operator_type& operation, 
 39266 |                                                       expression_node_ptr (&branch)[2]) 
 39267 |             { 
 39268 |                // v0 o0 ((v1 o1 c) o2 v2) 
 39269 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 39270 |  
 39271 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 39272 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39273 |                const Type& v1 = vocov->t0(); 
 39274 |                const Type   c = vocov->t1(); 
 39275 |                const Type& v2 = vocov->t2(); 
 39276 |                const details::operator_type o0 = operation; 
 39277 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 39278 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 39279 |  
 39280 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39281 |                binary_functor_t f1 = vocov->f0(); 
 39282 |                binary_functor_t f2 = vocov->f1(); 
 39283 |  
 39284 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39285 |  
 39286 |                expression_node_ptr result = error_node(); 
 39287 |  
 39288 |                const bool synthesis_result = 
 39289 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39290 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 39291 |  
 39292 |                if (synthesis_result) 
 39293 |                   return result; 
 39294 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39295 |                   return error_node(); 
 39296 |  
 39297 |                exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n")); 
 39298 |  
 39299 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 39300 |             } 
 39301 |  
 39302 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39303 |                                          const details::operator_type o0, 
 39304 |                                          const details::operator_type o1, 
 39305 |                                          const details::operator_type o2) 
 39306 |             { 
 39307 |                return details::build_string() 
 39308 |                   << "t"   << expr_gen.to_str(o0) 
 39309 |                   << "((t" << expr_gen.to_str(o1) 
 39310 |                   << "t)"  << expr_gen.to_str(o2) 
 39311 |                   << "t)" 
 39312 |             } 
 39313 |          }; 
 39314 |  
 39315 |          struct synthesize_vocovov_expression2 
 39316 |          { 
 39317 |             typedef typename vocovov_t::type2 node_type; 
 39318 |             typedef typename vocovov_t::sf4_type sf4_type; 
 39319 |             typedef typename node_type::T0 T0; 
 39320 |             typedef typename node_type::T1 T1; 
 39321 |             typedef typename node_type::T2 T2; 
 39322 |             typedef typename node_type::T3 T3; 
 39323 |  
 39324 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39325 |                                                       const details::operator_type& operation, 
 39326 |                                                       expression_node_ptr (&branch)[2]) 
 39327 |             { 
 39328 |                // v0 o0 ((c o1 v1) o2 v2) 
 39329 |                typedef typename synthesize_covov_expression0::node_type lcl_covov_t; 
 39330 |  
 39331 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]); 
 39332 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39333 |                const Type   c = covov->t0(); 
 39334 |                const Type& v1 = covov->t1(); 
 39335 |                const Type& v2 = covov->t2(); 
 39336 |                const details::operator_type o0 = operation; 
 39337 |                const details::operator_type o1 = expr_gen.get_operator(covov->f0()); 
 39338 |                const details::operator_type o2 = expr_gen.get_operator(covov->f1()); 
 39339 |  
 39340 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39341 |                binary_functor_t f1 = covov->f0(); 
 39342 |                binary_functor_t f2 = covov->f1(); 
 39343 |  
 39344 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39345 |  
 39346 |                expression_node_ptr result = error_node(); 
 39347 |  
 39348 |                const bool synthesis_result = 
 39349 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39350 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 39351 |  
 39352 |                if (synthesis_result) 
 39353 |                   return result; 
 39354 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39355 |                   return error_node(); 
 39356 |  
 39357 |                exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n")); 
 39358 |  
 39359 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 39360 |             } 
 39361 |  
 39362 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39363 |                                          const details::operator_type o0, 
 39364 |                                          const details::operator_type o1, 
 39365 |                                          const details::operator_type o2) 
 39366 |             { 
 39367 |                return details::build_string() 
 39368 |                   << "t"   << expr_gen.to_str(o0) 
 39369 |                   << "((t" << expr_gen.to_str(o1) 
 39370 |                   << "t)"  << expr_gen.to_str(o2) 
 39371 |                   << "t)" 
 39372 |             } 
 39373 |          }; 
 39374 |  
 39375 |          struct synthesize_covovov_expression2 
 39376 |          { 
 39377 |             typedef typename covovov_t::type2 node_type; 
 39378 |             typedef typename covovov_t::sf4_type sf4_type; 
 39379 |             typedef typename node_type::T0 T0; 
 39380 |             typedef typename node_type::T1 T1; 
 39381 |             typedef typename node_type::T2 T2; 
 39382 |             typedef typename node_type::T3 T3; 
 39383 |  
 39384 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39385 |                                                       const details::operator_type& operation, 
 39386 |                                                       expression_node_ptr (&branch)[2]) 
 39387 |             { 
 39388 |                // c o0 ((v1 o1 v2) o2 v3) 
 39389 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39390 |  
 39391 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]); 
 39392 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39393 |                const Type& v0 = vovov->t0(); 
 39394 |                const Type& v1 = vovov->t1(); 
 39395 |                const Type& v2 = vovov->t2(); 
 39396 |                const details::operator_type o0 = operation; 
 39397 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f0()); 
 39398 |                const details::operator_type o2 = expr_gen.get_operator(vovov->f1()); 
 39399 |  
 39400 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39401 |                binary_functor_t f1 = vovov->f0(); 
 39402 |                binary_functor_t f2 = vovov->f1(); 
 39403 |  
 39404 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39405 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39406 |  
 39407 |                expression_node_ptr result = error_node(); 
 39408 |  
 39409 |                const bool synthesis_result = 
 39410 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39411 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 39412 |  
 39413 |                if (synthesis_result) 
 39414 |                   return result; 
 39415 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39416 |                   return error_node(); 
 39417 |  
 39418 |                exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n")); 
 39419 |  
 39420 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 39421 |             } 
 39422 |  
 39423 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39424 |                                          const details::operator_type o0, 
 39425 |                                          const details::operator_type o1, 
 39426 |                                          const details::operator_type o2) 
 39427 |             { 
 39428 |                return details::build_string() 
 39429 |                   << "t"   << expr_gen.to_str(o0) 
 39430 |                   << "((t" << expr_gen.to_str(o1) 
 39431 |                   << "t)"  << expr_gen.to_str(o2) 
 39432 |                   << "t)" 
 39433 |             } 
 39434 |         }; 
 39435 |  
 39436 |          struct synthesize_covocov_expression2 
 39437 |          { 
 39438 |             typedef typename covocov_t::type2 node_type; 
 39439 |             typedef typename covocov_t::sf4_type sf4_type; 
 39440 |             typedef typename node_type::T0 T0; 
 39441 |             typedef typename node_type::T1 T1; 
 39442 |             typedef typename node_type::T2 T2; 
 39443 |             typedef typename node_type::T3 T3; 
 39444 |  
 39445 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39446 |                                                       const details::operator_type& operation, 
 39447 |                                                       expression_node_ptr (&branch)[2]) 
 39448 |             { 
 39449 |                // c0 o0 ((v0 o1 c1) o2 v1) 
 39450 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 39451 |  
 39452 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]); 
 39453 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39454 |                const Type& v0 = vocov->t0(); 
 39455 |                const Type  c1 = vocov->t1(); 
 39456 |                const Type& v1 = vocov->t2(); 
 39457 |                const details::operator_type o0 = operation; 
 39458 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f0()); 
 39459 |                const details::operator_type o2 = expr_gen.get_operator(vocov->f1()); 
 39460 |  
 39461 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39462 |                binary_functor_t f1 = vocov->f0(); 
 39463 |                binary_functor_t f2 = vocov->f1(); 
 39464 |  
 39465 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39466 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39467 |  
 39468 |                expression_node_ptr result = error_node(); 
 39469 |  
 39470 |                const bool synthesis_result = 
 39471 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39472 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 39473 |  
 39474 |                if (synthesis_result) 
 39475 |                   return result; 
 39476 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39477 |                   return error_node(); 
 39478 |  
 39479 |                exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n")); 
 39480 |  
 39481 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 39482 |             } 
 39483 |  
 39484 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39485 |                                          const details::operator_type o0, 
 39486 |                                          const details::operator_type o1, 
 39487 |                                          const details::operator_type o2) 
 39488 |             { 
 39489 |                return details::build_string() 
 39490 |                   << "t"   << expr_gen.to_str(o0) 
 39491 |                   << "((t" << expr_gen.to_str(o1) 
 39492 |                   << "t)"  << expr_gen.to_str(o2) 
 39493 |                   << "t)" 
 39494 |             } 
 39495 |          }; 
 39496 |  
 39497 |          struct synthesize_vocovoc_expression2 
 39498 |          { 
 39499 |             typedef typename vocovoc_t::type2 node_type; 
 39500 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 39501 |             typedef typename node_type::T0 T0; 
 39502 |             typedef typename node_type::T1 T1; 
 39503 |             typedef typename node_type::T2 T2; 
 39504 |             typedef typename node_type::T3 T3; 
 39505 |  
 39506 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39507 |                                                       const details::operator_type& operation, 
 39508 |                                                       expression_node_ptr (&branch)[2]) 
 39509 |             { 
 39510 |                // v0 o0 ((c0 o1 v1) o2 c1) 
 39511 |                typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t; 
 39512 |  
 39513 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]); 
 39514 |                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref(); 
 39515 |                const Type  c0 = covoc->t0(); 
 39516 |                const Type& v1 = covoc->t1(); 
 39517 |                const Type  c1 = covoc->t2(); 
 39518 |                const details::operator_type o0 = operation; 
 39519 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f0()); 
 39520 |                const details::operator_type o2 = expr_gen.get_operator(covoc->f1()); 
 39521 |  
 39522 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39523 |                binary_functor_t f1 = covoc->f0(); 
 39524 |                binary_functor_t f2 = covoc->f1(); 
 39525 |  
 39526 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39527 |  
 39528 |                expression_node_ptr result = error_node(); 
 39529 |  
 39530 |                const bool synthesis_result = 
 39531 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39532 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 39533 |  
 39534 |                if (synthesis_result) 
 39535 |                   return result; 
 39536 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39537 |                   return error_node(); 
 39538 |  
 39539 |                exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n")); 
 39540 |  
 39541 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 39542 |             } 
 39543 |  
 39544 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39545 |                                          const details::operator_type o0, 
 39546 |                                          const details::operator_type o1, 
 39547 |                                          const details::operator_type o2) 
 39548 |             { 
 39549 |                return details::build_string() 
 39550 |                   << "t"   << expr_gen.to_str(o0) 
 39551 |                   << "((t" << expr_gen.to_str(o1) 
 39552 |                   << "t)"  << expr_gen.to_str(o2) 
 39553 |                   << "t)" 
 39554 |             } 
 39555 |          }; 
 39556 |  
 39557 |          struct synthesize_covovoc_expression2 
 39558 |          { 
 39559 |             typedef typename covovoc_t::type2 node_type; 
 39560 |             typedef typename covovoc_t::sf4_type sf4_type; 
 39561 |             typedef typename node_type::T0 T0; 
 39562 |             typedef typename node_type::T1 T1; 
 39563 |             typedef typename node_type::T2 T2; 
 39564 |             typedef typename node_type::T3 T3; 
 39565 |  
 39566 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39567 |                                                       const details::operator_type& operation, 
 39568 |                                                       expression_node_ptr (&branch)[2]) 
 39569 |             { 
 39570 |                // c0 o0 ((v0 o1 v1) o2 c1) 
 39571 |                typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t; 
 39572 |  
 39573 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]); 
 39574 |                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value(); 
 39575 |                const Type& v0 = vovoc->t0(); 
 39576 |                const Type& v1 = vovoc->t1(); 
 39577 |                const Type  c1 = vovoc->t2(); 
 39578 |                const details::operator_type o0 = operation; 
 39579 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f0()); 
 39580 |                const details::operator_type o2 = expr_gen.get_operator(vovoc->f1()); 
 39581 |  
 39582 |                binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0); 
 39583 |                binary_functor_t f1 = vovoc->f0(); 
 39584 |                binary_functor_t f2 = vovoc->f1(); 
 39585 |  
 39586 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39587 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39588 |  
 39589 |                expression_node_ptr result = error_node(); 
 39590 |  
 39591 |                const bool synthesis_result = 
 39592 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39593 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 39594 |  
 39595 |                if (synthesis_result) 
 39596 |                   return result; 
 39597 |                else if (!expr_gen.valid_operator(o0,f0)) 
 39598 |                   return error_node(); 
 39599 |  
 39600 |                exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n")); 
 39601 |  
 39602 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 39603 |             } 
 39604 |  
 39605 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39606 |                                          const details::operator_type o0, 
 39607 |                                          const details::operator_type o1, 
 39608 |                                          const details::operator_type o2) 
 39609 |             { 
 39610 |                return details::build_string() 
 39611 |                   << "t"   << expr_gen.to_str(o0) 
 39612 |                   << "((t" << expr_gen.to_str(o1) 
 39613 |                   << "t)"  << expr_gen.to_str(o2) 
 39614 |                   << "t)" 
 39615 |             } 
 39616 |          }; 
 39617 |  
 39618 |          struct synthesize_vococov_expression2 
 39619 |          { 
 39620 |             typedef typename vococov_t::type2 node_type; 
 39621 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 39622 |                                                       const details::operator_type&, 
 39623 |                                                       expression_node_ptr (&)[2]) 
 39624 |             { 
 39625 |                // v0 o0 ((c0 o1 c1) o2 v1) - Not possible 
 39626 |                exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n")); 
 39627 |                return error_node(); 
 39628 |             } 
 39629 |  
 39630 |             static inline std::string id(expression_generator<Type>&, 
 39631 |                                          const details::operator_type, 
 39632 |                                          const details::operator_type, 
 39633 |                                          const details::operator_type) 
 39634 |             { 
 39635 |                return "INVALID" 
 39636 |             } 
 39637 |          }; 
 39638 |  
 39639 |          struct synthesize_vovovov_expression3 
 39640 |          { 
 39641 |             typedef typename vovovov_t::type3 node_type; 
 39642 |             typedef typename vovovov_t::sf4_type sf4_type; 
 39643 |             typedef typename node_type::T0 T0; 
 39644 |             typedef typename node_type::T1 T1; 
 39645 |             typedef typename node_type::T2 T2; 
 39646 |             typedef typename node_type::T3 T3; 
 39647 |  
 39648 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39649 |                                                       const details::operator_type& operation, 
 39650 |                                                       expression_node_ptr (&branch)[2]) 
 39651 |             { 
 39652 |                // ((v0 o0 v1) o1 v2) o2 v3 
 39653 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39654 |  
 39655 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 39656 |                const Type& v0 = vovov->t0(); 
 39657 |                const Type& v1 = vovov->t1(); 
 39658 |                const Type& v2 = vovov->t2(); 
 39659 |                const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39660 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 39661 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 39662 |                const details::operator_type o2 = operation; 
 39663 |  
 39664 |                binary_functor_t f0 = vovov->f0(); 
 39665 |                binary_functor_t f1 = vovov->f1(); 
 39666 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39667 |  
 39668 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39669 |  
 39670 |                expression_node_ptr result = error_node(); 
 39671 |  
 39672 |                const bool synthesis_result = 
 39673 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39674 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 39675 |  
 39676 |                if (synthesis_result) 
 39677 |                   return result; 
 39678 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39679 |                   return error_node(); 
 39680 |  
 39681 |                exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n")); 
 39682 |  
 39683 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 39684 |             } 
 39685 |  
 39686 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39687 |                                          const details::operator_type o0, 
 39688 |                                          const details::operator_type o1, 
 39689 |                                          const details::operator_type o2) 
 39690 |             { 
 39691 |                return details::build_string() 
 39692 |                   << "((t" << expr_gen.to_str(o0) 
 39693 |                   << "t)"  << expr_gen.to_str(o1) 
 39694 |                   << "t)"  << expr_gen.to_str(o2) 
 39695 |                   << "t" 
 39696 |             } 
 39697 |          }; 
 39698 |  
 39699 |          struct synthesize_vovovoc_expression3 
 39700 |          { 
 39701 |             typedef typename vovovoc_t::type3 node_type; 
 39702 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 39703 |             typedef typename node_type::T0 T0; 
 39704 |             typedef typename node_type::T1 T1; 
 39705 |             typedef typename node_type::T2 T2; 
 39706 |             typedef typename node_type::T3 T3; 
 39707 |  
 39708 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39709 |                                                       const details::operator_type& operation, 
 39710 |                                                       expression_node_ptr (&branch)[2]) 
 39711 |             { 
 39712 |                // ((v0 o0 v1) o1 v2) o2 c 
 39713 |                typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t; 
 39714 |  
 39715 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 39716 |                const Type& v0 = vovov->t0(); 
 39717 |                const Type& v1 = vovov->t1(); 
 39718 |                const Type& v2 = vovov->t2(); 
 39719 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 39720 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 39721 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 39722 |                const details::operator_type o2 = operation; 
 39723 |  
 39724 |                binary_functor_t f0 = vovov->f0(); 
 39725 |                binary_functor_t f1 = vovov->f1(); 
 39726 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39727 |  
 39728 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39729 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 39730 |  
 39731 |                expression_node_ptr result = error_node(); 
 39732 |  
 39733 |                const bool synthesis_result = 
 39734 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39735 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 39736 |  
 39737 |                if (synthesis_result) 
 39738 |                   return result; 
 39739 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39740 |                   return error_node(); 
 39741 |  
 39742 |                exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n")); 
 39743 |  
 39744 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 39745 |             } 
 39746 |  
 39747 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39748 |                                          const details::operator_type o0, 
 39749 |                                          const details::operator_type o1, 
 39750 |                                          const details::operator_type o2) 
 39751 |             { 
 39752 |                return details::build_string() 
 39753 |                   << "((t" << expr_gen.to_str(o0) 
 39754 |                   << "t)"  << expr_gen.to_str(o1) 
 39755 |                   << "t)"  << expr_gen.to_str(o2) 
 39756 |                   << "t" 
 39757 |             } 
 39758 |          }; 
 39759 |  
 39760 |          struct synthesize_vovocov_expression3 
 39761 |          { 
 39762 |             typedef typename vovocov_t::type3 node_type; 
 39763 |             typedef typename vovocov_t::sf4_type sf4_type; 
 39764 |             typedef typename node_type::T0 T0; 
 39765 |             typedef typename node_type::T1 T1; 
 39766 |             typedef typename node_type::T2 T2; 
 39767 |             typedef typename node_type::T3 T3; 
 39768 |  
 39769 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39770 |                                                       const details::operator_type& operation, 
 39771 |                                                       expression_node_ptr (&branch)[2]) 
 39772 |             { 
 39773 |                // ((v0 o0 v1) o1 c) o2 v2 
 39774 |                typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t; 
 39775 |  
 39776 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]); 
 39777 |                const Type& v0 = vovoc->t0(); 
 39778 |                const Type& v1 = vovoc->t1(); 
 39779 |                const Type   c = vovoc->t2(); 
 39780 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39781 |                const details::operator_type o0 = expr_gen.get_operator(vovoc->f0()); 
 39782 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f1()); 
 39783 |                const details::operator_type o2 = operation; 
 39784 |  
 39785 |                binary_functor_t f0 = vovoc->f0(); 
 39786 |                binary_functor_t f1 = vovoc->f1(); 
 39787 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39788 |  
 39789 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39790 |  
 39791 |                expression_node_ptr result = error_node(); 
 39792 |  
 39793 |                const bool synthesis_result = 
 39794 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39795 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 39796 |  
 39797 |                if (synthesis_result) 
 39798 |                   return result; 
 39799 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39800 |                   return error_node(); 
 39801 |  
 39802 |                exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n")); 
 39803 |  
 39804 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 39805 |             } 
 39806 |  
 39807 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39808 |                                          const details::operator_type o0, 
 39809 |                                          const details::operator_type o1, 
 39810 |                                          const details::operator_type o2) 
 39811 |             { 
 39812 |                return details::build_string() 
 39813 |                   << "((t" << expr_gen.to_str(o0) 
 39814 |                   << "t)"  << expr_gen.to_str(o1) 
 39815 |                   << "t)"  << expr_gen.to_str(o2) 
 39816 |                   << "t" 
 39817 |             } 
 39818 |          }; 
 39819 |  
 39820 |          struct synthesize_vocovov_expression3 
 39821 |          { 
 39822 |             typedef typename vocovov_t::type3 node_type; 
 39823 |             typedef typename vocovov_t::sf4_type sf4_type; 
 39824 |             typedef typename node_type::T0 T0; 
 39825 |             typedef typename node_type::T1 T1; 
 39826 |             typedef typename node_type::T2 T2; 
 39827 |             typedef typename node_type::T3 T3; 
 39828 |  
 39829 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39830 |                                                       const details::operator_type& operation, 
 39831 |                                                       expression_node_ptr (&branch)[2]) 
 39832 |             { 
 39833 |                // ((v0 o0 c) o1 v1) o2 v2 
 39834 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 39835 |  
 39836 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 39837 |                const Type& v0 = vocov->t0(); 
 39838 |                const Type   c = vocov->t1(); 
 39839 |                const Type& v1 = vocov->t2(); 
 39840 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39841 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 39842 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 39843 |                const details::operator_type o2 = operation; 
 39844 |  
 39845 |                binary_functor_t f0 = vocov->f0(); 
 39846 |                binary_functor_t f1 = vocov->f1(); 
 39847 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39848 |  
 39849 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39850 |  
 39851 |                expression_node_ptr result = error_node(); 
 39852 |  
 39853 |                const bool synthesis_result = 
 39854 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39855 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 39856 |  
 39857 |                if (synthesis_result) 
 39858 |                   return result; 
 39859 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39860 |                   return error_node(); 
 39861 |  
 39862 |                exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n")); 
 39863 |  
 39864 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 39865 |             } 
 39866 |  
 39867 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39868 |                                          const details::operator_type o0, 
 39869 |                                          const details::operator_type o1, 
 39870 |                                          const details::operator_type o2) 
 39871 |             { 
 39872 |                return details::build_string() 
 39873 |                   << "((t" << expr_gen.to_str(o0) 
 39874 |                   << "t)"  << expr_gen.to_str(o1) 
 39875 |                   << "t)"  << expr_gen.to_str(o2) 
 39876 |                   << "t" 
 39877 |             } 
 39878 |          }; 
 39879 |  
 39880 |          struct synthesize_covovov_expression3 
 39881 |          { 
 39882 |             typedef typename covovov_t::type3 node_type; 
 39883 |             typedef typename covovov_t::sf4_type sf4_type; 
 39884 |             typedef typename node_type::T0 T0; 
 39885 |             typedef typename node_type::T1 T1; 
 39886 |             typedef typename node_type::T2 T2; 
 39887 |             typedef typename node_type::T3 T3; 
 39888 |  
 39889 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39890 |                                                       const details::operator_type& operation, 
 39891 |                                                       expression_node_ptr (&branch)[2]) 
 39892 |             { 
 39893 |                // ((c o0 v0) o1 v1) o2 v2 
 39894 |                typedef typename synthesize_covov_expression0::node_type lcl_covov_t; 
 39895 |  
 39896 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 39897 |                const Type   c = covov->t0(); 
 39898 |                const Type& v0 = covov->t1(); 
 39899 |                const Type& v1 = covov->t2(); 
 39900 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39901 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 39902 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 39903 |                const details::operator_type o2 = operation; 
 39904 |  
 39905 |                binary_functor_t f0 = covov->f0(); 
 39906 |                binary_functor_t f1 = covov->f1(); 
 39907 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39908 |  
 39909 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39910 |  
 39911 |                expression_node_ptr result = error_node(); 
 39912 |  
 39913 |                const bool synthesis_result = 
 39914 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39915 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 39916 |  
 39917 |                if (synthesis_result) 
 39918 |                   return result; 
 39919 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39920 |                   return error_node(); 
 39921 |  
 39922 |                exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n")); 
 39923 |  
 39924 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 39925 |             } 
 39926 |  
 39927 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39928 |                                          const details::operator_type o0, 
 39929 |                                          const details::operator_type o1, 
 39930 |                                          const details::operator_type o2) 
 39931 |             { 
 39932 |                return details::build_string() 
 39933 |                   << "((t" << expr_gen.to_str(o0) 
 39934 |                   << "t)"  << expr_gen.to_str(o1) 
 39935 |                   << "t)"  << expr_gen.to_str(o2) 
 39936 |                   << "t" 
 39937 |             } 
 39938 |          }; 
 39939 |  
 39940 |          struct synthesize_covocov_expression3 
 39941 |          { 
 39942 |             typedef typename covocov_t::type3 node_type; 
 39943 |             typedef typename covocov_t::sf4_type sf4_type; 
 39944 |             typedef typename node_type::T0 T0; 
 39945 |             typedef typename node_type::T1 T1; 
 39946 |             typedef typename node_type::T2 T2; 
 39947 |             typedef typename node_type::T3 T3; 
 39948 |  
 39949 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 39950 |                                                       const details::operator_type& operation, 
 39951 |                                                       expression_node_ptr (&branch)[2]) 
 39952 |             { 
 39953 |                // ((c0 o0 v0) o1 c1) o2 v1 
 39954 |                typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t; 
 39955 |  
 39956 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]); 
 39957 |                const Type  c0 = covoc->t0(); 
 39958 |                const Type& v0 = covoc->t1(); 
 39959 |                const Type  c1 = covoc->t2(); 
 39960 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 39961 |                const details::operator_type o0 = expr_gen.get_operator(covoc->f0()); 
 39962 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f1()); 
 39963 |                const details::operator_type o2 = operation; 
 39964 |  
 39965 |                binary_functor_t f0 = covoc->f0(); 
 39966 |                binary_functor_t f1 = covoc->f1(); 
 39967 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 39968 |  
 39969 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 39970 |  
 39971 |                expression_node_ptr result = error_node(); 
 39972 |  
 39973 |                const bool synthesis_result = 
 39974 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 39975 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 39976 |  
 39977 |                if (synthesis_result) 
 39978 |                   return result; 
 39979 |                else if (!expr_gen.valid_operator(o2,f2)) 
 39980 |                   return error_node(); 
 39981 |  
 39982 |                exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n")); 
 39983 |  
 39984 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 39985 |             } 
 39986 |  
 39987 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 39988 |                                          const details::operator_type o0, 
 39989 |                                          const details::operator_type o1, 
 39990 |                                          const details::operator_type o2) 
 39991 |             { 
 39992 |                return details::build_string() 
 39993 |                   << "((t" << expr_gen.to_str(o0) 
 39994 |                   << "t)"  << expr_gen.to_str(o1) 
 39995 |                   << "t)"  << expr_gen.to_str(o2) 
 39996 |                   << "t" 
 39997 |             } 
 39998 |          }; 
 39999 |  
 40000 |          struct synthesize_vocovoc_expression3 
 40001 |          { 
 40002 |             typedef typename vocovoc_t::type3 node_type; 
 40003 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 40004 |             typedef typename node_type::T0 T0; 
 40005 |             typedef typename node_type::T1 T1; 
 40006 |             typedef typename node_type::T2 T2; 
 40007 |             typedef typename node_type::T3 T3; 
 40008 |  
 40009 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40010 |                                                       const details::operator_type& operation, 
 40011 |                                                       expression_node_ptr (&branch)[2]) 
 40012 |             { 
 40013 |                // ((v0 o0 c0) o1 v1) o2 c1 
 40014 |                typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t; 
 40015 |  
 40016 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 40017 |                const Type& v0 = vocov->t0(); 
 40018 |                const Type  c0 = vocov->t1(); 
 40019 |                const Type& v1 = vocov->t2(); 
 40020 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40021 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 40022 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 40023 |                const details::operator_type o2 = operation; 
 40024 |  
 40025 |                binary_functor_t f0 = vocov->f0(); 
 40026 |                binary_functor_t f1 = vocov->f1(); 
 40027 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40028 |  
 40029 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40030 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40031 |  
 40032 |                expression_node_ptr result = error_node(); 
 40033 |  
 40034 |                const bool synthesis_result = 
 40035 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40036 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 40037 |  
 40038 |                if (synthesis_result) 
 40039 |                   return result; 
 40040 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40041 |                   return error_node(); 
 40042 |  
 40043 |                exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n")); 
 40044 |  
 40045 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 40046 |             } 
 40047 |  
 40048 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40049 |                                          const details::operator_type o0, 
 40050 |                                          const details::operator_type o1, 
 40051 |                                          const details::operator_type o2) 
 40052 |             { 
 40053 |                return details::build_string() 
 40054 |                   << "((t" << expr_gen.to_str(o0) 
 40055 |                   << "t)"  << expr_gen.to_str(o1) 
 40056 |                   << "t)"  << expr_gen.to_str(o2) 
 40057 |                   << "t" 
 40058 |             } 
 40059 |          }; 
 40060 |  
 40061 |          struct synthesize_covovoc_expression3 
 40062 |          { 
 40063 |             typedef typename covovoc_t::type3 node_type; 
 40064 |             typedef typename covovoc_t::sf4_type sf4_type; 
 40065 |             typedef typename node_type::T0 T0; 
 40066 |             typedef typename node_type::T1 T1; 
 40067 |             typedef typename node_type::T2 T2; 
 40068 |             typedef typename node_type::T3 T3; 
 40069 |  
 40070 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40071 |                                                       const details::operator_type& operation, 
 40072 |                                                       expression_node_ptr (&branch)[2]) 
 40073 |             { 
 40074 |                // ((c0 o0 v0) o1 v1) o2 c1 
 40075 |                typedef typename synthesize_covov_expression0::node_type lcl_covov_t; 
 40076 |  
 40077 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 40078 |                const Type  c0 = covov->t0(); 
 40079 |                const Type& v0 = covov->t1(); 
 40080 |                const Type& v1 = covov->t2(); 
 40081 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40082 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 40083 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 40084 |                const details::operator_type o2 = operation; 
 40085 |  
 40086 |                binary_functor_t f0 = covov->f0(); 
 40087 |                binary_functor_t f1 = covov->f1(); 
 40088 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40089 |  
 40090 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40091 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40092 |  
 40093 |                expression_node_ptr result = error_node(); 
 40094 |  
 40095 |                const bool synthesis_result = 
 40096 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40097 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 40098 |  
 40099 |                if (synthesis_result) 
 40100 |                   return result; 
 40101 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40102 |                   return error_node(); 
 40103 |  
 40104 |                exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n")); 
 40105 |  
 40106 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 40107 |             } 
 40108 |  
 40109 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40110 |                                          const details::operator_type o0, 
 40111 |                                          const details::operator_type o1, 
 40112 |                                          const details::operator_type o2) 
 40113 |             { 
 40114 |                return details::build_string() 
 40115 |                   << "((t" << expr_gen.to_str(o0) 
 40116 |                   << "t)"  << expr_gen.to_str(o1) 
 40117 |                   << "t)"  << expr_gen.to_str(o2) 
 40118 |                   << "t" 
 40119 |             } 
 40120 |          }; 
 40121 |  
 40122 |          struct synthesize_vococov_expression3 
 40123 |          { 
 40124 |             typedef typename vococov_t::type3 node_type; 
 40125 |             typedef typename vococov_t::sf4_type sf4_type; 
 40126 |             typedef typename node_type::T0 T0; 
 40127 |             typedef typename node_type::T1 T1; 
 40128 |             typedef typename node_type::T2 T2; 
 40129 |             typedef typename node_type::T3 T3; 
 40130 |  
 40131 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40132 |                                                       const details::operator_type& operation, 
 40133 |                                                       expression_node_ptr (&branch)[2]) 
 40134 |             { 
 40135 |                // ((v0 o0 c0) o1 c1) o2 v1 
 40136 |                typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t; 
 40137 |  
 40138 |                const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]); 
 40139 |                const Type& v0 = vococ->t0(); 
 40140 |                const Type  c0 = vococ->t1(); 
 40141 |                const Type  c1 = vococ->t2(); 
 40142 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40143 |                const details::operator_type o0 = expr_gen.get_operator(vococ->f0()); 
 40144 |                const details::operator_type o1 = expr_gen.get_operator(vococ->f1()); 
 40145 |                const details::operator_type o2 = operation; 
 40146 |  
 40147 |                binary_functor_t f0 = vococ->f0(); 
 40148 |                binary_functor_t f1 = vococ->f1(); 
 40149 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40150 |  
 40151 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40152 |  
 40153 |                expression_node_ptr result = error_node(); 
 40154 |  
 40155 |                const bool synthesis_result = 
 40156 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40157 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result); 
 40158 |  
 40159 |                if (synthesis_result) 
 40160 |                   return result; 
 40161 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40162 |                   return error_node(); 
 40163 |  
 40164 |                exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n")); 
 40165 |  
 40166 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2); 
 40167 |             } 
 40168 |  
 40169 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40170 |                                          const details::operator_type o0, 
 40171 |                                          const details::operator_type o1, 
 40172 |                                          const details::operator_type o2) 
 40173 |             { 
 40174 |                return details::build_string() 
 40175 |                   << "((t" << expr_gen.to_str(o0) 
 40176 |                   << "t)"  << expr_gen.to_str(o1) 
 40177 |                   << "t)"  << expr_gen.to_str(o2) 
 40178 |                   << "t" 
 40179 |             } 
 40180 |          }; 
 40181 |  
 40182 |          struct synthesize_vovovov_expression4 
 40183 |          { 
 40184 |             typedef typename vovovov_t::type4 node_type; 
 40185 |             typedef typename vovovov_t::sf4_type sf4_type; 
 40186 |             typedef typename node_type::T0 T0; 
 40187 |             typedef typename node_type::T1 T1; 
 40188 |             typedef typename node_type::T2 T2; 
 40189 |             typedef typename node_type::T3 T3; 
 40190 |  
 40191 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40192 |                                                       const details::operator_type& operation, 
 40193 |                                                       expression_node_ptr (&branch)[2]) 
 40194 |             { 
 40195 |                // (v0 o0 (v1 o1 v2)) o2 v3 
 40196 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 40197 |  
 40198 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 40199 |                const Type& v0 = vovov->t0(); 
 40200 |                const Type& v1 = vovov->t1(); 
 40201 |                const Type& v2 = vovov->t2(); 
 40202 |                const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40203 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 40204 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 40205 |                const details::operator_type o2 = operation; 
 40206 |  
 40207 |                binary_functor_t f0 = vovov->f0(); 
 40208 |                binary_functor_t f1 = vovov->f1(); 
 40209 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40210 |  
 40211 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40212 |  
 40213 |                expression_node_ptr result = error_node(); 
 40214 |  
 40215 |                const bool synthesis_result = 
 40216 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40217 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result); 
 40218 |  
 40219 |                if (synthesis_result) 
 40220 |                   return result; 
 40221 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40222 |                   return error_node(); 
 40223 |  
 40224 |                exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n")); 
 40225 |  
 40226 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2); 
 40227 |             } 
 40228 |  
 40229 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40230 |                                          const details::operator_type o0, 
 40231 |                                          const details::operator_type o1, 
 40232 |                                          const details::operator_type o2) 
 40233 |             { 
 40234 |                return details::build_string() 
 40235 |                   << "(t" << expr_gen.to_str(o0) 
 40236 |                   << "(t" << expr_gen.to_str(o1) 
 40237 |                   << "t)" << expr_gen.to_str(o2) 
 40238 |                   << "t" 
 40239 |             } 
 40240 |          }; 
 40241 |  
 40242 |          struct synthesize_vovovoc_expression4 
 40243 |          { 
 40244 |             typedef typename vovovoc_t::type4 node_type; 
 40245 |             typedef typename vovovoc_t::sf4_type sf4_type; 
 40246 |             typedef typename node_type::T0 T0; 
 40247 |             typedef typename node_type::T1 T1; 
 40248 |             typedef typename node_type::T2 T2; 
 40249 |             typedef typename node_type::T3 T3; 
 40250 |  
 40251 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40252 |                                                       const details::operator_type& operation, 
 40253 |                                                       expression_node_ptr (&branch)[2]) 
 40254 |             { 
 40255 |                // ((v0 o0 (v1 o1 v2)) o2 c) 
 40256 |                typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t; 
 40257 |  
 40258 |                const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]); 
 40259 |                const Type& v0 = vovov->t0(); 
 40260 |                const Type& v1 = vovov->t1(); 
 40261 |                const Type& v2 = vovov->t2(); 
 40262 |                const Type   c = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40263 |                const details::operator_type o0 = expr_gen.get_operator(vovov->f0()); 
 40264 |                const details::operator_type o1 = expr_gen.get_operator(vovov->f1()); 
 40265 |                const details::operator_type o2 = operation; 
 40266 |  
 40267 |                binary_functor_t f0 = vovov->f0(); 
 40268 |                binary_functor_t f1 = vovov->f1(); 
 40269 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40270 |  
 40271 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40272 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40273 |  
 40274 |                expression_node_ptr result = error_node(); 
 40275 |  
 40276 |                const bool synthesis_result = 
 40277 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40278 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result); 
 40279 |  
 40280 |                if (synthesis_result) 
 40281 |                   return result; 
 40282 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40283 |                   return error_node(); 
 40284 |  
 40285 |                exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n")); 
 40286 |  
 40287 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2); 
 40288 |             } 
 40289 |  
 40290 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40291 |                                          const details::operator_type o0, 
 40292 |                                          const details::operator_type o1, 
 40293 |                                          const details::operator_type o2) 
 40294 |             { 
 40295 |                return details::build_string() 
 40296 |                   << "(t" << expr_gen.to_str(o0) 
 40297 |                   << "(t" << expr_gen.to_str(o1) 
 40298 |                   << "t)" << expr_gen.to_str(o2) 
 40299 |                   << "t" 
 40300 |             } 
 40301 |          }; 
 40302 |  
 40303 |          struct synthesize_vovocov_expression4 
 40304 |          { 
 40305 |             typedef typename vovocov_t::type4 node_type; 
 40306 |             typedef typename vovocov_t::sf4_type sf4_type; 
 40307 |             typedef typename node_type::T0 T0; 
 40308 |             typedef typename node_type::T1 T1; 
 40309 |             typedef typename node_type::T2 T2; 
 40310 |             typedef typename node_type::T3 T3; 
 40311 |  
 40312 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40313 |                                                       const details::operator_type& operation, 
 40314 |                                                       expression_node_ptr (&branch)[2]) 
 40315 |             { 
 40316 |                // ((v0 o0 (v1 o1 c)) o2 v1) 
 40317 |                typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t; 
 40318 |  
 40319 |                const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]); 
 40320 |                const Type& v0 = vovoc->t0(); 
 40321 |                const Type& v1 = vovoc->t1(); 
 40322 |                const Type   c = vovoc->t2(); 
 40323 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40324 |                const details::operator_type o0 = expr_gen.get_operator(vovoc->f0()); 
 40325 |                const details::operator_type o1 = expr_gen.get_operator(vovoc->f1()); 
 40326 |                const details::operator_type o2 = operation; 
 40327 |  
 40328 |                binary_functor_t f0 = vovoc->f0(); 
 40329 |                binary_functor_t f1 = vovoc->f1(); 
 40330 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40331 |  
 40332 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40333 |  
 40334 |                expression_node_ptr result = error_node(); 
 40335 |  
 40336 |                const bool synthesis_result = 
 40337 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40338 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result); 
 40339 |  
 40340 |                if (synthesis_result) 
 40341 |                   return result; 
 40342 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40343 |                   return error_node(); 
 40344 |  
 40345 |                exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n")); 
 40346 |  
 40347 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2); 
 40348 |             } 
 40349 |  
 40350 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40351 |                                          const details::operator_type o0, 
 40352 |                                          const details::operator_type o1, 
 40353 |                                          const details::operator_type o2) 
 40354 |             { 
 40355 |                return details::build_string() 
 40356 |                   << "(t" << expr_gen.to_str(o0) 
 40357 |                   << "(t" << expr_gen.to_str(o1) 
 40358 |                   << "t)" << expr_gen.to_str(o2) 
 40359 |                   << "t" 
 40360 |             } 
 40361 |          }; 
 40362 |  
 40363 |          struct synthesize_vocovov_expression4 
 40364 |          { 
 40365 |             typedef typename vocovov_t::type4 node_type; 
 40366 |             typedef typename vocovov_t::sf4_type sf4_type; 
 40367 |             typedef typename node_type::T0 T0; 
 40368 |             typedef typename node_type::T1 T1; 
 40369 |             typedef typename node_type::T2 T2; 
 40370 |             typedef typename node_type::T3 T3; 
 40371 |  
 40372 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40373 |                                                       const details::operator_type& operation, 
 40374 |                                                       expression_node_ptr (&branch)[2]) 
 40375 |             { 
 40376 |                // ((v0 o0 (c o1 v1)) o2 v2) 
 40377 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 40378 |  
 40379 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 40380 |                const Type& v0 = vocov->t0(); 
 40381 |                const Type   c = vocov->t1(); 
 40382 |                const Type& v1 = vocov->t2(); 
 40383 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40384 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 40385 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 40386 |                const details::operator_type o2 = operation; 
 40387 |  
 40388 |                binary_functor_t f0 = vocov->f0(); 
 40389 |                binary_functor_t f1 = vocov->f1(); 
 40390 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40391 |  
 40392 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40393 |                expression_node_ptr result = error_node(); 
 40394 |  
 40395 |                const bool synthesis_result = 
 40396 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40397 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result); 
 40398 |  
 40399 |                if (synthesis_result) 
 40400 |                   return result; 
 40401 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40402 |                   return error_node(); 
 40403 |  
 40404 |                exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n")); 
 40405 |  
 40406 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2); 
 40407 |             } 
 40408 |  
 40409 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40410 |                                          const details::operator_type o0, 
 40411 |                                          const details::operator_type o1, 
 40412 |                                          const details::operator_type o2) 
 40413 |             { 
 40414 |                return details::build_string() 
 40415 |                   << "(t" << expr_gen.to_str(o0) 
 40416 |                   << "(t" << expr_gen.to_str(o1) 
 40417 |                   << "t)" << expr_gen.to_str(o2) 
 40418 |                   << "t" 
 40419 |             } 
 40420 |          }; 
 40421 |  
 40422 |          struct synthesize_covovov_expression4 
 40423 |          { 
 40424 |             typedef typename covovov_t::type4 node_type; 
 40425 |             typedef typename covovov_t::sf4_type sf4_type; 
 40426 |             typedef typename node_type::T0 T0; 
 40427 |             typedef typename node_type::T1 T1; 
 40428 |             typedef typename node_type::T2 T2; 
 40429 |             typedef typename node_type::T3 T3; 
 40430 |  
 40431 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40432 |                                                       const details::operator_type& operation, 
 40433 |                                                       expression_node_ptr (&branch)[2]) 
 40434 |             { 
 40435 |                // ((c o0 (v0 o1 v1)) o2 v2) 
 40436 |                typedef typename synthesize_covov_expression1::node_type lcl_covov_t; 
 40437 |  
 40438 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 40439 |                const Type   c = covov->t0(); 
 40440 |                const Type& v0 = covov->t1(); 
 40441 |                const Type& v1 = covov->t2(); 
 40442 |                const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40443 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 40444 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 40445 |                const details::operator_type o2 = operation; 
 40446 |  
 40447 |                binary_functor_t f0 = covov->f0(); 
 40448 |                binary_functor_t f1 = covov->f1(); 
 40449 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40450 |  
 40451 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40452 |  
 40453 |                expression_node_ptr result = error_node(); 
 40454 |  
 40455 |                const bool synthesis_result = 
 40456 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40457 |                      (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result); 
 40458 |  
 40459 |                if (synthesis_result) 
 40460 |                   return result; 
 40461 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40462 |                   return error_node(); 
 40463 |  
 40464 |                exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n")); 
 40465 |  
 40466 |                return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2); 
 40467 |             } 
 40468 |  
 40469 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40470 |                                          const details::operator_type o0, 
 40471 |                                          const details::operator_type o1, 
 40472 |                                          const details::operator_type o2) 
 40473 |             { 
 40474 |                return details::build_string() 
 40475 |                   << "(t" << expr_gen.to_str(o0) 
 40476 |                   << "(t" << expr_gen.to_str(o1) 
 40477 |                   << "t)" << expr_gen.to_str(o2) 
 40478 |                   << "t" 
 40479 |             } 
 40480 |          }; 
 40481 |  
 40482 |          struct synthesize_covocov_expression4 
 40483 |          { 
 40484 |             typedef typename covocov_t::type4 node_type; 
 40485 |             typedef typename covocov_t::sf4_type sf4_type; 
 40486 |             typedef typename node_type::T0 T0; 
 40487 |             typedef typename node_type::T1 T1; 
 40488 |             typedef typename node_type::T2 T2; 
 40489 |             typedef typename node_type::T3 T3; 
 40490 |  
 40491 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40492 |                                                       const details::operator_type& operation, 
 40493 |                                                       expression_node_ptr (&branch)[2]) 
 40494 |             { 
 40495 |                // ((c0 o0 (v0 o1 c1)) o2 v1) 
 40496 |                typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t; 
 40497 |  
 40498 |                const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]); 
 40499 |                const Type  c0 = covoc->t0(); 
 40500 |                const Type& v0 = covoc->t1(); 
 40501 |                const Type  c1 = covoc->t2(); 
 40502 |                const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref(); 
 40503 |                const details::operator_type o0 = expr_gen.get_operator(covoc->f0()); 
 40504 |                const details::operator_type o1 = expr_gen.get_operator(covoc->f1()); 
 40505 |                const details::operator_type o2 = operation; 
 40506 |  
 40507 |                binary_functor_t f0 = covoc->f0(); 
 40508 |                binary_functor_t f1 = covoc->f1(); 
 40509 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40510 |  
 40511 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40512 |  
 40513 |                expression_node_ptr result = error_node(); 
 40514 |  
 40515 |                const bool synthesis_result = 
 40516 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40517 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result); 
 40518 |  
 40519 |                if (synthesis_result) 
 40520 |                   return result; 
 40521 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40522 |                   return error_node(); 
 40523 |  
 40524 |                exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n")); 
 40525 |  
 40526 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2); 
 40527 |             } 
 40528 |  
 40529 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40530 |                                          const details::operator_type o0, 
 40531 |                                          const details::operator_type o1, 
 40532 |                                          const details::operator_type o2) 
 40533 |             { 
 40534 |                return details::build_string() 
 40535 |                   << "(t" << expr_gen.to_str(o0) 
 40536 |                   << "(t" << expr_gen.to_str(o1) 
 40537 |                   << "t)" << expr_gen.to_str(o2) 
 40538 |                   << "t" 
 40539 |             } 
 40540 |          }; 
 40541 |  
 40542 |          struct synthesize_vocovoc_expression4 
 40543 |          { 
 40544 |             typedef typename vocovoc_t::type4 node_type; 
 40545 |             typedef typename vocovoc_t::sf4_type sf4_type; 
 40546 |             typedef typename node_type::T0 T0; 
 40547 |             typedef typename node_type::T1 T1; 
 40548 |             typedef typename node_type::T2 T2; 
 40549 |             typedef typename node_type::T3 T3; 
 40550 |  
 40551 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40552 |                                                       const details::operator_type& operation, 
 40553 |                                                       expression_node_ptr (&branch)[2]) 
 40554 |             { 
 40555 |                // ((v0 o0 (c0 o1 v1)) o2 c1) 
 40556 |                typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t; 
 40557 |  
 40558 |                const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]); 
 40559 |                const Type& v0 = vocov->t0(); 
 40560 |                const Type  c0 = vocov->t1(); 
 40561 |                const Type& v1 = vocov->t2(); 
 40562 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40563 |                const details::operator_type o0 = expr_gen.get_operator(vocov->f0()); 
 40564 |                const details::operator_type o1 = expr_gen.get_operator(vocov->f1()); 
 40565 |                const details::operator_type o2 = operation; 
 40566 |  
 40567 |                binary_functor_t f0 = vocov->f0(); 
 40568 |                binary_functor_t f1 = vocov->f1(); 
 40569 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40570 |  
 40571 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40572 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40573 |  
 40574 |                expression_node_ptr result = error_node(); 
 40575 |  
 40576 |                const bool synthesis_result = 
 40577 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40578 |                      (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result); 
 40579 |  
 40580 |                if (synthesis_result) 
 40581 |                   return result; 
 40582 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40583 |                   return error_node(); 
 40584 |  
 40585 |                exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n")); 
 40586 |  
 40587 |                return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2); 
 40588 |             } 
 40589 |  
 40590 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40591 |                                          const details::operator_type o0, 
 40592 |                                          const details::operator_type o1, 
 40593 |                                          const details::operator_type o2) 
 40594 |             { 
 40595 |                return details::build_string() 
 40596 |                   << "(t" << expr_gen.to_str(o0) 
 40597 |                   << "(t" << expr_gen.to_str(o1) 
 40598 |                   << "t)" << expr_gen.to_str(o2) 
 40599 |                   << "t" 
 40600 |             } 
 40601 |          }; 
 40602 |  
 40603 |          struct synthesize_covovoc_expression4 
 40604 |          { 
 40605 |             typedef typename covovoc_t::type4 node_type; 
 40606 |             typedef typename covovoc_t::sf4_type sf4_type; 
 40607 |             typedef typename node_type::T0 T0; 
 40608 |             typedef typename node_type::T1 T1; 
 40609 |             typedef typename node_type::T2 T2; 
 40610 |             typedef typename node_type::T3 T3; 
 40611 |  
 40612 |             static inline expression_node_ptr process(expression_generator<Type>& expr_gen, 
 40613 |                                                       const details::operator_type& operation, 
 40614 |                                                       expression_node_ptr (&branch)[2]) 
 40615 |             { 
 40616 |                // ((c0 o0 (v0 o1 v1)) o2 c1) 
 40617 |                typedef typename synthesize_covov_expression1::node_type lcl_covov_t; 
 40618 |  
 40619 |                const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]); 
 40620 |                const Type  c0 = covov->t0(); 
 40621 |                const Type& v0 = covov->t1(); 
 40622 |                const Type& v1 = covov->t2(); 
 40623 |                const Type  c1 = static_cast<details::literal_node<Type>*>(branch[1])->value(); 
 40624 |                const details::operator_type o0 = expr_gen.get_operator(covov->f0()); 
 40625 |                const details::operator_type o1 = expr_gen.get_operator(covov->f1()); 
 40626 |                const details::operator_type o2 = operation; 
 40627 |  
 40628 |                binary_functor_t f0 = covov->f0(); 
 40629 |                binary_functor_t f1 = covov->f1(); 
 40630 |                binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0); 
 40631 |  
 40632 |                details::free_node(*(expr_gen.node_allocator_),branch[0]); 
 40633 |                details::free_node(*(expr_gen.node_allocator_),branch[1]); 
 40634 |  
 40635 |                expression_node_ptr result = error_node(); 
 40636 |  
 40637 |                const bool synthesis_result = 
 40638 |                   synthesize_sf4ext_expression::template compile<T0, T1, T2, T3> 
 40639 |                      (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result); 
 40640 |  
 40641 |                if (synthesis_result) 
 40642 |                   return result; 
 40643 |                else if (!expr_gen.valid_operator(o2,f2)) 
 40644 |                   return error_node(); 
 40645 |  
 40646 |                exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n")); 
 40647 |  
 40648 |                return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2); 
 40649 |             } 
 40650 |  
 40651 |             static inline std::string id(expression_generator<Type>& expr_gen, 
 40652 |                                          const details::operator_type o0, 
 40653 |                                          const details::operator_type o1, 
 40654 |                                          const details::operator_type o2) 
 40655 |             { 
 40656 |                return details::build_string() 
 40657 |                   << "(t" << expr_gen.to_str(o0) 
 40658 |                   << "(t" << expr_gen.to_str(o1) 
 40659 |                   << "t)" << expr_gen.to_str(o2) 
 40660 |                   << "t" 
 40661 |             } 
 40662 |          }; 
 40663 |  
 40664 |          struct synthesize_vococov_expression4 
 40665 |          { 
 40666 |             typedef typename vococov_t::type4 node_type; 
 40667 |             static inline expression_node_ptr process(expression_generator<Type>&, 
 40668 |                                                       const details::operator_type&, 
 40669 |                                                       expression_node_ptr (&)[2]) 
 40670 |             { 
 40671 |                // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible 
 40672 |                exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n")); 
 40673 |                return error_node(); 
 40674 |             } 
 40675 |  
 40676 |             static inline std::string id(expression_generator<Type>&, 
 40677 |                                          const details::operator_type, 
 40678 |                                          const details::operator_type, 
 40679 |                                          const details::operator_type) 
 40680 |             { 
 40681 |                return "INVALID" 
 40682 |             } 
 40683 |          }; 
 40684 |          #endif 
 40685 |  
 40686 |          inline expression_node_ptr synthesize_uvouv_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 40687 |          { 
 40688 |             // Definition: uv o uv 
 40689 |             details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation(); 
 40690 |             details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation(); 
 40691 |             const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v(); 
 40692 |             const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v(); 
 40693 |             unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0); 
 40694 |             unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0); 
 40695 |             binary_functor_t f = reinterpret_cast<binary_functor_t>(0); 
 40696 |  
 40697 |             if (!valid_operator(o0,u0)) 
 40698 |                return error_node(); 
 40699 |             else if (!valid_operator(o1,u1)) 
 40700 |                return error_node(); 
 40701 |             else if (!valid_operator(operation,f)) 
 40702 |                return error_node(); 
 40703 |  
 40704 |             expression_node_ptr result = error_node(); 
 40705 |  
 40706 |             if ( 
 40707 |                  (details::e_neg == o0) && 
 40708 |                  (details::e_neg == o1) 
 40709 |                ) 
 40710 |             { 
 40711 |                switch (operation) 
 40712 |                { 
 40713 |                   // (-v0 + -v1) --> -(v0 + v1) 
 40714 |                   case details::e_add : result = (*this)(details::e_neg, 
 40715 |                                                     node_allocator_-> 
 40716 |                                                        allocate_rr<typename details:: 
 40717 |                                                           vov_node<Type,details::add_op<Type> > >(v0, v1)); 
 40718 |                                         exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n")); 
 40719 |                                         break; 
 40720 |  
 40721 |                   // (-v0 - -v1) --> (v1 - v0) 
 40722 |                   case details::e_sub : result = node_allocator_-> 
 40723 |                                                     allocate_rr<typename details:: 
 40724 |                                                        vov_node<Type,details::sub_op<Type> > >(v1, v0); 
 40725 |                                         exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n")); 
 40726 |                                         break; 
 40727 |  
 40728 |                   // (-v0 * -v1) --> (v0 * v1) 
 40729 |                   case details::e_mul : result = node_allocator_-> 
 40730 |                                                     allocate_rr<typename details:: 
 40731 |                                                        vov_node<Type,details::mul_op<Type> > >(v0, v1); 
 40732 |                                         exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n")); 
 40733 |                                         break; 
 40734 |  
 40735 |                   // (-v0 / -v1) --> (v0 / v1) 
 40736 |                   case details::e_div : result = node_allocator_-> 
 40737 |                                                     allocate_rr<typename details:: 
 40738 |                                                        vov_node<Type,details::div_op<Type> > >(v0, v1); 
 40739 |                                         exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n")); 
 40740 |                                         break; 
 40741 |  
 40742 |                   default             : break; 
 40743 |                } 
 40744 |             } 
 40745 |  
 40746 |             if (0 == result) 
 40747 |             { 
 40748 |                result = node_allocator_-> 
 40749 |                             allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f); 
 40750 |             } 
 40751 |  
 40752 |             details::free_all_nodes(*node_allocator_,branch); 
 40753 |             return result; 
 40754 |          } 
 40755 |  
 40756 |          #undef basic_opr_switch_statements 
 40757 |          #undef extended_opr_switch_statements 
 40758 |          #undef unary_opr_switch_statements 
 40759 |  
 40760 |          #ifndef exprtk_disable_string_capabilities 
 40761 |  
 40762 |          #define string_opr_switch_statements            \ 
 40763 |          case_stmt(details::e_lt    , details::lt_op   ) \ 
 40764 |          case_stmt(details::e_lte   , details::lte_op  ) \ 
 40765 |          case_stmt(details::e_gt    , details::gt_op   ) \ 
 40766 |          case_stmt(details::e_gte   , details::gte_op  ) \ 
 40767 |          case_stmt(details::e_eq    , details::eq_op   ) \ 
 40768 |          case_stmt(details::e_ne    , details::ne_op   ) \ 
 40769 |          case_stmt(details::e_in    , details::in_op   ) \ 
 40770 |          case_stmt(details::e_like  , details::like_op ) \ 
 40771 |          case_stmt(details::e_ilike , details::ilike_op) \ 
 40772 |  
 40773 |          template <typename T0, typename T1> 
 40774 |          inline expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type& opr, 
 40775 |                                                                         T0 s0, T1 s1, 
 40776 |                                                                         range_t rp0) 
 40777 |          { 
 40778 |             switch (opr) 
 40779 |             { 
 40780 |                #define case_stmt(op0, op1)                                                                      \ 
 40781 |                case op0 : return node_allocator_->                                                              \ 
 40782 |                              allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \ 
 40783 |                                 (s0, s1, rp0);                                                                  \ 
 40784 |  
 40785 |                string_opr_switch_statements 
 40786 |                #undef case_stmt 
 40787 |                default : return error_node(); 
 40788 |             } 
 40789 |          } 
 40790 |  
 40791 |          template <typename T0, typename T1> 
 40792 |          inline expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type& opr, 
 40793 |                                                                         T0 s0, T1 s1, 
 40794 |                                                                         range_t rp1) 
 40795 |          { 
 40796 |             switch (opr) 
 40797 |             { 
 40798 |                #define case_stmt(op0, op1)                                                                      \ 
 40799 |                case op0 : return node_allocator_->                                                              \ 
 40800 |                              allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \ 
 40801 |                                 (s0, s1, rp1);                                                                  \ 
 40802 |  
 40803 |                string_opr_switch_statements 
 40804 |                #undef case_stmt 
 40805 |                default : return error_node(); 
 40806 |             } 
 40807 |          } 
 40808 |  
 40809 |          template <typename T0, typename T1> 
 40810 |          inline expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type& opr, 
 40811 |                                                                          T0 s0, T1 s1, 
 40812 |                                                                          range_t rp0, range_t rp1) 
 40813 |          { 
 40814 |             switch (opr) 
 40815 |             { 
 40816 |                #define case_stmt(op0, op1)                                                                        \ 
 40817 |                case op0 : return node_allocator_->                                                                \ 
 40818 |                              allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \ 
 40819 |                                 (s0, s1, rp0, rp1);                                                               \ 
 40820 |  
 40821 |                string_opr_switch_statements 
 40822 |                #undef case_stmt 
 40823 |                default : return error_node(); 
 40824 |             } 
 40825 |          } 
 40826 |  
 40827 |          template <typename T0, typename T1> 
 40828 |          inline expression_node_ptr synthesize_sos_expression_impl(const details::operator_type& opr, T0 s0, T1 s1) 
 40829 |          { 
 40830 |             switch (opr) 
 40831 |             { 
 40832 |                #define case_stmt(op0, op1)                                                                 \ 
 40833 |                case op0 : return node_allocator_->                                                         \ 
 40834 |                              allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \ 
 40835 |  
 40836 |                string_opr_switch_statements 
 40837 |                #undef case_stmt 
 40838 |                default : return error_node(); 
 40839 |             } 
 40840 |          } 
 40841 |  
 40842 |          inline expression_node_ptr synthesize_sos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40843 |          { 
 40844 |             std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref(); 
 40845 |             std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref(); 
 40846 |  
 40847 |             return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1); 
 40848 |          } 
 40849 |  
 40850 |          inline expression_node_ptr synthesize_sros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40851 |          { 
 40852 |             std::string&  s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref  (); 
 40853 |             std::string&  s1 = static_cast<details::stringvar_node<Type>*>   (branch[1])->ref  (); 
 40854 |             range_t      rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range(); 
 40855 |  
 40856 |             static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 40857 |  
 40858 |             details::free_node(*node_allocator_,branch[0]); 
 40859 |  
 40860 |             return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0); 
 40861 |          } 
 40862 |  
 40863 |          inline expression_node_ptr synthesize_sosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40864 |          { 
 40865 |             std::string&  s0 = static_cast<details::stringvar_node<Type>*>   (branch[0])->ref  (); 
 40866 |             std::string&  s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref  (); 
 40867 |             range_t      rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range(); 
 40868 |  
 40869 |             static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 40870 |  
 40871 |             details::free_node(*node_allocator_,branch[1]); 
 40872 |  
 40873 |             return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1); 
 40874 |          } 
 40875 |  
 40876 |          inline expression_node_ptr synthesize_socsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40877 |          { 
 40878 |             std::string&  s0 = static_cast<details::stringvar_node<Type>*>         (branch[0])->ref  (); 
 40879 |             std::string   s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 40880 |             range_t      rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 40881 |  
 40882 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 40883 |  
 40884 |             details::free_node(*node_allocator_,branch[1]); 
 40885 |  
 40886 |             return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1); 
 40887 |          } 
 40888 |  
 40889 |          inline expression_node_ptr synthesize_srosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40890 |          { 
 40891 |             std::string&  s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref  (); 
 40892 |             std::string&  s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref  (); 
 40893 |             range_t      rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range(); 
 40894 |             range_t      rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range(); 
 40895 |  
 40896 |             static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 40897 |             static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 40898 |  
 40899 |             details::free_node(*node_allocator_,branch[0]); 
 40900 |             details::free_node(*node_allocator_,branch[1]); 
 40901 |  
 40902 |             return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1); 
 40903 |          } 
 40904 |  
 40905 |          inline expression_node_ptr synthesize_socs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40906 |          { 
 40907 |             std::string& s0 = static_cast<     details::stringvar_node<Type>*>(branch[0])->ref(); 
 40908 |             std::string  s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 40909 |  
 40910 |             details::free_node(*node_allocator_,branch[1]); 
 40911 |  
 40912 |             return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1); 
 40913 |          } 
 40914 |  
 40915 |          inline expression_node_ptr synthesize_csos_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40916 |          { 
 40917 |             std::string  s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 40918 |             std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 40919 |  
 40920 |             details::free_node(*node_allocator_,branch[0]); 
 40921 |  
 40922 |             return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1); 
 40923 |          } 
 40924 |  
 40925 |          inline expression_node_ptr synthesize_csosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40926 |          { 
 40927 |             std::string  s0  = static_cast<details::string_literal_node<Type>*>(branch[0])->str  (); 
 40928 |             std::string& s1  = static_cast<details::string_range_node<Type>*  >(branch[1])->ref  (); 
 40929 |             range_t      rp1 = static_cast<details::string_range_node<Type>*  >(branch[1])->range(); 
 40930 |  
 40931 |             static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 40932 |  
 40933 |             details::free_node(*node_allocator_,branch[0]); 
 40934 |             details::free_node(*node_allocator_,branch[1]); 
 40935 |  
 40936 |             return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1); 
 40937 |          } 
 40938 |  
 40939 |          inline expression_node_ptr synthesize_srocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40940 |          { 
 40941 |             std::string&  s0 = static_cast<details::string_range_node<Type>*  >(branch[0])->ref  (); 
 40942 |             std::string   s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str  (); 
 40943 |             range_t      rp0 = static_cast<details::string_range_node<Type>*  >(branch[0])->range(); 
 40944 |  
 40945 |             static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 40946 |  
 40947 |             details::free_node(*node_allocator_,branch[0]); 
 40948 |             details::free_node(*node_allocator_,branch[1]); 
 40949 |  
 40950 |             return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0); 
 40951 |          } 
 40952 |  
 40953 |          inline expression_node_ptr synthesize_srocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40954 |          { 
 40955 |             std::string&  s0 = static_cast<details::string_range_node<Type>*      >(branch[0])->ref  (); 
 40956 |             std::string   s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 40957 |             range_t      rp0 = static_cast<details::string_range_node<Type>*      >(branch[0])->range(); 
 40958 |             range_t      rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 40959 |  
 40960 |             static_cast<details::string_range_node<Type>*>      (branch[0])->range_ref().clear(); 
 40961 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 40962 |  
 40963 |             details::free_node(*node_allocator_,branch[0]); 
 40964 |             details::free_node(*node_allocator_,branch[1]); 
 40965 |  
 40966 |             return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1); 
 40967 |          } 
 40968 |  
 40969 |          inline expression_node_ptr synthesize_csocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 40970 |          { 
 40971 |             const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 40972 |             const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 40973 |  
 40974 |             expression_node_ptr result = error_node(); 
 40975 |  
 40976 |             if (details::e_add == opr) 
 40977 |                result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1); 
 40978 |             else if (details::e_in == opr) 
 40979 |                result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op   <Type>::process(s0,s1)); 
 40980 |             else if (details::e_like == opr) 
 40981 |                result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op <Type>::process(s0,s1)); 
 40982 |             else if (details::e_ilike == opr) 
 40983 |                result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1)); 
 40984 |             else 
 40985 |             { 
 40986 |                expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1); 
 40987 |  
 40988 |                const Type v = temp->value(); 
 40989 |  
 40990 |                details::free_node(*node_allocator_,temp); 
 40991 |  
 40992 |                result = node_allocator_->allocate<literal_node_t>(v); 
 40993 |             } 
 40994 |  
 40995 |             details::free_all_nodes(*node_allocator_,branch); 
 40996 |  
 40997 |             return result; 
 40998 |          } 
 40999 |  
 41000 |          inline expression_node_ptr synthesize_csocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41001 |          { 
 41002 |             const std::string s0 = static_cast<details::string_literal_node<Type>*    >(branch[0])->str  (); 
 41003 |                   std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 41004 |             range_t          rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 41005 |  
 41006 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41007 |  
 41008 |             details::free_node(*node_allocator_,branch[0]); 
 41009 |             details::free_node(*node_allocator_,branch[1]); 
 41010 |  
 41011 |             return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1); 
 41012 |          } 
 41013 |  
 41014 |          inline expression_node_ptr synthesize_csros_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41015 |          { 
 41016 |             std::string   s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41017 |             std::string&  s1 = static_cast<details::stringvar_node<Type>*         >(branch[1])->ref  (); 
 41018 |             range_t      rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41019 |  
 41020 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41021 |  
 41022 |             details::free_node(*node_allocator_,branch[0]); 
 41023 |  
 41024 |             return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0); 
 41025 |          } 
 41026 |  
 41027 |          inline expression_node_ptr synthesize_csrosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41028 |          { 
 41029 |             const std::string  s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41030 |                   std::string& s1 = static_cast<details::string_range_node<Type>*      >(branch[1])->ref  (); 
 41031 |             const range_t     rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41032 |             const range_t     rp1 = static_cast<details::string_range_node<Type>*      >(branch[1])->range(); 
 41033 |  
 41034 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41035 |             static_cast<details::string_range_node<Type>*>      (branch[1])->range_ref().clear(); 
 41036 |  
 41037 |             details::free_node(*node_allocator_,branch[0]); 
 41038 |             details::free_node(*node_allocator_,branch[1]); 
 41039 |  
 41040 |             return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1); 
 41041 |          } 
 41042 |  
 41043 |          inline expression_node_ptr synthesize_csrocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41044 |          { 
 41045 |             const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41046 |             const std::string s1 = static_cast<details::string_literal_node<Type>*    >(branch[1])->str  (); 
 41047 |             const range_t    rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41048 |  
 41049 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41050 |  
 41051 |             details::free_all_nodes(*node_allocator_,branch); 
 41052 |  
 41053 |             return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0); 
 41054 |          } 
 41055 |  
 41056 |          inline expression_node_ptr synthesize_csrocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41057 |          { 
 41058 |             const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str  (); 
 41059 |             const std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str  (); 
 41060 |             const range_t    rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range(); 
 41061 |             const range_t    rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range(); 
 41062 |  
 41063 |             static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear(); 
 41064 |             static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear(); 
 41065 |  
 41066 |             details::free_all_nodes(*node_allocator_,branch); 
 41067 |  
 41068 |             return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1); 
 41069 |          } 
 41070 |  
 41071 |          inline expression_node_ptr synthesize_strogen_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41072 |          { 
 41073 |             switch (opr) 
 41074 |             { 
 41075 |                #define case_stmt(op0, op1)                                                      \ 
 41076 |                case op0 : return node_allocator_->                                              \ 
 41077 |                              allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > >  \ 
 41078 |                                 (opr, branch[0], branch[1]);                                    \ 
 41079 |  
 41080 |                string_opr_switch_statements 
 41081 |                #undef case_stmt 
 41082 |                default : return error_node(); 
 41083 |             } 
 41084 |          } 
 41085 |  
 41086 |          #undef string_opr_switch_statements 
 41087 |          #endif 
 41088 |  
 41089 |          #ifndef exprtk_disable_string_capabilities 
 41090 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) 
 41091 |          { 
 41092 |             if ((0 == branch[0]) || (0 == branch[1])) 
 41093 |             { 
 41094 |                details::free_all_nodes(*node_allocator_,branch); 
 41095 |  
 41096 |                return error_node(); 
 41097 |             } 
 41098 |  
 41099 |             const bool b0_is_s   = details::is_string_node            (branch[0]); 
 41100 |             const bool b0_is_cs  = details::is_const_string_node      (branch[0]); 
 41101 |             const bool b0_is_sr  = details::is_string_range_node      (branch[0]); 
 41102 |             const bool b0_is_csr = details::is_const_string_range_node(branch[0]); 
 41103 |  
 41104 |             const bool b1_is_s   = details::is_string_node            (branch[1]); 
 41105 |             const bool b1_is_cs  = details::is_const_string_node      (branch[1]); 
 41106 |             const bool b1_is_sr  = details::is_string_range_node      (branch[1]); 
 41107 |             const bool b1_is_csr = details::is_const_string_range_node(branch[1]); 
 41108 |  
 41109 |             const bool b0_is_gen = details::is_string_assignment_node (branch[0]) || 
 41110 |                                    details::is_genricstring_range_node(branch[0]) || 
 41111 |                                    details::is_string_concat_node     (branch[0]) || 
 41112 |                                    details::is_string_function_node   (branch[0]) || 
 41113 |                                    details::is_string_condition_node  (branch[0]) || 
 41114 |                                    details::is_string_ccondition_node (branch[0]) || 
 41115 |                                    details::is_string_vararg_node     (branch[0]) ; 
 41116 |  
 41117 |             const bool b1_is_gen = details::is_string_assignment_node (branch[1]) || 
 41118 |                                    details::is_genricstring_range_node(branch[1]) || 
 41119 |                                    details::is_string_concat_node     (branch[1]) || 
 41120 |                                    details::is_string_function_node   (branch[1]) || 
 41121 |                                    details::is_string_condition_node  (branch[1]) || 
 41122 |                                    details::is_string_ccondition_node (branch[1]) || 
 41123 |                                    details::is_string_vararg_node     (branch[1]) ; 
 41124 |  
 41125 |             if (details::e_add == opr) 
 41126 |             { 
 41127 |                if (!b0_is_cs || !b1_is_cs) 
 41128 |                { 
 41129 |                   return synthesize_expression<string_concat_node_t,2>(opr,branch); 
 41130 |                } 
 41131 |             } 
 41132 |  
 41133 |             if (b0_is_gen || b1_is_gen) 
 41134 |             { 
 41135 |                return synthesize_strogen_expression(opr,branch); 
 41136 |             } 
 41137 |             else if (b0_is_s) 
 41138 |             { 
 41139 |                if      (b1_is_s  ) return synthesize_sos_expression   (opr,branch); 
 41140 |                else if (b1_is_cs ) return synthesize_socs_expression  (opr,branch); 
 41141 |                else if (b1_is_sr ) return synthesize_sosr_expression  (opr,branch); 
 41142 |                else if (b1_is_csr) return synthesize_socsr_expression (opr,branch); 
 41143 |             } 
 41144 |             else if (b0_is_cs) 
 41145 |             { 
 41146 |                if      (b1_is_s  ) return synthesize_csos_expression  (opr,branch); 
 41147 |                else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch); 
 41148 |                else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch); 
 41149 |                else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch); 
 41150 |             } 
 41151 |             else if (b0_is_sr) 
 41152 |             { 
 41153 |                if      (b1_is_s  ) return synthesize_sros_expression  (opr,branch); 
 41154 |                else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch); 
 41155 |                else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch); 
 41156 |                else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch); 
 41157 |             } 
 41158 |             else if (b0_is_csr) 
 41159 |             { 
 41160 |                if      (b1_is_s  ) return synthesize_csros_expression  (opr,branch); 
 41161 |                else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch); 
 41162 |                else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch); 
 41163 |                else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch); 
 41164 |             } 
 41165 |  
 41166 |             return error_node(); 
 41167 |          } 
 41168 |          #else 
 41169 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2]) 
 41170 |          { 
 41171 |             details::free_all_nodes(*node_allocator_,branch); 
 41172 |             return error_node(); 
 41173 |          } 
 41174 |          #endif 
 41175 |  
 41176 |          #ifndef exprtk_disable_string_capabilities 
 41177 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type& opr, expression_node_ptr (&branch)[3]) 
 41178 |          { 
 41179 |             if (details::e_inrange != opr) 
 41180 |                return error_node(); 
 41181 |             else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2])) 
 41182 |             { 
 41183 |                details::free_all_nodes(*node_allocator_,branch); 
 41184 |  
 41185 |                return error_node(); 
 41186 |             } 
 41187 |             else if ( 
 41188 |                       details::is_const_string_node(branch[0]) && 
 41189 |                       details::is_const_string_node(branch[1]) && 
 41190 |                       details::is_const_string_node(branch[2]) 
 41191 |                     ) 
 41192 |             { 
 41193 |                const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41194 |                const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 41195 |                const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str(); 
 41196 |  
 41197 |                const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0)); 
 41198 |  
 41199 |                details::free_all_nodes(*node_allocator_,branch); 
 41200 |  
 41201 |                return node_allocator_->allocate_c<details::literal_node<Type> >(v); 
 41202 |             } 
 41203 |             else if ( 
 41204 |                       details::is_string_node(branch[0]) && 
 41205 |                       details::is_string_node(branch[1]) && 
 41206 |                       details::is_string_node(branch[2]) 
 41207 |                     ) 
 41208 |             { 
 41209 |                std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref(); 
 41210 |                std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref(); 
 41211 |                std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref(); 
 41212 |  
 41213 |                typedef typename details::sosos_node<Type, std::string&, std::string&, std::string&, details::inrange_op<Type> > inrange_t; 
 41214 |  
 41215 |                return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string&>(s0, s1, s2); 
 41216 |             } 
 41217 |             else if ( 
 41218 |                       details::is_const_string_node(branch[0]) && 
 41219 |                             details::is_string_node(branch[1]) && 
 41220 |                       details::is_const_string_node(branch[2]) 
 41221 |                     ) 
 41222 |             { 
 41223 |                std::string  s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41224 |                std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 41225 |                std::string  s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str(); 
 41226 |  
 41227 |                typedef typename details::sosos_node<Type, std::string, std::string&, std::string, details::inrange_op<Type> > inrange_t; 
 41228 |  
 41229 |                details::free_node(*node_allocator_,branch[0]); 
 41230 |                details::free_node(*node_allocator_,branch[2]); 
 41231 |  
 41232 |                return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string>(s0, s1, s2); 
 41233 |             } 
 41234 |             else if ( 
 41235 |                             details::is_string_node(branch[0]) && 
 41236 |                       details::is_const_string_node(branch[1]) && 
 41237 |                             details::is_string_node(branch[2]) 
 41238 |                     ) 
 41239 |             { 
 41240 |                std::string&  s0 = static_cast<details::stringvar_node<Type>*     >(branch[0])->ref(); 
 41241 |                std::string   s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str(); 
 41242 |                std::string&  s2 = static_cast<details::stringvar_node<Type>*     >(branch[2])->ref(); 
 41243 |  
 41244 |                typedef typename details::sosos_node<Type, std::string&, std::string, std::string&, details::inrange_op<Type> > inrange_t; 
 41245 |  
 41246 |                details::free_node(*node_allocator_,branch[1]); 
 41247 |  
 41248 |                return node_allocator_->allocate_type<inrange_t, std::string&, std::string, std::string&>(s0, s1, s2); 
 41249 |             } 
 41250 |             else if ( 
 41251 |                       details::is_string_node(branch[0]) && 
 41252 |                       details::is_string_node(branch[1]) && 
 41253 |                       details::is_const_string_node(branch[2]) 
 41254 |                     ) 
 41255 |             { 
 41256 |                std::string& s0 = static_cast<details::stringvar_node<Type>*     >(branch[0])->ref(); 
 41257 |                std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 41258 |                std::string  s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str(); 
 41259 |  
 41260 |                typedef typename details::sosos_node<Type, std::string&, std::string&, std::string, details::inrange_op<Type> > inrange_t; 
 41261 |  
 41262 |                details::free_node(*node_allocator_,branch[2]); 
 41263 |  
 41264 |                return node_allocator_->allocate_type<inrange_t, std::string&, std::string&, std::string>(s0, s1, s2); 
 41265 |             } 
 41266 |             else if ( 
 41267 |                       details::is_const_string_node(branch[0]) && 
 41268 |                       details::      is_string_node(branch[1]) && 
 41269 |                       details::      is_string_node(branch[2]) 
 41270 |                     ) 
 41271 |             { 
 41272 |                std::string  s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str(); 
 41273 |                std::string& s1 = static_cast<details::stringvar_node<Type>*     >(branch[1])->ref(); 
 41274 |                std::string& s2 = static_cast<details::stringvar_node<Type>*     >(branch[2])->ref(); 
 41275 |  
 41276 |                typedef typename details::sosos_node<Type, std::string, std::string&, std::string&, details::inrange_op<Type> > inrange_t; 
 41277 |  
 41278 |                details::free_node(*node_allocator_,branch[0]); 
 41279 |  
 41280 |                return node_allocator_->allocate_type<inrange_t, std::string, std::string&, std::string&>(s0, s1, s2); 
 41281 |             } 
 41282 |             else 
 41283 |                return error_node(); 
 41284 |          } 
 41285 |          #else 
 41286 |          inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3]) 
 41287 |          { 
 41288 |             details::free_all_nodes(*node_allocator_,branch); 
 41289 |             return error_node(); 
 41290 |          } 
 41291 |          #endif 
 41292 |  
 41293 |          inline expression_node_ptr synthesize_null_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) 
 41294 |          { 
 41295 |             /* 
 41296 |              Note: The following are the type promotion rules 
 41297 |              that relate to operations that include 'null': 
 41298 |              0. null ==/!=     null --> true false 
 41299 |              1. null operation null --> null 
 41300 |              2. x    ==/!=     null --> true/false 
 41301 |              3. null ==/!=     x    --> true/false 
 41302 |              4. x   operation  null --> x 
 41303 |              5. null operation x    --> x 
 41304 |             */ 
 41305 |  
 41306 |             typedef typename details::null_eq_node<T> nulleq_node_t; 
 41307 |  
 41308 |             const bool b0_null = details::is_null_node(branch[0]); 
 41309 |             const bool b1_null = details::is_null_node(branch[1]); 
 41310 |  
 41311 |             if (b0_null && b1_null) 
 41312 |             { 
 41313 |                expression_node_ptr result = error_node(); 
 41314 |  
 41315 |                if (details::e_eq == operation) 
 41316 |                   result = node_allocator_->allocate_c<literal_node_t>(T(1)); 
 41317 |                else if (details::e_ne == operation) 
 41318 |                   result = node_allocator_->allocate_c<literal_node_t>(T(0)); 
 41319 |  
 41320 |                if (result) 
 41321 |                { 
 41322 |                   details::free_node(*node_allocator_,branch[0]); 
 41323 |                   details::free_node(*node_allocator_,branch[1]); 
 41324 |  
 41325 |                   return result; 
 41326 |                } 
 41327 |  
 41328 |                details::free_node(*node_allocator_,branch[1]); 
 41329 |  
 41330 |                return branch[0]; 
 41331 |             } 
 41332 |             else if (details::e_eq == operation) 
 41333 |             { 
 41334 |                expression_node_ptr result = node_allocator_-> 
 41335 |                                                 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true); 
 41336 |  
 41337 |                details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]); 
 41338 |  
 41339 |                return result; 
 41340 |             } 
 41341 |             else if (details::e_ne == operation) 
 41342 |             { 
 41343 |                expression_node_ptr result = node_allocator_-> 
 41344 |                                                 allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false); 
 41345 |  
 41346 |                details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]); 
 41347 |  
 41348 |                return result; 
 41349 |             } 
 41350 |             else if (b0_null) 
 41351 |             { 
 41352 |                details::free_node(*node_allocator_,branch[0]); 
 41353 |                branch[0] = branch[1]; 
 41354 |                branch[1] = error_node(); 
 41355 |             } 
 41356 |             else if (b1_null) 
 41357 |             { 
 41358 |                details::free_node(*node_allocator_,branch[1]); 
 41359 |                branch[1] = error_node(); 
 41360 |             } 
 41361 |  
 41362 |             if ( 
 41363 |                  (details::e_add == operation) || (details::e_sub == operation) || 
 41364 |                  (details::e_mul == operation) || (details::e_div == operation) || 
 41365 |                  (details::e_mod == operation) || (details::e_pow == operation) 
 41366 |                ) 
 41367 |             { 
 41368 |                return branch[0]; 
 41369 |             } 
 41370 |  
 41371 |             details::free_node(*node_allocator_, branch[0]); 
 41372 |  
 41373 |             if ( 
 41374 |                  (details::e_lt    == operation) || (details::e_lte  == operation) || 
 41375 |                  (details::e_gt    == operation) || (details::e_gte  == operation) || 
 41376 |                  (details::e_and   == operation) || (details::e_nand == operation) || 
 41377 |                  (details::e_or    == operation) || (details::e_nor  == operation) || 
 41378 |                  (details::e_xor   == operation) || (details::e_xnor == operation) || 
 41379 |                  (details::e_in    == operation) || (details::e_like == operation) || 
 41380 |                  (details::e_ilike == operation) 
 41381 |                ) 
 41382 |             { 
 41383 |                return node_allocator_->allocate_c<literal_node_t>(T(0)); 
 41384 |             } 
 41385 |  
 41386 |             return node_allocator_->allocate<details::null_node<Type> >(); 
 41387 |          } 
 41388 |  
 41389 |          template <typename NodeType, std::size_t N> 
 41390 |          inline expression_node_ptr synthesize_expression(const details::operator_type& operation, expression_node_ptr (&branch)[N]) 
 41391 |          { 
 41392 |             if ( 
 41393 |                  (details::e_in    == operation) || 
 41394 |                  (details::e_like  == operation) || 
 41395 |                  (details::e_ilike == operation) 
 41396 |                ) 
 41397 |             { 
 41398 |                free_all_nodes(*node_allocator_,branch); 
 41399 |  
 41400 |                return error_node(); 
 41401 |             } 
 41402 |             else if (!details::all_nodes_valid<N>(branch)) 
 41403 |             { 
 41404 |                free_all_nodes(*node_allocator_,branch); 
 41405 |  
 41406 |                return error_node(); 
 41407 |             } 
 41408 |             else if ((details::e_default != operation)) 
 41409 |             { 
 41410 |                // Attempt simple constant folding optimisation. 
 41411 |                expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch); 
 41412 |  
 41413 |                if (is_constant_foldable<N>(branch)) 
 41414 |                { 
 41415 |                   const Type v = expression_point->value(); 
 41416 |                   details::free_node(*node_allocator_,expression_point); 
 41417 |  
 41418 |                   return node_allocator_->allocate<literal_node_t>(v); 
 41419 |                } 
 41420 |  
 41421 |                if (expression_point && expression_point->valid()) 
 41422 |                { 
 41423 |                   return expression_point; 
 41424 |                } 
 41425 |  
 41426 |                parser_->set_error(parser_error::make_error( 
 41427 |                   parser_error::e_parser, 
 41428 |                   token_t(), 
 41429 |                   "ERR276 - Failed to synthesize node: NodeType", 
 41430 |                   exprtk_error_location)); 
 41431 |  
 41432 |                details::free_node(*node_allocator_, expression_point); 
 41433 |             } 
 41434 |  
 41435 |             return error_node(); 
 41436 |          } 
 41437 |  
 41438 |          template <typename NodeType, std::size_t N> 
 41439 |          inline expression_node_ptr synthesize_expression(F* f, expression_node_ptr (&branch)[N]) 
 41440 |          { 
 41441 |             if (!details::all_nodes_valid<N>(branch)) 
 41442 |             { 
 41443 |                free_all_nodes(*node_allocator_,branch); 
 41444 |  
 41445 |                return error_node(); 
 41446 |             } 
 41447 |  
 41448 |             typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t; 
 41449 |  
 41450 |             // Attempt simple constant folding optimisation. 
 41451 |  
 41452 |             expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f); 
 41453 |             function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point); 
 41454 |  
 41455 |             if (0 == func_node_ptr) 
 41456 |             { 
 41457 |                free_all_nodes(*node_allocator_,branch); 
 41458 |  
 41459 |                return error_node(); 
 41460 |             } 
 41461 |             else 
 41462 |                func_node_ptr->init_branches(branch); 
 41463 |  
 41464 |             if (is_constant_foldable<N>(branch) && !f->has_side_effects()) 
 41465 |             { 
 41466 |                Type v = expression_point->value(); 
 41467 |                details::free_node(*node_allocator_,expression_point); 
 41468 |  
 41469 |                return node_allocator_->allocate<literal_node_t>(v); 
 41470 |             } 
 41471 |  
 41472 |             parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)"); 
 41473 |  
 41474 |             return expression_point; 
 41475 |          } 
 41476 |  
 41477 |          bool                     strength_reduction_enabled_; 
 41478 |          details::node_allocator* node_allocator_; 
 41479 |          synthesize_map_t         synthesize_map_; 
 41480 |          unary_op_map_t*          unary_op_map_; 
 41481 |          binary_op_map_t*         binary_op_map_; 
 41482 |          inv_binary_op_map_t*     inv_binary_op_map_; 
 41483 |          sf3_map_t*               sf3_map_; 
 41484 |          sf4_map_t*               sf4_map_; 
 41485 |          parser_t*                parser_; 
 41486 |       }; // class expression_generator 
 41487 |  
 41488 |       inline void set_error(const parser_error::type& error_type) 
 41489 |       { 
 41490 |          error_list_.push_back(error_type); 
 41491 |       } 
 41492 |  
 41493 |       inline void remove_last_error() 
 41494 |       { 
 41495 |          if (!error_list_.empty()) 
 41496 |          { 
 41497 |             error_list_.pop_back(); 
 41498 |          } 
 41499 |       } 
 41500 |  
 41501 |       inline void set_synthesis_error(const std::string& synthesis_error_message) 
 41502 |       { 
 41503 |          if (synthesis_error_.empty()) 
 41504 |          { 
 41505 |             synthesis_error_ = synthesis_error_message; 
 41506 |          } 
 41507 |       } 
 41508 |  
 41509 |       inline void register_local_vars(expression<T>& e) 
 41510 |       { 
 41511 |          for (std::size_t i = 0; i < sem_.size(); ++i) 
 41512 |          { 
 41513 |             scope_element& se = sem_.get_element(i); 
 41514 |  
 41515 |             exprtk_debug(("register_local_vars() - se[%s]\n", se.name.c_str())); 
 41516 |  
 41517 |             if ( 
 41518 |                  (scope_element::e_variable == se.type) || 
 41519 |                  (scope_element::e_literal  == se.type) || 
 41520 |                  (scope_element::e_vecelem  == se.type) 
 41521 |                ) 
 41522 |             { 
 41523 |                if (se.var_node) 
 41524 |                { 
 41525 |                   e.register_local_var(se.var_node); 
 41526 |                } 
 41527 |  
 41528 |                if (se.data) 
 41529 |                { 
 41530 |                   e.register_local_data(se.data, 1, 0); 
 41531 |                } 
 41532 |             } 
 41533 |             else if (scope_element::e_vector == se.type) 
 41534 |             { 
 41535 |                if (se.vec_node) 
 41536 |                { 
 41537 |                   e.register_local_var(se.vec_node); 
 41538 |                } 
 41539 |  
 41540 |                if (se.data) 
 41541 |                { 
 41542 |                   e.register_local_data(se.data, se.size, 1); 
 41543 |                } 
 41544 |             } 
 41545 |             #ifndef exprtk_disable_string_capabilities 
 41546 |             else if (scope_element::e_string == se.type) 
 41547 |             { 
 41548 |                if (se.str_node) 
 41549 |                { 
 41550 |                   e.register_local_var(se.str_node); 
 41551 |                } 
 41552 |  
 41553 |                if (se.data) 
 41554 |                { 
 41555 |                   e.register_local_data(se.data, se.size, 2); 
 41556 |                } 
 41557 |             } 
 41558 |             #endif 
 41559 |  
 41560 |             se.var_node  = 0; 
 41561 |             se.vec_node  = 0; 
 41562 |             #ifndef exprtk_disable_string_capabilities 
 41563 |             se.str_node  = 0; 
 41564 |             #endif 
 41565 |             se.data      = 0; 
 41566 |             se.ref_count = 0; 
 41567 |             se.active    = false; 
 41568 |          } 
 41569 |       } 
 41570 |  
 41571 |       inline void register_return_results(expression<T>& e) 
 41572 |       { 
 41573 |          e.register_return_results(results_context_); 
 41574 |          results_context_ = 0; 
 41575 |       } 
 41576 |  
 41577 |       inline void load_unary_operations_map(unary_op_map_t& m) 
 41578 |       { 
 41579 |          #define register_unary_op(Op, UnaryFunctor)            \ 
 41580 |          m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \ 
 41581 |  
 41582 |          register_unary_op(details::e_abs   , details::abs_op  ) 
 41583 |          register_unary_op(details::e_acos  , details::acos_op ) 
 41584 |          register_unary_op(details::e_acosh , details::acosh_op) 
 41585 |          register_unary_op(details::e_asin  , details::asin_op ) 
 41586 |          register_unary_op(details::e_asinh , details::asinh_op) 
 41587 |          register_unary_op(details::e_atanh , details::atanh_op) 
 41588 |          register_unary_op(details::e_ceil  , details::ceil_op ) 
 41589 |          register_unary_op(details::e_cos   , details::cos_op  ) 
 41590 |          register_unary_op(details::e_cosh  , details::cosh_op ) 
 41591 |          register_unary_op(details::e_exp   , details::exp_op  ) 
 41592 |          register_unary_op(details::e_expm1 , details::expm1_op) 
 41593 |          register_unary_op(details::e_floor , details::floor_op) 
 41594 |          register_unary_op(details::e_log   , details::log_op  ) 
 41595 |          register_unary_op(details::e_log10 , details::log10_op) 
 41596 |          register_unary_op(details::e_log2  , details::log2_op ) 
 41597 |          register_unary_op(details::e_log1p , details::log1p_op) 
 41598 |          register_unary_op(details::e_neg   , details::neg_op  ) 
 41599 |          register_unary_op(details::e_pos   , details::pos_op  ) 
 41600 |          register_unary_op(details::e_round , details::round_op) 
 41601 |          register_unary_op(details::e_sin   , details::sin_op  ) 
 41602 |          register_unary_op(details::e_sinc  , details::sinc_op ) 
 41603 |          register_unary_op(details::e_sinh  , details::sinh_op ) 
 41604 |          register_unary_op(details::e_sqrt  , details::sqrt_op ) 
 41605 |          register_unary_op(details::e_tan   , details::tan_op  ) 
 41606 |          register_unary_op(details::e_tanh  , details::tanh_op ) 
 41607 |          register_unary_op(details::e_cot   , details::cot_op  ) 
 41608 |          register_unary_op(details::e_sec   , details::sec_op  ) 
 41609 |          register_unary_op(details::e_csc   , details::csc_op  ) 
 41610 |          register_unary_op(details::e_r2d   , details::r2d_op  ) 
 41611 |          register_unary_op(details::e_d2r   , details::d2r_op  ) 
 41612 |          register_unary_op(details::e_d2g   , details::d2g_op  ) 
 41613 |          register_unary_op(details::e_g2d   , details::g2d_op  ) 
 41614 |          register_unary_op(details::e_notl  , details::notl_op ) 
 41615 |          register_unary_op(details::e_sgn   , details::sgn_op  ) 
 41616 |          register_unary_op(details::e_erf   , details::erf_op  ) 
 41617 |          register_unary_op(details::e_erfc  , details::erfc_op ) 
 41618 |          register_unary_op(details::e_ncdf  , details::ncdf_op ) 
 41619 |          register_unary_op(details::e_frac  , details::frac_op ) 
 41620 |          register_unary_op(details::e_trunc , details::trunc_op) 
 41621 |          #undef register_unary_op 
 41622 |       } 
 41623 |  
 41624 |       inline void load_binary_operations_map(binary_op_map_t& m) 
 41625 |       { 
 41626 |          typedef typename binary_op_map_t::value_type value_type; 
 41627 |  
 41628 |          #define register_binary_op(Op, BinaryFunctor)       \ 
 41629 |          m.insert(value_type(Op,BinaryFunctor<T>::process)); \ 
 41630 |  
 41631 |          register_binary_op(details::e_add  , details::add_op ) 
 41632 |          register_binary_op(details::e_sub  , details::sub_op ) 
 41633 |          register_binary_op(details::e_mul  , details::mul_op ) 
 41634 |          register_binary_op(details::e_div  , details::div_op ) 
 41635 |          register_binary_op(details::e_mod  , details::mod_op ) 
 41636 |          register_binary_op(details::e_pow  , details::pow_op ) 
 41637 |          register_binary_op(details::e_lt   , details::lt_op  ) 
 41638 |          register_binary_op(details::e_lte  , details::lte_op ) 
 41639 |          register_binary_op(details::e_gt   , details::gt_op  ) 
 41640 |          register_binary_op(details::e_gte  , details::gte_op ) 
 41641 |          register_binary_op(details::e_eq   , details::eq_op  ) 
 41642 |          register_binary_op(details::e_ne   , details::ne_op  ) 
 41643 |          register_binary_op(details::e_and  , details::and_op ) 
 41644 |          register_binary_op(details::e_nand , details::nand_op) 
 41645 |          register_binary_op(details::e_or   , details::or_op  ) 
 41646 |          register_binary_op(details::e_nor  , details::nor_op ) 
 41647 |          register_binary_op(details::e_xor  , details::xor_op ) 
 41648 |          register_binary_op(details::e_xnor , details::xnor_op) 
 41649 |          #undef register_binary_op 
 41650 |       } 
 41651 |  
 41652 |       inline void load_inv_binary_operations_map(inv_binary_op_map_t& m) 
 41653 |       { 
 41654 |          typedef typename inv_binary_op_map_t::value_type value_type; 
 41655 |  
 41656 |          #define register_binary_op(Op, BinaryFunctor)       \ 
 41657 |          m.insert(value_type(BinaryFunctor<T>::process,Op)); \ 
 41658 |  
 41659 |          register_binary_op(details::e_add  , details::add_op ) 
 41660 |          register_binary_op(details::e_sub  , details::sub_op ) 
 41661 |          register_binary_op(details::e_mul  , details::mul_op ) 
 41662 |          register_binary_op(details::e_div  , details::div_op ) 
 41663 |          register_binary_op(details::e_mod  , details::mod_op ) 
 41664 |          register_binary_op(details::e_pow  , details::pow_op ) 
 41665 |          register_binary_op(details::e_lt   , details::lt_op  ) 
 41666 |          register_binary_op(details::e_lte  , details::lte_op ) 
 41667 |          register_binary_op(details::e_gt   , details::gt_op  ) 
 41668 |          register_binary_op(details::e_gte  , details::gte_op ) 
 41669 |          register_binary_op(details::e_eq   , details::eq_op  ) 
 41670 |          register_binary_op(details::e_ne   , details::ne_op  ) 
 41671 |          register_binary_op(details::e_and  , details::and_op ) 
 41672 |          register_binary_op(details::e_nand , details::nand_op) 
 41673 |          register_binary_op(details::e_or   , details::or_op  ) 
 41674 |          register_binary_op(details::e_nor  , details::nor_op ) 
 41675 |          register_binary_op(details::e_xor  , details::xor_op ) 
 41676 |          register_binary_op(details::e_xnor , details::xnor_op) 
 41677 |          #undef register_binary_op 
 41678 |       } 
 41679 |  
 41680 |       inline void load_sf3_map(sf3_map_t& sf3_map) 
 41681 |       { 
 41682 |          typedef std::pair<trinary_functor_t,details::operator_type> pair_t; 
 41683 |  
 41684 |          #define register_sf3(Op)                                                                             \ 
 41685 |          sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \ 
 41686 |  
 41687 |          register_sf3(00) register_sf3(01) register_sf3(02) register_sf3(03) 
 41688 |          register_sf3(04) register_sf3(05) register_sf3(06) register_sf3(07) 
 41689 |          register_sf3(08) register_sf3(09) register_sf3(10) register_sf3(11) 
 41690 |          register_sf3(12) register_sf3(13) register_sf3(14) register_sf3(15) 
 41691 |          register_sf3(16) register_sf3(17) register_sf3(18) register_sf3(19) 
 41692 |          register_sf3(20) register_sf3(21) register_sf3(22) register_sf3(23) 
 41693 |          register_sf3(24) register_sf3(25) register_sf3(26) register_sf3(27) 
 41694 |          register_sf3(28) register_sf3(29) register_sf3(30) 
 41695 |          #undef register_sf3 
 41696 |  
 41697 |          #define register_sf3_extid(Id, Op)                                        \ 
 41698 |          sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \ 
 41699 |  
 41700 |          register_sf3_extid("(t-t)-t",23)  // (t-t)-t --> t-(t+t) 
 41701 |          #undef register_sf3_extid 
 41702 |       } 
 41703 |  
 41704 |       inline void load_sf4_map(sf4_map_t& sf4_map) 
 41705 |       { 
 41706 |          typedef std::pair<quaternary_functor_t,details::operator_type> pair_t; 
 41707 |  
 41708 |          #define register_sf4(Op)                                                                             \ 
 41709 |          sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \ 
 41710 |  
 41711 |          register_sf4(48) register_sf4(49) register_sf4(50) register_sf4(51) 
 41712 |          register_sf4(52) register_sf4(53) register_sf4(54) register_sf4(55) 
 41713 |          register_sf4(56) register_sf4(57) register_sf4(58) register_sf4(59) 
 41714 |          register_sf4(60) register_sf4(61) register_sf4(62) register_sf4(63) 
 41715 |          register_sf4(64) register_sf4(65) register_sf4(66) register_sf4(67) 
 41716 |          register_sf4(68) register_sf4(69) register_sf4(70) register_sf4(71) 
 41717 |          register_sf4(72) register_sf4(73) register_sf4(74) register_sf4(75) 
 41718 |          register_sf4(76) register_sf4(77) register_sf4(78) register_sf4(79) 
 41719 |          register_sf4(80) register_sf4(81) register_sf4(82) register_sf4(83) 
 41720 |          #undef register_sf4 
 41721 |  
 41722 |          #define register_sf4ext(Op)                                                                                    \ 
 41723 |          sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \ 
 41724 |  
 41725 |          register_sf4ext(00) register_sf4ext(01) register_sf4ext(02) register_sf4ext(03) 
 41726 |          register_sf4ext(04) register_sf4ext(05) register_sf4ext(06) register_sf4ext(07) 
 41727 |          register_sf4ext(08) register_sf4ext(09) register_sf4ext(10) register_sf4ext(11) 
 41728 |          register_sf4ext(12) register_sf4ext(13) register_sf4ext(14) register_sf4ext(15) 
 41729 |          register_sf4ext(16) register_sf4ext(17) register_sf4ext(18) register_sf4ext(19) 
 41730 |          register_sf4ext(20) register_sf4ext(21) register_sf4ext(22) register_sf4ext(23) 
 41731 |          register_sf4ext(24) register_sf4ext(25) register_sf4ext(26) register_sf4ext(27) 
 41732 |          register_sf4ext(28) register_sf4ext(29) register_sf4ext(30) register_sf4ext(31) 
 41733 |          register_sf4ext(32) register_sf4ext(33) register_sf4ext(34) register_sf4ext(35) 
 41734 |          register_sf4ext(36) register_sf4ext(36) register_sf4ext(38) register_sf4ext(39) 
 41735 |          register_sf4ext(40) register_sf4ext(41) register_sf4ext(42) register_sf4ext(43) 
 41736 |          register_sf4ext(44) register_sf4ext(45) register_sf4ext(46) register_sf4ext(47) 
 41737 |          register_sf4ext(48) register_sf4ext(49) register_sf4ext(50) register_sf4ext(51) 
 41738 |          register_sf4ext(52) register_sf4ext(53) register_sf4ext(54) register_sf4ext(55) 
 41739 |          register_sf4ext(56) register_sf4ext(57) register_sf4ext(58) register_sf4ext(59) 
 41740 |          register_sf4ext(60) register_sf4ext(61) 
 41741 |          #undef register_sf4ext 
 41742 |       } 
 41743 |  
 41744 |       inline results_context_t& results_ctx() 
 41745 |       { 
 41746 |          if (0 == results_context_) 
 41747 |          { 
 41748 |             results_context_ = new results_context_t(); 
 41749 |          } 
 41750 |  
 41751 |          return (*results_context_); 
 41752 |       } 
 41753 |  
 41754 |       inline void return_cleanup() 
 41755 |       { 
 41756 |          #ifndef exprtk_disable_return_statement 
 41757 |          if (results_context_) 
 41758 |          { 
 41759 |             delete results_context_; 
 41760 |             results_context_ = 0; 
 41761 |          } 
 41762 |  
 41763 |          state_.return_stmt_present = false; 
 41764 |          #endif 
 41765 |       } 
 41766 |  
 41767 |    private: 
 41768 |  
 41769 |       parser(const parser<T>&) exprtk_delete; 
 41770 |       parser<T>& operator=(const parser<T>&) exprtk_delete; 
 41771 |  
 41772 |       settings_store settings_; 
 41773 |       expression_generator<T> expression_generator_; 
 41774 |       details::node_allocator node_allocator_; 
 41775 |       symtab_store symtab_store_; 
 41776 |       dependent_entity_collector dec_; 
 41777 |       std::deque<parser_error::type> error_list_; 
 41778 |       std::deque<bool> brkcnt_list_; 
 41779 |       parser_state state_; 
 41780 |       bool resolve_unknown_symbol_; 
 41781 |       results_context_t* results_context_; 
 41782 |       unknown_symbol_resolver* unknown_symbol_resolver_; 
 41783 |       unknown_symbol_resolver default_usr_; 
 41784 |       base_ops_map_t base_ops_map_; 
 41785 |       unary_op_map_t unary_op_map_; 
 41786 |       binary_op_map_t binary_op_map_; 
 41787 |       inv_binary_op_map_t inv_binary_op_map_; 
 41788 |       sf3_map_t sf3_map_; 
 41789 |       sf4_map_t sf4_map_; 
 41790 |       std::string synthesis_error_; 
 41791 |       scope_element_manager sem_; 
 41792 |       std::vector<state_t> current_state_stack_; 
 41793 |  
 41794 |       immutable_memory_map_t immutable_memory_map_; 
 41795 |       immutable_symtok_map_t immutable_symtok_map_; 
 41796 |  
 41797 |       lexer::helper::helper_assembly helper_assembly_; 
 41798 |  
 41799 |       lexer::helper::commutative_inserter       commutative_inserter_; 
 41800 |       lexer::helper::operator_joiner            operator_joiner_2_; 
 41801 |       lexer::helper::operator_joiner            operator_joiner_3_; 
 41802 |       lexer::helper::symbol_replacer            symbol_replacer_; 
 41803 |       lexer::helper::bracket_checker            bracket_checker_; 
 41804 |       lexer::helper::numeric_checker<T>         numeric_checker_; 
 41805 |       lexer::helper::sequence_validator         sequence_validator_; 
 41806 |       lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_; 
 41807 |  
 41808 |       loop_runtime_check_ptr          loop_runtime_check_; 
 41809 |       vector_access_runtime_check_ptr vector_access_runtime_check_; 
 41810 |       compilation_check_ptr           compilation_check_ptr_; 
 41811 |       assert_check_ptr                assert_check_; 
 41812 |       std::set<std::string>           assert_ids_; 
 41813 |  
 41814 |       template <typename ParserType> 
 41815 |       friend void details::disable_type_checking(ParserType& p); 
 41816 |    }; // class parser 
 41817 |  
 41818 |    namespace details 
 41819 |    { 
 41820 |       template <typename T> 
 41821 |       struct collector_helper 
 41822 |       { 
 41823 |          typedef exprtk::symbol_table<T> symbol_table_t; 
 41824 |          typedef exprtk::expression<T>   expression_t; 
 41825 |          typedef exprtk::parser<T>       parser_t; 
 41826 |          typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t; 
 41827 |          typedef typename parser_t::unknown_symbol_resolver usr_t; 
 41828 |  
 41829 |          struct resolve_as_vector : public usr_t 
 41830 |          { 
 41831 |             typedef exprtk::parser<T> parser_t; 
 41832 |  
 41833 |             using usr_t::process; 
 41834 |  
 41835 |             resolve_as_vector() 
 41836 |             : usr_t(usr_t::e_usrmode_extended) 
 41837 |             {} 
 41838 |  
 41839 |             virtual bool process(const std::string& unknown_symbol, 
 41840 |                                  symbol_table_t& symbol_table, 
 41841 |                                  std::string&) exprtk_override 
 41842 |             { 
 41843 |                static T v[1]; 
 41844 |                symbol_table.add_vector(unknown_symbol,v); 
 41845 |                return true; 
 41846 |             } 
 41847 |          }; 
 41848 |  
 41849 |          static inline bool collection_pass(const std::string& expression_string, 
 41850 |                                             std::set<std::string>& symbol_set, 
 41851 |                                             const bool collect_variables, 
 41852 |                                             const bool collect_functions, 
 41853 |                                             const bool vector_pass, 
 41854 |                                             symbol_table_t& ext_symbol_table) 
 41855 |          { 
 41856 |             symbol_table_t symbol_table; 
 41857 |             expression_t   expression; 
 41858 |             parser_t       parser; 
 41859 |  
 41860 |             resolve_as_vector vect_resolver; 
 41861 |  
 41862 |             expression.register_symbol_table(symbol_table    ); 
 41863 |             expression.register_symbol_table(ext_symbol_table); 
 41864 |  
 41865 |             if (vector_pass) 
 41866 |                parser.enable_unknown_symbol_resolver(&vect_resolver); 
 41867 |             else 
 41868 |                parser.enable_unknown_symbol_resolver(); 
 41869 |  
 41870 |             if (collect_variables) 
 41871 |                parser.dec().collect_variables() = true; 
 41872 |  
 41873 |             if (collect_functions) 
 41874 |                parser.dec().collect_functions() = true; 
 41875 |  
 41876 |             bool pass_result = false; 
 41877 |  
 41878 |             details::disable_type_checking(parser); 
 41879 |  
 41880 |             if (parser.compile(expression_string, expression)) 
 41881 |             { 
 41882 |                pass_result = true; 
 41883 |  
 41884 |                std::deque<symbol_t> symb_list; 
 41885 |                parser.dec().symbols(symb_list); 
 41886 |  
 41887 |                for (std::size_t i = 0; i < symb_list.size(); ++i) 
 41888 |                { 
 41889 |                   symbol_set.insert(symb_list[i].first); 
 41890 |                } 
 41891 |             } 
 41892 |  
 41893 |             return pass_result; 
 41894 |          } 
 41895 |       }; 
 41896 |    } 
 41897 |  
 41898 |    template <typename Allocator, 
 41899 |              template <typename, typename> class Sequence> 
 41900 |    inline bool collect_variables(const std::string& expression, 
 41901 |                                  Sequence<std::string, Allocator>& symbol_list) 
 41902 |    { 
 41903 |       typedef double T; 
 41904 |       typedef details::collector_helper<T> collect_t; 
 41905 |  
 41906 |       collect_t::symbol_table_t null_symbol_table; 
 41907 |  
 41908 |       std::set<std::string> symbol_set; 
 41909 |  
 41910 |       const bool variable_pass = collect_t::collection_pass 
 41911 |                                     (expression, symbol_set, true, false, false, null_symbol_table); 
 41912 |       const bool vector_pass   = collect_t::collection_pass 
 41913 |                                     (expression, symbol_set, true, false,  true, null_symbol_table); 
 41914 |  
 41915 |       if (!variable_pass && !vector_pass) 
 41916 |          return false; 
 41917 |  
 41918 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 41919 |  
 41920 |       while (symbol_set.end() != itr) 
 41921 |       { 
 41922 |          symbol_list.push_back(*itr); 
 41923 |          ++itr; 
 41924 |       } 
 41925 |  
 41926 |       return true; 
 41927 |    } 
 41928 |  
 41929 |    template <typename T, 
 41930 |              typename Allocator, 
 41931 |              template <typename, typename> class Sequence> 
 41932 |    inline bool collect_variables(const std::string& expression, 
 41933 |                                  exprtk::symbol_table<T>& extrnl_symbol_table, 
 41934 |                                  Sequence<std::string, Allocator>& symbol_list) 
 41935 |    { 
 41936 |       typedef details::collector_helper<T> collect_t; 
 41937 |  
 41938 |       std::set<std::string> symbol_set; 
 41939 |  
 41940 |       const bool variable_pass = collect_t::collection_pass 
 41941 |                                     (expression, symbol_set, true, false, false, extrnl_symbol_table); 
 41942 |       const bool vector_pass   = collect_t::collection_pass 
 41943 |                                     (expression, symbol_set, true, false,  true, extrnl_symbol_table); 
 41944 |  
 41945 |       if (!variable_pass && !vector_pass) 
 41946 |          return false; 
 41947 |  
 41948 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 41949 |  
 41950 |       while (symbol_set.end() != itr) 
 41951 |       { 
 41952 |          symbol_list.push_back(*itr); 
 41953 |          ++itr; 
 41954 |       } 
 41955 |  
 41956 |       return true; 
 41957 |    } 
 41958 |  
 41959 |    template <typename Allocator, 
 41960 |              template <typename, typename> class Sequence> 
 41961 |    inline bool collect_functions(const std::string& expression, 
 41962 |                                  Sequence<std::string, Allocator>& symbol_list) 
 41963 |    { 
 41964 |       typedef double T; 
 41965 |       typedef details::collector_helper<T> collect_t; 
 41966 |  
 41967 |       collect_t::symbol_table_t null_symbol_table; 
 41968 |  
 41969 |       std::set<std::string> symbol_set; 
 41970 |  
 41971 |       const bool variable_pass = collect_t::collection_pass 
 41972 |                                     (expression, symbol_set, false, true, false, null_symbol_table); 
 41973 |       const bool vector_pass   = collect_t::collection_pass 
 41974 |                                     (expression, symbol_set, false, true,  true, null_symbol_table); 
 41975 |  
 41976 |       if (!variable_pass && !vector_pass) 
 41977 |          return false; 
 41978 |  
 41979 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 41980 |  
 41981 |       while (symbol_set.end() != itr) 
 41982 |       { 
 41983 |          symbol_list.push_back(*itr); 
 41984 |          ++itr; 
 41985 |       } 
 41986 |  
 41987 |       return true; 
 41988 |    } 
 41989 |  
 41990 |    template <typename T, 
 41991 |              typename Allocator, 
 41992 |              template <typename, typename> class Sequence> 
 41993 |    inline bool collect_functions(const std::string& expression, 
 41994 |                                  exprtk::symbol_table<T>& extrnl_symbol_table, 
 41995 |                                  Sequence<std::string, Allocator>& symbol_list) 
 41996 |    { 
 41997 |       typedef details::collector_helper<T> collect_t; 
 41998 |  
 41999 |       std::set<std::string> symbol_set; 
 42000 |  
 42001 |       const bool variable_pass = collect_t::collection_pass 
 42002 |                                     (expression, symbol_set, false, true, false, extrnl_symbol_table); 
 42003 |       const bool vector_pass   = collect_t::collection_pass 
 42004 |                                     (expression, symbol_set, false, true,  true, extrnl_symbol_table); 
 42005 |  
 42006 |       if (!variable_pass && !vector_pass) 
 42007 |          return false; 
 42008 |  
 42009 |       std::set<std::string>::iterator itr = symbol_set.begin(); 
 42010 |  
 42011 |       while (symbol_set.end() != itr) 
 42012 |       { 
 42013 |          symbol_list.push_back(*itr); 
 42014 |          ++itr; 
 42015 |       } 
 42016 |  
 42017 |       return true; 
 42018 |    } 
 42019 |  
 42020 |    template <typename T> 
 42021 |    inline T integrate(const expression<T>& e, 
 42022 |                       T& x, 
 42023 |                       const T& r0, const T& r1, 
 42024 |                       const std::size_t number_of_intervals = 1000000) 
 42025 |    { 
 42026 |       if (r0 > r1) 
 42027 |          return T(0); 
 42028 |  
 42029 |       const T h = (r1 - r0) / (T(2) * number_of_intervals); 
 42030 |       T total_area = T(0); 
 42031 |  
 42032 |       for (std::size_t i = 0; i < number_of_intervals; ++i) 
 42033 |       { 
 42034 |          x = r0 + T(2) * i * h; 
 42035 |          const T y0 = e.value(); x += h; 
 42036 |          const T y1 = e.value(); x += h; 
 42037 |          const T y2 = e.value(); x += h; 
 42038 |          total_area += h * (y0 + T(4) * y1 + y2) / T(3); 
 42039 |       } 
 42040 |  
 42041 |       return total_area; 
 42042 |    } 
 42043 |  
 42044 |    template <typename T> 
 42045 |    inline T integrate(const expression<T>& e, 
 42046 |                       const std::string& variable_name, 
 42047 |                       const T& r0, const T& r1, 
 42048 |                       const std::size_t number_of_intervals = 1000000) 
 42049 |    { 
 42050 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42051 |  
 42052 |       if (!sym_table.valid()) 
 42053 |       { 
 42054 |          return std::numeric_limits<T>::quiet_NaN(); 
 42055 |       } 
 42056 |  
 42057 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42058 |  
 42059 |       if (var) 
 42060 |       { 
 42061 |          T& x = var->ref(); 
 42062 |          const T x_original = x; 
 42063 |          const T result = integrate(e, x, r0, r1, number_of_intervals); 
 42064 |          x = x_original; 
 42065 |  
 42066 |          return result; 
 42067 |       } 
 42068 |  
 42069 |       return std::numeric_limits<T>::quiet_NaN(); 
 42070 |    } 
 42071 |  
 42072 |    template <typename T> 
 42073 |    inline T derivative(const expression<T>& e, 
 42074 |                        T& x, 
 42075 |                        const T& h = T(0.00000001)) 
 42076 |    { 
 42077 |       const T x_init = x; 
 42078 |       const T _2h    = T(2) * h; 
 42079 |  
 42080 |       x = x_init + _2h; 
 42081 |       const T y0 = e.value(); 
 42082 |       x = x_init + h; 
 42083 |       const T y1 = e.value(); 
 42084 |       x = x_init - h; 
 42085 |       const T y2 = e.value(); 
 42086 |       x = x_init - _2h; 
 42087 |       const T y3 = e.value(); 
 42088 |       x = x_init; 
 42089 |  
 42090 |       return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h); 
 42091 |    } 
 42092 |  
 42093 |    template <typename T> 
 42094 |    inline T second_derivative(const expression<T>& e, 
 42095 |                               T& x, 
 42096 |                               const T& h = T(0.00001)) 
 42097 |    { 
 42098 |       const T x_init = x; 
 42099 |       const T _2h    = T(2) * h; 
 42100 |  
 42101 |       const T y = e.value(); 
 42102 |       x = x_init + _2h; 
 42103 |       const T y0 = e.value(); 
 42104 |       x = x_init + h; 
 42105 |       const T y1 = e.value(); 
 42106 |       x = x_init - h; 
 42107 |       const T y2 = e.value(); 
 42108 |       x = x_init - _2h; 
 42109 |       const T y3 = e.value(); 
 42110 |       x = x_init; 
 42111 |  
 42112 |       return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h); 
 42113 |    } 
 42114 |  
 42115 |    template <typename T> 
 42116 |    inline T third_derivative(const expression<T>& e, 
 42117 |                              T& x, 
 42118 |                              const T& h = T(0.0001)) 
 42119 |    { 
 42120 |       const T x_init = x; 
 42121 |       const T _2h    = T(2) * h; 
 42122 |  
 42123 |       x = x_init + _2h; 
 42124 |       const T y0 = e.value(); 
 42125 |       x = x_init + h; 
 42126 |       const T y1 = e.value(); 
 42127 |       x = x_init - h; 
 42128 |       const T y2 = e.value(); 
 42129 |       x = x_init - _2h; 
 42130 |       const T y3 = e.value(); 
 42131 |       x = x_init; 
 42132 |  
 42133 |       return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h); 
 42134 |    } 
 42135 |  
 42136 |    template <typename T> 
 42137 |    inline T derivative(const expression<T>& e, 
 42138 |                        const std::string& variable_name, 
 42139 |                        const T& h = T(0.00000001)) 
 42140 |    { 
 42141 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42142 |  
 42143 |       if (!sym_table.valid()) 
 42144 |       { 
 42145 |          return std::numeric_limits<T>::quiet_NaN(); 
 42146 |       } 
 42147 |  
 42148 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42149 |  
 42150 |       if (var) 
 42151 |       { 
 42152 |          T& x = var->ref(); 
 42153 |          const T x_original = x; 
 42154 |          const T result = derivative(e, x, h); 
 42155 |          x = x_original; 
 42156 |  
 42157 |          return result; 
 42158 |       } 
 42159 |  
 42160 |       return std::numeric_limits<T>::quiet_NaN(); 
 42161 |    } 
 42162 |  
 42163 |    template <typename T> 
 42164 |    inline T second_derivative(const expression<T>& e, 
 42165 |                               const std::string& variable_name, 
 42166 |                               const T& h = T(0.00001)) 
 42167 |    { 
 42168 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42169 |  
 42170 |       if (!sym_table.valid()) 
 42171 |       { 
 42172 |          return std::numeric_limits<T>::quiet_NaN(); 
 42173 |       } 
 42174 |  
 42175 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42176 |  
 42177 |       if (var) 
 42178 |       { 
 42179 |          T& x = var->ref(); 
 42180 |          const T x_original = x; 
 42181 |          const T result = second_derivative(e, x, h); 
 42182 |          x = x_original; 
 42183 |  
 42184 |          return result; 
 42185 |       } 
 42186 |  
 42187 |       return std::numeric_limits<T>::quiet_NaN(); 
 42188 |    } 
 42189 |  
 42190 |    template <typename T> 
 42191 |    inline T third_derivative(const expression<T>& e, 
 42192 |                              const std::string& variable_name, 
 42193 |                              const T& h = T(0.0001)) 
 42194 |    { 
 42195 |       const symbol_table<T>& sym_table = e.get_symbol_table(); 
 42196 |  
 42197 |       if (!sym_table.valid()) 
 42198 |       { 
 42199 |          return std::numeric_limits<T>::quiet_NaN(); 
 42200 |       } 
 42201 |  
 42202 |       details::variable_node<T>* var = sym_table.get_variable(variable_name); 
 42203 |  
 42204 |       if (var) 
 42205 |       { 
 42206 |          T& x = var->ref(); 
 42207 |          const T x_original = x; 
 42208 |          const T result = third_derivative(e, x, h); 
 42209 |          x = x_original; 
 42210 |  
 42211 |          return result; 
 42212 |       } 
 42213 |  
 42214 |       return std::numeric_limits<T>::quiet_NaN(); 
 42215 |    } 
 42216 |  
 42217 |    /* 
 42218 |       Note: The following 'compute' routines are simple helpers, 
 42219 |       for quickly setting up the required pieces of code in order 
 42220 |       to evaluate an expression. By virtue of how they operate 
 42221 |       there will be an overhead with regards to their setup and 
 42222 |       teardown and hence should not be used in time critical 
 42223 |       sections of code. 
 42224 |       Furthermore they only assume a small sub set of variables, 
 42225 |       no string variables or user defined functions. 
 42226 |    */ 
 42227 |    template <typename T> 
 42228 |    inline bool compute(const std::string& expression_string, T& result) 
 42229 |    { 
 42230 |       // No variables 
 42231 |       symbol_table<T> symbol_table; 
 42232 |       symbol_table.add_constants(); 
 42233 |  
 42234 |       expression<T> expression; 
 42235 |       expression.register_symbol_table(symbol_table); 
 42236 |  
 42237 |       parser<T> parser; 
 42238 |  
 42239 |       if (parser.compile(expression_string,expression)) 
 42240 |       { 
 42241 |          result = expression.value(); 
 42242 |  
 42243 |          return true; 
 42244 |       } 
 42245 |       else 
 42246 |          return false; 
 42247 |    } 
 42248 |  
 42249 |    template <typename T> 
 42250 |    inline bool compute(const std::string& expression_string, 
 42251 |                        const T& x, 
 42252 |                        T& result) 
 42253 |    { 
 42254 |       // Only 'x' 
 42255 |       static const std::string x_var("x"); 
 42256 |  
 42257 |       symbol_table<T> symbol_table; 
 42258 |       symbol_table.add_constants(); 
 42259 |       symbol_table.add_constant(x_var,x); 
 42260 |  
 42261 |       expression<T> expression; 
 42262 |       expression.register_symbol_table(symbol_table); 
 42263 |  
 42264 |       parser<T> parser; 
 42265 |  
 42266 |       if (parser.compile(expression_string,expression)) 
 42267 |       { 
 42268 |          result = expression.value(); 
 42269 |  
 42270 |          return true; 
 42271 |       } 
 42272 |       else 
 42273 |          return false; 
 42274 |    } 
 42275 |  
 42276 |    template <typename T> 
 42277 |    inline bool compute(const std::string& expression_string, 
 42278 |                        const T&x, const T& y, 
 42279 |                        T& result) 
 42280 |    { 
 42281 |       // Only 'x' and 'y' 
 42282 |       static const std::string x_var("x"); 
 42283 |       static const std::string y_var("y"); 
 42284 |  
 42285 |       symbol_table<T> symbol_table; 
 42286 |       symbol_table.add_constants(); 
 42287 |       symbol_table.add_constant(x_var,x); 
 42288 |       symbol_table.add_constant(y_var,y); 
 42289 |  
 42290 |       expression<T> expression; 
 42291 |       expression.register_symbol_table(symbol_table); 
 42292 |  
 42293 |       parser<T> parser; 
 42294 |  
 42295 |       if (parser.compile(expression_string,expression)) 
 42296 |       { 
 42297 |          result = expression.value(); 
 42298 |  
 42299 |          return true; 
 42300 |       } 
 42301 |       else 
 42302 |          return false; 
 42303 |    } 
 42304 |  
 42305 |    template <typename T> 
 42306 |    inline bool compute(const std::string& expression_string, 
 42307 |                        const T& x, const T& y, const T& z, 
 42308 |                        T& result) 
 42309 |    { 
 42310 |       // Only 'x', 'y' or 'z' 
 42311 |       static const std::string x_var("x"); 
 42312 |       static const std::string y_var("y"); 
 42313 |       static const std::string z_var("z"); 
 42314 |  
 42315 |       symbol_table<T> symbol_table; 
 42316 |       symbol_table.add_constants(); 
 42317 |       symbol_table.add_constant(x_var,x); 
 42318 |       symbol_table.add_constant(y_var,y); 
 42319 |       symbol_table.add_constant(z_var,z); 
 42320 |  
 42321 |       expression<T> expression; 
 42322 |       expression.register_symbol_table(symbol_table); 
 42323 |  
 42324 |       parser<T> parser; 
 42325 |  
 42326 |       if (parser.compile(expression_string,expression)) 
 42327 |       { 
 42328 |          result = expression.value(); 
 42329 |  
 42330 |          return true; 
 42331 |       } 
 42332 |       else 
 42333 |          return false; 
 42334 |    } 
 42335 |  
 42336 |    template <typename T, std::size_t N> 
 42337 |    class polynomial : public ifunction<T> 
 42338 |    { 
 42339 |    private: 
 42340 |  
 42341 |       template <typename Type, std::size_t NumberOfCoefficients> 
 42342 |       struct poly_impl { }; 
 42343 |  
 42344 |       template <typename Type> 
 42345 |       struct poly_impl <Type,12> 
 42346 |       { 
 42347 |          static inline T evaluate(const Type x, 
 42348 |                                   const Type c12, const Type c11, const Type c10, const Type c9, const Type c8, 
 42349 |                                   const Type  c7, const Type  c6, const Type  c5, const Type c4, const Type c3, 
 42350 |                                   const Type  c2, const Type  c1, const Type  c0) 
 42351 |          { 
 42352 |             // 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 
 42353 |             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); 
 42354 |          } 
 42355 |       }; 
 42356 |  
 42357 |       template <typename Type> 
 42358 |       struct poly_impl <Type,11> 
 42359 |       { 
 42360 |          static inline T evaluate(const Type x, 
 42361 |                                   const Type c11, const Type c10, const Type c9, const Type c8, const Type c7, 
 42362 |                                   const Type c6,  const Type  c5, const Type c4, const Type c3, const Type c2, 
 42363 |                                   const Type c1,  const Type  c0) 
 42364 |          { 
 42365 |             // 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 
 42366 |             return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42367 |          } 
 42368 |       }; 
 42369 |  
 42370 |       template <typename Type> 
 42371 |       struct poly_impl <Type,10> 
 42372 |       { 
 42373 |          static inline T evaluate(const Type x, 
 42374 |                                   const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, 
 42375 |                                   const Type c5,  const Type c4, const Type c3, const Type c2, const Type c1, 
 42376 |                                   const Type c0) 
 42377 |          { 
 42378 |             // 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 
 42379 |             return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42380 |          } 
 42381 |       }; 
 42382 |  
 42383 |       template <typename Type> 
 42384 |       struct poly_impl <Type,9> 
 42385 |       { 
 42386 |          static inline T evaluate(const Type x, 
 42387 |                                   const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, 
 42388 |                                   const Type c4, const Type c3, const Type c2, const Type c1, const Type c0) 
 42389 |          { 
 42390 |             // 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 
 42391 |             return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42392 |          } 
 42393 |       }; 
 42394 |  
 42395 |       template <typename Type> 
 42396 |       struct poly_impl <Type,8> 
 42397 |       { 
 42398 |          static inline T evaluate(const Type x, 
 42399 |                                   const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, 
 42400 |                                   const Type c3, const Type c2, const Type c1, const Type c0) 
 42401 |          { 
 42402 |             // 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 
 42403 |             return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42404 |          } 
 42405 |       }; 
 42406 |  
 42407 |       template <typename Type> 
 42408 |       struct poly_impl <Type,7> 
 42409 |       { 
 42410 |          static inline T evaluate(const Type x, 
 42411 |                                   const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, 
 42412 |                                   const Type c2, const Type c1, const Type c0) 
 42413 |          { 
 42414 |             // 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 
 42415 |             return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42416 |          } 
 42417 |       }; 
 42418 |  
 42419 |       template <typename Type> 
 42420 |       struct poly_impl <Type,6> 
 42421 |       { 
 42422 |          static inline T evaluate(const Type x, 
 42423 |                                   const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, 
 42424 |                                   const Type c1, const Type c0) 
 42425 |          { 
 42426 |             // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42427 |             return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42428 |          } 
 42429 |       }; 
 42430 |  
 42431 |       template <typename Type> 
 42432 |       struct poly_impl <Type,5> 
 42433 |       { 
 42434 |          static inline T evaluate(const Type x, 
 42435 |                                   const Type c5, const Type c4, const Type c3, const Type c2, 
 42436 |                                   const Type c1, const Type c0) 
 42437 |          { 
 42438 |             // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42439 |             return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0); 
 42440 |          } 
 42441 |       }; 
 42442 |  
 42443 |       template <typename Type> 
 42444 |       struct poly_impl <Type,4> 
 42445 |       { 
 42446 |          static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0) 
 42447 |          { 
 42448 |             // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42449 |             return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0); 
 42450 |          } 
 42451 |       }; 
 42452 |  
 42453 |       template <typename Type> 
 42454 |       struct poly_impl <Type,3> 
 42455 |       { 
 42456 |          static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0) 
 42457 |          { 
 42458 |             // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0 
 42459 |             return (((c3 * x + c2) * x + c1) * x + c0); 
 42460 |          } 
 42461 |       }; 
 42462 |  
 42463 |       template <typename Type> 
 42464 |       struct poly_impl <Type,2> 
 42465 |       { 
 42466 |          static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0) 
 42467 |          { 
 42468 |             // p(x) = c_2x^2 + c_1x^1 + c_0x^0 
 42469 |             return ((c2 * x + c1) * x + c0); 
 42470 |          } 
 42471 |       }; 
 42472 |  
 42473 |       template <typename Type> 
 42474 |       struct poly_impl <Type,1> 
 42475 |       { 
 42476 |          static inline T evaluate(const Type x, const Type c1, const Type c0) 
 42477 |          { 
 42478 |             // p(x) = c_1x^1 + c_0x^0 
 42479 |             return (c1 * x + c0); 
 42480 |          } 
 42481 |       }; 
 42482 |  
 42483 |    public: 
 42484 |  
 42485 |       using ifunction<T>::operator(); 
 42486 |  
 42487 |       polynomial() 
 42488 |       : ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max()) 
 42489 |       { 
 42490 |          disable_has_side_effects(*this); 
 42491 |       } 
 42492 |  
 42493 |       virtual ~polynomial() 
 42494 |       {} 
 42495 |  
 42496 |       #define poly_rtrn(NN) \ 
 42497 |       return (NN != N) ? std::numeric_limits<T>::quiet_NaN() : 
 42498 |  
 42499 |       inline virtual T operator() (const T& x, const T& c1, const T& c0) exprtk_override 
 42500 |       { 
 42501 |          poly_rtrn(1) (poly_impl<T,1>::evaluate(x, c1, c0)); 
 42502 |       } 
 42503 |  
 42504 |       inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) exprtk_override 
 42505 |       { 
 42506 |          poly_rtrn(2) (poly_impl<T,2>::evaluate(x, c2, c1, c0)); 
 42507 |       } 
 42508 |  
 42509 |       inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42510 |       { 
 42511 |          poly_rtrn(3) (poly_impl<T,3>::evaluate(x, c3, c2, c1, c0)); 
 42512 |       } 
 42513 |  
 42514 |       inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1, 
 42515 |                                    const T& c0) exprtk_override 
 42516 |       { 
 42517 |          poly_rtrn(4) (poly_impl<T,4>::evaluate(x, c4, c3, c2, c1, c0)); 
 42518 |       } 
 42519 |  
 42520 |       inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2, 
 42521 |                                    const T& c1, const T& c0) exprtk_override 
 42522 |       { 
 42523 |          poly_rtrn(5) (poly_impl<T,5>::evaluate(x, c5, c4, c3, c2, c1, c0)); 
 42524 |       } 
 42525 |  
 42526 |       inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3, 
 42527 |                                    const T& c2, const T& c1, const T& c0) exprtk_override 
 42528 |       { 
 42529 |          poly_rtrn(6) (poly_impl<T,6>::evaluate(x, c6, c5, c4, c3, c2, c1, c0)); 
 42530 |       } 
 42531 |  
 42532 |       inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4, 
 42533 |                                    const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42534 |       { 
 42535 |          poly_rtrn(7) (poly_impl<T,7>::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42536 |       } 
 42537 |  
 42538 |       inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5, 
 42539 |                                    const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42540 |       { 
 42541 |          poly_rtrn(8) (poly_impl<T,8>::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42542 |       } 
 42543 |  
 42544 |       inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6, 
 42545 |                                    const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, 
 42546 |                                    const T& c0) exprtk_override 
 42547 |       { 
 42548 |          poly_rtrn(9) (poly_impl<T,9>::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42549 |       } 
 42550 |  
 42551 |       inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7, 
 42552 |                                    const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, 
 42553 |                                    const T& c1, const T& c0) exprtk_override 
 42554 |       { 
 42555 |          poly_rtrn(10) (poly_impl<T,10>::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42556 |       } 
 42557 |  
 42558 |       inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8, 
 42559 |                                    const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, 
 42560 |                                    const T& c2, const T& c1, const T& c0) exprtk_override 
 42561 |       { 
 42562 |          poly_rtrn(11) (poly_impl<T,11>::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42563 |       } 
 42564 |  
 42565 |       inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9, 
 42566 |                                    const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, 
 42567 |                                    const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override 
 42568 |       { 
 42569 |          poly_rtrn(12) (poly_impl<T,12>::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); 
 42570 |       } 
 42571 |  
 42572 |       #undef poly_rtrn 
 42573 |  
 42574 |       inline virtual T operator() () exprtk_override 
 42575 |       { 
 42576 |          return std::numeric_limits<T>::quiet_NaN(); 
 42577 |       } 
 42578 |  
 42579 |       inline virtual T operator() (const T&) exprtk_override 
 42580 |       { 
 42581 |          return std::numeric_limits<T>::quiet_NaN(); 
 42582 |       } 
 42583 |  
 42584 |       inline virtual T operator() (const T&, const T&) exprtk_override 
 42585 |       { 
 42586 |          return std::numeric_limits<T>::quiet_NaN(); 
 42587 |       } 
 42588 |    }; 
 42589 |  
 42590 |    template <typename T> 
 42591 |    class function_compositor 
 42592 |    { 
 42593 |    public: 
 42594 |  
 42595 |       typedef exprtk::expression<T>             expression_t; 
 42596 |       typedef exprtk::symbol_table<T>           symbol_table_t; 
 42597 |       typedef exprtk::parser<T>                 parser_t; 
 42598 |       typedef typename parser_t::settings_store settings_t; 
 42599 |  
 42600 |       struct function 
 42601 |       { 
 42602 |          function() 
 42603 |          {} 
 42604 |  
 42605 |          function(const std::string& n) 
 42606 |          : name_(n) 
 42607 |          {} 
 42608 |  
 42609 |          function(const std::string& name, 
 42610 |                   const std::string& expression) 
 42611 |          : name_(name) 
 42612 |          , expression_(expression) 
 42613 |          {} 
 42614 |  
 42615 |          function(const std::string& name, 
 42616 |                   const std::string& expression, 
 42617 |                   const std::string& v0) 
 42618 |          : name_(name) 
 42619 |          , expression_(expression) 
 42620 |          { 
 42621 |             v_.push_back(v0); 
 42622 |          } 
 42623 |  
 42624 |          function(const std::string& name, 
 42625 |                   const std::string& expression, 
 42626 |                   const std::string& v0, const std::string& v1) 
 42627 |          : name_(name) 
 42628 |          , expression_(expression) 
 42629 |          { 
 42630 |             v_.push_back(v0); v_.push_back(v1); 
 42631 |          } 
 42632 |  
 42633 |          function(const std::string& name, 
 42634 |                   const std::string& expression, 
 42635 |                   const std::string& v0, const std::string& v1, 
 42636 |                   const std::string& v2) 
 42637 |          : name_(name) 
 42638 |          , expression_(expression) 
 42639 |          { 
 42640 |             v_.push_back(v0); v_.push_back(v1); 
 42641 |             v_.push_back(v2); 
 42642 |          } 
 42643 |  
 42644 |          function(const std::string& name, 
 42645 |                   const std::string& expression, 
 42646 |                   const std::string& v0, const std::string& v1, 
 42647 |                   const std::string& v2, const std::string& v3) 
 42648 |          : name_(name) 
 42649 |          , expression_(expression) 
 42650 |          { 
 42651 |             v_.push_back(v0); v_.push_back(v1); 
 42652 |             v_.push_back(v2); v_.push_back(v3); 
 42653 |          } 
 42654 |  
 42655 |          function(const std::string& name, 
 42656 |                   const std::string& expression, 
 42657 |                   const std::string& v0, const std::string& v1, 
 42658 |                   const std::string& v2, const std::string& v3, 
 42659 |                   const std::string& v4) 
 42660 |          : name_(name) 
 42661 |          , expression_(expression) 
 42662 |          { 
 42663 |             v_.push_back(v0); v_.push_back(v1); 
 42664 |             v_.push_back(v2); v_.push_back(v3); 
 42665 |             v_.push_back(v4); 
 42666 |          } 
 42667 |  
 42668 |          inline function& name(const std::string& n) 
 42669 |          { 
 42670 |             name_ = n; 
 42671 |             return (*this); 
 42672 |          } 
 42673 |  
 42674 |          inline function& expression(const std::string& e) 
 42675 |          { 
 42676 |             expression_ = e; 
 42677 |             return (*this); 
 42678 |          } 
 42679 |  
 42680 |          inline function& var(const std::string& v) 
 42681 |          { 
 42682 |             v_.push_back(v); 
 42683 |             return (*this); 
 42684 |          } 
 42685 |  
 42686 |          inline function& vars(const std::string& v0, 
 42687 |                                const std::string& v1) 
 42688 |          { 
 42689 |             v_.push_back(v0); 
 42690 |             v_.push_back(v1); 
 42691 |             return (*this); 
 42692 |          } 
 42693 |  
 42694 |          inline function& vars(const std::string& v0, 
 42695 |                                const std::string& v1, 
 42696 |                                const std::string& v2) 
 42697 |          { 
 42698 |             v_.push_back(v0); 
 42699 |             v_.push_back(v1); 
 42700 |             v_.push_back(v2); 
 42701 |             return (*this); 
 42702 |          } 
 42703 |  
 42704 |          inline function& vars(const std::string& v0, 
 42705 |                                const std::string& v1, 
 42706 |                                const std::string& v2, 
 42707 |                                const std::string& v3) 
 42708 |          { 
 42709 |             v_.push_back(v0); 
 42710 |             v_.push_back(v1); 
 42711 |             v_.push_back(v2); 
 42712 |             v_.push_back(v3); 
 42713 |             return (*this); 
 42714 |          } 
 42715 |  
 42716 |          inline function& vars(const std::string& v0, 
 42717 |                                const std::string& v1, 
 42718 |                                const std::string& v2, 
 42719 |                                const std::string& v3, 
 42720 |                                const std::string& v4) 
 42721 |          { 
 42722 |             v_.push_back(v0); 
 42723 |             v_.push_back(v1); 
 42724 |             v_.push_back(v2); 
 42725 |             v_.push_back(v3); 
 42726 |             v_.push_back(v4); 
 42727 |             return (*this); 
 42728 |          } 
 42729 |  
 42730 |          std::string name_; 
 42731 |          std::string expression_; 
 42732 |          std::deque<std::string> v_; 
 42733 |       }; 
 42734 |  
 42735 |    private: 
 42736 |  
 42737 |       struct base_func : public exprtk::ifunction<T> 
 42738 |       { 
 42739 |          typedef const T&                  type; 
 42740 |          typedef exprtk::ifunction<T>      function_t; 
 42741 |          typedef std::vector<T*>           varref_t; 
 42742 |          typedef std::vector<T>            var_t; 
 42743 |          typedef std::vector<std::string>  str_t; 
 42744 |          typedef std::pair<T*,std::size_t> lvarref_t; 
 42745 |          typedef std::vector<lvarref_t>    lvr_vec_t; 
 42746 |          typedef std::vector<std::string*> lstr_vec_t; 
 42747 |  
 42748 |          using exprtk::ifunction<T>::operator(); 
 42749 |  
 42750 |          base_func(const std::size_t& pc = 0) 
 42751 |          : exprtk::ifunction<T>(pc) 
 42752 |          , local_var_stack_size(0) 
 42753 |          , stack_depth(0) 
 42754 |          { 
 42755 |             v.resize(pc); 
 42756 |          } 
 42757 |  
 42758 |          virtual ~base_func() 
 42759 |          {} 
 42760 |  
 42761 |          #define exprtk_assign(Index) \ 
 42762 |          (*v[Index]) = v##Index;      \ 
 42763 |  
 42764 |          inline void update(const T& v0) 
 42765 |          { 
 42766 |             exprtk_assign(0) 
 42767 |          } 
 42768 |  
 42769 |          inline void update(const T& v0, const T& v1) 
 42770 |          { 
 42771 |             exprtk_assign(0) exprtk_assign(1) 
 42772 |          } 
 42773 |  
 42774 |          inline void update(const T& v0, const T& v1, const T& v2) 
 42775 |          { 
 42776 |             exprtk_assign(0) exprtk_assign(1) 
 42777 |             exprtk_assign(2) 
 42778 |          } 
 42779 |  
 42780 |          inline void update(const T& v0, const T& v1, const T& v2, const T& v3) 
 42781 |          { 
 42782 |             exprtk_assign(0) exprtk_assign(1) 
 42783 |             exprtk_assign(2) exprtk_assign(3) 
 42784 |          } 
 42785 |  
 42786 |          inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) 
 42787 |          { 
 42788 |             exprtk_assign(0) exprtk_assign(1) 
 42789 |             exprtk_assign(2) exprtk_assign(3) 
 42790 |             exprtk_assign(4) 
 42791 |          } 
 42792 |  
 42793 |          inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) 
 42794 |          { 
 42795 |             exprtk_assign(0) exprtk_assign(1) 
 42796 |             exprtk_assign(2) exprtk_assign(3) 
 42797 |             exprtk_assign(4) exprtk_assign(5) 
 42798 |          } 
 42799 |  
 42800 |          #ifdef exprtk_assign 
 42801 |          #undef exprtk_assign 
 42802 |          #endif 
 42803 |  
 42804 |          inline function_t& setup(expression_t& expr) 
 42805 |          { 
 42806 |             expression = expr; 
 42807 |  
 42808 |             typedef typename expression_t::control_block  ctrlblk_t; 
 42809 |             typedef typename ctrlblk_t::local_data_list_t ldl_t; 
 42810 |             typedef typename ctrlblk_t::data_type         data_t; 
 42811 |             typedef typename ldl_t::value_type            ldl_value_type; 
 42812 |  
 42813 |             const ldl_t ldl = expr.local_data_list(); 
 42814 |  
 42815 |             std::vector<std::pair<std::size_t,data_t> > index_list; 
 42816 |  
 42817 |             for (std::size_t i = 0; i < ldl.size(); ++i) 
 42818 |             { 
 42819 |                exprtk_debug(("base_func::setup() - element[%02d] type: %s size: %d\n", 
 42820 |                              static_cast<int>(i), 
 42821 |                              expression_t::control_block::to_str(ldl[i].type).c_str(), 
 42822 |                              static_cast<int>(ldl[i].size))); 
 42823 |  
 42824 |                switch (ldl[i].type) 
 42825 |                { 
 42826 |                   case ctrlblk_t::e_unknown   : continue; 
 42827 |                   case ctrlblk_t::e_expr      : continue; 
 42828 |                   case ctrlblk_t::e_vecholder : continue; 
 42829 |                   default                     : break; 
 42830 |                } 
 42831 |  
 42832 |                if (ldl[i].size) 
 42833 |                { 
 42834 |                   index_list.push_back(std::make_pair(i,ldl[i].type)); 
 42835 |                } 
 42836 |             } 
 42837 |  
 42838 |             std::size_t input_param_count = 0; 
 42839 |  
 42840 |             for (std::size_t i = 0; i < index_list.size(); ++i) 
 42841 |             { 
 42842 |                const std::size_t index         = index_list[i].first; 
 42843 |                const ldl_value_type& local_var = ldl[index]; 
 42844 |  
 42845 |                assert(local_var.pointer); 
 42846 |  
 42847 |                if (i < (index_list.size() - v.size())) 
 42848 |                { 
 42849 |                   if (local_var.type == ctrlblk_t::e_string) 
 42850 |                   { 
 42851 |                      local_str_vars.push_back( 
 42852 |                         reinterpret_cast<std::string*>(local_var.pointer)); 
 42853 |                   } 
 42854 |                   else if ( 
 42855 |                             (local_var.type == ctrlblk_t::e_data   ) || 
 42856 |                             (local_var.type == ctrlblk_t::e_vecdata) 
 42857 |                           ) 
 42858 |                   { 
 42859 |                      local_vars.push_back(std::make_pair( 
 42860 |                         reinterpret_cast<T*>(local_var.pointer), 
 42861 |                         local_var.size)); 
 42862 |  
 42863 |                      local_var_stack_size += local_var.size; 
 42864 |                   } 
 42865 |                } 
 42866 |                else 
 42867 |                { 
 42868 |                   v[input_param_count++] = reinterpret_cast<T*>(local_var.pointer); 
 42869 |                } 
 42870 |             } 
 42871 |  
 42872 |             clear_stack(); 
 42873 |  
 42874 |             return (*this); 
 42875 |          } 
 42876 |  
 42877 |          inline void pre() 
 42878 |          { 
 42879 |             if (stack_depth++) 
 42880 |             { 
 42881 |                if (!v.empty()) 
 42882 |                { 
 42883 |                   var_t var_stack(v.size(),T(0)); 
 42884 |                   copy(v,var_stack); 
 42885 |                   input_params_stack.push_back(var_stack); 
 42886 |                } 
 42887 |  
 42888 |                if (!local_vars.empty()) 
 42889 |                { 
 42890 |                   var_t local_vec_frame(local_var_stack_size,T(0)); 
 42891 |                   copy(local_vars,local_vec_frame); 
 42892 |                   local_var_stack.push_back(local_vec_frame); 
 42893 |                } 
 42894 |  
 42895 |                if (!local_str_vars.empty()) 
 42896 |                { 
 42897 |                   str_t local_str_frame(local_str_vars.size()); 
 42898 |                   copy(local_str_vars,local_str_frame); 
 42899 |                   local_str_stack.push_back(local_str_frame); 
 42900 |                } 
 42901 |             } 
 42902 |          } 
 42903 |  
 42904 |          inline void post() 
 42905 |          { 
 42906 |             if (--stack_depth) 
 42907 |             { 
 42908 |                if (!v.empty()) 
 42909 |                { 
 42910 |                   copy(input_params_stack.back(), v); 
 42911 |                   input_params_stack.pop_back(); 
 42912 |                } 
 42913 |  
 42914 |                if (!local_vars.empty()) 
 42915 |                { 
 42916 |                   copy(local_var_stack.back(), local_vars); 
 42917 |                   local_var_stack.pop_back(); 
 42918 |                } 
 42919 |  
 42920 |                if (!local_str_vars.empty()) 
 42921 |                { 
 42922 |                   copy(local_str_stack.back(), local_str_vars); 
 42923 |                   local_str_stack.pop_back(); 
 42924 |                } 
 42925 |             } 
 42926 |          } 
 42927 |  
 42928 |          void copy(const varref_t& src_v, var_t& dest_v) 
 42929 |          { 
 42930 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 42931 |             { 
 42932 |                dest_v[i] = (*src_v[i]); 
 42933 |             } 
 42934 |          } 
 42935 |  
 42936 |          void copy(const lstr_vec_t& src_v, str_t& dest_v) 
 42937 |          { 
 42938 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 42939 |             { 
 42940 |                dest_v[i] = (*src_v[i]); 
 42941 |             } 
 42942 |          } 
 42943 |  
 42944 |          void copy(const var_t& src_v, varref_t& dest_v) 
 42945 |          { 
 42946 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 42947 |             { 
 42948 |                (*dest_v[i]) = src_v[i]; 
 42949 |             } 
 42950 |          } 
 42951 |  
 42952 |          void copy(const lvr_vec_t& src_v, var_t& dest_v) 
 42953 |          { 
 42954 |             typename var_t::iterator itr = dest_v.begin(); 
 42955 |             typedef  typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t; 
 42956 |  
 42957 |             for (std::size_t i = 0; i < src_v.size(); ++i) 
 42958 |             { 
 42959 |                lvarref_t vr = src_v[i]; 
 42960 |  
 42961 |                if (1 == vr.second) 
 42962 |                   *itr++ = (*vr.first); 
 42963 |                else 
 42964 |                { 
 42965 |                   std::copy(vr.first, vr.first + vr.second, itr); 
 42966 |                   itr += static_cast<diff_t>(vr.second); 
 42967 |                } 
 42968 |             } 
 42969 |          } 
 42970 |  
 42971 |          void copy(const var_t& src_v, lvr_vec_t& dest_v) 
 42972 |          { 
 42973 |             typename var_t::const_iterator itr = src_v.begin(); 
 42974 |             typedef  typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t; 
 42975 |  
 42976 |             for (std::size_t i = 0; i < dest_v.size(); ++i) 
 42977 |             { 
 42978 |                lvarref_t& vr = dest_v[i]; 
 42979 |  
 42980 |                assert(vr.first != 0); 
 42981 |                assert(vr.second > 0); 
 42982 |  
 42983 |                if (1 == vr.second) 
 42984 |                   (*vr.first) = *itr++; 
 42985 |                else 
 42986 |                { 
 42987 |                   std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first); 
 42988 |                   itr += static_cast<diff_t>(vr.second); 
 42989 |                } 
 42990 |             } 
 42991 |          } 
 42992 |  
 42993 |          void copy(const str_t& src_str, lstr_vec_t& dest_str) 
 42994 |          { 
 42995 |             assert(src_str.size() == dest_str.size()); 
 42996 |  
 42997 |             for (std::size_t i = 0; i < dest_str.size(); ++i) 
 42998 |             { 
 42999 |                *dest_str[i] = src_str[i]; 
 43000 |             } 
 43001 |          } 
 43002 |  
 43003 |          inline void clear_stack() 
 43004 |          { 
 43005 |             for (std::size_t i = 0; i < v.size(); ++i) 
 43006 |             { 
 43007 |                (*v[i]) = 0; 
 43008 |             } 
 43009 |          } 
 43010 |  
 43011 |          inline virtual T value(expression_t& e) 
 43012 |          { 
 43013 |             return e.value(); 
 43014 |          } 
 43015 |  
 43016 |          expression_t      expression; 
 43017 |          varref_t          v; 
 43018 |          lvr_vec_t         local_vars; 
 43019 |          lstr_vec_t        local_str_vars; 
 43020 |          std::size_t       local_var_stack_size; 
 43021 |          std::size_t       stack_depth; 
 43022 |          std::deque<var_t> input_params_stack; 
 43023 |          std::deque<var_t> local_var_stack; 
 43024 |          std::deque<str_t> local_str_stack; 
 43025 |       }; 
 43026 |  
 43027 |       typedef std::map<std::string,base_func*> funcparam_t; 
 43028 |  
 43029 |       typedef const T& type; 
 43030 |  
 43031 |       template <typename BaseFuncType> 
 43032 |       struct scoped_bft 
 43033 |       { 
 43034 |          explicit scoped_bft(BaseFuncType& bft) 
 43035 |          : bft_(bft) 
 43036 |          { 
 43037 |             bft_.pre (); 
 43038 |          } 
 43039 |  
 43040 |         ~scoped_bft() 
 43041 |          { 
 43042 |             bft_.post(); 
 43043 |          } 
 43044 |  
 43045 |          BaseFuncType& bft_; 
 43046 |  
 43047 |       private: 
 43048 |  
 43049 |          scoped_bft(const scoped_bft&) exprtk_delete; 
 43050 |          scoped_bft& operator=(const scoped_bft&) exprtk_delete; 
 43051 |       }; 
 43052 |  
 43053 |       struct func_0param : public base_func 
 43054 |       { 
 43055 |          using exprtk::ifunction<T>::operator(); 
 43056 |  
 43057 |          func_0param() : base_func(0) {} 
 43058 |  
 43059 |          inline T operator() () exprtk_override 
 43060 |          { 
 43061 |             scoped_bft<func_0param> sb(*this); 
 43062 |             return this->value(base_func::expression); 
 43063 |          } 
 43064 |       }; 
 43065 |  
 43066 |       struct func_1param : public base_func 
 43067 |       { 
 43068 |          using exprtk::ifunction<T>::operator(); 
 43069 |  
 43070 |          func_1param() : base_func(1) {} 
 43071 |  
 43072 |          inline T operator() (type v0) exprtk_override 
 43073 |          { 
 43074 |             scoped_bft<func_1param> sb(*this); 
 43075 |             base_func::update(v0); 
 43076 |             return this->value(base_func::expression); 
 43077 |          } 
 43078 |       }; 
 43079 |  
 43080 |       struct func_2param : public base_func 
 43081 |       { 
 43082 |          using exprtk::ifunction<T>::operator(); 
 43083 |  
 43084 |          func_2param() : base_func(2) {} 
 43085 |  
 43086 |          inline T operator() (type v0, type v1) exprtk_override 
 43087 |          { 
 43088 |             scoped_bft<func_2param> sb(*this); 
 43089 |             base_func::update(v0, v1); 
 43090 |             return this->value(base_func::expression); 
 43091 |          } 
 43092 |       }; 
 43093 |  
 43094 |       struct func_3param : public base_func 
 43095 |       { 
 43096 |          using exprtk::ifunction<T>::operator(); 
 43097 |  
 43098 |          func_3param() : base_func(3) {} 
 43099 |  
 43100 |          inline T operator() (type v0, type v1, type v2) exprtk_override 
 43101 |          { 
 43102 |             scoped_bft<func_3param> sb(*this); 
 43103 |             base_func::update(v0, v1, v2); 
 43104 |             return this->value(base_func::expression); 
 43105 |          } 
 43106 |       }; 
 43107 |  
 43108 |       struct func_4param : public base_func 
 43109 |       { 
 43110 |          using exprtk::ifunction<T>::operator(); 
 43111 |  
 43112 |          func_4param() : base_func(4) {} 
 43113 |  
 43114 |          inline T operator() (type v0, type v1, type v2, type v3) exprtk_override 
 43115 |          { 
 43116 |             scoped_bft<func_4param> sb(*this); 
 43117 |             base_func::update(v0, v1, v2, v3); 
 43118 |             return this->value(base_func::expression); 
 43119 |          } 
 43120 |       }; 
 43121 |  
 43122 |       struct func_5param : public base_func 
 43123 |       { 
 43124 |          using exprtk::ifunction<T>::operator(); 
 43125 |  
 43126 |          func_5param() : base_func(5) {} 
 43127 |  
 43128 |          inline T operator() (type v0, type v1, type v2, type v3, type v4) exprtk_override 
 43129 |          { 
 43130 |             scoped_bft<func_5param> sb(*this); 
 43131 |             base_func::update(v0, v1, v2, v3, v4); 
 43132 |             return this->value(base_func::expression); 
 43133 |          } 
 43134 |       }; 
 43135 |  
 43136 |       struct func_6param : public base_func 
 43137 |       { 
 43138 |          using exprtk::ifunction<T>::operator(); 
 43139 |  
 43140 |          func_6param() : base_func(6) {} 
 43141 |  
 43142 |          inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) exprtk_override 
 43143 |          { 
 43144 |             scoped_bft<func_6param> sb(*this); 
 43145 |             base_func::update(v0, v1, v2, v3, v4, v5); 
 43146 |             return this->value(base_func::expression); 
 43147 |          } 
 43148 |       }; 
 43149 |  
 43150 |       static T return_value(expression_t& e) 
 43151 |       { 
 43152 |          typedef exprtk::results_context<T> results_context_t; 
 43153 |          typedef typename results_context_t::type_store_t type_t; 
 43154 |          typedef typename type_t::scalar_view scalar_t; 
 43155 |  
 43156 |          const T result = e.value(); 
 43157 |  
 43158 |          if (e.return_invoked()) 
 43159 |          { 
 43160 |             // Due to the post compilation checks, it can be safely 
 43161 |             // assumed that there will be at least one parameter 
 43162 |             // and that the first parameter will always be scalar. 
 43163 |             return scalar_t(e.results()[0])(); 
 43164 |          } 
 43165 |  
 43166 |          return result; 
 43167 |       } 
 43168 |  
 43169 |       #define def_fp_retval(N)                                            \ 
 43170 |       struct func_##N##param_retval exprtk_final : public func_##N##param \ 
 43171 |       {                                                                   \ 
 43172 |          inline T value(expression_t& e) exprtk_override                  \ 
 43173 |          {                                                                \ 
 43174 |             return return_value(e);                                       \ 
 43175 |          }                                                                \ 
 43176 |       };                                                                  \ 
 43177 |  
 43178 |       def_fp_retval(0) 
 43179 |       def_fp_retval(1) 
 43180 |       def_fp_retval(2) 
 43181 |       def_fp_retval(3) 
 43182 |       def_fp_retval(4) 
 43183 |       def_fp_retval(5) 
 43184 |       def_fp_retval(6) 
 43185 |  
 43186 |       #undef def_fp_retval 
 43187 |  
 43188 |       template <typename Allocator, 
 43189 |                 template <typename, typename> class Sequence> 
 43190 |       inline bool add(const std::string& name, 
 43191 |                       const std::string& expression, 
 43192 |                       const Sequence<std::string,Allocator>& var_list, 
 43193 |                       const bool override = false) 
 43194 |       { 
 43195 |          const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name); 
 43196 |  
 43197 |          if (expr_map_.end() != itr) 
 43198 |          { 
 43199 |             if (!override) 
 43200 |             { 
 43201 |                exprtk_debug(("Compositor error(add): function '%s' already defined\n", 
 43202 |                              name.c_str())); 
 43203 |  
 43204 |                return false; 
 43205 |             } 
 43206 |  
 43207 |             remove(name, var_list.size()); 
 43208 |          } 
 43209 |  
 43210 |          if (compile_expression(name, expression, var_list)) 
 43211 |          { 
 43212 |             const std::size_t n = var_list.size(); 
 43213 |  
 43214 |             fp_map_[n][name]->setup(expr_map_[name]); 
 43215 |  
 43216 |             return true; 
 43217 |          } 
 43218 |          else 
 43219 |          { 
 43220 |             exprtk_debug(("Compositor error(add): Failed to compile function '%s'\n", 
 43221 |                           name.c_str())); 
 43222 |  
 43223 |             return false; 
 43224 |          } 
 43225 |       } 
 43226 |  
 43227 |    public: 
 43228 |  
 43229 |       function_compositor() 
 43230 |       : parser_(settings_t::default_compile_all_opts + 
 43231 |                 settings_t::e_disable_zero_return) 
 43232 |       , fp_map_(7) 
 43233 |       , load_variables_(false) 
 43234 |       , load_vectors_(false) 
 43235 |       {} 
 43236 |  
 43237 |       explicit function_compositor(const symbol_table_t& st) 
 43238 |       : symbol_table_(st) 
 43239 |       , parser_(settings_t::default_compile_all_opts + 
 43240 |                 settings_t::e_disable_zero_return) 
 43241 |       , fp_map_(7) 
 43242 |       , load_variables_(false) 
 43243 |       , load_vectors_(false) 
 43244 |       {} 
 43245 |  
 43246 |      ~function_compositor() 
 43247 |       { 
 43248 |          clear(); 
 43249 |       } 
 43250 |  
 43251 |       inline symbol_table_t& symbol_table() 
 43252 |       { 
 43253 |          return symbol_table_; 
 43254 |       } 
 43255 |  
 43256 |       inline const symbol_table_t& symbol_table() const 
 43257 |       { 
 43258 |          return symbol_table_; 
 43259 |       } 
 43260 |  
 43261 |       inline void add_auxiliary_symtab(symbol_table_t& symtab) 
 43262 |       { 
 43263 |          auxiliary_symtab_list_.push_back(&symtab); 
 43264 |       } 
 43265 |  
 43266 |       void load_variables(const bool load = true) 
 43267 |       { 
 43268 |          load_variables_ = load; 
 43269 |       } 
 43270 |  
 43271 |       void load_vectors(const bool load = true) 
 43272 |       { 
 43273 |          load_vectors_ = load; 
 43274 |       } 
 43275 |  
 43276 |       inline void register_loop_runtime_check(loop_runtime_check& lrtchk) 
 43277 |       { 
 43278 |          parser_.register_loop_runtime_check(lrtchk); 
 43279 |       } 
 43280 |  
 43281 |       inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk) 
 43282 |       { 
 43283 |          parser_.register_vector_access_runtime_check(vartchk); 
 43284 |       } 
 43285 |  
 43286 |       inline void register_compilation_timeout_check(compilation_check& compchk) 
 43287 |       { 
 43288 |          parser_.register_compilation_timeout_check(compchk); 
 43289 |       } 
 43290 |  
 43291 |       inline void clear_loop_runtime_check() 
 43292 |       { 
 43293 |          parser_.clear_loop_runtime_check(); 
 43294 |       } 
 43295 |  
 43296 |       inline void clear_vector_access_runtime_check() 
 43297 |       { 
 43298 |          parser_.clear_vector_access_runtime_check(); 
 43299 |       } 
 43300 |  
 43301 |       inline void clear_compilation_timeout_check() 
 43302 |       { 
 43303 |          parser_.clear_compilation_timeout_check(); 
 43304 |       } 
 43305 |  
 43306 |       void clear() 
 43307 |       { 
 43308 |          symbol_table_.clear(); 
 43309 |          expr_map_    .clear(); 
 43310 |  
 43311 |          for (std::size_t i = 0; i < fp_map_.size(); ++i) 
 43312 |          { 
 43313 |             typename funcparam_t::iterator itr = fp_map_[i].begin(); 
 43314 |             typename funcparam_t::iterator end = fp_map_[i].end  (); 
 43315 |  
 43316 |             while (itr != end) 
 43317 |             { 
 43318 |                delete itr->second; 
 43319 |                ++itr; 
 43320 |             } 
 43321 |  
 43322 |             fp_map_[i].clear(); 
 43323 |          } 
 43324 |  
 43325 |          clear_loop_runtime_check         (); 
 43326 |          clear_vector_access_runtime_check(); 
 43327 |          clear_compilation_timeout_check  (); 
 43328 |       } 
 43329 |  
 43330 |       inline bool add(const function& f, const bool override = false) 
 43331 |       { 
 43332 |          return add(f.name_, f.expression_, f.v_,override); 
 43333 |       } 
 43334 |  
 43335 |       inline std::string error() const 
 43336 |       { 
 43337 |          if (!error_list_.empty()) 
 43338 |          { 
 43339 |             return error_list_[0].diagnostic; 
 43340 |          } 
 43341 |          else 
 43342 |             return std::string("No Error"); 
 43343 |       } 
 43344 |  
 43345 |       inline std::size_t error_count() const 
 43346 |       { 
 43347 |          return error_list_.size(); 
 43348 |       } 
 43349 |  
 43350 |       inline parser_error::type get_error(const std::size_t& index) const 
 43351 |       { 
 43352 |          if (index < error_list_.size()) 
 43353 |          { 
 43354 |             return error_list_[index]; 
 43355 |          } 
 43356 |  
 43357 |          throw std::invalid_argument("compositor::get_error() - Invalid error index specified"); 
 43358 |       } 
 43359 |  
 43360 |    private: 
 43361 |  
 43362 |       template <typename Allocator, 
 43363 |                 template <typename, typename> class Sequence> 
 43364 |       bool compile_expression(const std::string& name, 
 43365 |                               const std::string& expression, 
 43366 |                               const Sequence<std::string,Allocator>& input_var_list, 
 43367 |                               bool  return_present = false) 
 43368 |       { 
 43369 |          expression_t compiled_expression; 
 43370 |          symbol_table_t local_symbol_table; 
 43371 |  
 43372 |          local_symbol_table.load_from(symbol_table_); 
 43373 |          local_symbol_table.add_constants(); 
 43374 |  
 43375 |          if (load_variables_) 
 43376 |          { 
 43377 |             local_symbol_table.load_variables_from(symbol_table_); 
 43378 |          } 
 43379 |  
 43380 |          if (load_vectors_) 
 43381 |          { 
 43382 |             local_symbol_table.load_vectors_from(symbol_table_); 
 43383 |          } 
 43384 |  
 43385 |          error_list_.clear(); 
 43386 |  
 43387 |          if (!valid(name,input_var_list.size())) 
 43388 |          { 
 43389 |             parser_error::type error = 
 43390 |                parser_error::make_error( 
 43391 |                   parser_error::e_parser, 
 43392 |                   lexer::token(), 
 43393 |                   "ERR277 - Function '" + name + "' is an invalid overload", 
 43394 |                   exprtk_error_location); 
 43395 |  
 43396 |             error_list_.push_back(error); 
 43397 |             return false; 
 43398 |          } 
 43399 |  
 43400 |          if (!forward(name, 
 43401 |                       input_var_list.size(), 
 43402 |                       local_symbol_table, 
 43403 |                       return_present)) 
 43404 |             return false; 
 43405 |  
 43406 |          compiled_expression.register_symbol_table(local_symbol_table); 
 43407 |  
 43408 |          for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i) 
 43409 |          { 
 43410 |             compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i])); 
 43411 |          } 
 43412 |  
 43413 |          std::string mod_expression; 
 43414 |  
 43415 |          for (std::size_t i = 0; i < input_var_list.size(); ++i) 
 43416 |          { 
 43417 |             mod_expression += " var " + input_var_list[i] + "{};\n" 
 43418 |          } 
 43419 |  
 43420 |          if ( 
 43421 |               ('{' == details::front(expression)) && 
 43422 |               ('}' == details::back (expression)) 
 43423 |             ) 
 43424 |             mod_expression += "~" + expression + "" 
 43425 |          else 
 43426 |             mod_expression += "~{" + expression + "};" 
 43427 |  
 43428 |          if (!parser_.compile(mod_expression,compiled_expression)) 
 43429 |          { 
 43430 |             exprtk_debug(("Compositor Error: %s\n", parser_.error().c_str())); 
 43431 |             exprtk_debug(("Compositor modified expression: \n%s\n", mod_expression.c_str())); 
 43432 |  
 43433 |             remove(name,input_var_list.size()); 
 43434 |  
 43435 |             for (std::size_t err_index = 0; err_index < parser_.error_count(); ++err_index) 
 43436 |             { 
 43437 |                error_list_.push_back(parser_.get_error(err_index)); 
 43438 |             } 
 43439 |  
 43440 |             return false; 
 43441 |          } 
 43442 |  
 43443 |          if (!return_present && parser_.dec().return_present()) 
 43444 |          { 
 43445 |             remove(name,input_var_list.size()); 
 43446 |             return compile_expression(name, expression, input_var_list, true); 
 43447 |          } 
 43448 |  
 43449 |          // Make sure every return point has a scalar as its first parameter 
 43450 |          if (parser_.dec().return_present()) 
 43451 |          { 
 43452 |             typedef std::vector<std::string> str_list_t; 
 43453 |  
 43454 |             str_list_t ret_param_list = parser_.dec().return_param_type_list(); 
 43455 |  
 43456 |             for (std::size_t i = 0; i < ret_param_list.size(); ++i) 
 43457 |             { 
 43458 |                const std::string& params = ret_param_list[i]; 
 43459 |  
 43460 |                if (params.empty() || ('T' != params[0])) 
 43461 |                { 
 43462 |                   exprtk_debug(("Compositor Error: Return statement in function '%s' is invalid\n", 
 43463 |                                 name.c_str())); 
 43464 |  
 43465 |                   remove(name,input_var_list.size()); 
 43466 |  
 43467 |                   return false; 
 43468 |                } 
 43469 |             } 
 43470 |          } 
 43471 |  
 43472 |          expr_map_[name] = compiled_expression; 
 43473 |  
 43474 |          exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]); 
 43475 |  
 43476 |          if (symbol_table_.add_function(name,ifunc)) 
 43477 |             return true; 
 43478 |          else 
 43479 |          { 
 43480 |             exprtk_debug(("Compositor Error: Failed to add function '%s' to symbol table\n", 
 43481 |                           name.c_str())); 
 43482 |             return false; 
 43483 |          } 
 43484 |       } 
 43485 |  
 43486 |       inline bool symbol_used(const std::string& symbol) const 
 43487 |       { 
 43488 |          return ( 
 43489 |                   symbol_table_.is_variable       (symbol) || 
 43490 |                   symbol_table_.is_stringvar      (symbol) || 
 43491 |                   symbol_table_.is_function       (symbol) || 
 43492 |                   symbol_table_.is_vector         (symbol) || 
 43493 |                   symbol_table_.is_vararg_function(symbol) 
 43494 |                 ); 
 43495 |       } 
 43496 |  
 43497 |       inline bool valid(const std::string& name, 
 43498 |                         const std::size_t& arg_count) const 
 43499 |       { 
 43500 |          if (arg_count > 6) 
 43501 |             return false; 
 43502 |          else if (symbol_used(name)) 
 43503 |             return false; 
 43504 |          else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name)) 
 43505 |             return false; 
 43506 |          else 
 43507 |             return true; 
 43508 |       } 
 43509 |  
 43510 |       inline bool forward(const std::string& name, 
 43511 |                           const std::size_t& arg_count, 
 43512 |                           symbol_table_t& sym_table, 
 43513 |                           const bool ret_present = false) 
 43514 |       { 
 43515 |          switch (arg_count) 
 43516 |          { 
 43517 |             #define case_stmt(N)                                     \ 
 43518 |             case N : (fp_map_[arg_count])[name] =                    \ 
 43519 |                      (!ret_present) ? static_cast<base_func*>        \ 
 43520 |                                       (new func_##N##param) :        \ 
 43521 |                                       static_cast<base_func*>        \ 
 43522 |                                       (new func_##N##param_retval) ; \ 
 43523 |                      break;                                          \ 
 43524 |  
 43525 |             case_stmt(0) case_stmt(1) case_stmt(2) 
 43526 |             case_stmt(3) case_stmt(4) case_stmt(5) 
 43527 |             case_stmt(6) 
 43528 |             #undef case_stmt 
 43529 |          } 
 43530 |  
 43531 |          exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]); 
 43532 |  
 43533 |          return sym_table.add_function(name,ifunc); 
 43534 |       } 
 43535 |  
 43536 |       inline void remove(const std::string& name, const std::size_t& arg_count) 
 43537 |       { 
 43538 |          if (arg_count > 6) 
 43539 |             return; 
 43540 |  
 43541 |          const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name); 
 43542 |  
 43543 |          if (expr_map_.end() != em_itr) 
 43544 |          { 
 43545 |             expr_map_.erase(em_itr); 
 43546 |          } 
 43547 |  
 43548 |          const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name); 
 43549 |  
 43550 |          if (fp_map_[arg_count].end() != fp_itr) 
 43551 |          { 
 43552 |             delete fp_itr->second; 
 43553 |             fp_map_[arg_count].erase(fp_itr); 
 43554 |          } 
 43555 |  
 43556 |          symbol_table_.remove_function(name); 
 43557 |       } 
 43558 |  
 43559 |    private: 
 43560 |  
 43561 |       symbol_table_t symbol_table_; 
 43562 |       parser_t parser_; 
 43563 |       std::map<std::string,expression_t> expr_map_; 
 43564 |       std::vector<funcparam_t> fp_map_; 
 43565 |       std::vector<symbol_table_t*> auxiliary_symtab_list_; 
 43566 |       std::deque<parser_error::type> error_list_; 
 43567 |       bool load_variables_; 
 43568 |       bool load_vectors_; 
 43569 |    }; // class function_compositor 
 43570 |  
 43571 | } // namespace exprtk 
 43572 |  
 43573 | #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 
 43574 | #   ifndef NOMINMAX 
 43575 | #      define NOMINMAX 
 43576 | #   endif 
 43577 | #   ifndef WIN32_LEAN_AND_MEAN 
 43578 | #      define WIN32_LEAN_AND_MEAN 
 43579 | #   endif 
 43580 | #   include  
 43581 | #   include  
 43582 | #else 
 43583 | #   include  
 43584 | #   include  
 43585 | #   include  
 43586 | #endif 
 43587 |  
 43588 | namespace exprtk 
 43589 | { 
 43590 |    class timer 
 43591 |    { 
 43592 |    public: 
 43593 |  
 43594 |       #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 
 43595 |       timer() 
 43596 |       : in_use_(false) 
 43597 |       , start_time_{ {0, 0} } 
 43598 |       , stop_time_ { {0, 0} } 
 43599 |       { 
 43600 |          QueryPerformanceFrequency(&clock_frequency_); 
 43601 |       } 
 43602 |  
 43603 |       inline void start() 
 43604 |       { 
 43605 |          in_use_ = true; 
 43606 |          QueryPerformanceCounter(&start_time_); 
 43607 |       } 
 43608 |  
 43609 |       inline void stop() 
 43610 |       { 
 43611 |          QueryPerformanceCounter(&stop_time_); 
 43612 |          in_use_ = false; 
 43613 |       } 
 43614 |  
 43615 |       inline double time() const 
 43616 |       { 
 43617 |          return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart); 
 43618 |       } 
 43619 |  
 43620 |       #else 
 43621 |  
 43622 |       timer() 
 43623 |       : in_use_(false) 
 43624 |       { 
 43625 |          start_time_.tv_sec  = 0; 
 43626 |          start_time_.tv_usec = 0; 
 43627 |  
 43628 |          stop_time_.tv_sec   = 0; 
 43629 |          stop_time_.tv_usec  = 0; 
 43630 |       } 
 43631 |  
 43632 |       inline void start() 
 43633 |       { 
 43634 |          in_use_ = true; 
 43635 |          gettimeofday(&start_time_,0); 
 43636 |       } 
 43637 |  
 43638 |       inline void stop() 
 43639 |       { 
 43640 |          gettimeofday(&stop_time_, 0); 
 43641 |          in_use_ = false; 
 43642 |       } 
 43643 |  
 43644 |       inline unsigned long long int usec_time() const 
 43645 |       { 
 43646 |          if (!in_use_) 
 43647 |          { 
 43648 |             if (stop_time_.tv_sec >= start_time_.tv_sec) 
 43649 |             { 
 43650 |                return 1000000LLU * static_cast<details::_uint64_t>(stop_time_.tv_sec  - start_time_.tv_sec ) + 
 43651 |                                    static_cast<details::_uint64_t>(stop_time_.tv_usec - start_time_.tv_usec) ; 
 43652 |             } 
 43653 |             else 
 43654 |                return std::numeric_limits<details::_uint64_t>::max(); 
 43655 |          } 
 43656 |          else 
 43657 |             return std::numeric_limits<details::_uint64_t>::max(); 
 43658 |       } 
 43659 |  
 43660 |       inline double time() const 
 43661 |       { 
 43662 |          return usec_time() * 0.000001; 
 43663 |       } 
 43664 |  
 43665 |       #endif 
 43666 |  
 43667 |       inline bool in_use() const 
 43668 |       { 
 43669 |          return in_use_; 
 43670 |       } 
 43671 |  
 43672 |    private: 
 43673 |  
 43674 |       bool in_use_; 
 43675 |  
 43676 |       #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 
 43677 |          LARGE_INTEGER start_time_; 
 43678 |          LARGE_INTEGER stop_time_; 
 43679 |          LARGE_INTEGER clock_frequency_; 
 43680 |       #else 
 43681 |          struct timeval start_time_; 
 43682 |          struct timeval stop_time_; 
 43683 |       #endif 
 43684 |    }; 
 43685 |  
 43686 |    template <typename T> 
 43687 |    struct type_defs 
 43688 |    { 
 43689 |       typedef symbol_table<T>         symbol_table_t; 
 43690 |       typedef expression<T>           expression_t; 
 43691 |       typedef parser<T>               parser_t; 
 43692 |       typedef parser_error::type      error_t; 
 43693 |       typedef function_compositor<T>  compositor_t; 
 43694 |       typedef typename compositor_t::function function_t; 
 43695 |    }; 
 43696 |  
 43697 | } // namespace exprtk 
 43698 |  
 43699 | #ifndef exprtk_disable_rtl_io 
 43700 | namespace exprtk 
 43701 | { 
 43702 |    namespace rtl { namespace io { namespace details 
 43703 |    { 
 43704 |       template <typename T> 
 43705 |       inline void print_type(const std::string& fmt, 
 43706 |                              const T v, 
 43707 |                              exprtk::details::numeric::details::real_type_tag) 
 43708 |       { 
 43709 |          #if defined(__clang__) 
 43710 |             #pragma clang diagnostic push 
 43711 |             #pragma clang diagnostic ignored "-Wformat-nonliteral" 
 43712 |          #elif defined(__GNUC__) || defined(__GNUG__) 
 43713 |             #pragma GCC diagnostic push 
 43714 |             #pragma GCC diagnostic ignored "-Wformat-nonliteral" 
 43715 |          #elif defined(_MSC_VER) 
 43716 |          #endif 
 43717 |  
 43718 |          printf(fmt.c_str(), v); 
 43719 |  
 43720 |          #if defined(__clang__) 
 43721 |             #pragma clang diagnostic pop 
 43722 |          #elif defined(__GNUC__) || defined(__GNUG__) 
 43723 |             #pragma GCC diagnostic pop 
 43724 |          #elif defined(_MSC_VER) 
 43725 |          #endif 
 43726 |       } 
 43727 |  
 43728 |       template <typename T> 
 43729 |       struct print_impl 
 43730 |       { 
 43731 |          typedef typename igeneric_function<T>::generic_type generic_type; 
 43732 |          typedef typename igeneric_function<T>::parameter_list_t parameter_list_t; 
 43733 |          typedef typename generic_type::scalar_view scalar_t; 
 43734 |          typedef typename generic_type::vector_view vector_t; 
 43735 |          typedef typename generic_type::string_view string_t; 
 43736 |          typedef typename exprtk::details::numeric::details::number_type<T>::type num_type; 
 43737 |  
 43738 |          static void process(const std::string& scalar_format, parameter_list_t parameters) 
 43739 |          { 
 43740 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 43741 |             { 
 43742 |                generic_type& gt = parameters[i]; 
 43743 |  
 43744 |                switch (gt.type) 
 43745 |                { 
 43746 |                   case generic_type::e_scalar : print(scalar_format,scalar_t(gt)); 
 43747 |                                                 break; 
 43748 |  
 43749 |                   case generic_type::e_vector : print(scalar_format,vector_t(gt)); 
 43750 |                                                 break; 
 43751 |  
 43752 |                   case generic_type::e_string : print(string_t(gt)); 
 43753 |                                                 break; 
 43754 |  
 43755 |                   default                     : continue; 
 43756 |                } 
 43757 |             } 
 43758 |          } 
 43759 |  
 43760 |          static inline void print(const std::string& scalar_format, const scalar_t& s) 
 43761 |          { 
 43762 |             print_type(scalar_format,s(),num_type()); 
 43763 |          } 
 43764 |  
 43765 |          static inline void print(const std::string& scalar_format, const vector_t& v) 
 43766 |          { 
 43767 |             for (std::size_t i = 0; i < v.size(); ++i) 
 43768 |             { 
 43769 |                print_type(scalar_format,v[i],num_type()); 
 43770 |  
 43771 |                if ((i + 1) < v.size()) 
 43772 |                   printf(" "); 
 43773 |             } 
 43774 |          } 
 43775 |  
 43776 |          static inline void print(const string_t& s) 
 43777 |          { 
 43778 |             printf("%s",to_str(s).c_str()); 
 43779 |          } 
 43780 |       }; 
 43781 |  
 43782 |    } // namespace exprtk::rtl::io::details 
 43783 |  
 43784 |    template <typename T> 
 43785 |    struct print exprtk_final : public exprtk::igeneric_function<T> 
 43786 |    { 
 43787 |       typedef typename igeneric_function<T>::parameter_list_t parameter_list_t; 
 43788 |  
 43789 |       using exprtk::igeneric_function<T>::operator(); 
 43790 |  
 43791 |       explicit print(const std::string& scalar_format = "%10.5f") 
 43792 |       : scalar_format_(scalar_format) 
 43793 |       { 
 43794 |          exprtk::enable_zero_parameters(*this); 
 43795 |       } 
 43796 |  
 43797 |       inline T operator() (parameter_list_t parameters) exprtk_override 
 43798 |       { 
 43799 |          details::print_impl<T>::process(scalar_format_,parameters); 
 43800 |          return T(0); 
 43801 |       } 
 43802 |  
 43803 |       std::string scalar_format_; 
 43804 |    }; 
 43805 |  
 43806 |    template <typename T> 
 43807 |    struct println exprtk_final : public exprtk::igeneric_function<T> 
 43808 |    { 
 43809 |       typedef typename igeneric_function<T>::parameter_list_t parameter_list_t; 
 43810 |  
 43811 |       using exprtk::igeneric_function<T>::operator(); 
 43812 |  
 43813 |       explicit println(const std::string& scalar_format = "%10.5f") 
 43814 |       : scalar_format_(scalar_format) 
 43815 |       { 
 43816 |          exprtk::enable_zero_parameters(*this); 
 43817 |       } 
 43818 |  
 43819 |       inline T operator() (parameter_list_t parameters) exprtk_override 
 43820 |       { 
 43821 |          details::print_impl<T>::process(scalar_format_,parameters); 
 43822 |          printf("\n"); 
 43823 |          return T(0); 
 43824 |       } 
 43825 |  
 43826 |       std::string scalar_format_; 
 43827 |    }; 
 43828 |  
 43829 |    template <typename T> 
 43830 |    struct package 
 43831 |    { 
 43832 |       print  <T> p; 
 43833 |       println<T> pl; 
 43834 |  
 43835 |       bool register_package(exprtk::symbol_table<T>& symtab) 
 43836 |       { 
 43837 |          #define exprtk_register_function(FunctionName, FunctionType)             \ 
 43838 |          if (!symtab.add_function(FunctionName,FunctionType))                     \ 
 43839 |          {                                                                        \ 
 43840 |             exprtk_debug((                                                        \ 
 43841 |               "exprtk::rtl::io::register_package - Failed to add function: %s\n", \ 
 43842 |               FunctionName));                                                     \ 
 43843 |             return false;                                                         \ 
 43844 |          }                                                                        \ 
 43845 |  
 43846 |          exprtk_register_function("print"  , p ) 
 43847 |          exprtk_register_function("println", pl) 
 43848 |          #undef exprtk_register_function 
 43849 |  
 43850 |          return true; 
 43851 |       } 
 43852 |    }; 
 43853 |  
 43854 |    } // namespace exprtk::rtl::io 
 43855 |    } // namespace exprtk::rtl 
 43856 | }    // namespace exprtk 
 43857 | #endif 
 43858 |  
 43859 | #ifndef exprtk_disable_rtl_io_file 
 43860 | #include  
 43861 | namespace exprtk 
 43862 | { 
 43863 |    namespace rtl { namespace io { namespace file { namespace details 
 43864 |    { 
 43865 |       using ::exprtk::details::char_ptr; 
 43866 |       using ::exprtk::details::char_cptr; 
 43867 |  
 43868 |       enum file_mode 
 43869 |       { 
 43870 |          e_error = 0, 
 43871 |          e_read  = 1, 
 43872 |          e_write = 2, 
 43873 |          e_rdwrt = 4 
 43874 |       }; 
 43875 |  
 43876 |       struct file_descriptor 
 43877 |       { 
 43878 |          file_descriptor(const std::string& fname, const std::string& access) 
 43879 |          : stream_ptr(0) 
 43880 |          , mode(get_file_mode(access)) 
 43881 |          , file_name(fname) 
 43882 |          {} 
 43883 |  
 43884 |          void*       stream_ptr; 
 43885 |          file_mode   mode; 
 43886 |          std::string file_name; 
 43887 |  
 43888 |          bool open() 
 43889 |          { 
 43890 |             if (e_read == mode) 
 43891 |             { 
 43892 |                std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary); 
 43893 |  
 43894 |                if (!(*stream)) 
 43895 |                { 
 43896 |                   file_name.clear(); 
 43897 |                   delete stream; 
 43898 |  
 43899 |                   return false; 
 43900 |                } 
 43901 |  
 43902 |                stream_ptr = stream; 
 43903 |  
 43904 |                return true; 
 43905 |             } 
 43906 |             else if (e_write == mode) 
 43907 |             { 
 43908 |                std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary); 
 43909 |  
 43910 |                if (!(*stream)) 
 43911 |                { 
 43912 |                   file_name.clear(); 
 43913 |                   delete stream; 
 43914 |  
 43915 |                   return false; 
 43916 |                } 
 43917 |  
 43918 |                stream_ptr = stream; 
 43919 |  
 43920 |                return true; 
 43921 |             } 
 43922 |             else if (e_rdwrt == mode) 
 43923 |             { 
 43924 |                std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary); 
 43925 |  
 43926 |                if (!(*stream)) 
 43927 |                { 
 43928 |                   file_name.clear(); 
 43929 |                   delete stream; 
 43930 |  
 43931 |                   return false; 
 43932 |                } 
 43933 |  
 43934 |                stream_ptr = stream; 
 43935 |  
 43936 |                return true; 
 43937 |             } 
 43938 |  
 43939 |             return false; 
 43940 |          } 
 43941 |  
 43942 |          template <typename Stream, typename Ptr> 
 43943 |          void close(Ptr& p) 
 43944 |          { 
 43945 |             Stream* stream = reinterpret_cast<Stream*>(p); 
 43946 |             stream->close(); 
 43947 |             delete stream; 
 43948 |             p = reinterpret_cast<Ptr>(0); 
 43949 |          } 
 43950 |  
 43951 |          bool close() 
 43952 |          { 
 43953 |             switch (mode) 
 43954 |             { 
 43955 |                case e_read  : close<std::ifstream>(stream_ptr); 
 43956 |                               break; 
 43957 |  
 43958 |                case e_write : close<std::ofstream>(stream_ptr); 
 43959 |                               break; 
 43960 |  
 43961 |                case e_rdwrt : close<std::fstream> (stream_ptr); 
 43962 |                               break; 
 43963 |  
 43964 |                default      : return false; 
 43965 |             } 
 43966 |  
 43967 |             return true; 
 43968 |          } 
 43969 |  
 43970 |          template <typename View> 
 43971 |          bool write(const View& view, const std::size_t amount, const std::size_t offset = 0) 
 43972 |          { 
 43973 |             switch (mode) 
 43974 |             { 
 43975 |                case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)-> 
 43976 |                                  write(reinterpret_cast<char_cptr>(view.begin() + offset), amount * sizeof(typename View::value_t)); 
 43977 |                               break; 
 43978 |  
 43979 |                case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)-> 
 43980 |                                  write(reinterpret_cast<char_cptr>(view.begin() + offset) , amount * sizeof(typename View::value_t)); 
 43981 |                               break; 
 43982 |  
 43983 |                default      : return false; 
 43984 |             } 
 43985 |  
 43986 |             return true; 
 43987 |          } 
 43988 |  
 43989 |          template <typename View> 
 43990 |          bool read(View& view, const std::size_t amount, const std::size_t offset = 0) 
 43991 |          { 
 43992 |             switch (mode) 
 43993 |             { 
 43994 |                case e_read  : reinterpret_cast<std::ifstream*>(stream_ptr)-> 
 43995 |                                  read(reinterpret_cast<char_ptr>(view.begin() + offset), amount * sizeof(typename View::value_t)); 
 43996 |                               break; 
 43997 |  
 43998 |                case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)-> 
 43999 |                                  read(reinterpret_cast<char_ptr>(view.begin() + offset) , amount * sizeof(typename View::value_t)); 
 44000 |                               break; 
 44001 |  
 44002 |                default      : return false; 
 44003 |             } 
 44004 |  
 44005 |             return true; 
 44006 |          } 
 44007 |  
 44008 |          bool getline(std::string& s) 
 44009 |          { 
 44010 |             switch (mode) 
 44011 |             { 
 44012 |                case e_read  : return (!!std::getline(*reinterpret_cast<std::ifstream*>(stream_ptr),s)); 
 44013 |                case e_rdwrt : return (!!std::getline(*reinterpret_cast<std::fstream* >(stream_ptr),s)); 
 44014 |                default      : return false; 
 44015 |             } 
 44016 |          } 
 44017 |  
 44018 |          bool eof() const 
 44019 |          { 
 44020 |             switch (mode) 
 44021 |             { 
 44022 |                case e_read  : return reinterpret_cast<std::ifstream*>(stream_ptr)->eof(); 
 44023 |                case e_write : return reinterpret_cast<std::ofstream*>(stream_ptr)->eof(); 
 44024 |                case e_rdwrt : return reinterpret_cast<std::fstream* >(stream_ptr)->eof(); 
 44025 |                default      : return true; 
 44026 |             } 
 44027 |          } 
 44028 |  
 44029 |          file_mode get_file_mode(const std::string& access) const 
 44030 |          { 
 44031 |             if (access.empty() || access.size() > 2) 
 44032 |                return e_error; 
 44033 |  
 44034 |             std::size_t w_cnt = 0; 
 44035 |             std::size_t r_cnt = 0; 
 44036 |  
 44037 |             for (std::size_t i = 0; i < access.size(); ++i) 
 44038 |             { 
 44039 |                switch (std::tolower(access[i])) 
 44040 |                { 
 44041 |                   case 'r' : r_cnt++; break; 
 44042 |                   case 'w' : w_cnt++; break; 
 44043 |                   default  : return e_error; 
 44044 |                } 
 44045 |             } 
 44046 |  
 44047 |             if ((0 == r_cnt) && (0 == w_cnt)) 
 44048 |                return e_error; 
 44049 |             else if ((r_cnt > 1) || (w_cnt > 1)) 
 44050 |                return e_error; 
 44051 |             else if ((1 == r_cnt) && (1 == w_cnt)) 
 44052 |                return e_rdwrt; 
 44053 |             else if (1 == r_cnt) 
 44054 |                return e_read; 
 44055 |             else 
 44056 |                return e_write; 
 44057 |          } 
 44058 |       }; 
 44059 |  
 44060 |       template <typename T> 
 44061 |       file_descriptor* make_handle(T v) 
 44062 |       { 
 44063 |          const std::size_t fd_size    = sizeof(details::file_descriptor*); 
 44064 |          details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0); 
 44065 |  
 44066 |          std::memcpy(reinterpret_cast<char_ptr >(&fd), 
 44067 |                      reinterpret_cast<char_cptr>(&v ), 
 44068 |                      fd_size); 
 44069 |          return fd; 
 44070 |       } 
 44071 |  
 44072 |       template <typename T> 
 44073 |       void perform_check() 
 44074 |       { 
 44075 |          #ifdef _MSC_VER 
 44076 |          #pragma warning(push) 
 44077 |          #pragma warning(disable: 4127) 
 44078 |          #endif 
 44079 |          if (sizeof(T) < sizeof(void*)) 
 44080 |          { 
 44081 |             throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder."); 
 44082 |          } 
 44083 |          #ifdef _MSC_VER 
 44084 |          #pragma warning(pop) 
 44085 |          #endif 
 44086 |          assert(sizeof(T) <= sizeof(void*)); 
 44087 |       } 
 44088 |  
 44089 |    } // namespace exprtk::rtl::io::file::details 
 44090 |  
 44091 |    template <typename T> 
 44092 |    class open exprtk_final : public exprtk::igeneric_function<T> 
 44093 |    { 
 44094 |    public: 
 44095 |  
 44096 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44097 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44098 |       typedef typename igfun_t::generic_type        generic_type; 
 44099 |       typedef typename generic_type::string_view    string_t; 
 44100 |  
 44101 |       using igfun_t::operator(); 
 44102 |  
 44103 |       open() 
 44104 |       : exprtk::igeneric_function<T>("S|SS") 
 44105 |       { details::perform_check<T>(); } 
 44106 |  
 44107 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44108 |       { 
 44109 |          const std::string file_name = to_str(string_t(parameters[0])); 
 44110 |  
 44111 |          if (file_name.empty()) 
 44112 |          { 
 44113 |             return T(0); 
 44114 |          } 
 44115 |  
 44116 |          if ((1 == ps_index) && (0 == string_t(parameters[1]).size())) 
 44117 |          { 
 44118 |             return T(0); 
 44119 |          } 
 44120 |  
 44121 |          const std::string access = 
 44122 |             (0 == ps_index) ? "r" : to_str(string_t(parameters[1])); 
 44123 |  
 44124 |          details::file_descriptor* fd = new details::file_descriptor(file_name,access); 
 44125 |  
 44126 |          if (fd->open()) 
 44127 |          { 
 44128 |             T t = T(0); 
 44129 |  
 44130 |             const std::size_t fd_size = sizeof(details::file_descriptor*); 
 44131 |  
 44132 |             std::memcpy(reinterpret_cast<char*>(&t ), 
 44133 |                         reinterpret_cast<char*>(&fd), 
 44134 |                         fd_size); 
 44135 |             return t; 
 44136 |          } 
 44137 |          else 
 44138 |          { 
 44139 |             delete fd; 
 44140 |             return T(0); 
 44141 |          } 
 44142 |       } 
 44143 |    }; 
 44144 |  
 44145 |    template <typename T> 
 44146 |    struct close exprtk_final : public exprtk::ifunction<T> 
 44147 |    { 
 44148 |       using exprtk::ifunction<T>::operator(); 
 44149 |  
 44150 |       close() 
 44151 |       : exprtk::ifunction<T>(1) 
 44152 |       { details::perform_check<T>(); } 
 44153 |  
 44154 |       inline T operator() (const T& v) exprtk_override 
 44155 |       { 
 44156 |          details::file_descriptor* fd = details::make_handle(v); 
 44157 |  
 44158 |          if (!fd->close()) 
 44159 |             return T(0); 
 44160 |  
 44161 |          delete fd; 
 44162 |  
 44163 |          return T(1); 
 44164 |       } 
 44165 |    }; 
 44166 |  
 44167 |    template <typename T> 
 44168 |    class write exprtk_final : public exprtk::igeneric_function<T> 
 44169 |    { 
 44170 |    public: 
 44171 |  
 44172 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44173 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44174 |       typedef typename igfun_t::generic_type        generic_type; 
 44175 |       typedef typename generic_type::string_view    string_t; 
 44176 |       typedef typename generic_type::scalar_view    scalar_t; 
 44177 |       typedef typename generic_type::vector_view    vector_t; 
 44178 |  
 44179 |       using igfun_t::operator(); 
 44180 |  
 44181 |       write() 
 44182 |       : igfun_t("TS|TST|TV|TVT") 
 44183 |       { details::perform_check<T>(); } 
 44184 |  
 44185 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44186 |       { 
 44187 |          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); 
 44188 |  
 44189 |          switch (ps_index) 
 44190 |          { 
 44191 |             case 0  : { 
 44192 |                          const string_t buffer(parameters[1]); 
 44193 |                          const std::size_t amount = buffer.size(); 
 44194 |                          return T(fd->write(buffer, amount) ? 1 : 0); 
 44195 |                       } 
 44196 |  
 44197 |             case 1  : { 
 44198 |                          const string_t buffer(parameters[1]); 
 44199 |                          const std::size_t amount = 
 44200 |                                   std::min(buffer.size(), 
 44201 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44202 |                          return T(fd->write(buffer, amount) ? 1 : 0); 
 44203 |                       } 
 44204 |  
 44205 |             case 2  : { 
 44206 |                          const vector_t vec(parameters[1]); 
 44207 |                          const std::size_t amount = vec.size(); 
 44208 |                          return T(fd->write(vec, amount) ? 1 : 0); 
 44209 |                       } 
 44210 |  
 44211 |             case 3  : { 
 44212 |                          const vector_t vec(parameters[1]); 
 44213 |                          const std::size_t amount = 
 44214 |                                   std::min(vec.size(), 
 44215 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44216 |                          return T(fd->write(vec, amount) ? 1 : 0); 
 44217 |                       } 
 44218 |          } 
 44219 |  
 44220 |          return T(0); 
 44221 |       } 
 44222 |    }; 
 44223 |  
 44224 |    template <typename T> 
 44225 |    class read exprtk_final : public exprtk::igeneric_function<T> 
 44226 |    { 
 44227 |    public: 
 44228 |  
 44229 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44230 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44231 |       typedef typename igfun_t::generic_type        generic_type; 
 44232 |       typedef typename generic_type::string_view    string_t; 
 44233 |       typedef typename generic_type::scalar_view    scalar_t; 
 44234 |       typedef typename generic_type::vector_view    vector_t; 
 44235 |  
 44236 |       using igfun_t::operator(); 
 44237 |  
 44238 |       read() 
 44239 |       : igfun_t("TS|TST|TV|TVT") 
 44240 |       { details::perform_check<T>(); } 
 44241 |  
 44242 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44243 |       { 
 44244 |          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); 
 44245 |  
 44246 |          switch (ps_index) 
 44247 |          { 
 44248 |             case 0  : { 
 44249 |                          string_t buffer(parameters[1]); 
 44250 |                          const std::size_t amount = buffer.size(); 
 44251 |                          return T(fd->read(buffer,amount) ? 1 : 0); 
 44252 |                       } 
 44253 |  
 44254 |             case 1  : { 
 44255 |                          string_t buffer(parameters[1]); 
 44256 |                          const std::size_t amount = 
 44257 |                                   std::min(buffer.size(), 
 44258 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44259 |                          return T(fd->read(buffer,amount) ? 1 : 0); 
 44260 |                       } 
 44261 |  
 44262 |             case 2  : { 
 44263 |                          vector_t vec(parameters[1]); 
 44264 |                          const std::size_t amount = vec.size(); 
 44265 |                          return T(fd->read(vec,amount) ? 1 : 0); 
 44266 |                       } 
 44267 |  
 44268 |             case 3  : { 
 44269 |                          vector_t vec(parameters[1]); 
 44270 |                          const std::size_t amount = 
 44271 |                                   std::min(vec.size(), 
 44272 |                                            static_cast<std::size_t>(scalar_t(parameters[2])())); 
 44273 |                          return T(fd->read(vec,amount) ? 1 : 0); 
 44274 |                       } 
 44275 |          } 
 44276 |  
 44277 |          return T(0); 
 44278 |       } 
 44279 |    }; 
 44280 |  
 44281 |    template <typename T> 
 44282 |    class getline exprtk_final : public exprtk::igeneric_function<T> 
 44283 |    { 
 44284 |    public: 
 44285 |  
 44286 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44287 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44288 |       typedef typename igfun_t::generic_type        generic_type; 
 44289 |       typedef typename generic_type::string_view    string_t; 
 44290 |       typedef typename generic_type::scalar_view    scalar_t; 
 44291 |  
 44292 |       using igfun_t::operator(); 
 44293 |  
 44294 |       getline() 
 44295 |       : igfun_t("T",igfun_t::e_rtrn_string) 
 44296 |       { details::perform_check<T>(); } 
 44297 |  
 44298 |       inline T operator() (std::string& result, parameter_list_t parameters) exprtk_override 
 44299 |       { 
 44300 |          details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); 
 44301 |          return T(fd->getline(result) ? 1 : 0); 
 44302 |       } 
 44303 |    }; 
 44304 |  
 44305 |    template <typename T> 
 44306 |    struct eof exprtk_final : public exprtk::ifunction<T> 
 44307 |    { 
 44308 |       using exprtk::ifunction<T>::operator(); 
 44309 |  
 44310 |       eof() 
 44311 |       : exprtk::ifunction<T>(1) 
 44312 |       { details::perform_check<T>(); } 
 44313 |  
 44314 |       inline T operator() (const T& v) exprtk_override 
 44315 |       { 
 44316 |          details::file_descriptor* fd = details::make_handle(v); 
 44317 |          return (fd->eof() ? T(1) : T(0)); 
 44318 |       } 
 44319 |    }; 
 44320 |  
 44321 |    template <typename T> 
 44322 |    struct package 
 44323 |    { 
 44324 |       open   <T> o; 
 44325 |       close  <T> c; 
 44326 |       write  <T> w; 
 44327 |       read   <T> r; 
 44328 |       getline<T> g; 
 44329 |       eof    <T> e; 
 44330 |  
 44331 |       bool register_package(exprtk::symbol_table<T>& symtab) 
 44332 |       { 
 44333 |          #define exprtk_register_function(FunctionName, FunctionType)                   \ 
 44334 |          if (!symtab.add_function(FunctionName,FunctionType))                           \ 
 44335 |          {                                                                              \ 
 44336 |             exprtk_debug((                                                              \ 
 44337 |               "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \ 
 44338 |               FunctionName));                                                           \ 
 44339 |             return false;                                                               \ 
 44340 |          }                                                                              \ 
 44341 |  
 44342 |          exprtk_register_function("open"    , o) 
 44343 |          exprtk_register_function("close"   , c) 
 44344 |          exprtk_register_function("write"   , w) 
 44345 |          exprtk_register_function("read"    , r) 
 44346 |          exprtk_register_function("getline" , g) 
 44347 |          exprtk_register_function("eof"     , e) 
 44348 |          #undef exprtk_register_function 
 44349 |  
 44350 |          return true; 
 44351 |       } 
 44352 |    }; 
 44353 |  
 44354 |    } // namespace exprtk::rtl::io::file 
 44355 |    } // namespace exprtk::rtl::io 
 44356 |    } // namespace exprtk::rtl 
 44357 | }    // namespace exprtk 
 44358 | #endif 
 44359 |  
 44360 | #ifndef exprtk_disable_rtl_vecops 
 44361 | namespace exprtk 
 44362 | { 
 44363 |    namespace rtl { namespace vecops { 
 44364 |  
 44365 |    namespace helper 
 44366 |    { 
 44367 |       template <typename Vector> 
 44368 |       inline bool invalid_range(const Vector& v, const std::size_t r0, const std::size_t r1) 
 44369 |       { 
 44370 |          if (r0 > (v.size() - 1)) 
 44371 |             return true; 
 44372 |          else if (r1 > (v.size() - 1)) 
 44373 |             return true; 
 44374 |          else if (r1 < r0) 
 44375 |             return true; 
 44376 |          else 
 44377 |             return false; 
 44378 |       } 
 44379 |  
 44380 |       template <typename T> 
 44381 |       struct load_vector_range 
 44382 |       { 
 44383 |          typedef typename exprtk::igeneric_function<T> igfun_t; 
 44384 |          typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44385 |          typedef typename igfun_t::generic_type        generic_type; 
 44386 |          typedef typename generic_type::scalar_view    scalar_t; 
 44387 |          typedef typename generic_type::vector_view    vector_t; 
 44388 |  
 44389 |          static inline bool process(parameter_list_t& parameters, 
 44390 |                                     std::size_t& r0, std::size_t& r1, 
 44391 |                                     const std::size_t& r0_prmidx, 
 44392 |                                     const std::size_t& r1_prmidx, 
 44393 |                                     const std::size_t vec_idx = 0) 
 44394 |          { 
 44395 |             if (r0_prmidx >= parameters.size()) 
 44396 |                return false; 
 44397 |  
 44398 |             if (r1_prmidx >= parameters.size()) 
 44399 |                return false; 
 44400 |  
 44401 |             if (!scalar_t(parameters[r0_prmidx]).to_uint(r0)) 
 44402 |                return false; 
 44403 |  
 44404 |             if (!scalar_t(parameters[r1_prmidx]).to_uint(r1)) 
 44405 |                return false; 
 44406 |  
 44407 |             return !invalid_range(vector_t(parameters[vec_idx]), r0, r1); 
 44408 |          } 
 44409 |       }; 
 44410 |    } 
 44411 |  
 44412 |    namespace details 
 44413 |    { 
 44414 |       template <typename T> 
 44415 |       inline void kahan_sum(T& sum, T& error, const T v) 
 44416 |       { 
 44417 |          const T x = v - error; 
 44418 |          const T y = sum + x; 
 44419 |          error = (y - sum) - x; 
 44420 |          sum = y; 
 44421 |       } 
 44422 |  
 44423 |    } // namespace exprtk::rtl::details 
 44424 |  
 44425 |    template <typename T> 
 44426 |    class all_true exprtk_final : public exprtk::igeneric_function<T> 
 44427 |    { 
 44428 |    public: 
 44429 |  
 44430 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44431 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44432 |       typedef typename igfun_t::generic_type        generic_type; 
 44433 |       typedef typename generic_type::scalar_view    scalar_t; 
 44434 |       typedef typename generic_type::vector_view    vector_t; 
 44435 |  
 44436 |       using igfun_t::operator(); 
 44437 |  
 44438 |       all_true() 
 44439 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44440 |         /* 
 44441 |            Overloads: 
 44442 |            0. V   - vector 
 44443 |            1. VTT - vector, r0, r1 
 44444 |            2. T*  - T....T 
 44445 |         */ 
 44446 |       {} 
 44447 |  
 44448 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44449 |       { 
 44450 |          if (2 == ps_index) 
 44451 |          { 
 44452 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44453 |             { 
 44454 |                if (scalar_t(parameters[i])() == T(0)) 
 44455 |                { 
 44456 |                   return T(0); 
 44457 |                } 
 44458 |             } 
 44459 |          } 
 44460 |          else 
 44461 |          { 
 44462 |             const vector_t vec(parameters[0]); 
 44463 |  
 44464 |             std::size_t r0 = 0; 
 44465 |             std::size_t r1 = vec.size() - 1; 
 44466 |  
 44467 |             if ( 
 44468 |                  (1 == ps_index) && 
 44469 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44470 |                ) 
 44471 |             { 
 44472 |                return std::numeric_limits<T>::quiet_NaN(); 
 44473 |             } 
 44474 |  
 44475 |             for (std::size_t i = r0; i <= r1; ++i) 
 44476 |             { 
 44477 |                if (vec[i] == T(0)) 
 44478 |                { 
 44479 |                   return T(0); 
 44480 |                } 
 44481 |             } 
 44482 |          } 
 44483 |  
 44484 |          return T(1); 
 44485 |       } 
 44486 |    }; 
 44487 |  
 44488 |    template <typename T> 
 44489 |    class all_false exprtk_final : public exprtk::igeneric_function<T> 
 44490 |    { 
 44491 |    public: 
 44492 |  
 44493 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44494 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44495 |       typedef typename igfun_t::generic_type        generic_type; 
 44496 |       typedef typename generic_type::scalar_view    scalar_t; 
 44497 |       typedef typename generic_type::vector_view    vector_t; 
 44498 |  
 44499 |       using igfun_t::operator(); 
 44500 |  
 44501 |       all_false() 
 44502 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44503 |         /* 
 44504 |            Overloads: 
 44505 |            0. V   - vector 
 44506 |            1. VTT - vector, r0, r1 
 44507 |            2. T*  - T....T 
 44508 |         */ 
 44509 |       {} 
 44510 |  
 44511 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44512 |       { 
 44513 |          if (2 == ps_index) 
 44514 |          { 
 44515 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44516 |             { 
 44517 |                if (scalar_t(parameters[i])() != T(0)) 
 44518 |                { 
 44519 |                   return T(0); 
 44520 |                } 
 44521 |             } 
 44522 |          } 
 44523 |          else 
 44524 |          { 
 44525 |             const vector_t vec(parameters[0]); 
 44526 |  
 44527 |             std::size_t r0 = 0; 
 44528 |             std::size_t r1 = vec.size() - 1; 
 44529 |  
 44530 |             if ( 
 44531 |                  (1 == ps_index) && 
 44532 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44533 |                ) 
 44534 |             { 
 44535 |                return std::numeric_limits<T>::quiet_NaN(); 
 44536 |             } 
 44537 |  
 44538 |             for (std::size_t i = r0; i <= r1; ++i) 
 44539 |             { 
 44540 |                if (vec[i] != T(0)) 
 44541 |                { 
 44542 |                   return T(0); 
 44543 |                } 
 44544 |             } 
 44545 |          } 
 44546 |  
 44547 |          return T(1); 
 44548 |       } 
 44549 |    }; 
 44550 |  
 44551 |    template <typename T> 
 44552 |    class any_true exprtk_final : public exprtk::igeneric_function<T> 
 44553 |    { 
 44554 |    public: 
 44555 |  
 44556 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44557 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44558 |       typedef typename igfun_t::generic_type        generic_type; 
 44559 |       typedef typename generic_type::scalar_view    scalar_t; 
 44560 |       typedef typename generic_type::vector_view    vector_t; 
 44561 |  
 44562 |       using igfun_t::operator(); 
 44563 |  
 44564 |       any_true() 
 44565 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44566 |         /* 
 44567 |            Overloads: 
 44568 |            0. V   - vector 
 44569 |            1. VTT - vector, r0, r1 
 44570 |            2. T*  - T....T 
 44571 |         */ 
 44572 |       {} 
 44573 |  
 44574 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44575 |       { 
 44576 |          if (2 == ps_index) 
 44577 |          { 
 44578 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44579 |             { 
 44580 |                if (scalar_t(parameters[i])() != T(0)) 
 44581 |                { 
 44582 |                   return T(1); 
 44583 |                } 
 44584 |             } 
 44585 |          } 
 44586 |          else 
 44587 |          { 
 44588 |             const vector_t vec(parameters[0]); 
 44589 |  
 44590 |             std::size_t r0 = 0; 
 44591 |             std::size_t r1 = vec.size() - 1; 
 44592 |  
 44593 |             if ( 
 44594 |                  (1 == ps_index) && 
 44595 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44596 |                ) 
 44597 |             { 
 44598 |                return std::numeric_limits<T>::quiet_NaN(); 
 44599 |             } 
 44600 |  
 44601 |             for (std::size_t i = r0; i <= r1; ++i) 
 44602 |             { 
 44603 |                if (vec[i] != T(0)) 
 44604 |                { 
 44605 |                   return T(1); 
 44606 |                } 
 44607 |             } 
 44608 |          } 
 44609 |  
 44610 |          return T(0); 
 44611 |       } 
 44612 |    }; 
 44613 |  
 44614 |    template <typename T> 
 44615 |    class any_false exprtk_final : public exprtk::igeneric_function<T> 
 44616 |    { 
 44617 |    public: 
 44618 |  
 44619 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44620 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44621 |       typedef typename igfun_t::generic_type        generic_type; 
 44622 |       typedef typename generic_type::scalar_view    scalar_t; 
 44623 |       typedef typename generic_type::vector_view    vector_t; 
 44624 |  
 44625 |       using igfun_t::operator(); 
 44626 |  
 44627 |       any_false() 
 44628 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44629 |         /* 
 44630 |            Overloads: 
 44631 |            0. V   - vector 
 44632 |            1. VTT - vector, r0, r1 
 44633 |            2. T*  - T....T 
 44634 |         */ 
 44635 |       {} 
 44636 |  
 44637 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44638 |       { 
 44639 |          if (2 == ps_index) 
 44640 |          { 
 44641 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44642 |             { 
 44643 |                if (scalar_t(parameters[i])() == T(0)) 
 44644 |                { 
 44645 |                   return T(1); 
 44646 |                } 
 44647 |             } 
 44648 |          } 
 44649 |          else 
 44650 |          { 
 44651 |             const vector_t vec(parameters[0]); 
 44652 |  
 44653 |             std::size_t r0 = 0; 
 44654 |             std::size_t r1 = vec.size() - 1; 
 44655 |  
 44656 |             if ( 
 44657 |                  (1 == ps_index) && 
 44658 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44659 |                ) 
 44660 |             { 
 44661 |                return std::numeric_limits<T>::quiet_NaN(); 
 44662 |             } 
 44663 |  
 44664 |             for (std::size_t i = r0; i <= r1; ++i) 
 44665 |             { 
 44666 |                if (vec[i] == T(0)) 
 44667 |                { 
 44668 |                   return T(1); 
 44669 |                } 
 44670 |             } 
 44671 |          } 
 44672 |  
 44673 |          return T(0); 
 44674 |       } 
 44675 |    }; 
 44676 |  
 44677 |    template <typename T> 
 44678 |    class count exprtk_final : public exprtk::igeneric_function<T> 
 44679 |    { 
 44680 |    public: 
 44681 |  
 44682 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44683 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44684 |       typedef typename igfun_t::generic_type        generic_type; 
 44685 |       typedef typename generic_type::scalar_view    scalar_t; 
 44686 |       typedef typename generic_type::vector_view    vector_t; 
 44687 |  
 44688 |       using igfun_t::operator(); 
 44689 |  
 44690 |       count() 
 44691 |       : exprtk::igeneric_function<T>("V|VTT|T*") 
 44692 |         /* 
 44693 |            Overloads: 
 44694 |            0. V   - vector 
 44695 |            1. VTT - vector, r0, r1 
 44696 |            2. T*  - T....T 
 44697 |         */ 
 44698 |       {} 
 44699 |  
 44700 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44701 |       { 
 44702 |          std::size_t cnt = 0; 
 44703 |  
 44704 |          if (2 == ps_index) 
 44705 |          { 
 44706 |             for (std::size_t i = 0; i < parameters.size(); ++i) 
 44707 |             { 
 44708 |                if (scalar_t(parameters[i])() != T(0)) ++cnt; 
 44709 |             } 
 44710 |          } 
 44711 |          else 
 44712 |          { 
 44713 |             const vector_t vec(parameters[0]); 
 44714 |  
 44715 |             std::size_t r0 = 0; 
 44716 |             std::size_t r1 = vec.size() - 1; 
 44717 |  
 44718 |             if ( 
 44719 |                  (1 == ps_index) && 
 44720 |                  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44721 |                ) 
 44722 |             { 
 44723 |                return std::numeric_limits<T>::quiet_NaN(); 
 44724 |             } 
 44725 |  
 44726 |             for (std::size_t i = r0; i <= r1; ++i) 
 44727 |             { 
 44728 |                if (vec[i] != T(0)) ++cnt; 
 44729 |             } 
 44730 |          } 
 44731 |  
 44732 |          return T(cnt); 
 44733 |       } 
 44734 |    }; 
 44735 |  
 44736 |    template <typename T> 
 44737 |    class copy exprtk_final : public exprtk::igeneric_function<T> 
 44738 |    { 
 44739 |    public: 
 44740 |  
 44741 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44742 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44743 |       typedef typename igfun_t::generic_type        generic_type; 
 44744 |       typedef typename generic_type::scalar_view    scalar_t; 
 44745 |       typedef typename generic_type::vector_view    vector_t; 
 44746 |  
 44747 |       using igfun_t::operator(); 
 44748 |  
 44749 |       copy() 
 44750 |       : exprtk::igeneric_function<T>("VV|VTTVTT") 
 44751 |         /* 
 44752 |            Overloads: 
 44753 |            0. VV     - x(vector), y(vector) 
 44754 |            1. VTTVTT - x(vector), xr0, xr1, y(vector), yr0, yr1, 
 44755 |         */ 
 44756 |       {} 
 44757 |  
 44758 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44759 |       { 
 44760 |          const vector_t x(parameters[0]); 
 44761 |                vector_t y(parameters[(0 == ps_index) ? 1 : 3]); 
 44762 |  
 44763 |          std::size_t xr0 = 0; 
 44764 |          std::size_t xr1 = x.size() - 1; 
 44765 |  
 44766 |          std::size_t yr0 = 0; 
 44767 |          std::size_t yr1 = y.size() - 1; 
 44768 |  
 44769 |          if (1 == ps_index) 
 44770 |          { 
 44771 |             if ( 
 44772 |                  !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) || 
 44773 |                  !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3) 
 44774 |                ) 
 44775 |                return T(0); 
 44776 |          } 
 44777 |  
 44778 |          const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1); 
 44779 |  
 44780 |          std::copy( 
 44781 |             x.begin() + xr0, 
 44782 |             x.begin() + xr0 + n, 
 44783 |             y.begin() + yr0); 
 44784 |  
 44785 |          return T(n); 
 44786 |       } 
 44787 |    }; 
 44788 |  
 44789 |    template <typename T> 
 44790 |    class rol exprtk_final : public exprtk::igeneric_function<T> 
 44791 |    { 
 44792 |    public: 
 44793 |  
 44794 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44795 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44796 |       typedef typename igfun_t::generic_type        generic_type; 
 44797 |       typedef typename generic_type::scalar_view    scalar_t; 
 44798 |       typedef typename generic_type::vector_view    vector_t; 
 44799 |  
 44800 |       using igfun_t::operator(); 
 44801 |  
 44802 |       rol() 
 44803 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 44804 |         /* 
 44805 |            Overloads: 
 44806 |            0. VT   - vector, N 
 44807 |            1. VTTT - vector, N, r0, r1 
 44808 |         */ 
 44809 |       {} 
 44810 |  
 44811 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44812 |       { 
 44813 |          vector_t vec(parameters[0]); 
 44814 |  
 44815 |          std::size_t n  = 0; 
 44816 |          std::size_t r0 = 0; 
 44817 |          std::size_t r1 = vec.size() - 1; 
 44818 |  
 44819 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 44820 |             return T(0); 
 44821 |  
 44822 |          if ( 
 44823 |               (1 == ps_index) && 
 44824 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 44825 |             ) 
 44826 |             return T(0); 
 44827 |  
 44828 |          const std::size_t dist  = r1 - r0 + 1; 
 44829 |          const std::size_t shift = n % dist; 
 44830 |  
 44831 |          std::rotate( 
 44832 |             vec.begin() + r0, 
 44833 |             vec.begin() + r0 + shift, 
 44834 |             vec.begin() + r1 + 1); 
 44835 |  
 44836 |          return T(1); 
 44837 |       } 
 44838 |    }; 
 44839 |  
 44840 |    template <typename T> 
 44841 |    class ror exprtk_final : public exprtk::igeneric_function<T> 
 44842 |    { 
 44843 |    public: 
 44844 |  
 44845 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44846 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44847 |       typedef typename igfun_t::generic_type        generic_type; 
 44848 |       typedef typename generic_type::scalar_view    scalar_t; 
 44849 |       typedef typename generic_type::vector_view    vector_t; 
 44850 |  
 44851 |       using igfun_t::operator(); 
 44852 |  
 44853 |       ror() 
 44854 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 44855 |         /* 
 44856 |            Overloads: 
 44857 |            0. VT   - vector, N 
 44858 |            1. VTTT - vector, N, r0, r1 
 44859 |         */ 
 44860 |       {} 
 44861 |  
 44862 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44863 |       { 
 44864 |          vector_t vec(parameters[0]); 
 44865 |  
 44866 |          std::size_t n  = 0; 
 44867 |          std::size_t r0 = 0; 
 44868 |          std::size_t r1 = vec.size() - 1; 
 44869 |  
 44870 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 44871 |             return T(0); 
 44872 |  
 44873 |          if ( 
 44874 |               (1 == ps_index) && 
 44875 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 44876 |             ) 
 44877 |             return T(0); 
 44878 |  
 44879 |          const std::size_t dist  = r1 - r0 + 1; 
 44880 |          const std::size_t shift = (dist - (n % dist)) % dist; 
 44881 |  
 44882 |          std::rotate( 
 44883 |             vec.begin() + r0, 
 44884 |             vec.begin() + r0 + shift, 
 44885 |             vec.begin() + r1 + 1); 
 44886 |  
 44887 |          return T(1); 
 44888 |       } 
 44889 |    }; 
 44890 |  
 44891 |    template <typename T> 
 44892 |    class reverse exprtk_final : public exprtk::igeneric_function<T> 
 44893 |    { 
 44894 |    public: 
 44895 |  
 44896 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44897 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44898 |       typedef typename igfun_t::generic_type        generic_type; 
 44899 |       typedef typename generic_type::scalar_view    scalar_t; 
 44900 |       typedef typename generic_type::vector_view    vector_t; 
 44901 |  
 44902 |       using igfun_t::operator(); 
 44903 |  
 44904 |       reverse() 
 44905 |       : exprtk::igeneric_function<T>("V|VTT") 
 44906 |         /* 
 44907 |            Overloads: 
 44908 |            0. V   - vector 
 44909 |            1. VTT - vector, r0, r1 
 44910 |         */ 
 44911 |       {} 
 44912 |  
 44913 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44914 |       { 
 44915 |          vector_t vec(parameters[0]); 
 44916 |  
 44917 |          std::size_t r0 = 0; 
 44918 |          std::size_t r1 = vec.size() - 1; 
 44919 |  
 44920 |          if ( 
 44921 |               (1 == ps_index) && 
 44922 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 44923 |             ) 
 44924 |             return T(0); 
 44925 |  
 44926 |          std::reverse(vec.begin() + r0, vec.begin() + r1 + 1); 
 44927 |  
 44928 |          return T(1); 
 44929 |       } 
 44930 |    }; 
 44931 |  
 44932 |    template <typename T> 
 44933 |    class shift_left exprtk_final : public exprtk::igeneric_function<T> 
 44934 |    { 
 44935 |    public: 
 44936 |  
 44937 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44938 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44939 |       typedef typename igfun_t::generic_type        generic_type; 
 44940 |       typedef typename generic_type::scalar_view    scalar_t; 
 44941 |       typedef typename generic_type::vector_view    vector_t; 
 44942 |  
 44943 |       using igfun_t::operator(); 
 44944 |  
 44945 |       shift_left() 
 44946 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 44947 |         /* 
 44948 |            Overloads: 
 44949 |            0. VT   - vector, N 
 44950 |            1. VTTT - vector, N, r0, r1 
 44951 |         */ 
 44952 |       {} 
 44953 |  
 44954 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 44955 |       { 
 44956 |          vector_t vec(parameters[0]); 
 44957 |  
 44958 |          std::size_t n  = 0; 
 44959 |          std::size_t r0 = 0; 
 44960 |          std::size_t r1 = vec.size() - 1; 
 44961 |  
 44962 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 44963 |             return T(0); 
 44964 |  
 44965 |          if ( 
 44966 |               (1 == ps_index) && 
 44967 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 44968 |             ) 
 44969 |             return T(0); 
 44970 |  
 44971 |          const std::size_t dist = r1 - r0 + 1; 
 44972 |  
 44973 |          if (n > dist) 
 44974 |             return T(0); 
 44975 |  
 44976 |          std::rotate( 
 44977 |             vec.begin() + r0, 
 44978 |             vec.begin() + r0 + n, 
 44979 |             vec.begin() + r1 + 1); 
 44980 |  
 44981 |          for (std::size_t i = r1 - n + 1ULL; i <= r1; ++i) 
 44982 |          { 
 44983 |             vec[i] = T(0); 
 44984 |          } 
 44985 |  
 44986 |          return T(1); 
 44987 |       } 
 44988 |    }; 
 44989 |  
 44990 |    template <typename T> 
 44991 |    class shift_right exprtk_final : public exprtk::igeneric_function<T> 
 44992 |    { 
 44993 |    public: 
 44994 |  
 44995 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 44996 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 44997 |       typedef typename igfun_t::generic_type        generic_type; 
 44998 |       typedef typename generic_type::scalar_view    scalar_t; 
 44999 |       typedef typename generic_type::vector_view    vector_t; 
 45000 |  
 45001 |       using igfun_t::operator(); 
 45002 |  
 45003 |       shift_right() 
 45004 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 45005 |         /* 
 45006 |            Overloads: 
 45007 |            0. VT   - vector, N 
 45008 |            1. VTTT - vector, N, r0, r1 
 45009 |         */ 
 45010 |       {} 
 45011 |  
 45012 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45013 |       { 
 45014 |          vector_t vec(parameters[0]); 
 45015 |  
 45016 |          std::size_t n  = 0; 
 45017 |          std::size_t r0 = 0; 
 45018 |          std::size_t r1 = vec.size() - 1; 
 45019 |  
 45020 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 45021 |             return T(0); 
 45022 |  
 45023 |          if ( 
 45024 |               (1 == ps_index) && 
 45025 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 45026 |             ) 
 45027 |             return T(0); 
 45028 |  
 45029 |          const std::size_t dist = r1 - r0 + 1; 
 45030 |  
 45031 |          if (n > dist) 
 45032 |             return T(0); 
 45033 |  
 45034 |          const std::size_t shift = (dist - (n % dist)) % dist; 
 45035 |  
 45036 |          std::rotate( 
 45037 |             vec.begin() + r0, 
 45038 |             vec.begin() + r0 + shift, 
 45039 |             vec.begin() + r1 + 1); 
 45040 |  
 45041 |          for (std::size_t i = r0; i < r0 + n; ++i) 
 45042 |          { 
 45043 |             vec[i] = T(0); 
 45044 |          } 
 45045 |  
 45046 |          return T(1); 
 45047 |       } 
 45048 |    }; 
 45049 |  
 45050 |    template <typename T> 
 45051 |    class sort exprtk_final : public exprtk::igeneric_function<T> 
 45052 |    { 
 45053 |    public: 
 45054 |  
 45055 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45056 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45057 |       typedef typename igfun_t::generic_type        generic_type; 
 45058 |       typedef typename generic_type::string_view    string_t; 
 45059 |       typedef typename generic_type::vector_view    vector_t; 
 45060 |  
 45061 |       using igfun_t::operator(); 
 45062 |  
 45063 |       sort() 
 45064 |       : exprtk::igeneric_function<T>("V|VTT|VS|VSTT") 
 45065 |         /* 
 45066 |            Overloads: 
 45067 |            0. V    - vector 
 45068 |            1. VTT  - vector, r0, r1 
 45069 |            2. VS   - vector, string 
 45070 |            3. VSTT - vector, string, r0, r1 
 45071 |         */ 
 45072 |       {} 
 45073 |  
 45074 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45075 |       { 
 45076 |          vector_t vec(parameters[0]); 
 45077 |  
 45078 |          std::size_t r0 = 0; 
 45079 |          std::size_t r1 = vec.size() - 1; 
 45080 |  
 45081 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)) 
 45082 |             return T(0); 
 45083 |          if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45084 |             return T(0); 
 45085 |  
 45086 |          bool ascending = true; 
 45087 |  
 45088 |          if ((2 == ps_index) || (3 == ps_index)) 
 45089 |          { 
 45090 |             if (exprtk::details::imatch(to_str(string_t(parameters[1])),"ascending")) 
 45091 |                ascending = true; 
 45092 |             else if (exprtk::details::imatch(to_str(string_t(parameters[1])),"descending")) 
 45093 |                ascending = false; 
 45094 |             else 
 45095 |                return T(0); 
 45096 |          } 
 45097 |  
 45098 |          if (ascending) 
 45099 |             std::sort( 
 45100 |                vec.begin() + r0, 
 45101 |                vec.begin() + r1 + 1, 
 45102 |                std::less<T>()); 
 45103 |          else 
 45104 |             std::sort( 
 45105 |                vec.begin() + r0, 
 45106 |                vec.begin() + r1 + 1, 
 45107 |                std::greater<T>()); 
 45108 |  
 45109 |          return T(1); 
 45110 |       } 
 45111 |    }; 
 45112 |  
 45113 |    template <typename T> 
 45114 |    class nthelement exprtk_final : public exprtk::igeneric_function<T> 
 45115 |    { 
 45116 |    public: 
 45117 |  
 45118 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45119 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45120 |       typedef typename igfun_t::generic_type        generic_type; 
 45121 |       typedef typename generic_type::scalar_view    scalar_t; 
 45122 |       typedef typename generic_type::vector_view    vector_t; 
 45123 |  
 45124 |       using igfun_t::operator(); 
 45125 |  
 45126 |       nthelement() 
 45127 |       : exprtk::igeneric_function<T>("VT|VTTT") 
 45128 |         /* 
 45129 |            Overloads: 
 45130 |            0. VT   - vector, nth-element 
 45131 |            1. VTTT - vector, nth-element, r0, r1 
 45132 |         */ 
 45133 |       {} 
 45134 |  
 45135 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45136 |       { 
 45137 |          vector_t vec(parameters[0]); 
 45138 |  
 45139 |          std::size_t n  = 0; 
 45140 |          std::size_t r0 = 0; 
 45141 |          std::size_t r1 = vec.size() - 1; 
 45142 |  
 45143 |          if (!scalar_t(parameters[1]).to_uint(n)) 
 45144 |             return T(0); 
 45145 |  
 45146 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45147 |          { 
 45148 |             return std::numeric_limits<T>::quiet_NaN(); 
 45149 |          } 
 45150 |  
 45151 |          std::nth_element( 
 45152 |             vec.begin() + r0, 
 45153 |             vec.begin() + r0 + n , 
 45154 |             vec.begin() + r1 + 1); 
 45155 |  
 45156 |          return T(1); 
 45157 |       } 
 45158 |    }; 
 45159 |  
 45160 |    template <typename T> 
 45161 |    class assign exprtk_final : public exprtk::igeneric_function<T> 
 45162 |    { 
 45163 |    public: 
 45164 |  
 45165 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45166 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45167 |       typedef typename igfun_t::generic_type        generic_type; 
 45168 |       typedef typename generic_type::scalar_view    scalar_t; 
 45169 |       typedef typename generic_type::vector_view    vector_t; 
 45170 |  
 45171 |       using igfun_t::operator(); 
 45172 |  
 45173 |       assign() 
 45174 |       : exprtk::igeneric_function<T>("VT|VTTT|VTTTT") 
 45175 |         /* 
 45176 |            Overloads: 
 45177 |            0. VT    - vector, V 
 45178 |            1. VTTT  - vector, V, r0, r1 
 45179 |            2. VTTTT - vector, V, r0, r1, SS 
 45180 |         */ 
 45181 |       {} 
 45182 |  
 45183 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45184 |       { 
 45185 |          vector_t vec(parameters[0]); 
 45186 |  
 45187 |          const T assign_value = scalar_t(parameters[1]); 
 45188 |  
 45189 |          const std::size_t step_size = (2 != ps_index) ? 1 : 
 45190 |                                        static_cast<std::size_t>(scalar_t(parameters.back())()); 
 45191 |  
 45192 |          std::size_t r0 = 0; 
 45193 |          std::size_t r1 = vec.size() - 1; 
 45194 |  
 45195 |          if ( 
 45196 |               ((ps_index == 1) || (ps_index == 2)) && 
 45197 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0) 
 45198 |             ) 
 45199 |          { 
 45200 |             return T(0); 
 45201 |          } 
 45202 |  
 45203 |          for (std::size_t i = r0; i <= r1; i += step_size) 
 45204 |          { 
 45205 |             vec[i] = assign_value; 
 45206 |          } 
 45207 |  
 45208 |          return T(1); 
 45209 |       } 
 45210 |    }; 
 45211 |  
 45212 |    template <typename T> 
 45213 |    class iota exprtk_final : public exprtk::igeneric_function<T> 
 45214 |    { 
 45215 |    public: 
 45216 |  
 45217 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45218 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45219 |       typedef typename igfun_t::generic_type        generic_type; 
 45220 |       typedef typename generic_type::scalar_view    scalar_t; 
 45221 |       typedef typename generic_type::vector_view    vector_t; 
 45222 |  
 45223 |       using igfun_t::operator(); 
 45224 |  
 45225 |       iota() 
 45226 |       : exprtk::igeneric_function<T>("VTT|VT|VTTTT|VTTT") 
 45227 |         /* 
 45228 |            Overloads: 
 45229 |            0. VTT  - vector, SV, SS 
 45230 |            1. VT   - vector, SV, SS (+1) 
 45231 |            2. VTTT - vector, r0, r1, SV, SS 
 45232 |            3. VTT  - vector, r0, r1, SV, SS (+1) 
 45233 |  
 45234 |            Where: 
 45235 |            1. SV - Start value 
 45236 |            2. SS - Step size 
 45237 |         */ 
 45238 |       {} 
 45239 |  
 45240 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45241 |       { 
 45242 |          vector_t vec(parameters[0]); 
 45243 |  
 45244 |          const T start_value = (ps_index <= 1) ? 
 45245 |                                scalar_t(parameters[1]) : 
 45246 |                                scalar_t(parameters[3]) ; 
 45247 |  
 45248 |          const T step_size = ((0 == ps_index) || (2 == ps_index)) ? 
 45249 |                              scalar_t(parameters.back())() : 
 45250 |                              T(1) ; 
 45251 |  
 45252 |          std::size_t r0 = 0; 
 45253 |          std::size_t r1 = vec.size() - 1; 
 45254 |  
 45255 |          if ( 
 45256 |               ((ps_index == 2) || (ps_index == 3)) && 
 45257 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 45258 |             ) 
 45259 |          { 
 45260 |             return T(0); 
 45261 |          } 
 45262 |  
 45263 |          for (std::size_t i = r0; i <= r1; ++i) 
 45264 |          { 
 45265 |             vec[i] = start_value + ((i - r0) * step_size); 
 45266 |          } 
 45267 |  
 45268 |          return T(1); 
 45269 |       } 
 45270 |    }; 
 45271 |  
 45272 |    template <typename T> 
 45273 |    class sumk exprtk_final : public exprtk::igeneric_function<T> 
 45274 |    { 
 45275 |    public: 
 45276 |  
 45277 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45278 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45279 |       typedef typename igfun_t::generic_type        generic_type; 
 45280 |       typedef typename generic_type::scalar_view    scalar_t; 
 45281 |       typedef typename generic_type::vector_view    vector_t; 
 45282 |  
 45283 |       using igfun_t::operator(); 
 45284 |  
 45285 |       sumk() 
 45286 |       : exprtk::igeneric_function<T>("V|VTT|VTTT") 
 45287 |         /* 
 45288 |            Overloads: 
 45289 |            0. V    - vector 
 45290 |            1. VTT  - vector, r0, r1 
 45291 |            2. VTTT - vector, r0, r1, stride 
 45292 |         */ 
 45293 |       {} 
 45294 |  
 45295 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45296 |       { 
 45297 |          const vector_t vec(parameters[0]); 
 45298 |  
 45299 |          const std::size_t stride = (2 != ps_index) ? 1 : 
 45300 |                                     static_cast<std::size_t>(scalar_t(parameters[3])()); 
 45301 |  
 45302 |          std::size_t r0 = 0; 
 45303 |          std::size_t r1 = vec.size() - 1; 
 45304 |  
 45305 |          if ( 
 45306 |               ((1 == ps_index) || (2 == ps_index)) && 
 45307 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 45308 |             ) 
 45309 |          { 
 45310 |             return std::numeric_limits<T>::quiet_NaN(); 
 45311 |          } 
 45312 |  
 45313 |          T result = T(0); 
 45314 |          T error  = T(0); 
 45315 |  
 45316 |          for (std::size_t i = r0; i <= r1; i += stride) 
 45317 |          { 
 45318 |             details::kahan_sum(result, error, vec[i]); 
 45319 |          } 
 45320 |  
 45321 |          return result; 
 45322 |       } 
 45323 |    }; 
 45324 |  
 45325 |    template <typename T> 
 45326 |    class axpy exprtk_final : public exprtk::igeneric_function<T> 
 45327 |    { 
 45328 |    public: 
 45329 |  
 45330 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45331 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45332 |       typedef typename igfun_t::generic_type        generic_type; 
 45333 |       typedef typename generic_type::scalar_view    scalar_t; 
 45334 |       typedef typename generic_type::vector_view    vector_t; 
 45335 |  
 45336 |       using igfun_t::operator(); 
 45337 |  
 45338 |       axpy() 
 45339 |       : exprtk::igeneric_function<T>("TVV|TVVTT") 
 45340 |         /* 
 45341 |            y <- ax + y 
 45342 |            Overloads: 
 45343 |            0. TVV   - a, x(vector), y(vector) 
 45344 |            1. TVVTT - a, x(vector), y(vector), r0, r1 
 45345 |         */ 
 45346 |       {} 
 45347 |  
 45348 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45349 |       { 
 45350 |          const vector_t x(parameters[1]); 
 45351 |                vector_t y(parameters[2]); 
 45352 |  
 45353 |          std::size_t r0 = 0; 
 45354 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45355 |  
 45356 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1)) 
 45357 |             return std::numeric_limits<T>::quiet_NaN(); 
 45358 |          else if (helper::invalid_range(y, r0, r1)) 
 45359 |             return std::numeric_limits<T>::quiet_NaN(); 
 45360 |  
 45361 |          const T a = scalar_t(parameters[0])(); 
 45362 |  
 45363 |          for (std::size_t i = r0; i <= r1; ++i) 
 45364 |          { 
 45365 |             y[i] = (a * x[i]) + y[i]; 
 45366 |          } 
 45367 |  
 45368 |          return T(1); 
 45369 |       } 
 45370 |    }; 
 45371 |  
 45372 |    template <typename T> 
 45373 |    class axpby exprtk_final : public exprtk::igeneric_function<T> 
 45374 |    { 
 45375 |    public: 
 45376 |  
 45377 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45378 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45379 |       typedef typename igfun_t::generic_type        generic_type; 
 45380 |       typedef typename generic_type::scalar_view    scalar_t; 
 45381 |       typedef typename generic_type::vector_view    vector_t; 
 45382 |  
 45383 |       using igfun_t::operator(); 
 45384 |  
 45385 |       axpby() 
 45386 |       : exprtk::igeneric_function<T>("TVTV|TVTVTT") 
 45387 |         /* 
 45388 |            y <- ax + by 
 45389 |            Overloads: 
 45390 |            0. TVTV   - a, x(vector), b, y(vector) 
 45391 |            1. TVTVTT - a, x(vector), b, y(vector), r0, r1 
 45392 |         */ 
 45393 |       {} 
 45394 |  
 45395 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45396 |       { 
 45397 |          const vector_t x(parameters[1]); 
 45398 |                vector_t y(parameters[3]); 
 45399 |  
 45400 |          std::size_t r0 = 0; 
 45401 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45402 |  
 45403 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1)) 
 45404 |             return std::numeric_limits<T>::quiet_NaN(); 
 45405 |          else if (helper::invalid_range(y, r0, r1)) 
 45406 |             return std::numeric_limits<T>::quiet_NaN(); 
 45407 |  
 45408 |          const T a = scalar_t(parameters[0])(); 
 45409 |          const T b = scalar_t(parameters[2])(); 
 45410 |  
 45411 |          for (std::size_t i = r0; i <= r1; ++i) 
 45412 |          { 
 45413 |             y[i] = (a * x[i]) + (b * y[i]); 
 45414 |          } 
 45415 |  
 45416 |          return T(1); 
 45417 |       } 
 45418 |    }; 
 45419 |  
 45420 |    template <typename T> 
 45421 |    class axpyz exprtk_final : public exprtk::igeneric_function<T> 
 45422 |    { 
 45423 |    public: 
 45424 |  
 45425 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45426 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45427 |       typedef typename igfun_t::generic_type        generic_type; 
 45428 |       typedef typename generic_type::scalar_view    scalar_t; 
 45429 |       typedef typename generic_type::vector_view    vector_t; 
 45430 |  
 45431 |       using igfun_t::operator(); 
 45432 |  
 45433 |       axpyz() 
 45434 |       : exprtk::igeneric_function<T>("TVVV|TVVVTT") 
 45435 |         /* 
 45436 |            z <- ax + y 
 45437 |            Overloads: 
 45438 |            0. TVVV   - a, x(vector), y(vector), z(vector) 
 45439 |            1. TVVVTT - a, x(vector), y(vector), z(vector), r0, r1 
 45440 |         */ 
 45441 |       {} 
 45442 |  
 45443 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45444 |       { 
 45445 |          const vector_t x(parameters[1]); 
 45446 |          const vector_t y(parameters[2]); 
 45447 |                vector_t z(parameters[3]); 
 45448 |  
 45449 |          std::size_t r0 = 0; 
 45450 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45451 |  
 45452 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1)) 
 45453 |             return std::numeric_limits<T>::quiet_NaN(); 
 45454 |          else if (helper::invalid_range(y, r0, r1)) 
 45455 |             return std::numeric_limits<T>::quiet_NaN(); 
 45456 |          else if (helper::invalid_range(z, r0, r1)) 
 45457 |             return std::numeric_limits<T>::quiet_NaN(); 
 45458 |  
 45459 |          const T a = scalar_t(parameters[0])(); 
 45460 |  
 45461 |          for (std::size_t i = r0; i <= r1; ++i) 
 45462 |          { 
 45463 |             z[i] = (a * x[i]) + y[i]; 
 45464 |          } 
 45465 |  
 45466 |          return T(1); 
 45467 |       } 
 45468 |    }; 
 45469 |  
 45470 |    template <typename T> 
 45471 |    class axpbyz exprtk_final : public exprtk::igeneric_function<T> 
 45472 |    { 
 45473 |    public: 
 45474 |  
 45475 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45476 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45477 |       typedef typename igfun_t::generic_type        generic_type; 
 45478 |       typedef typename generic_type::scalar_view    scalar_t; 
 45479 |       typedef typename generic_type::vector_view    vector_t; 
 45480 |  
 45481 |       using igfun_t::operator(); 
 45482 |  
 45483 |       axpbyz() 
 45484 |       : exprtk::igeneric_function<T>("TVTVV|TVTVVTT") 
 45485 |         /* 
 45486 |            z <- ax + by 
 45487 |            Overloads: 
 45488 |            0. TVTVV   - a, x(vector), b, y(vector), z(vector) 
 45489 |            1. TVTVVTT - a, x(vector), b, y(vector), z(vector), r0, r1 
 45490 |         */ 
 45491 |       {} 
 45492 |  
 45493 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45494 |       { 
 45495 |          const vector_t x(parameters[1]); 
 45496 |          const vector_t y(parameters[3]); 
 45497 |                vector_t z(parameters[4]); 
 45498 |  
 45499 |          std::size_t r0 = 0; 
 45500 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45501 |  
 45502 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1)) 
 45503 |             return std::numeric_limits<T>::quiet_NaN(); 
 45504 |          else if (helper::invalid_range(y, r0, r1)) 
 45505 |             return std::numeric_limits<T>::quiet_NaN(); 
 45506 |          else if (helper::invalid_range(z, r0, r1)) 
 45507 |             return std::numeric_limits<T>::quiet_NaN(); 
 45508 |  
 45509 |          const T a = scalar_t(parameters[0])(); 
 45510 |          const T b = scalar_t(parameters[2])(); 
 45511 |  
 45512 |          for (std::size_t i = r0; i <= r1; ++i) 
 45513 |          { 
 45514 |             z[i] = (a * x[i]) + (b * y[i]); 
 45515 |          } 
 45516 |  
 45517 |          return T(1); 
 45518 |       } 
 45519 |    }; 
 45520 |  
 45521 |    template <typename T> 
 45522 |    class axpbsy exprtk_final : public exprtk::igeneric_function<T> 
 45523 |    { 
 45524 |    public: 
 45525 |  
 45526 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45527 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45528 |       typedef typename igfun_t::generic_type        generic_type; 
 45529 |       typedef typename generic_type::scalar_view    scalar_t; 
 45530 |       typedef typename generic_type::vector_view    vector_t; 
 45531 |  
 45532 |       using igfun_t::operator(); 
 45533 |  
 45534 |       axpbsy() 
 45535 |       : exprtk::igeneric_function<T>("TVTTV|TVTTVTT") 
 45536 |         /* 
 45537 |            y <- ax + by 
 45538 |            Overloads: 
 45539 |            0. TVTVV   - a, x(vector), b, shift, y(vector), z(vector) 
 45540 |            1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1 
 45541 |         */ 
 45542 |       {} 
 45543 |  
 45544 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45545 |       { 
 45546 |          const vector_t x(parameters[1]); 
 45547 |                vector_t y(parameters[4]); 
 45548 |  
 45549 |          std::size_t r0 = 0; 
 45550 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45551 |  
 45552 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 5, 6, 1)) 
 45553 |             return std::numeric_limits<T>::quiet_NaN(); 
 45554 |          else if (helper::invalid_range(y, r0, r1)) 
 45555 |             return std::numeric_limits<T>::quiet_NaN(); 
 45556 |  
 45557 |          const T a = scalar_t(parameters[0])(); 
 45558 |          const T b = scalar_t(parameters[2])(); 
 45559 |  
 45560 |          const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])()); 
 45561 |  
 45562 |          for (std::size_t i = r0; i <= r1; ++i) 
 45563 |          { 
 45564 |             y[i] = (a * x[i]) + (b * y[i + s]); 
 45565 |          } 
 45566 |  
 45567 |          return T(1); 
 45568 |       } 
 45569 |    }; 
 45570 |  
 45571 |    template <typename T> 
 45572 |    class axpbsyz exprtk_final : public exprtk::igeneric_function<T> 
 45573 |    { 
 45574 |    public: 
 45575 |  
 45576 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45577 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45578 |       typedef typename igfun_t::generic_type        generic_type; 
 45579 |       typedef typename generic_type::scalar_view    scalar_t; 
 45580 |       typedef typename generic_type::vector_view    vector_t; 
 45581 |  
 45582 |       using igfun_t::operator(); 
 45583 |  
 45584 |       axpbsyz() 
 45585 |       : exprtk::igeneric_function<T>("TVTTVV|TVTTVVTT") 
 45586 |         /* 
 45587 |            z <- ax + by 
 45588 |            Overloads: 
 45589 |            0. TVTVV   - a, x(vector), b, shift, y(vector), z(vector) 
 45590 |            1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1 
 45591 |         */ 
 45592 |       {} 
 45593 |  
 45594 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45595 |       { 
 45596 |          const vector_t x(parameters[1]); 
 45597 |          const vector_t y(parameters[4]); 
 45598 |                vector_t z(parameters[5]); 
 45599 |  
 45600 |          std::size_t r0 = 0; 
 45601 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45602 |  
 45603 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 6, 7, 1)) 
 45604 |             return std::numeric_limits<T>::quiet_NaN(); 
 45605 |          else if (helper::invalid_range(y, r0, r1)) 
 45606 |             return std::numeric_limits<T>::quiet_NaN(); 
 45607 |          else if (helper::invalid_range(z, r0, r1)) 
 45608 |             return std::numeric_limits<T>::quiet_NaN(); 
 45609 |  
 45610 |          const T a = scalar_t(parameters[0])(); 
 45611 |          const T b = scalar_t(parameters[2])(); 
 45612 |  
 45613 |          const std::size_t s = static_cast<std::size_t>(scalar_t(parameters[3])()); 
 45614 |  
 45615 |          for (std::size_t i = r0; i <= r1; ++i) 
 45616 |          { 
 45617 |             z[i] = (a * x[i]) + (b * y[i + s]); 
 45618 |          } 
 45619 |  
 45620 |          return T(1); 
 45621 |       } 
 45622 |    }; 
 45623 |  
 45624 |    template <typename T> 
 45625 |    class axpbz exprtk_final : public exprtk::igeneric_function<T> 
 45626 |    { 
 45627 |    public: 
 45628 |  
 45629 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45630 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45631 |       typedef typename igfun_t::generic_type        generic_type; 
 45632 |       typedef typename generic_type::scalar_view    scalar_t; 
 45633 |       typedef typename generic_type::vector_view    vector_t; 
 45634 |  
 45635 |       using igfun_t::operator(); 
 45636 |  
 45637 |       axpbz() 
 45638 |       : exprtk::igeneric_function<T>("TVTV|TVTVTT") 
 45639 |         /* 
 45640 |            z <- ax + b 
 45641 |            Overloads: 
 45642 |            0. TVTV   - a, x(vector), b, z(vector) 
 45643 |            1. TVTVTT - a, x(vector), b, z(vector), r0, r1 
 45644 |         */ 
 45645 |       {} 
 45646 |  
 45647 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45648 |       { 
 45649 |          const vector_t x(parameters[1]); 
 45650 |                vector_t z(parameters[3]); 
 45651 |  
 45652 |          std::size_t r0 = 0; 
 45653 |          std::size_t r1 = x.size() - 1; 
 45654 |  
 45655 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1)) 
 45656 |             return std::numeric_limits<T>::quiet_NaN(); 
 45657 |          else if (helper::invalid_range(z, r0, r1)) 
 45658 |             return std::numeric_limits<T>::quiet_NaN(); 
 45659 |  
 45660 |          const T a = scalar_t(parameters[0])(); 
 45661 |          const T b = scalar_t(parameters[2])(); 
 45662 |  
 45663 |          for (std::size_t i = r0; i <= r1; ++i) 
 45664 |          { 
 45665 |             z[i] = (a * x[i]) + b; 
 45666 |          } 
 45667 |  
 45668 |          return T(1); 
 45669 |       } 
 45670 |    }; 
 45671 |  
 45672 |    template <typename T> 
 45673 |    class diff exprtk_final : public exprtk::igeneric_function<T> 
 45674 |    { 
 45675 |    public: 
 45676 |  
 45677 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45678 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45679 |       typedef typename igfun_t::generic_type        generic_type; 
 45680 |       typedef typename generic_type::scalar_view    scalar_t; 
 45681 |       typedef typename generic_type::vector_view    vector_t; 
 45682 |  
 45683 |       using igfun_t::operator(); 
 45684 |  
 45685 |       diff() 
 45686 |       : exprtk::igeneric_function<T>("VV|VVT") 
 45687 |         /* 
 45688 |            x_(i - stride) - x_i 
 45689 |            Overloads: 
 45690 |            0. VV  - x(vector), y(vector) 
 45691 |            1. VVT - x(vector), y(vector), stride 
 45692 |         */ 
 45693 |       {} 
 45694 |  
 45695 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45696 |       { 
 45697 |          const vector_t x(parameters[0]); 
 45698 |                vector_t y(parameters[1]); 
 45699 |  
 45700 |          const std::size_t r0 = 0; 
 45701 |          const std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45702 |  
 45703 |          const std::size_t stride = (1 != ps_index) ? 1 : 
 45704 |                                     std::min(r1,static_cast<std::size_t>(scalar_t(parameters[2])())); 
 45705 |  
 45706 |          for (std::size_t i = 0; i < stride; ++i) 
 45707 |          { 
 45708 |             y[i] = std::numeric_limits<T>::quiet_NaN(); 
 45709 |          } 
 45710 |  
 45711 |          for (std::size_t i = (r0 + stride); i <= r1; ++i) 
 45712 |          { 
 45713 |             y[i] = x[i] - x[i - stride]; 
 45714 |          } 
 45715 |  
 45716 |          return T(1); 
 45717 |       } 
 45718 |    }; 
 45719 |  
 45720 |    template <typename T> 
 45721 |    class dot exprtk_final : public exprtk::igeneric_function<T> 
 45722 |    { 
 45723 |    public: 
 45724 |  
 45725 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45726 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45727 |       typedef typename igfun_t::generic_type        generic_type; 
 45728 |       typedef typename generic_type::scalar_view    scalar_t; 
 45729 |       typedef typename generic_type::vector_view    vector_t; 
 45730 |  
 45731 |       using igfun_t::operator(); 
 45732 |  
 45733 |       dot() 
 45734 |       : exprtk::igeneric_function<T>("VV|VVTT") 
 45735 |         /* 
 45736 |            Overloads: 
 45737 |            0. VV   - x(vector), y(vector) 
 45738 |            1. VVTT - x(vector), y(vector), r0, r1 
 45739 |         */ 
 45740 |       {} 
 45741 |  
 45742 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45743 |       { 
 45744 |          const vector_t x(parameters[0]); 
 45745 |          const vector_t y(parameters[1]); 
 45746 |  
 45747 |          std::size_t r0 = 0; 
 45748 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45749 |  
 45750 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45751 |             return std::numeric_limits<T>::quiet_NaN(); 
 45752 |          else if (helper::invalid_range(y, r0, r1)) 
 45753 |             return std::numeric_limits<T>::quiet_NaN(); 
 45754 |  
 45755 |          T result = T(0); 
 45756 |  
 45757 |          for (std::size_t i = r0; i <= r1; ++i) 
 45758 |          { 
 45759 |             result += (x[i] * y[i]); 
 45760 |          } 
 45761 |  
 45762 |          return result; 
 45763 |       } 
 45764 |    }; 
 45765 |  
 45766 |    template <typename T> 
 45767 |    class dotk exprtk_final : public exprtk::igeneric_function<T> 
 45768 |    { 
 45769 |    public: 
 45770 |  
 45771 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45772 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45773 |       typedef typename igfun_t::generic_type        generic_type; 
 45774 |       typedef typename generic_type::scalar_view    scalar_t; 
 45775 |       typedef typename generic_type::vector_view    vector_t; 
 45776 |  
 45777 |       using igfun_t::operator(); 
 45778 |  
 45779 |       dotk() 
 45780 |       : exprtk::igeneric_function<T>("VV|VVTT") 
 45781 |         /* 
 45782 |            Overloads: 
 45783 |            0. VV   - x(vector), y(vector) 
 45784 |            1. VVTT - x(vector), y(vector), r0, r1 
 45785 |         */ 
 45786 |       {} 
 45787 |  
 45788 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45789 |       { 
 45790 |          const vector_t x(parameters[0]); 
 45791 |          const vector_t y(parameters[1]); 
 45792 |  
 45793 |          std::size_t r0 = 0; 
 45794 |          std::size_t r1 = std::min(x.size(),y.size()) - 1; 
 45795 |  
 45796 |          if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)) 
 45797 |             return std::numeric_limits<T>::quiet_NaN(); 
 45798 |          else if (helper::invalid_range(y, r0, r1)) 
 45799 |             return std::numeric_limits<T>::quiet_NaN(); 
 45800 |  
 45801 |          T result = T(0); 
 45802 |          T error  = T(0); 
 45803 |  
 45804 |          for (std::size_t i = r0; i <= r1; ++i) 
 45805 |          { 
 45806 |             details::kahan_sum(result, error, (x[i] * y[i])); 
 45807 |          } 
 45808 |  
 45809 |          return result; 
 45810 |       } 
 45811 |    }; 
 45812 |  
 45813 |    template <typename T> 
 45814 |    class threshold_below exprtk_final : public exprtk::igeneric_function<T> 
 45815 |    { 
 45816 |    public: 
 45817 |  
 45818 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45819 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45820 |       typedef typename igfun_t::generic_type        generic_type; 
 45821 |       typedef typename generic_type::scalar_view    scalar_t; 
 45822 |       typedef typename generic_type::vector_view    vector_t; 
 45823 |  
 45824 |       using igfun_t::operator(); 
 45825 |  
 45826 |       threshold_below() 
 45827 |       : exprtk::igeneric_function<T>("VTT|VTTTT") 
 45828 |       /* 
 45829 |          Overloads: 
 45830 |          0. VTT   - vector, TV, SV 
 45831 |          1. VTTTT - vector, r0, r1, TV, SV 
 45832 |  
 45833 |          Where: 
 45834 |          TV - Threshold value 
 45835 |          SV - Snap-to value 
 45836 |       */ 
 45837 |       {} 
 45838 |  
 45839 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45840 |       { 
 45841 |          vector_t vec(parameters[0]); 
 45842 |  
 45843 |          const T threshold_value = (0 == ps_index) ? 
 45844 |                                    scalar_t(parameters[1]) : 
 45845 |                                    scalar_t(parameters[3]) ; 
 45846 |  
 45847 |          const T snap_value = scalar_t(parameters.back()); 
 45848 |  
 45849 |          std::size_t r0 = 0; 
 45850 |          std::size_t r1 = vec.size() - 1; 
 45851 |  
 45852 |          if ( 
 45853 |               (1 == ps_index) && 
 45854 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 45855 |             ) 
 45856 |          { 
 45857 |             return T(0); 
 45858 |          } 
 45859 |  
 45860 |          for (std::size_t i = r0; i <= r1; ++i) 
 45861 |          { 
 45862 |             if (vec[i] < threshold_value) 
 45863 |             { 
 45864 |                vec[i] = snap_value; 
 45865 |             } 
 45866 |          } 
 45867 |  
 45868 |          return T(1); 
 45869 |       } 
 45870 |    }; 
 45871 |  
 45872 |    template <typename T> 
 45873 |    class threshold_above exprtk_final : public exprtk::igeneric_function<T> 
 45874 |    { 
 45875 |    public: 
 45876 |  
 45877 |       typedef typename exprtk::igeneric_function<T> igfun_t; 
 45878 |       typedef typename igfun_t::parameter_list_t    parameter_list_t; 
 45879 |       typedef typename igfun_t::generic_type        generic_type; 
 45880 |       typedef typename generic_type::scalar_view    scalar_t; 
 45881 |       typedef typename generic_type::vector_view    vector_t; 
 45882 |  
 45883 |       using igfun_t::operator(); 
 45884 |  
 45885 |       threshold_above() 
 45886 |       : exprtk::igeneric_function<T>("VTT|VTTTT") 
 45887 |       /* 
 45888 |          Overloads: 
 45889 |          0. VTT   - vector, TV, SV 
 45890 |          1. VTTTT - vector, r0, r1, TV, SV 
 45891 |  
 45892 |          Where: 
 45893 |          TV - Threshold value 
 45894 |          SV - Snap-to value 
 45895 |       */ 
 45896 |       {} 
 45897 |  
 45898 |       inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override 
 45899 |       { 
 45900 |          vector_t vec(parameters[0]); 
 45901 |  
 45902 |          const T threshold_value = (0 == ps_index) ? 
 45903 |                                    scalar_t(parameters[1]) : 
 45904 |                                    scalar_t(parameters[3]) ; 
 45905 |  
 45906 |          const T snap_value = scalar_t(parameters.back()); 
 45907 |  
 45908 |          std::size_t r0 = 0; 
 45909 |          std::size_t r1 = vec.size() - 1; 
 45910 |  
 45911 |          if ( 
 45912 |               (1 == ps_index) && 
 45913 |               !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0) 
 45914 |             ) 
 45915 |          { 
 45916 |             return T(0); 
 45917 |          } 
 45918 |  
 45919 |          for (std::size_t i = r0; i <= r1; ++i) 
 45920 |          { 
 45921 |             if (vec[i] > threshold_value) 
 45922 |             { 
 45923 |                vec[i] = snap_value; 
 45924 |             } 
 45925 |          } 
 45926 |  
 45927 |          return T(1); 
 45928 |       } 
 45929 |    }; 
 45930 |  
 45931 |    template <typename T> 
 45932 |    struct package 
 45933 |    { 
 45934 |       all_true       <T> at; 
 45935 |       all_false      <T> af; 
 45936 |       any_true       <T> nt; 
 45937 |       any_false      <T> nf; 
 45938 |       count          <T>  c; 
 45939 |       copy           <T> cp; 
 45940 |       rol            <T> rl; 
 45941 |       ror            <T> rr; 
 45942 |       reverse        <T> rev; 
 45943 |       shift_left     <T> sl; 
 45944 |       shift_right    <T> sr; 
 45945 |       sort           <T> st; 
 45946 |       nthelement     <T> ne; 
 45947 |       assign         <T> an; 
 45948 |       iota           <T> ia; 
 45949 |       sumk           <T> sk; 
 45950 |       axpy           <T> b1_axpy; 
 45951 |       axpby          <T> b1_axpby; 
 45952 |       axpyz          <T> b1_axpyz; 
 45953 |       axpbyz         <T> b1_axpbyz; 
 45954 |       axpbsy         <T> b1_axpbsy; 
 45955 |       axpbsyz        <T> b1_axpbsyz; 
 45956 |       axpbz          <T> b1_axpbz; 
 45957 |       diff           <T> df; 
 45958 |       dot            <T> dt; 
 45959 |       dotk           <T> dtk; 
 45960 |       threshold_above<T> ta; 
 45961 |       threshold_below<T> tb; 
 45962 |  
 45963 |       bool register_package(exprtk::symbol_table<T>& symtab) 
 45964 |       { 
 45965 |          #define exprtk_register_function(FunctionName, FunctionType)                 \ 
 45966 |          if (!symtab.add_function(FunctionName,FunctionType))                         \ 
 45967 |          {                                                                            \ 
 45968 |             exprtk_debug((                                                            \ 
 45969 |               "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \ 
 45970 |               FunctionName));                                                         \ 
 45971 |             return false;                                                             \ 
 45972 |          }                                                                            \ 
 45973 |  
 45974 |          exprtk_register_function("all_true"        , at        ) 
 45975 |          exprtk_register_function("all_false"       , af        ) 
 45976 |          exprtk_register_function("any_true"        , nt        ) 
 45977 |          exprtk_register_function("any_false"       , nf        ) 
 45978 |          exprtk_register_function("count"           , c         ) 
 45979 |          exprtk_register_function("copy"            , cp        ) 
 45980 |          exprtk_register_function("rotate_left"     , rl        ) 
 45981 |          exprtk_register_function("rol"             , rl        ) 
 45982 |          exprtk_register_function("rotate_right"    , rr        ) 
 45983 |          exprtk_register_function("ror"             , rr        ) 
 45984 |          exprtk_register_function("reverse"         , rev       ) 
 45985 |          exprtk_register_function("shftl"           , sl        ) 
 45986 |          exprtk_register_function("shftr"           , sr        ) 
 45987 |          exprtk_register_function("sort"            , st        ) 
 45988 |          exprtk_register_function("nth_element"     , ne        ) 
 45989 |          exprtk_register_function("assign"          , an        ) 
 45990 |          exprtk_register_function("iota"            , ia        ) 
 45991 |          exprtk_register_function("sumk"            , sk        ) 
 45992 |          exprtk_register_function("axpy"            , b1_axpy   ) 
 45993 |          exprtk_register_function("axpby"           , b1_axpby  ) 
 45994 |          exprtk_register_function("axpyz"           , b1_axpyz  ) 
 45995 |          exprtk_register_function("axpbyz"          , b1_axpbyz ) 
 45996 |          exprtk_register_function("axpbsy"          , b1_axpbsy ) 
 45997 |          exprtk_register_function("axpbsyz"         , b1_axpbsyz) 
 45998 |          exprtk_register_function("axpbz"           , b1_axpbz  ) 
 45999 |          exprtk_register_function("diff"            , df        ) 
 46000 |          exprtk_register_function("dot"             , dt        ) 
 46001 |          exprtk_register_function("dotk"            , dtk       ) 
 46002 |          exprtk_register_function("threshold_above" , ta        ) 
 46003 |          exprtk_register_function("threshold_below" , tb        ) 
 46004 |          #undef exprtk_register_function 
 46005 |  
 46006 |          return true; 
 46007 |       } 
 46008 |    }; 
 46009 |  
 46010 |    } // namespace exprtk::rtl::vecops 
 46011 |    } // namespace exprtk::rtl 
 46012 | }    // namespace exprtk 
 46013 | #endif 
 46014 |  
 46015 | namespace exprtk 
 46016 | { 
 46017 |    namespace information 
 46018 |    { 
 46019 |       using ::exprtk::details::char_cptr; 
 46020 |  
 46021 |       static char_cptr library = "Mathematical Expression Toolkit" 
 46022 |       static char_cptr version = "2.718281828459045235360287471352662497757" 
 46023 |                                  "24709369995957496696762772407663035354759" 
 46024 |                                  "45713821785251664274274663919320030599218" 
 46025 |                                  "17413596629043572900334295260595630738132" 
 46026 |       static char_cptr date    = "20240101" 
 46027 |       static char_cptr min_cpp = "199711L" 
 46028 |  
 46029 |       static inline std::string data() 
 46030 |       { 
 46031 |          static const std::string info_str = std::string(library) + 
 46032 |                                              std::string(" v") + std::string(version) + 
 46033 |                                              std::string(" (") + date + std::string(")") + 
 46034 |                                              std::string(" (") + min_cpp + std::string(")"); 
 46035 |          return info_str; 
 46036 |       } 
 46037 |  
 46038 |    } // namespace information 
 46039 |  
 46040 |    #ifdef exprtk_debug 
 46041 |    #undef exprtk_debug 
 46042 |    #endif 
 46043 |  
 46044 |    #ifdef exprtk_error_location 
 46045 |    #undef exprtk_error_location 
 46046 |    #endif 
 46047 |  
 46048 |    #ifdef exprtk_fallthrough 
 46049 |    #undef exprtk_fallthrough 
 46050 |    #endif 
 46051 |  
 46052 |    #ifdef exprtk_override 
 46053 |    #undef exprtk_override 
 46054 |    #endif 
 46055 |  
 46056 |    #ifdef exprtk_final 
 46057 |    #undef exprtk_final 
 46058 |    #endif 
 46059 |  
 46060 |    #ifdef exprtk_delete 
 46061 |    #undef exprtk_delete 
 46062 |    #endif 
 46063 |  
 46064 | } // namespace exprtk 
 46065 |  
 46066 | #endif